summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>2017-01-09 00:31:46 +0100
committerMichael Ellerman <mpe@ellerman.id.au>2017-02-06 09:46:04 +0100
commit5d451a87e5ebbde18c2b48284778f29d308816c2 (patch)
tree022254fe5c10af8fd5d997df53ce5b7fe15def6e
parentpowerpc/64: Fix naming of cache block vs. cache line (diff)
downloadlinux-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.h2
-rw-r--r--arch/powerpc/kernel/setup_64.c28
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);