powerpc/64: Retrieve number of L1 cache sets from device-tree
authorBenjamin Herrenschmidt <benh@kernel.crashing.org>
Sun, 8 Jan 2017 23:31:46 +0000 (17:31 -0600)
committerMichael Ellerman <mpe@ellerman.id.au>
Mon, 6 Feb 2017 08:46:04 +0000 (19:46 +1100)
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>
arch/powerpc/include/asm/cache.h
arch/powerpc/kernel/setup_64.c

index 25ee433a8261b9a466fbf2dc79422069888c2ec7..1fa364340146d483993da850dcd80b17049b0eda 100644 (file)
@@ -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;
index 08cccb2501e7129b5d95b504c79e44d3b3d9f2db..75c9a8641ba17557b6199192e52db29d3a8629e0 100644 (file)
@@ -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);