Index: sys/arch/sparc64/sparc64/cpu.c =================================================================== RCS file: /cvsroot/src/sys/arch/sparc64/sparc64/cpu.c,v retrieving revision 1.121 diff -u -r1.121 cpu.c --- sys/arch/sparc64/sparc64/cpu.c 5 Dec 2014 11:34:00 -0000 1.121 +++ sys/arch/sparc64/sparc64/cpu.c 21 Jan 2015 21:28:29 -0000 @@ -75,6 +75,7 @@ #include #include +#include #define SUN4V_MONDO_QUEUE_SIZE 32 #define SUN4V_QUEUE_ENTRY_SIZE 64 @@ -153,6 +154,140 @@ return id; } +static int +cpu_cache_info_sun4v(const char *type, int level, const char *prop) +{ + int idx = 0; + uint64_t val = 0;; + idx = mdesc_find_node_by_idx(idx, "cache"); + while (idx != -1 && val == 0) { + const char *p; + size_t len = 0; + p = mdesc_get_prop_data(idx, "type", &len); + if (p == NULL) + panic("No type found\n"); + if (len == 0) + panic("Len is zero"); + if (type == NULL || strcmp(p, type) == 0) { + uint64_t l; + l = mdesc_get_prop_val(idx, "level"); + if (l == level) + val = mdesc_get_prop_val(idx, prop); + } + if (val == 0) + idx = mdesc_next_node(idx); + } + return val; +} + +static int +cpu_icache_size(int node) +{ + if (CPU_ISSUN4V) + return cpu_cache_info_sun4v("instn", 1, "size"); + else + return prom_getpropint(node, "icache-size", 0); +} + +static int +cpu_icache_line_size(int node) +{ + if (CPU_ISSUN4V) + return cpu_cache_info_sun4v("instn", 1, "line-size"); + else + return prom_getpropint(node, "icache-line-size", 0); +} + +static int +cpu_icache_nlines(int node) +{ + if (CPU_ISSUN4V) + return 0; + else + return prom_getpropint(node, "icache-nlines", 64); +} + +static int +cpu_icache_associativity(int node) +{ + if (CPU_ISSUN4V) + return cpu_cache_info_sun4v("instn", 1, "associativity"); + else + return prom_getpropint(node, "icache-associativity", 1); +} + +static int +cpu_dcache_size(int node) +{ + if (CPU_ISSUN4V) + return cpu_cache_info_sun4v("data", 1, "size"); + else + return prom_getpropint(node, "dcache-size", 0); +} + +static int +cpu_dcache_line_size(int node) +{ + if (CPU_ISSUN4V) + return cpu_cache_info_sun4v("data", 1, "line-size"); + else + return prom_getpropint(node, "dcache-line-size", 0); +} + +static int +cpu_dcache_nlines(int node) +{ + if (CPU_ISSUN4V) + return 0; + else + return prom_getpropint(node, "dcache-nlines", 128); +} + +static int +cpu_dcache_associativity(int node) +{ + if (CPU_ISSUN4V) + return cpu_cache_info_sun4v("data", 1, "associativity"); + else + return prom_getpropint(node, "dcache-associativity", 1); +} + +static int +cpu_ecache_size(int node) +{ + if (CPU_ISSUN4V) + return cpu_cache_info_sun4v(NULL, 2, "size"); + else + return prom_getpropint(node, "ecache-size", 0); +} + +static int +cpu_ecache_line_size(int node) +{ + if (CPU_ISSUN4V) + return cpu_cache_info_sun4v(NULL, 2, "line-size"); + else + return prom_getpropint(node, "ecache-line-size", 0); +} + +static int +cpu_ecache_nlines(int node) +{ + if (CPU_ISSUN4V) + return 0; + else + return prom_getpropint(node, "ecache-nlines", 32768); +} + +static int +cpu_ecache_associativity(int node) +{ + if (CPU_ISSUN4V) + return cpu_cache_info_sun4v(NULL, 2, "associativity"); + else + return prom_getpropint(node, "ecache-associativity", 1); +} + struct cpu_info * alloc_cpuinfo(u_int cpu_node) { @@ -352,13 +487,12 @@ } aprint_normal_dev(dev, ""); - /* XXX sun4v mising cache info printout */ bigcache = 0; - icachesize = prom_getpropint(node, "icache-size", 0); + icachesize = cpu_icache_size(node); if (icachesize > icache_size) icache_size = icachesize; - linesize = l = prom_getpropint(node, "icache-line-size", 0); + linesize = l = cpu_icache_line_size(node); if (linesize > icache_line_size) icache_line_size = linesize; @@ -369,11 +503,9 @@ totalsize = icachesize; if (totalsize == 0) totalsize = l * - prom_getpropint(node, "icache-nlines", 64) * - prom_getpropint(node, "icache-associativity", 1); + cpu_icache_nlines(node) * cpu_icache_associativity(node); - cachesize = totalsize / - prom_getpropint(node, "icache-associativity", 1); + cachesize = totalsize / cpu_icache_associativity(node); bigcache = cachesize; sep = ""; @@ -384,10 +516,10 @@ sep = ", "; } - dcachesize = prom_getpropint(node, "dcache-size", 0); + dcachesize = cpu_dcache_size(node); if (dcachesize > dcache_size) dcache_size = dcachesize; - linesize = l = prom_getpropint(node, "dcache-line-size", 0); + linesize = l = cpu_dcache_line_size(node); if (linesize > dcache_line_size) dcache_line_size = linesize; @@ -398,11 +530,9 @@ totalsize = dcachesize; if (totalsize == 0) totalsize = l * - prom_getpropint(node, "dcache-nlines", 128) * - prom_getpropint(node, "dcache-associativity", 1); + cpu_dcache_nlines(node) * cpu_dcache_associativity(node); - cachesize = totalsize / - prom_getpropint(node, "dcache-associativity", 1); + cachesize = totalsize / cpu_dcache_associativity(node); if (cachesize > bigcache) bigcache = cachesize; @@ -413,20 +543,17 @@ sep = ", "; } - linesize = l = - prom_getpropint(node, "ecache-line-size", 0); + linesize = l = cpu_ecache_line_size(node); for (i = 0; (1 << i) < l && l; i++) /* void */; if ((1 << i) != l && l) panic("bad ecache line size %d", l); - totalsize = prom_getpropint(node, "ecache-size", 0); + totalsize = cpu_ecache_size(node); if (totalsize == 0) totalsize = l * - prom_getpropint(node, "ecache-nlines", 32768) * - prom_getpropint(node, "ecache-associativity", 1); + cpu_ecache_nlines(node) * cpu_ecache_associativity(node); - cachesize = totalsize / - prom_getpropint(node, "ecache-associativity", 1); + cachesize = totalsize / cpu_ecache_associativity(node); if (cachesize > bigcache) bigcache = cachesize;