Path: blob/master/arch/powerpc/kernel/85xx_entry_mapping.S
26439 views
/* SPDX-License-Identifier: GPL-2.0 */12/* 1. Find the index of the entry we're executing in */3bcl 20,31,$+4 /* Find our address */4invstr: mflr r6 /* Make it accessible */5mfmsr r76rlwinm r4,r7,27,31,31 /* extract MSR[IS] */7mfspr r7, SPRN_PID08slwi r7,r7,169or r7,r7,r410mtspr SPRN_MAS6,r711tlbsx 0,r6 /* search MSR[IS], SPID=PID0 */12mfspr r7,SPRN_MAS113andis. r7,r7,MAS1_VALID@h14bne match_TLB1516mfspr r7,SPRN_MMUCFG17rlwinm r7,r7,21,28,31 /* extract MMUCFG[NPIDS] */18cmpwi r7,319bne match_TLB /* skip if NPIDS != 3 */2021mfspr r7,SPRN_PID122slwi r7,r7,1623or r7,r7,r424mtspr SPRN_MAS6,r725tlbsx 0,r6 /* search MSR[IS], SPID=PID1 */26mfspr r7,SPRN_MAS127andis. r7,r7,MAS1_VALID@h28bne match_TLB29mfspr r7, SPRN_PID230slwi r7,r7,1631or r7,r7,r432mtspr SPRN_MAS6,r733tlbsx 0,r6 /* Fall through, we had to match */3435match_TLB:36mfspr r7,SPRN_MAS037rlwinm r3,r7,16,20,31 /* Extract MAS0(Entry) */3839mfspr r7,SPRN_MAS1 /* Insure IPROT set */40oris r7,r7,MAS1_IPROT@h41mtspr SPRN_MAS1,r742tlbwe4344/* 2. Invalidate all entries except the entry we're executing in */45mfspr r9,SPRN_TLB1CFG46andi. r9,r9,0xfff47li r6,0 /* Set Entry counter to 0 */481: lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */49rlwimi r7,r6,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r6) */50mtspr SPRN_MAS0,r751tlbre52mfspr r7,SPRN_MAS153rlwinm r7,r7,0,2,31 /* Clear MAS1 Valid and IPROT */54cmpw r3,r655beq skpinv /* Dont update the current execution TLB */56mtspr SPRN_MAS1,r757tlbwe58isync59skpinv: addi r6,r6,1 /* Increment */60cmpw r6,r9 /* Are we done? */61bne 1b /* If not, repeat */6263/* Invalidate TLB0 */64li r6,0x0465tlbivax 0,r666TLBSYNC67/* Invalidate TLB1 */68li r6,0x0c69tlbivax 0,r670TLBSYNC7172/* 3. Setup a temp mapping and jump to it */73andi. r5, r3, 0x1 /* Find an entry not used and is non-zero */74addi r5, r5, 0x175lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */76rlwimi r7,r3,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */77mtspr SPRN_MAS0,r778tlbre7980/* grab and fixup the RPN */81mfspr r6,SPRN_MAS1 /* extract MAS1[SIZE] */82rlwinm r6,r6,25,27,3183li r8,-184addi r6,r6,1085slw r6,r8,r6 /* convert to mask */8687bcl 20,31,$+4 /* Find our address */881: mflr r78990mfspr r8,SPRN_MAS391#ifdef CONFIG_PHYS_64BIT92mfspr r23,SPRN_MAS793#endif94and r8,r6,r895subfic r9,r6,-409696and r9,r9,r79798or r25,r8,r999ori r8,r25,(MAS3_SX|MAS3_SW|MAS3_SR)100101/* Just modify the entry ID and EPN for the temp mapping */102lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */103rlwimi r7,r5,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r5) */104mtspr SPRN_MAS0,r7105xori r6,r4,1 /* Setup TMP mapping in the other Address space */106slwi r6,r6,12107oris r6,r6,(MAS1_VALID|MAS1_IPROT)@h108ori r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_4K))@l109mtspr SPRN_MAS1,r6110mfspr r6,SPRN_MAS2111li r7,0 /* temp EPN = 0 */112rlwimi r7,r6,0,20,31113mtspr SPRN_MAS2,r7114mtspr SPRN_MAS3,r8115tlbwe116117xori r6,r4,1118slwi r6,r6,5 /* setup new context with other address space */119bcl 20,31,$+4 /* Find our address */1201: mflr r9121rlwimi r7,r9,0,20,31122addi r7,r7,(2f - 1b)123mtspr SPRN_SRR0,r7124mtspr SPRN_SRR1,r6125rfi1262:127/* 4. Clear out PIDs & Search info */128li r6,0129mtspr SPRN_MAS6,r6130mtspr SPRN_PID0,r6131132mfspr r7,SPRN_MMUCFG133rlwinm r7,r7,21,28,31 /* extract MMUCFG[NPIDS] */134cmpwi r7,3135bne 2f /* skip if NPIDS != 3 */136137mtspr SPRN_PID1,r6138mtspr SPRN_PID2,r6139140/* 5. Invalidate mapping we started in */1412:142lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */143rlwimi r7,r3,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */144mtspr SPRN_MAS0,r7145tlbre146mfspr r6,SPRN_MAS1147rlwinm r6,r6,0,2,0 /* clear IPROT */148mtspr SPRN_MAS1,r6149tlbwe150/* Invalidate TLB1 */151li r9,0x0c152tlbivax 0,r9153TLBSYNC154155#if defined(ENTRY_MAPPING_BOOT_SETUP)156157/* 6. Setup kernstart_virt_addr mapping in TLB1[0] */158lis r6,0x1000 /* Set MAS0(TLBSEL) = TLB1(1), ESEL = 0 */159mtspr SPRN_MAS0,r6160lis r6,(MAS1_VALID|MAS1_IPROT)@h161ori r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_64M))@l162mtspr SPRN_MAS1,r6163lis r6,MAS2_EPN_MASK(BOOK3E_PAGESZ_64M)@h164ori r6,r6,MAS2_EPN_MASK(BOOK3E_PAGESZ_64M)@l165and r6,r6,r20166ori r6,r6,MAS2_M_IF_NEEDED@l167mtspr SPRN_MAS2,r6168mtspr SPRN_MAS3,r8169tlbwe170171/* 7. Jump to kernstart_virt_addr mapping */172mr r6,r20173174#elif defined(ENTRY_MAPPING_KEXEC_SETUP)175/*176* 6. Setup a 1:1 mapping in TLB1. Esel 0 is unsued, 1 or 2 contains the tmp177* mapping so we start at 3. We setup 8 mappings, each 256MiB in size. This178* will cover the first 2GiB of memory.179*/180181lis r10, (MAS1_VALID|MAS1_IPROT)@h182ori r10,r10, (MAS1_TSIZE(BOOK3E_PAGESZ_256M))@l183li r11, 0184li r0, 8185mtctr r0186187next_tlb_setup:188addi r0, r11, 3189rlwinm r0, r0, 16, 4, 15 // Compute esel190rlwinm r9, r11, 28, 0, 3 // Compute [ER]PN191oris r0, r0, (MAS0_TLBSEL(1))@h192mtspr SPRN_MAS0,r0193mtspr SPRN_MAS1,r10194mtspr SPRN_MAS2,r9195ori r9, r9, (MAS3_SX|MAS3_SW|MAS3_SR)196mtspr SPRN_MAS3,r9197tlbwe198addi r11, r11, 1199bdnz+ next_tlb_setup200201/* 7. Jump to our 1:1 mapping */202mr r6, r25203#else204#error You need to specify the mapping or not use this at all.205#endif206207lis r7,MSR_KERNEL@h208ori r7,r7,MSR_KERNEL@l209bcl 20,31,$+4 /* Find our address */2101: mflr r9211rlwimi r6,r9,0,20,31212addi r6,r6,(2f - 1b)213mtspr SPRN_SRR0,r6214mtspr SPRN_SRR1,r7215rfi /* start execution out of TLB1[0] entry */216217/* 8. Clear out the temp mapping */2182: lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */219rlwimi r7,r5,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r5) */220mtspr SPRN_MAS0,r7221tlbre222mfspr r8,SPRN_MAS1223rlwinm r8,r8,0,2,0 /* clear IPROT */224mtspr SPRN_MAS1,r8225tlbwe226/* Invalidate TLB1 */227li r9,0x0c228tlbivax 0,r9229TLBSYNC230231232