mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-09 07:23:14 +00:00
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)
|
#define IFETCH_ALIGN_BYTES (1 << IFETCH_ALIGN_SHIFT)
|
||||||
|
|
||||||
#if defined(__powerpc64__) && !defined(__ASSEMBLY__)
|
#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 {
|
struct ppc64_caches {
|
||||||
u32 dsize; /* L1 d-cache size */
|
struct ppc_cache_info l1d;
|
||||||
u32 dline_size; /* L1 d-cache line size */
|
struct ppc_cache_info l1i;
|
||||||
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;
|
extern struct ppc64_caches ppc64_caches;
|
||||||
|
@ -47,14 +47,14 @@ static inline void clear_page(void *addr)
|
|||||||
unsigned long iterations;
|
unsigned long iterations;
|
||||||
unsigned long onex, twox, fourx, eightx;
|
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
|
* Some verisions of gcc use multiply instructions to
|
||||||
* calculate the offsets so lets give it a hand to
|
* calculate the offsets so lets give it a hand to
|
||||||
* do better.
|
* do better.
|
||||||
*/
|
*/
|
||||||
onex = ppc64_caches.dblock_size;
|
onex = ppc64_caches.l1d.block_size;
|
||||||
twox = onex << 1;
|
twox = onex << 1;
|
||||||
fourx = onex << 2;
|
fourx = onex << 2;
|
||||||
eightx = onex << 3;
|
eightx = onex << 3;
|
||||||
|
@ -204,7 +204,7 @@ static int emulate_dcbz(struct pt_regs *regs, unsigned char __user *addr)
|
|||||||
int i, size;
|
int i, size;
|
||||||
|
|
||||||
#ifdef __powerpc64__
|
#ifdef __powerpc64__
|
||||||
size = ppc64_caches.dblock_size;
|
size = ppc64_caches.l1d.block_size;
|
||||||
#else
|
#else
|
||||||
size = L1_CACHE_BYTES;
|
size = L1_CACHE_BYTES;
|
||||||
#endif
|
#endif
|
||||||
|
@ -163,12 +163,12 @@ int main(void)
|
|||||||
DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
|
DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
|
||||||
|
|
||||||
#ifdef CONFIG_PPC64
|
#ifdef CONFIG_PPC64
|
||||||
DEFINE(DCACHEL1BLOCKSIZE, offsetof(struct ppc64_caches, dblock_size));
|
DEFINE(DCACHEL1BLOCKSIZE, offsetof(struct ppc64_caches, l1d.block_size));
|
||||||
DEFINE(DCACHEL1LOGBLOCKSIZE, offsetof(struct ppc64_caches, log_dblock_size));
|
DEFINE(DCACHEL1LOGBLOCKSIZE, offsetof(struct ppc64_caches, l1d.log_block_size));
|
||||||
DEFINE(DCACHEL1BLOCKSPERPAGE, offsetof(struct ppc64_caches, dblocks_per_page));
|
DEFINE(DCACHEL1BLOCKSPERPAGE, offsetof(struct ppc64_caches, l1d.blocks_per_page));
|
||||||
DEFINE(ICACHEL1BLOCKSIZE, offsetof(struct ppc64_caches, iblock_size));
|
DEFINE(ICACHEL1BLOCKSIZE, offsetof(struct ppc64_caches, l1i.block_size));
|
||||||
DEFINE(ICACHEL1LOGBLOCKSIZE, offsetof(struct ppc64_caches, log_iblock_size));
|
DEFINE(ICACHEL1LOGBLOCKSIZE, offsetof(struct ppc64_caches, l1i.log_block_size));
|
||||||
DEFINE(ICACHEL1BLOCKSPERPAGE, offsetof(struct ppc64_caches, iblocks_per_page));
|
DEFINE(ICACHEL1BLOCKSPERPAGE, offsetof(struct ppc64_caches, l1i.blocks_per_page));
|
||||||
/* paca */
|
/* paca */
|
||||||
DEFINE(PACA_SIZE, sizeof(struct paca_struct));
|
DEFINE(PACA_SIZE, sizeof(struct paca_struct));
|
||||||
DEFINE(PACAPACAINDEX, offsetof(struct paca_struct, paca_index));
|
DEFINE(PACAPACAINDEX, offsetof(struct paca_struct, paca_index));
|
||||||
|
@ -78,10 +78,14 @@ int spinning_secondaries;
|
|||||||
u64 ppc64_pft_size;
|
u64 ppc64_pft_size;
|
||||||
|
|
||||||
struct ppc64_caches ppc64_caches = {
|
struct ppc64_caches ppc64_caches = {
|
||||||
.dblock_size = 0x40,
|
.l1d = {
|
||||||
.log_dblock_size = 6,
|
.block_size = 0x40,
|
||||||
.iblock_size = 0x40,
|
.log_block_size = 6,
|
||||||
.log_iblock_size = 6
|
},
|
||||||
|
.l1i = {
|
||||||
|
.block_size = 0x40,
|
||||||
|
.log_block_size = 6
|
||||||
|
},
|
||||||
};
|
};
|
||||||
EXPORT_SYMBOL_GPL(ppc64_caches);
|
EXPORT_SYMBOL_GPL(ppc64_caches);
|
||||||
|
|
||||||
@ -397,37 +401,50 @@ void smp_release_cpus(void)
|
|||||||
* cache informations about the CPU that will be used by cache flush
|
* cache informations about the CPU that will be used by cache flush
|
||||||
* routines and/or provided to userland
|
* routines and/or provided to userland
|
||||||
*/
|
*/
|
||||||
void __init initialize_cache_info(void)
|
|
||||||
|
static void init_cache_info(struct ppc_cache_info *info, u32 size, u32 lsize,
|
||||||
|
u32 bsize, u32 sets)
|
||||||
{
|
{
|
||||||
struct device_node *np;
|
info->size = size;
|
||||||
unsigned long num_cpus = 0;
|
info->sets = sets;
|
||||||
|
info->line_size = lsize;
|
||||||
|
info->block_size = bsize;
|
||||||
|
info->log_block_size = __ilog2(bsize);
|
||||||
|
info->blocks_per_page = PAGE_SIZE / bsize;
|
||||||
|
}
|
||||||
|
|
||||||
DBG(" -> initialize_cache_info()\n");
|
static bool __init parse_cache_info(struct device_node *np,
|
||||||
|
bool icache,
|
||||||
for_each_node_by_type(np, "cpu") {
|
struct ppc_cache_info *info)
|
||||||
num_cpus += 1;
|
{
|
||||||
|
static const char *ipropnames[] __initdata = {
|
||||||
/*
|
"i-cache-size",
|
||||||
* We're assuming *all* of the CPUs have the same
|
"i-cache-sets",
|
||||||
* d-cache and i-cache sizes... -Peter
|
"i-cache-block-size",
|
||||||
*/
|
"i-cache-line-size",
|
||||||
if (num_cpus == 1) {
|
};
|
||||||
|
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;
|
const __be32 *sizep, *lsizep, *bsizep, *setsp;
|
||||||
u32 size, lsize, bsize, sets;
|
u32 size, lsize, bsize, sets;
|
||||||
|
bool success = true;
|
||||||
|
|
||||||
size = 0;
|
size = 0;
|
||||||
sets = -1u;
|
sets = -1u;
|
||||||
lsize = bsize = cur_cpu_spec->dcache_bsize;
|
lsize = bsize = cur_cpu_spec->dcache_bsize;
|
||||||
sizep = of_get_property(np, "d-cache-size", NULL);
|
sizep = of_get_property(np, propnames[0], NULL);
|
||||||
if (sizep != NULL)
|
if (sizep != NULL)
|
||||||
size = be32_to_cpu(*sizep);
|
size = be32_to_cpu(*sizep);
|
||||||
setsp = of_get_property(np, "d-cache-sets", NULL);
|
setsp = of_get_property(np, propnames[1], NULL);
|
||||||
if (setsp != NULL)
|
if (setsp != NULL)
|
||||||
sets = be32_to_cpu(*setsp);
|
sets = be32_to_cpu(*setsp);
|
||||||
bsizep = of_get_property(np, "d-cache-block-size",
|
bsizep = of_get_property(np, propnames[2], NULL);
|
||||||
NULL);
|
lsizep = of_get_property(np, propnames[3], NULL);
|
||||||
lsizep = of_get_property(np, "d-cache-line-size",
|
|
||||||
NULL);
|
|
||||||
if (bsizep == NULL)
|
if (bsizep == NULL)
|
||||||
bsizep = lsizep;
|
bsizep = lsizep;
|
||||||
if (lsizep != NULL)
|
if (lsizep != NULL)
|
||||||
@ -435,9 +452,7 @@ void __init initialize_cache_info(void)
|
|||||||
if (bsizep != NULL)
|
if (bsizep != NULL)
|
||||||
bsize = be32_to_cpu(*bsizep);
|
bsize = be32_to_cpu(*bsizep);
|
||||||
if (sizep == NULL || bsizep == NULL || lsizep == NULL)
|
if (sizep == NULL || bsizep == NULL || lsizep == NULL)
|
||||||
DBG("Argh, can't find dcache properties ! "
|
success = false;
|
||||||
"sizep: %p, bsizep: %p, lsizep: %p\n",
|
|
||||||
sizep, bsizep, lsizep);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* OF is weird .. it represents fully associative caches
|
* OF is weird .. it represents fully associative caches
|
||||||
@ -449,53 +464,35 @@ void __init initialize_cache_info(void)
|
|||||||
sets = 0;
|
sets = 0;
|
||||||
else if (sets == 0)
|
else if (sets == 0)
|
||||||
sets = 1;
|
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;
|
init_cache_info(info, size, lsize, bsize, sets);
|
||||||
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)
|
return success;
|
||||||
sets = 0;
|
}
|
||||||
else if (sets == 0)
|
|
||||||
sets = 1;
|
void __init initialize_cache_info(void)
|
||||||
ppc64_caches.isize = size;
|
{
|
||||||
ppc64_caches.isets = sets;
|
struct device_node *np;
|
||||||
ppc64_caches.iline_size = lsize;
|
|
||||||
ppc64_caches.iblock_size = bsize;
|
DBG(" -> initialize_cache_info()\n");
|
||||||
ppc64_caches.log_iblock_size = __ilog2(bsize);
|
|
||||||
ppc64_caches.iblocks_per_page = PAGE_SIZE / bsize;
|
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 (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 */
|
/* For use by binfmt_elf */
|
||||||
dcache_bsize = ppc64_caches.dblock_size;
|
dcache_bsize = ppc64_caches.l1d.block_size;
|
||||||
icache_bsize = ppc64_caches.iblock_size;
|
icache_bsize = ppc64_caches.l1i.block_size;
|
||||||
|
|
||||||
DBG(" <- initialize_cache_info()\n");
|
DBG(" <- initialize_cache_info()\n");
|
||||||
}
|
}
|
||||||
|
@ -736,14 +736,14 @@ static int __init vdso_init(void)
|
|||||||
if (firmware_has_feature(FW_FEATURE_LPAR))
|
if (firmware_has_feature(FW_FEATURE_LPAR))
|
||||||
vdso_data->platform |= 1;
|
vdso_data->platform |= 1;
|
||||||
vdso_data->physicalMemorySize = memblock_phys_mem_size();
|
vdso_data->physicalMemorySize = memblock_phys_mem_size();
|
||||||
vdso_data->dcache_size = ppc64_caches.dsize;
|
vdso_data->dcache_size = ppc64_caches.l1d.size;
|
||||||
vdso_data->dcache_line_size = ppc64_caches.dline_size;
|
vdso_data->dcache_line_size = ppc64_caches.l1d.line_size;
|
||||||
vdso_data->icache_size = ppc64_caches.isize;
|
vdso_data->icache_size = ppc64_caches.l1i.size;
|
||||||
vdso_data->icache_line_size = ppc64_caches.iline_size;
|
vdso_data->icache_line_size = ppc64_caches.l1i.line_size;
|
||||||
vdso_data->dcache_block_size = ppc64_caches.dblock_size;
|
vdso_data->dcache_block_size = ppc64_caches.l1d.block_size;
|
||||||
vdso_data->icache_block_size = ppc64_caches.iblock_size;
|
vdso_data->icache_block_size = ppc64_caches.l1i.block_size;
|
||||||
vdso_data->dcache_log_block_size = ppc64_caches.log_dblock_size;
|
vdso_data->dcache_log_block_size = ppc64_caches.l1d.log_block_size;
|
||||||
vdso_data->icache_log_block_size = ppc64_caches.log_iblock_size;
|
vdso_data->icache_log_block_size = ppc64_caches.l1i.log_block_size;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Calculate the size of the 64 bits vDSO
|
* Calculate the size of the 64 bits vDSO
|
||||||
|
Loading…
Reference in New Issue
Block a user