blob: 047003008bc3b7e08d964075fcb2095d6958a09e [file] [log] [blame]
David 'Digit' Turner8848f632014-01-16 18:10:21 +01001#include "qemu-common.h"
David 'Digit' Turner37dc41a2013-12-14 14:45:51 +01002#include "qemu/cache-utils.h"
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -07003
4#if defined(_ARCH_PPC)
5struct qemu_cache_conf qemu_cache_conf = {
6 .dcache_bsize = 16,
7 .icache_bsize = 16
8};
9
10#if defined _AIX
11#include <sys/systemcfg.h>
12
David 'Digit' Turner8848f632014-01-16 18:10:21 +010013void qemu_cache_utils_init(void)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070014{
15 qemu_cache_conf.icache_bsize = _system_configuration.icache_line;
16 qemu_cache_conf.dcache_bsize = _system_configuration.dcache_line;
17}
18
19#elif defined __linux__
David 'Digit' Turner8848f632014-01-16 18:10:21 +010020#include "qemu/osdep.h"
21#include "elf.h"
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070022
David 'Digit' Turner8848f632014-01-16 18:10:21 +010023void qemu_cache_utils_init(void)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070024{
David 'Digit' Turner8848f632014-01-16 18:10:21 +010025 unsigned long dsize = qemu_getauxval(AT_DCACHEBSIZE);
26 unsigned long isize = qemu_getauxval(AT_ICACHEBSIZE);
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070027
David 'Digit' Turner8848f632014-01-16 18:10:21 +010028 if (dsize == 0 || isize == 0) {
29 if (dsize == 0) {
30 fprintf(stderr, "getauxval AT_DCACHEBSIZE failed\n");
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070031 }
David 'Digit' Turner8848f632014-01-16 18:10:21 +010032 if (isize == 0) {
33 fprintf(stderr, "getauxval AT_ICACHEBSIZE failed\n");
34 }
35 exit(1);
36
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070037 }
David 'Digit' Turner8848f632014-01-16 18:10:21 +010038 qemu_cache_conf.dcache_bsize = dsize;
39 qemu_cache_conf.icache_bsize = isize;
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070040}
41
42#elif defined __APPLE__
43#include <stdio.h>
44#include <sys/types.h>
45#include <sys/sysctl.h>
46
David 'Digit' Turner8848f632014-01-16 18:10:21 +010047void qemu_cache_utils_init(void)
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070048{
49 size_t len;
50 unsigned cacheline;
51 int name[2] = { CTL_HW, HW_CACHELINE };
52
53 len = sizeof(cacheline);
54 if (sysctl(name, 2, &cacheline, &len, NULL, 0)) {
55 perror("sysctl CTL_HW HW_CACHELINE failed");
56 } else {
57 qemu_cache_conf.dcache_bsize = cacheline;
58 qemu_cache_conf.icache_bsize = cacheline;
59 }
60}
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070061
David 'Digit' Turner8848f632014-01-16 18:10:21 +010062#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
David Turner3b290c32010-09-09 23:49:44 +020063#include <errno.h>
David 'Digit' Turner92518662010-05-10 23:26:01 -070064#include <stdio.h>
David Turner3b290c32010-09-09 23:49:44 +020065#include <stdlib.h>
66#include <string.h>
David 'Digit' Turner92518662010-05-10 23:26:01 -070067#include <sys/types.h>
68#include <sys/sysctl.h>
69
David 'Digit' Turner8848f632014-01-16 18:10:21 +010070void qemu_cache_utils_init(void)
David 'Digit' Turner92518662010-05-10 23:26:01 -070071{
72 size_t len = 4;
73 unsigned cacheline;
74
75 if (sysctlbyname ("machdep.cacheline_size", &cacheline, &len, NULL, 0)) {
76 fprintf(stderr, "sysctlbyname machdep.cacheline_size failed: %s\n",
77 strerror(errno));
78 exit(1);
79 }
80
81 qemu_cache_conf.dcache_bsize = cacheline;
82 qemu_cache_conf.icache_bsize = cacheline;
83}
David 'Digit' Turner5d8f37a2009-09-14 14:32:27 -070084#endif
85
86#endif /* _ARCH_PPC */