Path: blob/master/arch/powerpc/kernel/fsl_booke_entry_mapping.S
10817 views
1/* 1. Find the index of the entry we're executing in */2bl invstr /* Find our address */3invstr: mflr r6 /* Make it accessible */4mfmsr r75rlwinm r4,r7,27,31,31 /* extract MSR[IS] */6mfspr r7, SPRN_PID07slwi r7,r7,168or r7,r7,r49mtspr SPRN_MAS6,r710tlbsx 0,r6 /* search MSR[IS], SPID=PID0 */11mfspr r7,SPRN_MAS112andis. r7,r7,MAS1_VALID@h13bne match_TLB1415mfspr r7,SPRN_MMUCFG16rlwinm r7,r7,21,28,31 /* extract MMUCFG[NPIDS] */17cmpwi r7,318bne match_TLB /* skip if NPIDS != 3 */1920mfspr r7,SPRN_PID121slwi r7,r7,1622or r7,r7,r423mtspr SPRN_MAS6,r724tlbsx 0,r6 /* search MSR[IS], SPID=PID1 */25mfspr r7,SPRN_MAS126andis. r7,r7,MAS1_VALID@h27bne match_TLB28mfspr r7, SPRN_PID229slwi r7,r7,1630or r7,r7,r431mtspr SPRN_MAS6,r732tlbsx 0,r6 /* Fall through, we had to match */3334match_TLB:35mfspr r7,SPRN_MAS036rlwinm r3,r7,16,20,31 /* Extract MAS0(Entry) */3738mfspr r7,SPRN_MAS1 /* Insure IPROT set */39oris r7,r7,MAS1_IPROT@h40mtspr SPRN_MAS1,r741tlbwe4243/* 2. Invalidate all entries except the entry we're executing in */44mfspr r9,SPRN_TLB1CFG45andi. r9,r9,0xfff46li r6,0 /* Set Entry counter to 0 */471: lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */48rlwimi r7,r6,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r6) */49mtspr SPRN_MAS0,r750tlbre51mfspr r7,SPRN_MAS152rlwinm r7,r7,0,2,31 /* Clear MAS1 Valid and IPROT */53cmpw r3,r654beq skpinv /* Dont update the current execution TLB */55mtspr SPRN_MAS1,r756tlbwe57isync58skpinv: addi r6,r6,1 /* Increment */59cmpw r6,r9 /* Are we done? */60bne 1b /* If not, repeat */6162/* Invalidate TLB0 */63li r6,0x0464tlbivax 0,r665TLBSYNC66/* Invalidate TLB1 */67li r6,0x0c68tlbivax 0,r669TLBSYNC7071/* 3. Setup a temp mapping and jump to it */72andi. r5, r3, 0x1 /* Find an entry not used and is non-zero */73addi r5, r5, 0x174lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */75rlwimi r7,r3,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */76mtspr SPRN_MAS0,r777tlbre7879/* grab and fixup the RPN */80mfspr r6,SPRN_MAS1 /* extract MAS1[SIZE] */81rlwinm r6,r6,25,27,3182li r8,-183addi r6,r6,1084slw r6,r8,r6 /* convert to mask */8586bl 1f /* Find our address */871: mflr r78889mfspr r8,SPRN_MAS390#ifdef CONFIG_PHYS_64BIT91mfspr r23,SPRN_MAS792#endif93and r8,r6,r894subfic r9,r6,-409695and r9,r9,r79697or r25,r8,r998ori r8,r25,(MAS3_SX|MAS3_SW|MAS3_SR)99100/* Just modify the entry ID and EPN for the temp mapping */101lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */102rlwimi r7,r5,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r5) */103mtspr SPRN_MAS0,r7104xori r6,r4,1 /* Setup TMP mapping in the other Address space */105slwi r6,r6,12106oris r6,r6,(MAS1_VALID|MAS1_IPROT)@h107ori r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_4K))@l108mtspr SPRN_MAS1,r6109mfspr r6,SPRN_MAS2110li r7,0 /* temp EPN = 0 */111rlwimi r7,r6,0,20,31112mtspr SPRN_MAS2,r7113mtspr SPRN_MAS3,r8114tlbwe115116xori r6,r4,1117slwi r6,r6,5 /* setup new context with other address space */118bl 1f /* Find our address */1191: mflr r9120rlwimi r7,r9,0,20,31121addi r7,r7,(2f - 1b)122mtspr SPRN_SRR0,r7123mtspr SPRN_SRR1,r6124rfi1252:126/* 4. Clear out PIDs & Search info */127li r6,0128mtspr SPRN_MAS6,r6129mtspr SPRN_PID0,r6130131mfspr r7,SPRN_MMUCFG132rlwinm r7,r7,21,28,31 /* extract MMUCFG[NPIDS] */133cmpwi r7,3134bne 2f /* skip if NPIDS != 3 */135136mtspr SPRN_PID1,r6137mtspr SPRN_PID2,r6138139/* 5. Invalidate mapping we started in */1402:141lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */142rlwimi r7,r3,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r3) */143mtspr SPRN_MAS0,r7144tlbre145mfspr r6,SPRN_MAS1146rlwinm r6,r6,0,2,0 /* clear IPROT */147mtspr SPRN_MAS1,r6148tlbwe149/* Invalidate TLB1 */150li r9,0x0c151tlbivax 0,r9152TLBSYNC153154/* The mapping only needs to be cache-coherent on SMP */155#ifdef CONFIG_SMP156#define M_IF_SMP MAS2_M157#else158#define M_IF_SMP 0159#endif160161#if defined(ENTRY_MAPPING_BOOT_SETUP)162163/* 6. Setup KERNELBASE mapping in TLB1[0] */164lis r6,0x1000 /* Set MAS0(TLBSEL) = TLB1(1), ESEL = 0 */165mtspr SPRN_MAS0,r6166lis r6,(MAS1_VALID|MAS1_IPROT)@h167ori r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_64M))@l168mtspr SPRN_MAS1,r6169lis r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_SMP)@h170ori r6,r6,MAS2_VAL(PAGE_OFFSET, BOOK3E_PAGESZ_64M, M_IF_SMP)@l171mtspr SPRN_MAS2,r6172mtspr SPRN_MAS3,r8173tlbwe174175/* 7. Jump to KERNELBASE mapping */176lis r6,(KERNELBASE & ~0xfff)@h177ori r6,r6,(KERNELBASE & ~0xfff)@l178179#elif defined(ENTRY_MAPPING_KEXEC_SETUP)180/*181* 6. Setup a 1:1 mapping in TLB1. Esel 0 is unsued, 1 or 2 contains the tmp182* mapping so we start at 3. We setup 8 mappings, each 256MiB in size. This183* will cover the first 2GiB of memory.184*/185186lis r10, (MAS1_VALID|MAS1_IPROT)@h187ori r10,r10, (MAS1_TSIZE(BOOK3E_PAGESZ_256M))@l188li r11, 0189li r0, 8190mtctr r0191192next_tlb_setup:193addi r0, r11, 3194rlwinm r0, r0, 16, 4, 15 // Compute esel195rlwinm r9, r11, 28, 0, 3 // Compute [ER]PN196oris r0, r0, (MAS0_TLBSEL(1))@h197mtspr SPRN_MAS0,r0198mtspr SPRN_MAS1,r10199mtspr SPRN_MAS2,r9200ori r9, r9, (MAS3_SX|MAS3_SW|MAS3_SR)201mtspr SPRN_MAS3,r9202tlbwe203addi r11, r11, 1204bdnz+ next_tlb_setup205206/* 7. Jump to our 1:1 mapping */207mr r6, r25208#else209#error You need to specify the mapping or not use this at all.210#endif211212lis r7,MSR_KERNEL@h213ori r7,r7,MSR_KERNEL@l214bl 1f /* Find our address */2151: mflr r9216rlwimi r6,r9,0,20,31217addi r6,r6,(2f - 1b)218mtspr SPRN_SRR0,r6219mtspr SPRN_SRR1,r7220rfi /* start execution out of TLB1[0] entry */221222/* 8. Clear out the temp mapping */2232: lis r7,0x1000 /* Set MAS0(TLBSEL) = 1 */224rlwimi r7,r5,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r5) */225mtspr SPRN_MAS0,r7226tlbre227mfspr r8,SPRN_MAS1228rlwinm r8,r8,0,2,0 /* clear IPROT */229mtspr SPRN_MAS1,r8230tlbwe231/* Invalidate TLB1 */232li r9,0x0c233tlbivax 0,r9234TLBSYNC235236237