diff options
Diffstat (limited to 'sys/powerpc/booke/locore.S')
-rw-r--r-- | sys/powerpc/booke/locore.S | 157 |
1 files changed, 125 insertions, 32 deletions
diff --git a/sys/powerpc/booke/locore.S b/sys/powerpc/booke/locore.S index 330a61f..2ce6e69 100644 --- a/sys/powerpc/booke/locore.S +++ b/sys/powerpc/booke/locore.S @@ -61,11 +61,11 @@ __start: /* * Assumptions on the boot loader: - * - system memory starts from physical address 0 - * - it's mapped by a single TBL1 entry + * - System memory starts from physical address 0 + * - It's mapped by a single TLB1 entry * - TLB1 mapping is 1:1 pa to va - * - kernel is loaded at 16MB boundary - * - all PID registers are set to the same value + * - Kernel is loaded at 64MB boundary + * - All PID registers are set to the same value * - CPU is running in AS=0 * * Registers contents provided by the loader(8): @@ -73,14 +73,14 @@ __start: * r3 : metadata pointer * * We rearrange the TLB1 layout as follows: - * - find TLB1 entry we started in - * - make sure it's protected, ivalidate other entries - * - create temp entry in the second AS (make sure it's not TLB[1]) - * - switch to temp mapping - * - map 16MB of RAM in TLB1[1] - * - use AS=1, set EPN to KERNBASE and RPN to kernel load address - * - switch to to TLB1[1] mapping - * - invalidate temp mapping + * - Find TLB1 entry we started in + * - Make sure it's protected, invalidate other entries + * - Create temp entry in the second AS (make sure it's not TLB[1]) + * - Switch to temp mapping + * - Map 64MB of RAM in TLB1[1] + * - Use AS=1, set EPN to KERNBASE and RPN to kernel load address + * - Switch to to TLB1[1] mapping + * - Invalidate temp mapping * * locore registers use: * r1 : stack pointer @@ -104,15 +104,44 @@ __start: mtmsr %r3 isync - lis %r3, HID0_E500_DEFAULT_SET@h - ori %r3, %r3, HID0_E500_DEFAULT_SET@l - mtspr SPR_HID0, %r3 + mfpvr %r3 + rlwinm %r3, %r3, 16, 16, 31 + + lis %r4, HID0_E500_DEFAULT_SET@h + ori %r4, %r4, HID0_E500_DEFAULT_SET@l + + /* Check for e500mc and e5500 */ + cmpli 0, 0, %r3, FSL_E500mc + bne 2f + + lis %r4, HID0_E500MC_DEFAULT_SET@h + ori %r4, %r4, HID0_E500MC_DEFAULT_SET@l + b 3f +2: + cmpli 0, 0, %r3, FSL_E5500 + bne 3f + + lis %r4, HID0_E5500_DEFAULT_SET@h + ori %r4, %r4, HID0_E5500_DEFAULT_SET@l + +3: + mtspr SPR_HID0, %r4 isync + +/* + * E500mc and E5500 do not have HID1 register, so skip HID1 setup on + * this core. + */ + cmpli 0, 0, %r3, FSL_E500mc + beq 1f + cmpli 0, 0, %r3, FSL_E5500 + beq 1f + lis %r3, HID1_E500_DEFAULT_SET@h ori %r3, %r3, HID1_E500_DEFAULT_SET@l mtspr SPR_HID1, %r3 isync - +1: /* Invalidate all entries in TLB0 */ li %r3, 0 bl tlb_inval_all @@ -153,10 +182,10 @@ __start: /* * Setup final mapping in TLB1[1] and switch to it */ - /* Final kernel mapping, map in 16 MB of RAM */ + /* Final kernel mapping, map in 64 MB of RAM */ lis %r3, MAS0_TLBSEL1@h /* Select TLB1 */ li %r4, 0 /* Entry 0 */ - rlwimi %r3, %r4, 16, 12, 15 + rlwimi %r3, %r4, 16, 10, 15 mtspr SPR_MAS0, %r3 isync @@ -176,10 +205,12 @@ __start: /* Discover phys load address */ bl 3f 3: mflr %r4 /* Use current address */ - rlwinm %r4, %r4, 0, 0, 7 /* 16MB alignment mask */ + rlwinm %r4, %r4, 0, 0, 5 /* 64MB alignment mask */ ori %r4, %r4, (MAS3_SX | MAS3_SW | MAS3_SR)@l mtspr SPR_MAS3, %r4 /* Set RPN and protection */ isync + bl zero_mas7 + bl zero_mas8 tlbwe isync msync @@ -281,15 +312,40 @@ bp_tlb1_end: 1: mflr %r31 /* r31 hold the address of bp_ntlb1s */ /* Set HIDs */ - lis %r3, HID0_E500_DEFAULT_SET@h - ori %r3, %r3, HID0_E500_DEFAULT_SET@l - mtspr SPR_HID0, %r3 - isync + mfpvr %r3 + rlwinm %r3, %r3, 16, 16, 31 + + /* HID0 for E500 is default */ + lis %r4, HID0_E500_DEFAULT_SET@h + ori %r4, %r4, HID0_E500_DEFAULT_SET@l + + cmpli 0, 0, %r3, FSL_E500mc + bne 2f + lis %r4, HID0_E500MC_DEFAULT_SET@h + ori %r4, %r4, HID0_E500MC_DEFAULT_SET@l + b 3f +2: + cmpli 0, 0, %r3, FSL_E5500 + bne 3f + lis %r4, HID0_E5500_DEFAULT_SET@h + ori %r4, %r4, HID0_E5500_DEFAULT_SET@l +3: + mtspr SPR_HID0, %r4 + isync +/* + * E500mc and E5500 do not have HID1 register, so skip HID1 setup on + * this core. + */ + cmpli 0, 0, %r3, FSL_E500mc + beq 1f + cmpli 0, 0, %r3, FSL_E5500 + beq 1f + lis %r3, HID1_E500_DEFAULT_SET@h ori %r3, %r3, HID1_E500_DEFAULT_SET@l mtspr SPR_HID1, %r3 isync - +1: /* Enable branch prediction */ li %r3, BUCSR_BPEN mtspr SPR_BUCSR, %r3 @@ -429,8 +485,8 @@ bp_tlb1_end: * r3 TLBSEL */ tlb_inval_all: - rlwinm %r3, %r3, 3, 0x18 /* TLBSEL */ - ori %r3, %r3, 0x4 /* INVALL */ + rlwinm %r3, %r3, 3, (1 << 3) /* TLBSEL */ + ori %r3, %r3, (1 << 2) /* INVALL */ tlbivax 0, %r3 isync msync @@ -472,7 +528,7 @@ tlb1_find_current: */ tlb1_inval_entry: lis %r4, MAS0_TLBSEL1@h /* Select TLB1 */ - rlwimi %r4, %r3, 16, 12, 15 /* Select our entry */ + rlwimi %r4, %r3, 16, 10, 15 /* Select our entry */ mtspr SPR_MAS0, %r4 isync tlbre @@ -495,14 +551,14 @@ tlb1_temp_mapping_as1: /* Read our current translation */ lis %r3, MAS0_TLBSEL1@h /* Select TLB1 */ - rlwimi %r3, %r29, 16, 12, 15 /* Select our current entry */ + rlwimi %r3, %r29, 16, 10, 15 /* Select our current entry */ mtspr SPR_MAS0, %r3 isync tlbre /* Prepare and write temp entry */ lis %r3, MAS0_TLBSEL1@h /* Select TLB1 */ - rlwimi %r3, %r28, 16, 12, 15 /* Select temp entry */ + rlwimi %r3, %r28, 16, 10, 15 /* Select temp entry */ mtspr SPR_MAS0, %r3 isync mfspr %r5, SPR_MAS1 @@ -513,6 +569,10 @@ tlb1_temp_mapping_as1: oris %r5, %r5, (MAS1_VALID | MAS1_IPROT)@h mtspr SPR_MAS1, %r5 isync + mflr %r3 + bl zero_mas7 + bl zero_mas8 + mtlr %r3 tlbwe isync msync @@ -531,7 +591,7 @@ tlb1_inval_all_but_current: andi. %r3, %r3, TLBCFG_NENTRY_MASK@l li %r4, 0 /* Start from Entry 0 */ 1: lis %r5, MAS0_TLBSEL1@h - rlwimi %r5, %r4, 16, 12, 15 + rlwimi %r5, %r4, 16, 10, 15 mtspr SPR_MAS0, %r5 isync tlbre @@ -549,6 +609,38 @@ tlb1_inval_all_but_current: bne 1b blr +/* + * MAS7 and MAS8 conditional zeroing. + */ +.globl zero_mas7 +zero_mas7: + mfpvr %r20 + rlwinm %r20, %r20, 16, 16, 31 + cmpli 0, 0, %r20, FSL_E500v1 + beq 1f + + li %r20, 0 + mtspr SPR_MAS7, %r20 + isync +1: + blr + +.globl zero_mas8 +zero_mas8: + mfpvr %r20 + rlwinm %r20, %r20, 16, 16, 31 + cmpli 0, 0, %r20, FSL_E500mc + beq 1f + cmpli 0, 0, %r20, FSL_E5500 + beq 1f + + blr +1: + li %r20, 0 + mtspr SPR_MAS8, %r20 + isync + blr + #ifdef SMP __boot_page_padding: /* @@ -723,11 +815,12 @@ setfault: mfsprg0 %r4 lwz %r4, TD_PCB(%r2) stw %r3, PCB_ONFAULT(%r4) - mfcr %r10 + mfcr %r4 stw %r0, 0(%r3) stw %r1, 4(%r3) stw %r2, 8(%r3) - stmw %r13, 12(%r3) /* store CR, CTR, XER, [r13 .. r31] */ + stw %r4, 12(%r3) + stmw %r13, 16(%r3) /* store CR, CTR, XER, [r13 .. r31] */ li %r3, 0 /* return FALSE */ blr |