Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e2827fe5 authored by Benjamin Herrenschmidt's avatar Benjamin Herrenschmidt Committed by Michael Ellerman
Browse files

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: default avatarBenjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
parent 5d451a87
Loading
Loading
Loading
Loading
+12 −12
Original line number Diff line number Diff line
@@ -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;
+2 −2
Original line number Diff line number Diff line
@@ -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;
+1 −1
Original line number Diff line number Diff line
@@ -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
+6 −6
Original line number Diff line number Diff line
@@ -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));
+90 −93
Original line number Diff line number Diff line
@@ -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,37 +401,50 @@ void smp_release_cpus(void)
 * cache informations about the CPU that will be used by cache flush
 * routines and/or provided to userland
 */
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;
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;
}

		/*
		 * We're assuming *all* of the CPUs have the same
		 * d-cache and i-cache sizes... -Peter
		 */
		if (num_cpus == 1) {
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, "d-cache-size", NULL);
	sizep = of_get_property(np, propnames[0], NULL);
	if (sizep != NULL)
		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)
		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);
	bsizep = of_get_property(np, propnames[2], NULL);
	lsizep = of_get_property(np, propnames[3], NULL);
	if (bsizep == NULL)
		bsizep = lsizep;
	if (lsizep != NULL)
@@ -435,9 +452,7 @@ void __init initialize_cache_info(void)
	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);
		success = false;

	/*
	 * OF is weird .. it represents fully associative caches
@@ -449,53 +464,35 @@ void __init initialize_cache_info(void)
		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);
	init_cache_info(info, size, lsize, bsize, sets);

			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;
	return success;
}

void __init initialize_cache_info(void)
{
	struct device_node *np;

	DBG(" -> initialize_cache_info()\n");

	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 */
	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");
}
Loading