From 159aad211bf918f2b582f8a12622bf02fb7dd64f Mon Sep 17 00:00:00 2001 From: Jerry Pei Date: Mon, 23 Apr 2012 14:20:03 +0800 Subject: [PATCH 2/7] Patch to head_44x.S to support lsi acp3448v2 Signed-off-by: Jerry Pei --- arch/powerpc/kernel/head_44x.S | 130 ++++++++++++++++++++++++++++++++++++--- 1 files changed, 120 insertions(+), 10 deletions(-) diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S index 5e12b74..ac8d20e 100644 --- a/arch/powerpc/kernel/head_44x.S +++ b/arch/powerpc/kernel/head_44x.S @@ -26,6 +26,8 @@ * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. + * + * These patches add ACP3400 support signed-off-by: john.jacques@lsi.com */ #include @@ -41,6 +43,8 @@ #include #include "head_booke.h" +#undef TLBERRORCOUNTER +/*#define TLBERRORCOUNTER*/ /* As with the other PowerPC ports, it is expected that when code * execution begins here, the following registers contain valid, yet @@ -93,6 +97,30 @@ _ENTRY(_start); bl early_init +#ifdef CONFIG_RELOCATABLE + /* + * r25 will contain RPN/ERPN for the start address of memory + * + * Add the difference between KERNELBASE and PAGE_OFFSET to the + * start of physical memory to get kernstart_addr. + */ + lis r3,kernstart_addr@ha + la r3,kernstart_addr@l(r3) + + lis r4,KERNELBASE@h + ori r4,r4,KERNELBASE@l + lis r5,PAGE_OFFSET@h + ori r5,r5,PAGE_OFFSET@l + subf r4,r5,r4 + + rlwinm r6,r25,0,28,31 /* ERPN */ + rlwinm r7,r25,0,0,3 /* RPN - assuming 256 MB page size */ + add r7,r7,r4 + + stw r6,0(r3) + stw r7,4(r3) +#endif + /* * Decide what sort of machine this is and initialize the MMU. */ @@ -449,6 +477,15 @@ finish_tlb_load_44x: mtspr SPRN_SPRG_WSCRATCH1,r11 mtspr SPRN_SPRG_WSCRATCH2,r12 mtspr SPRN_SPRG_WSCRATCH3,r13 + /* ZZZ */ +#ifdef TLBERRORCOUNTER + lis r10,dtlb_misses@h + ori r10,r10,dtlb_misses@l + lwzu r11,0(r10) + addi r11,r11,1 + stwu r11,0(r10) +#endif + /* ZZZ */ mfcr r11 mtspr SPRN_SPRG_WSCRATCH4,r11 mfspr r10,SPRN_DEAR /* Get faulting address */ @@ -546,6 +583,15 @@ finish_tlb_load_44x: mtspr SPRN_SPRG_WSCRATCH1,r11 mtspr SPRN_SPRG_WSCRATCH2,r12 mtspr SPRN_SPRG_WSCRATCH3,r13 + /* ZZZ */ +#ifdef TLBERRORCOUNTER + lis r10,itlb_misses@h + ori r10,r10,itlb_misses@l + lwzu r11,0(r10) + addi r11,r11,1 + stwu r11,0(r10) +#endif + /* ZZZ */ mfcr r11 mtspr SPRN_SPRG_WSCRATCH4,r11 mfspr r10,SPRN_SRR0 /* Get faulting address */ @@ -704,6 +750,7 @@ _GLOBAL(set_context) stw r4, 0x4(r5) #endif mtspr SPRN_PID,r3 + PPC476_ERR_MTPID() isync /* Force context change */ blr @@ -718,9 +765,12 @@ _GLOBAL(init_cpu_state) /* We use the PVR to differenciate 44x cores from 476 */ mfspr r3,SPRN_PVR srwi r3,r3,16 - cmplwi cr0,r3,PVR_476@h + cmplwi cr0,r3,PVR_476X2@h /* some x2 had a non-standard PVR */ beq head_start_47x - cmplwi cr0,r3,PVR_476_ISS@h + + /* All other 476 cores have a 0x5 as the 4th nibble */ + rlwinm r3,r3,0,28,31 + cmplwi cr0,r3,PVR_476@h beq head_start_47x #endif /* CONFIG_PPC_47x */ @@ -1001,9 +1051,6 @@ clear_utlb_entry: lis r3,PAGE_OFFSET@h ori r3,r3,PAGE_OFFSET@l - /* Kernel is at the base of RAM */ - li r4, 0 /* Load the kernel physical address */ - /* Load the kernel PID = 0 */ li r0,0 mtspr SPRN_PID,r0 @@ -1013,9 +1060,8 @@ clear_utlb_entry: clrrwi r3,r3,12 /* Mask off the effective page number */ ori r3,r3,PPC47x_TLB0_VALID | PPC47x_TLB0_256M - /* Word 1 */ - clrrwi r4,r4,12 /* Mask off the real page number */ - /* ERPN is 0 for first 4GB page */ + /* Word 1 - use r25. RPN is the same as the original entry */ + /* Word 2 */ li r5,0 ori r5,r5,PPC47x_TLB2_S_RWX @@ -1026,7 +1072,7 @@ clear_utlb_entry: /* We write to way 0 and bolted 0 */ lis r0,0x8800 tlbwe r3,r0,0 - tlbwe r4,r0,1 + tlbwe r25,r0,1 tlbwe r5,r0,2 /* @@ -1057,6 +1103,7 @@ clear_utlb_entry: tlbwe r24,r23,2 isync /* Clear out the shadow TLB entries */ +#ifndef CONFIG_ACP #ifdef CONFIG_PPC_EARLY_DEBUG_44x /* Add UART mapping for early debug. */ @@ -1083,6 +1130,54 @@ clear_utlb_entry: /* Force context change */ isync #endif /* CONFIG_PPC_EARLY_DEBUG_44x */ +#endif /* CONFIG_ACP */ + +#ifdef CONFIG_ACP + /* Add bolted entries for I/O. */ + + /* Word 0 */ + lis r3,(0xf0000000)@h + ori r3,r3,PPC47x_TLB0_VALID | PPC47x_TLB0_1M + + /* Word 1 */ + lis r4,(0x00400000)@h + ori r4,r4,0x20 + + /* Word 2 */ + li r5,(PPC47x_TLB2_SW | PPC47x_TLB2_SR | PPC47x_TLB2_I | PPC47x_TLB2_G) + + /* Bolted in way 0, bolt slot 4, we -hope- we don't hit the same + * congruence class as the kernel, we need to make sure of it at + * some point + */ + lis r0,0x8d00 + tlbwe r3,r0,0 + tlbwe r4,r0,1 + tlbwe r5,r0,2 + + /* Word 0 */ + lis r3,(0xf0100000)@h + ori r3,r3,PPC47x_TLB0_VALID | PPC47x_TLB0_1M + + /* Word 1 */ + lis r4,(0x00500000)@h + ori r4,r4,0x20 + + /* Word 2 */ + li r5,(PPC47x_TLB2_SW | PPC47x_TLB2_SR | PPC47x_TLB2_I | PPC47x_TLB2_G) + + /* Bolted in way 0, bolt slot 4, we -hope- we don't hit the same + * congruence class as the kernel, we need to make sure of it at + * some point + */ + lis r0,0x8c00 + tlbwe r3,r0,0 + tlbwe r4,r0,1 + tlbwe r5,r0,2 + + /* Force context change */ + isync +#endif /* CONFIG_ACP */ /* Establish the interrupt vector offsets */ SET_IVOR(0, CriticalInput); @@ -1111,6 +1206,15 @@ clear_utlb_entry: mtspr SPRN_CCR0,r3 isync + /* XXX DD1.1 workaround, trap on dcbz & dcbf. We pre-configure + * IOCR1 and 2 but we don't enable them in IOCCR, this will + * be done on kernel entry/exit + */ + LOAD_REG_IMMEDIATE(r3, (31 << 26) | ( 86 << 1)) /* dcbf */ + LOAD_REG_IMMEDIATE(r4, (31 << 26) | (1014 << 1)) /* dcbz */ + mtspr SPRN_IOCR1, r3 + mtspr SPRN_IOCR2, r4 + #endif /* CONFIG_PPC_47x */ /* @@ -1124,7 +1228,13 @@ head_start_common: lis r4,interrupt_base@h /* IVPR only uses the high 16-bits */ mtspr SPRN_IVPR,r4 - addis r22,r22,KERNELBASE@h + /* + * If the kernel was loaded at a non-zero 256 MB page, we need to + * mask off the most significant 4 bits to get the relative address + * from the start of physical memory + */ + rlwinm r22,r22,0,4,31 + addis r22,r22,PAGE_OFFSET@h mtlr r22 isync blr -- 1.7.0.4