From 21a06b0459f5e3ecdeccacfbf076c229514c1840 Mon Sep 17 00:00:00 2001 From: Dave Kleikamp Date: Wed, 26 Jan 2011 06:17:59 +0000 Subject: powerpc/476: Workaround for PLB6 hang The 476FP core may hang if an instruction fetch happens during an msync following a tlbsync. This workaround makes sure that enough instruction cache lines are pre-fetched before executing the msync. (sync and msync are the same to the compiler.) Signed-off-by: Dave Kleikamp Signed-off-by: Josh Boyer --- arch/powerpc/mm/tlb_nohash_low.S | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'arch/powerpc/mm') diff --git a/arch/powerpc/mm/tlb_nohash_low.S b/arch/powerpc/mm/tlb_nohash_low.S index af405eefe48d..7c63c0ed4f1b 100644 --- a/arch/powerpc/mm/tlb_nohash_low.S +++ b/arch/powerpc/mm/tlb_nohash_low.S @@ -189,6 +189,13 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_47x) blr #ifdef CONFIG_PPC_47x + +/* + * 47x variant of icbt + */ +# define ICBT(CT,RA,RB) \ + .long 0x7c00002c | ((CT) << 21) | ((RA) << 16) | ((RB) << 11) + /* * _tlbivax_bcast is only on 47x. We don't bother doing a runtime * check though, it will blow up soon enough if we mistakenly try @@ -206,7 +213,35 @@ _GLOBAL(_tlbivax_bcast) isync eieio tlbsync +BEGIN_FTR_SECTION + b 1f +END_FTR_SECTION_IFSET(CPU_FTR_476_DD2) + sync + wrtee r10 + blr +/* + * DD2 HW could hang if in instruction fetch happens before msync completes. + * Touch enough instruction cache lines to ensure cache hits + */ +1: mflr r9 + bl 2f +2: mflr r6 + li r7,32 + ICBT(0,r6,r7) /* touch next cache line */ + add r6,r6,r7 + ICBT(0,r6,r7) /* touch next cache line */ + add r6,r6,r7 + ICBT(0,r6,r7) /* touch next cache line */ sync + nop + nop + nop + nop + nop + nop + nop + nop + mtlr r9 wrtee r10 blr #endif /* CONFIG_PPC_47x */ -- cgit v1.2.3 From 6dd227002972be910c6191f38f8641e01796557f Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Thu, 27 Jan 2011 10:30:44 +0000 Subject: powerpc: Fix memory limits when starting at a non-zero address memblock_enforce_memory_limit() takes the desired maximum quantity of memory to end up with, not an address above which memory will not be used. Signed-off-by: Scott Wood Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/prom.c | 2 +- arch/powerpc/mm/init_32.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/powerpc/mm') diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 7185f0da7dc3..05b7139d6a27 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c @@ -97,7 +97,7 @@ static void __init move_device_tree(void) start = __pa(initial_boot_params); size = be32_to_cpu(initial_boot_params->totalsize); - if ((memory_limit && (start + size) > memory_limit) || + if ((memory_limit && (start + size) > PHYSICAL_START + memory_limit) || overlaps_crashkernel(start, size)) { p = __va(memblock_alloc(size, PAGE_SIZE)); memcpy(p, initial_boot_params, size); diff --git a/arch/powerpc/mm/init_32.c b/arch/powerpc/mm/init_32.c index 742da43b4ab6..d65b591e5556 100644 --- a/arch/powerpc/mm/init_32.c +++ b/arch/powerpc/mm/init_32.c @@ -148,7 +148,7 @@ void __init MMU_init(void) lowmem_end_addr = memstart_addr + total_lowmem; #ifndef CONFIG_HIGHMEM total_memory = total_lowmem; - memblock_enforce_memory_limit(lowmem_end_addr); + memblock_enforce_memory_limit(total_lowmem); memblock_analyze(); #endif /* CONFIG_HIGHMEM */ } -- cgit v1.2.3