powerpc/64: Clean up ppc64_caches using a struct per cache
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> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
This commit is contained in:
parent
5d451a87e5
commit
e2827fe5c1
|
@ -30,19 +30,19 @@
|
|||
#define IFETCH_ALIGN_BYTES (1 << IFETCH_ALIGN_SHIFT)
|
||||
|
||||
#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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -163,12 +163,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));
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
@ -397,105 +401,98 @@ void smp_release_cpus(void)
|
|||
* cache informations about the CPU that will be used by cache flush
|
||||
* routines and/or provided to userland
|
||||
*/
|
||||
|
||||
static void init_cache_info(struct ppc_cache_info *info, u32 size, u32 lsize,
|
||||
u32 bsize, u32 sets)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
init_cache_info(info, size, lsize, bsize, sets);
|
||||
|
||||
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;
|
||||
/*
|
||||
* 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");
|
||||
|
||||
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;
|
||||
}
|
||||
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");
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue