From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
To: linuxppc-dev@lists.ozlabs.org
Cc: Steven Munroe <munroesj@linux.vnet.ibm.com>,
Benjamin Herrenschmidt <benh@kernel.crashing.org>
Subject: [PATCH 6/9] powerpc/64: Clean up ppc64_caches using a struct per cache
Date: Wed, 4 Jan 2017 16:15:32 +1100 [thread overview]
Message-ID: <20170104051535.9454-6-benh@kernel.crashing.org> (raw)
In-Reply-To: <20170104051535.9454-1-benh@kernel.crashing.org>
We have two set of identical struct members for the I and D sides
and mostly identical bunches of code to parse the device-tree to
populate them. Instead make a ppc_cache_info structure with one
copy for I and one for D
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/include/asm/cache.h | 24 ++---
arch/powerpc/include/asm/page_64.h | 4 +-
arch/powerpc/kernel/align.c | 2 +-
arch/powerpc/kernel/asm-offsets.c | 12 +--
arch/powerpc/kernel/setup_64.c | 175 ++++++++++++++++++-------------------
arch/powerpc/kernel/vdso.c | 16 ++--
6 files changed, 112 insertions(+), 121 deletions(-)
diff --git a/arch/powerpc/include/asm/cache.h b/arch/powerpc/include/asm/cache.h
index ceb1244..ceb7376 100644
--- a/arch/powerpc/include/asm/cache.h
+++ b/arch/powerpc/include/asm/cache.h
@@ -27,19 +27,19 @@
#define SMP_CACHE_BYTES L1_CACHE_BYTES
#if defined(__powerpc64__) && !defined(__ASSEMBLY__)
+
+struct ppc_cache_info {
+ u32 size;
+ u32 line_size;
+ u32 block_size; /* L1 only */
+ u32 log_block_size;
+ u32 blocks_per_page;
+ u32 sets;
+};
+
struct ppc64_caches {
- u32 dsize; /* L1 d-cache size */
- u32 dline_size; /* L1 d-cache line size */
- 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;
+ struct ppc_cache_info l1d;
+ struct ppc_cache_info l1i;
};
extern struct ppc64_caches ppc64_caches;
diff --git a/arch/powerpc/include/asm/page_64.h b/arch/powerpc/include/asm/page_64.h
index c50a666..3e83d2a 100644
--- a/arch/powerpc/include/asm/page_64.h
+++ b/arch/powerpc/include/asm/page_64.h
@@ -47,14 +47,14 @@ static inline void clear_page(void *addr)
unsigned long iterations;
unsigned long onex, twox, fourx, eightx;
- iterations = ppc64_caches.dblocks_per_page / 8;
+ iterations = ppc64_caches.l1d.blocks_per_page / 8;
/*
* Some verisions of gcc use multiply instructions to
* calculate the offsets so lets give it a hand to
* do better.
*/
- onex = ppc64_caches.dblock_size;
+ onex = ppc64_caches.l1d.block_size;
twox = onex << 1;
fourx = onex << 2;
eightx = onex << 3;
diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c
index a617751..7806211 100644
--- a/arch/powerpc/kernel/align.c
+++ b/arch/powerpc/kernel/align.c
@@ -204,7 +204,7 @@ static int emulate_dcbz(struct pt_regs *regs, unsigned char __user *addr)
int i, size;
#ifdef __powerpc64__
- size = ppc64_caches.dblock_size;
+ size = ppc64_caches.l1d.block_size;
#else
size = L1_CACHE_BYTES;
#endif
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index e2a881f..100261b 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -160,12 +160,12 @@ int main(void)
DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
#ifdef CONFIG_PPC64
- DEFINE(DCACHEL1BLOCKSIZE, offsetof(struct ppc64_caches, dblock_size));
- DEFINE(DCACHEL1LOGBLOCKSIZE, offsetof(struct ppc64_caches, log_dblock_size));
- DEFINE(DCACHEL1BLOCKSPERPAGE, offsetof(struct ppc64_caches, dblocks_per_page));
- DEFINE(ICACHEL1BLOCKSIZE, offsetof(struct ppc64_caches, iblock_size));
- DEFINE(ICACHEL1LOGBLOCKSIZE, offsetof(struct ppc64_caches, log_iblock_size));
- DEFINE(ICACHEL1BLOCKSPERPAGE, offsetof(struct ppc64_caches, iblocks_per_page));
+ DEFINE(DCACHEL1BLOCKSIZE, offsetof(struct ppc64_caches, l1d.block_size));
+ DEFINE(DCACHEL1LOGBLOCKSIZE, offsetof(struct ppc64_caches, l1d.log_block_size));
+ DEFINE(DCACHEL1BLOCKSPERPAGE, offsetof(struct ppc64_caches, l1d.blocks_per_page));
+ DEFINE(ICACHEL1BLOCKSIZE, offsetof(struct ppc64_caches, l1i.block_size));
+ DEFINE(ICACHEL1LOGBLOCKSIZE, offsetof(struct ppc64_caches, l1i.log_block_size));
+ DEFINE(ICACHEL1BLOCKSPERPAGE, offsetof(struct ppc64_caches, l1i.blocks_per_page));
/* paca */
DEFINE(PACA_SIZE, sizeof(struct paca_struct));
DEFINE(PACAPACAINDEX, offsetof(struct paca_struct, paca_index));
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index d36b6f4..e2946a7 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -78,10 +78,14 @@ int spinning_secondaries;
u64 ppc64_pft_size;
struct ppc64_caches ppc64_caches = {
- .dblock_size = 0x40,
- .log_dblock_size = 6,
- .iblock_size = 0x40,
- .log_iblock_size = 6
+ .l1d = {
+ .block_size = 0x40,
+ .log_block_size = 6,
+ },
+ .l1i = {
+ .block_size = 0x40,
+ .log_block_size = 6
+ },
};
EXPORT_SYMBOL_GPL(ppc64_caches);
@@ -389,104 +393,91 @@ void smp_release_cpus(void)
* cache informations about the CPU that will be used by cache flush
* routines and/or provided to userland
*/
+
+static bool __init parse_cache_info(struct device_node *np,
+ bool icache,
+ struct ppc_cache_info *info)
+{
+ static const char *ipropnames[] __initdata = {
+ "i-cache-size",
+ "i-cache-sets",
+ "i-cache-block-size",
+ "i-cache-line-size",
+ };
+ static const char *dpropnames[] __initdata = {
+ "d-cache-size",
+ "d-cache-sets",
+ "d-cache-block-size",
+ "d-cache-line-size",
+ };
+ const char **propnames = icache ? ipropnames : dpropnames;
+ const __be32 *sizep, *lsizep, *bsizep, *setsp;
+ u32 size, lsize, bsize, sets;
+ bool success = true;
+
+ size = 0;
+ sets = -1u;
+ lsize = bsize = cur_cpu_spec->dcache_bsize;
+ sizep = of_get_property(np, propnames[0], NULL);
+ if (sizep != NULL)
+ size = be32_to_cpu(*sizep);
+ setsp = of_get_property(np, propnames[1], NULL);
+ if (setsp != NULL)
+ sets = be32_to_cpu(*setsp);
+ bsizep = of_get_property(np, propnames[2], NULL);
+ lsizep = of_get_property(np, propnames[3], NULL);
+ if (bsizep == NULL)
+ bsizep = lsizep;
+ if (lsizep != NULL)
+ lsize = be32_to_cpu(*lsizep);
+ if (bsizep != NULL)
+ bsize = be32_to_cpu(*bsizep);
+ if (sizep == NULL || bsizep == NULL || lsizep == NULL)
+ success = false;
+
+ /* 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;
+
+ info->size = size;
+ info->sets = sets;
+ info->line_size = lsize;
+ info->block_size = bsize;
+ info->log_block_size = __ilog2(bsize);
+ info->blocks_per_page = PAGE_SIZE / bsize;
+
+ return success;
+}
+
void __init initialize_cache_info(void)
{
struct device_node *np;
- unsigned long num_cpus = 0;
DBG(" -> initialize_cache_info()\n");
- for_each_node_by_type(np, "cpu") {
- num_cpus += 1;
+ np = of_find_node_by_type(NULL, "cpu");
- /*
- * We're assuming *all* of the CPUs have the same
- * d-cache and i-cache sizes... -Peter
- */
- if (num_cpus == 1) {
- 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",
- NULL);
- if (bsizep == NULL)
- bsizep = lsizep;
- if (lsizep != NULL)
- lsize = be32_to_cpu(*lsizep);
- if (bsizep != NULL)
- bsize = be32_to_cpu(*bsizep);
- if (sizep == NULL || bsizep == NULL || lsizep == NULL)
- DBG("Argh, can't find dcache properties ! "
- "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",
- NULL);
- if (bsizep == NULL)
- bsizep = lsizep;
- if (lsizep != NULL)
- lsize = be32_to_cpu(*lsizep);
- if (bsizep != NULL)
- bsize = be32_to_cpu(*bsizep);
- if (sizep == NULL || bsizep == NULL || lsizep == NULL)
- DBG("Argh, can't find icache properties ! "
- "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);
- ppc64_caches.iblocks_per_page = PAGE_SIZE / bsize;
- }
+ /*
+ * We're assuming *all* of the CPUs have the same
+ * d-cache and i-cache sizes... -Peter
+ */
+ if (np) {
+ if (!parse_cache_info(np, false, &ppc64_caches.l1d))
+ DBG("Argh, can't find dcache properties !\n");
+
+ if (!parse_cache_info(np, true, &ppc64_caches.l1i))
+ DBG("Argh, can't find icache properties !\n");
}
/* For use by binfmt_elf */
- dcache_bsize = ppc64_caches.dblock_size;
- icache_bsize = ppc64_caches.iblock_size;
+ dcache_bsize = ppc64_caches.l1d.block_size;
+ icache_bsize = ppc64_caches.l1i.block_size;
DBG(" <- initialize_cache_info()\n");
}
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index 9c0a857..22b01a3 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -736,14 +736,14 @@ static int __init vdso_init(void)
if (firmware_has_feature(FW_FEATURE_LPAR))
vdso_data->platform |= 1;
vdso_data->physicalMemorySize = memblock_phys_mem_size();
- vdso_data->dcache_size = ppc64_caches.dsize;
- vdso_data->dcache_line_size = ppc64_caches.dline_size;
- vdso_data->icache_size = ppc64_caches.isize;
- vdso_data->icache_line_size = ppc64_caches.iline_size;
- vdso_data->dcache_block_size = ppc64_caches.dblock_size;
- vdso_data->icache_block_size = ppc64_caches.iblock_size;
- vdso_data->dcache_log_block_size = ppc64_caches.log_dblock_size;
- vdso_data->icache_log_block_size = ppc64_caches.log_iblock_size;
+ vdso_data->dcache_size = ppc64_caches.l1d.size;
+ vdso_data->dcache_line_size = ppc64_caches.l1d.line_size;
+ vdso_data->icache_size = ppc64_caches.l1i.size;
+ vdso_data->icache_line_size = ppc64_caches.l1i.line_size;
+ vdso_data->dcache_block_size = ppc64_caches.l1d.block_size;
+ vdso_data->icache_block_size = ppc64_caches.l1i.block_size;
+ vdso_data->dcache_log_block_size = ppc64_caches.l1d.log_block_size;
+ vdso_data->icache_log_block_size = ppc64_caches.l1i.log_block_size;
/*
* Calculate the size of the 64 bits vDSO
--
2.9.3
next prev parent reply other threads:[~2017-01-04 5:17 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-01-04 5:15 [PATCH 1/9] powerpc: Move ARCH_DLINFO out of uapi Benjamin Herrenschmidt
2017-01-04 5:15 ` [PATCH 2/9] powerpc: Move {d, i, u}cache_bsize definitions to a common place Benjamin Herrenschmidt
2017-01-04 5:15 ` [PATCH 3/9] powerpc: Remove obsolete comment about patching instructions Benjamin Herrenschmidt
2017-01-04 5:15 ` [PATCH 4/9] powerpc/64: Fix naming of cache block vs. cache line Benjamin Herrenschmidt
2017-01-04 5:15 ` [PATCH 5/9] powerpc/64: Retrieve number of L1 cache sets from device-tree Benjamin Herrenschmidt
2017-01-04 5:15 ` Benjamin Herrenschmidt [this message]
2017-01-04 5:15 ` [PATCH 7/9] powerpc/64: Add L2 and L3 cache shape info Benjamin Herrenschmidt
2017-01-04 5:15 ` [PATCH 8/9] powerpc/64: Hard code cache geometry on POWER8 Benjamin Herrenschmidt
2017-01-04 5:15 ` [PATCH 9/9] powerpc: A new cache shape aux vectors Benjamin Herrenschmidt
2017-01-04 13:04 ` Tulio Magno Quites Machado Filho
2017-01-04 22:03 ` Benjamin Herrenschmidt
2017-01-05 11:15 ` Tulio Magno Quites Machado Filho
2017-01-10 13:15 ` Segher Boessenkool
2017-01-10 15:18 ` Benjamin Herrenschmidt
2017-01-08 23:31 [PATCH 1/9] powerpc: Move ARCH_DLINFO out of uapi Benjamin Herrenschmidt
2017-01-08 23:31 ` [PATCH 6/9] powerpc/64: Clean up ppc64_caches using a struct per cache Benjamin Herrenschmidt
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170104051535.9454-6-benh@kernel.crashing.org \
--to=benh@kernel.crashing.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=munroesj@linux.vnet.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).