diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2017-01-09 00:31:46 +0100 |
---|---|---|
committer | Michael Ellerman <mpe@ellerman.id.au> | 2017-02-06 09:46:04 +0100 |
commit | 5d451a87e5ebbde18c2b48284778f29d308816c2 (patch) | |
tree | 022254fe5c10af8fd5d997df53ce5b7fe15def6e | |
parent | powerpc/64: Fix naming of cache block vs. cache line (diff) | |
download | linux-5d451a87e5ebbde18c2b48284778f29d308816c2.tar.xz linux-5d451a87e5ebbde18c2b48284778f29d308816c2.zip |
powerpc/64: Retrieve number of L1 cache sets from device-tree
It will be used to calculate the associativity
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
-rw-r--r-- | arch/powerpc/include/asm/cache.h | 2 | ||||
-rw-r--r-- | arch/powerpc/kernel/setup_64.c | 28 |
2 files changed, 28 insertions, 2 deletions
diff --git a/arch/powerpc/include/asm/cache.h b/arch/powerpc/include/asm/cache.h index 25ee433a8261..1fa364340146 100644 --- a/arch/powerpc/include/asm/cache.h +++ b/arch/powerpc/include/asm/cache.h @@ -36,11 +36,13 @@ struct ppc64_caches { u32 dblock_size; /* L1 d-cache block size */ u32 log_dblock_size; u32 dblocks_per_page; + u32 dsets; u32 isize; /* L1 i-cache size */ u32 iline_size; /* L1 d-cache line size */ u32 iblock_size; /* L1 i-cache block size */ u32 log_iblock_size; u32 iblocks_per_page; + u32 isets; }; extern struct ppc64_caches ppc64_caches; diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index 08cccb2501e7..75c9a8641ba1 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -412,14 +412,18 @@ void __init initialize_cache_info(void) * d-cache and i-cache sizes... -Peter */ if (num_cpus == 1) { - const __be32 *sizep, *lsizep, *bsizep; - u32 size, lsize, bsize; + const __be32 *sizep, *lsizep, *bsizep, *setsp; + u32 size, lsize, bsize, sets; size = 0; + sets = -1u; lsize = bsize = cur_cpu_spec->dcache_bsize; sizep = of_get_property(np, "d-cache-size", NULL); if (sizep != NULL) size = be32_to_cpu(*sizep); + setsp = of_get_property(np, "d-cache-sets", NULL); + if (setsp != NULL) + sets = be32_to_cpu(*setsp); bsizep = of_get_property(np, "d-cache-block-size", NULL); lsizep = of_get_property(np, "d-cache-line-size", @@ -435,17 +439,32 @@ void __init initialize_cache_info(void) "sizep: %p, bsizep: %p, lsizep: %p\n", sizep, bsizep, lsizep); + /* + * OF is weird .. it represents fully associative caches + * as "1 way" which doesn't make much sense and doesn't + * leave room for direct mapped. We'll assume that 0 + * in OF means direct mapped for that reason. + */ + if (sets == 1) + sets = 0; + else if (sets == 0) + sets = 1; ppc64_caches.dsize = size; + ppc64_caches.dsets = sets; ppc64_caches.dline_size = lsize; ppc64_caches.dblock_size = bsize; ppc64_caches.log_dblock_size = __ilog2(bsize); ppc64_caches.dblocks_per_page = PAGE_SIZE / bsize; size = 0; + sets = -1u; lsize = bsize = cur_cpu_spec->icache_bsize; sizep = of_get_property(np, "i-cache-size", NULL); if (sizep != NULL) size = be32_to_cpu(*sizep); + setsp = of_get_property(np, "i-cache-sets", NULL); + if (setsp != NULL) + sets = be32_to_cpu(*setsp); bsizep = of_get_property(np, "i-cache-block-size", NULL); lsizep = of_get_property(np, "i-cache-line-size", @@ -461,7 +480,12 @@ void __init initialize_cache_info(void) "sizep: %p, bsizep: %p, lsizep: %p\n", sizep, bsizep, lsizep); + if (sets == 1) + sets = 0; + else if (sets == 0) + sets = 1; ppc64_caches.isize = size; + ppc64_caches.isets = sets; ppc64_caches.iline_size = lsize; ppc64_caches.iblock_size = bsize; ppc64_caches.log_iblock_size = __ilog2(bsize); |