12874c5fdSThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-or-later */ 215f6527eSJosh Boyer/* 315f6527eSJosh Boyer * Copyright (c) 1995-1996 Gary Thomas <gdt@linuxppc.org> 415f6527eSJosh Boyer * Initial PowerPC version. 515f6527eSJosh Boyer * Copyright (c) 1996 Cort Dougan <cort@cs.nmt.edu> 615f6527eSJosh Boyer * Rewritten for PReP 715f6527eSJosh Boyer * Copyright (c) 1996 Paul Mackerras <paulus@cs.anu.edu.au> 815f6527eSJosh Boyer * Low-level exception handers, MMU support, and rewrite. 915f6527eSJosh Boyer * Copyright (c) 1997 Dan Malek <dmalek@jlc.net> 1015f6527eSJosh Boyer * PowerPC 8xx modifications. 1115f6527eSJosh Boyer * Copyright (c) 1998-1999 TiVo, Inc. 1215f6527eSJosh Boyer * PowerPC 403GCX modifications. 1315f6527eSJosh Boyer * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu> 1415f6527eSJosh Boyer * PowerPC 403GCX/405GP modifications. 1515f6527eSJosh Boyer * Copyright 2000 MontaVista Software Inc. 1615f6527eSJosh Boyer * PPC405 modifications 1715f6527eSJosh Boyer * PowerPC 403GCX/405GP modifications. 1815f6527eSJosh Boyer * Author: MontaVista Software, Inc. 1915f6527eSJosh Boyer * frank_rowand@mvista.com or source@mvista.com 2015f6527eSJosh Boyer * debbie_chu@mvista.com 2115f6527eSJosh Boyer * 2215f6527eSJosh Boyer * Module name: head_4xx.S 2315f6527eSJosh Boyer * 2415f6527eSJosh Boyer * Description: 2515f6527eSJosh Boyer * Kernel execution entry point code. 2615f6527eSJosh Boyer */ 2715f6527eSJosh Boyer 28e7039845STim Abbott#include <linux/init.h> 2965fddcfcSMike Rapoport#include <linux/pgtable.h> 3006e7cbc2SChristophe Leroy#include <linux/sizes.h> 312da37761SChristophe Leroy#include <linux/linkage.h> 322da37761SChristophe Leroy 3315f6527eSJosh Boyer#include <asm/processor.h> 3415f6527eSJosh Boyer#include <asm/page.h> 3515f6527eSJosh Boyer#include <asm/mmu.h> 3615f6527eSJosh Boyer#include <asm/cputable.h> 3715f6527eSJosh Boyer#include <asm/thread_info.h> 3815f6527eSJosh Boyer#include <asm/ppc_asm.h> 3915f6527eSJosh Boyer#include <asm/asm-offsets.h> 4046f52210SStephen Rothwell#include <asm/ptrace.h> 4115f6527eSJosh Boyer 4290f204b9SChristophe Leroy#include "head_32.h" 4390f204b9SChristophe Leroy 4415f6527eSJosh Boyer/* As with the other PowerPC ports, it is expected that when code 4515f6527eSJosh Boyer * execution begins here, the following registers contain valid, yet 4615f6527eSJosh Boyer * optional, information: 4715f6527eSJosh Boyer * 4815f6527eSJosh Boyer * r3 - Board info structure pointer (DRAM, frequency, MAC address, etc.) 4915f6527eSJosh Boyer * r4 - Starting address of the init RAM disk 5015f6527eSJosh Boyer * r5 - Ending address of the init RAM disk 5115f6527eSJosh Boyer * r6 - Start of kernel command line string (e.g. "mem=96m") 5215f6527eSJosh Boyer * r7 - End of kernel command line string 5315f6527eSJosh Boyer * 5415f6527eSJosh Boyer * This is all going to change RSN when we add bi_recs....... -- Dan 5515f6527eSJosh Boyer */ 56e7039845STim Abbott __HEAD 5727e21e8fSChristophe Leroy_GLOBAL(_stext); 5827e21e8fSChristophe Leroy_GLOBAL(_start); 5915f6527eSJosh Boyer 606dece0ebSScott Wood mr r31,r3 /* save device tree ptr */ 6115f6527eSJosh Boyer 6215f6527eSJosh Boyer /* We have to turn on the MMU right away so we get cache modes 6315f6527eSJosh Boyer * set correctly. 6415f6527eSJosh Boyer */ 6515f6527eSJosh Boyer bl initial_mmu 6615f6527eSJosh Boyer 6715f6527eSJosh Boyer/* We now have the lower 16 Meg mapped into TLB entries, and the caches 6815f6527eSJosh Boyer * ready to work. 6915f6527eSJosh Boyer */ 7015f6527eSJosh Boyerturn_on_mmu: 7115f6527eSJosh Boyer lis r0,MSR_KERNEL@h 7215f6527eSJosh Boyer ori r0,r0,MSR_KERNEL@l 7315f6527eSJosh Boyer mtspr SPRN_SRR1,r0 7415f6527eSJosh Boyer lis r0,start_here@h 7515f6527eSJosh Boyer ori r0,r0,start_here@l 7615f6527eSJosh Boyer mtspr SPRN_SRR0,r0 7715f6527eSJosh Boyer rfi /* enables MMU */ 7815f6527eSJosh Boyer b . /* prevent prefetch past rfi */ 7915f6527eSJosh Boyer 8015f6527eSJosh Boyer/* 8115f6527eSJosh Boyer * This area is used for temporarily saving registers during the 8215f6527eSJosh Boyer * critical exception prolog. 8315f6527eSJosh Boyer */ 8415f6527eSJosh Boyer . = 0xc0 8515f6527eSJosh Boyercrit_save: 8627e21e8fSChristophe Leroy_GLOBAL(crit_r10) 8715f6527eSJosh Boyer .space 4 8827e21e8fSChristophe Leroy_GLOBAL(crit_r11) 8915f6527eSJosh Boyer .space 4 9027e21e8fSChristophe Leroy_GLOBAL(crit_srr0) 91fca622c5SKumar Gala .space 4 9227e21e8fSChristophe Leroy_GLOBAL(crit_srr1) 93fca622c5SKumar Gala .space 4 9427e21e8fSChristophe Leroy_GLOBAL(crit_r1) 950fc1e934SChristophe Leroy .space 4 9627e21e8fSChristophe Leroy_GLOBAL(crit_dear) 970fc1e934SChristophe Leroy .space 4 9827e21e8fSChristophe Leroy_GLOBAL(crit_esr) 990fc1e934SChristophe Leroy .space 4 10015f6527eSJosh Boyer 10115f6527eSJosh Boyer/* 10215f6527eSJosh Boyer * Exception prolog for critical exceptions. This is a little different 10315f6527eSJosh Boyer * from the normal exception prolog above since a critical exception 10415f6527eSJosh Boyer * can potentially occur at any point during normal exception processing. 10515f6527eSJosh Boyer * Thus we cannot use the same SPRG registers as the normal prolog above. 10615f6527eSJosh Boyer * Instead we use a couple of words of memory at low physical addresses. 10715f6527eSJosh Boyer * This is OK since we don't support SMP on these processors. 10815f6527eSJosh Boyer */ 109719e7e21SChristophe Leroy.macro CRITICAL_EXCEPTION_PROLOG trapno name 1109d3c18a1SChristophe Leroy stw r10,crit_r10@l(0) /* save two registers to work with */ 1119d3c18a1SChristophe Leroy stw r11,crit_r11@l(0) 112fcd4b43cSChristophe Leroy mfspr r10,SPRN_SRR0 113fcd4b43cSChristophe Leroy mfspr r11,SPRN_SRR1 114fcd4b43cSChristophe Leroy stw r10,crit_srr0@l(0) 115fcd4b43cSChristophe Leroy stw r11,crit_srr1@l(0) 1160fc1e934SChristophe Leroy mfspr r10,SPRN_DEAR 1170fc1e934SChristophe Leroy mfspr r11,SPRN_ESR 1180fc1e934SChristophe Leroy stw r10,crit_dear@l(0) 1190fc1e934SChristophe Leroy stw r11,crit_esr@l(0) 1209d3c18a1SChristophe Leroy mfcr r10 /* save CR in r10 for now */ 1219d3c18a1SChristophe Leroy mfspr r11,SPRN_SRR3 /* check whether user or kernel */ 1229d3c18a1SChristophe Leroy andi. r11,r11,MSR_PR 1230fc1e934SChristophe Leroy lis r11,(critirq_ctx-PAGE_OFFSET)@ha 1240fc1e934SChristophe Leroy lwz r11,(critirq_ctx-PAGE_OFFSET)@l(r11) 1259d3c18a1SChristophe Leroy beq 1f 1269d3c18a1SChristophe Leroy /* COMING FROM USER MODE */ 1279d3c18a1SChristophe Leroy mfspr r11,SPRN_SPRG_THREAD /* if from user, start at top of */ 1289d3c18a1SChristophe Leroy lwz r11,TASK_STACK-THREAD(r11) /* this thread's kernel stack */ 1290fc1e934SChristophe Leroy1: stw r1,crit_r1@l(0) 1300fc1e934SChristophe Leroy addi r1,r11,THREAD_SIZE-INT_FRAME_SIZE /* Alloc an excpt frm */ 1319b6150fbSChristophe Leroy LOAD_REG_IMMEDIATE(r11, MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)) /* re-enable MMU */ 1329b6150fbSChristophe Leroy mtspr SPRN_SRR1, r11 1339b6150fbSChristophe Leroy lis r11, 1f@h 1349b6150fbSChristophe Leroy ori r11, r11, 1f@l 1359b6150fbSChristophe Leroy mtspr SPRN_SRR0, r11 1369b6150fbSChristophe Leroy rfi 137dc13b889SChristophe Leroy 138dc13b889SChristophe Leroy .text 1399b6150fbSChristophe Leroy1: 1408f844c06SChristophe Leroy\name\()_virt: 1410fc1e934SChristophe Leroy lwz r11,crit_r1@l(0) 1420fc1e934SChristophe Leroy stw r11,GPR1(r1) 1430fc1e934SChristophe Leroy stw r11,0(r1) 1440fc1e934SChristophe Leroy mr r11,r1 1459d3c18a1SChristophe Leroy stw r10,_CCR(r11) /* save various registers */ 1469d3c18a1SChristophe Leroy stw r12,GPR12(r11) 1479d3c18a1SChristophe Leroy stw r9,GPR9(r11) 1489d3c18a1SChristophe Leroy mflr r10 1499d3c18a1SChristophe Leroy stw r10,_LINK(r11) 1500fc1e934SChristophe Leroy lis r9,PAGE_OFFSET@ha 1510fc1e934SChristophe Leroy lwz r10,crit_r10@l(r9) 1520fc1e934SChristophe Leroy lwz r12,crit_r11@l(r9) 153fcd4b43cSChristophe Leroy stw r10,GPR10(r11) 154fcd4b43cSChristophe Leroy stw r12,GPR11(r11) 1550fc1e934SChristophe Leroy lwz r12,crit_dear@l(r9) 1560fc1e934SChristophe Leroy lwz r9,crit_esr@l(r9) 15726c46886SChristophe Leroy stw r12,_DEAR(r11) /* since they may have had stuff */ 1589d3c18a1SChristophe Leroy stw r9,_ESR(r11) /* exception was taken */ 1599d3c18a1SChristophe Leroy mfspr r12,SPRN_SRR2 1609d3c18a1SChristophe Leroy mfspr r9,SPRN_SRR3 1619d3c18a1SChristophe Leroy rlwinm r9,r9,0,14,12 /* clear MSR_WE (necessary?) */ 162a3055978SChristophe Leroy COMMON_EXCEPTION_PROLOG_END \trapno + 2 1638f844c06SChristophe Leroy_ASM_NOKPROBE_SYMBOL(\name\()_virt) 1649d3c18a1SChristophe Leroy.endm 16515f6527eSJosh Boyer 16615f6527eSJosh Boyer /* 16715f6527eSJosh Boyer * State at this point: 16815f6527eSJosh Boyer * r9 saved in stack frame, now saved SRR3 & ~MSR_WE 16915f6527eSJosh Boyer * r10 saved in crit_r10 and in stack frame, trashed 17015f6527eSJosh Boyer * r11 saved in crit_r11 and in stack frame, 17115f6527eSJosh Boyer * now phys stack/exception frame pointer 17215f6527eSJosh Boyer * r12 saved in stack frame, now saved SRR2 17315f6527eSJosh Boyer * CR saved in stack frame, CR0.EQ = !SRR3.PR 17415f6527eSJosh Boyer * LR, DEAR, ESR in stack frame 17515f6527eSJosh Boyer * r1 saved in stack frame, now virt stack/excframe pointer 17615f6527eSJosh Boyer * r0, r3-r8 saved in stack frame 17715f6527eSJosh Boyer */ 17815f6527eSJosh Boyer 17915f6527eSJosh Boyer/* 18015f6527eSJosh Boyer * Exception vectors. 18115f6527eSJosh Boyer */ 18215f6527eSJosh Boyer#define CRITICAL_EXCEPTION(n, label, hdlr) \ 18315f6527eSJosh Boyer START_EXCEPTION(n, label); \ 184719e7e21SChristophe Leroy CRITICAL_EXCEPTION_PROLOG n label; \ 1854c0104a8SChristophe Leroy prepare_transfer_to_handler; \ 1864c0104a8SChristophe Leroy bl hdlr; \ 1874c0104a8SChristophe Leroy b ret_from_crit_exc 18815f6527eSJosh Boyer 18915f6527eSJosh Boyer/* 19015f6527eSJosh Boyer * 0x0100 - Critical Interrupt Exception 19115f6527eSJosh Boyer */ 19215f6527eSJosh Boyer CRITICAL_EXCEPTION(0x0100, CriticalInterrupt, unknown_exception) 19315f6527eSJosh Boyer 19415f6527eSJosh Boyer/* 19515f6527eSJosh Boyer * 0x0200 - Machine Check Exception 19615f6527eSJosh Boyer */ 19715f6527eSJosh Boyer CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception) 19815f6527eSJosh Boyer 19915f6527eSJosh Boyer/* 20015f6527eSJosh Boyer * 0x0300 - Data Storage Exception 20115f6527eSJosh Boyer * This happens for just a few reasons. U0 set (but we don't do that), 20215f6527eSJosh Boyer * or zone protection fault (user violation, write to protected page). 2032c74e258SChristophe Leroy * The other Data TLB exceptions bail out to this point 2042c74e258SChristophe Leroy * if they can't resolve the lightweight TLB fault. 20515f6527eSJosh Boyer */ 20615f6527eSJosh Boyer START_EXCEPTION(0x0300, DataStorage) 207719e7e21SChristophe Leroy EXCEPTION_PROLOG 0x300 DataStorage handle_dar_dsisr=1 2084c0104a8SChristophe Leroy prepare_transfer_to_handler 2094c0104a8SChristophe Leroy bl do_page_fault 2104c0104a8SChristophe Leroy b interrupt_return 21115f6527eSJosh Boyer 21215f6527eSJosh Boyer/* 21315f6527eSJosh Boyer * 0x0400 - Instruction Storage Exception 21415f6527eSJosh Boyer * This is caused by a fetch from non-execute or guarded pages. 21515f6527eSJosh Boyer */ 21615f6527eSJosh Boyer START_EXCEPTION(0x0400, InstructionAccess) 217719e7e21SChristophe Leroy EXCEPTION_PROLOG 0x400 InstructionAccess 218a01a3f2dSNicholas Piggin li r5,0 219a01a3f2dSNicholas Piggin stw r5, _ESR(r11) /* Zero ESR */ 220a01a3f2dSNicholas Piggin stw r12, _DEAR(r11) /* SRR0 as DEAR */ 2214c0104a8SChristophe Leroy prepare_transfer_to_handler 2224c0104a8SChristophe Leroy bl do_page_fault 2234c0104a8SChristophe Leroy b interrupt_return 22415f6527eSJosh Boyer 22515f6527eSJosh Boyer/* 0x0500 - External Interrupt Exception */ 226acc142b6SChristophe Leroy EXCEPTION(0x0500, HardwareInterrupt, do_IRQ) 22715f6527eSJosh Boyer 22815f6527eSJosh Boyer/* 0x0600 - Alignment Exception */ 22915f6527eSJosh Boyer START_EXCEPTION(0x0600, Alignment) 230719e7e21SChristophe Leroy EXCEPTION_PROLOG 0x600 Alignment handle_dar_dsisr=1 2318f6ff5bdSChristophe Leroy prepare_transfer_to_handler 2328f6ff5bdSChristophe Leroy bl alignment_exception 2338f6ff5bdSChristophe Leroy REST_NVGPRS(r1) 2348f6ff5bdSChristophe Leroy b interrupt_return 23515f6527eSJosh Boyer 23615f6527eSJosh Boyer/* 0x0700 - Program Exception */ 23715f6527eSJosh Boyer START_EXCEPTION(0x0700, ProgramCheck) 238719e7e21SChristophe Leroy EXCEPTION_PROLOG 0x700 ProgramCheck handle_dar_dsisr=1 2398f6ff5bdSChristophe Leroy prepare_transfer_to_handler 2408f6ff5bdSChristophe Leroy bl program_check_exception 2418f6ff5bdSChristophe Leroy REST_NVGPRS(r1) 2428f6ff5bdSChristophe Leroy b interrupt_return 24315f6527eSJosh Boyer 244acc142b6SChristophe Leroy EXCEPTION(0x0800, Trap_08, unknown_exception) 245acc142b6SChristophe Leroy EXCEPTION(0x0900, Trap_09, unknown_exception) 246acc142b6SChristophe Leroy EXCEPTION(0x0A00, Trap_0A, unknown_exception) 247acc142b6SChristophe Leroy EXCEPTION(0x0B00, Trap_0B, unknown_exception) 24815f6527eSJosh Boyer 24915f6527eSJosh Boyer/* 0x0C00 - System Call Exception */ 25015f6527eSJosh Boyer START_EXCEPTION(0x0C00, SystemCall) 251b86fb888SChristophe Leroy SYSCALL_ENTRY 0xc00 252249c9b0cSChristophe Leroy/* Trap_0D is commented out to get more space for system call exception */ 25315f6527eSJosh Boyer 254acc142b6SChristophe Leroy/* EXCEPTION(0x0D00, Trap_0D, unknown_exception) */ 255acc142b6SChristophe Leroy EXCEPTION(0x0E00, Trap_0E, unknown_exception) 256acc142b6SChristophe Leroy EXCEPTION(0x0F00, Trap_0F, unknown_exception) 25715f6527eSJosh Boyer 25815f6527eSJosh Boyer/* 0x1000 - Programmable Interval Timer (PIT) Exception */ 2597bf1d7e1SChristophe Leroy START_EXCEPTION(0x1000, DecrementerTrap) 2601e18c17aSJason Gunthorpe b Decrementer 26115f6527eSJosh Boyer 2627bf1d7e1SChristophe Leroy/* 0x1010 - Fixed Interval Timer (FIT) Exception */ 2637bf1d7e1SChristophe Leroy START_EXCEPTION(0x1010, FITExceptionTrap) 2641e18c17aSJason Gunthorpe b FITException 26515f6527eSJosh Boyer 2667bf1d7e1SChristophe Leroy/* 0x1020 - Watchdog Timer (WDT) Exception */ 2677bf1d7e1SChristophe Leroy START_EXCEPTION(0x1020, WDTExceptionTrap) 2681e18c17aSJason Gunthorpe b WDTException 26915f6527eSJosh Boyer 27015f6527eSJosh Boyer/* 0x1100 - Data TLB Miss Exception 27115f6527eSJosh Boyer * As the name implies, translation is not in the MMU, so search the 27215f6527eSJosh Boyer * page tables and fix it. The only purpose of this function is to 27315f6527eSJosh Boyer * load TLB entries from the page table if they exist. 27415f6527eSJosh Boyer */ 27515f6527eSJosh Boyer START_EXCEPTION(0x1100, DTLBMiss) 27652ae92ccSChristophe Leroy mtspr SPRN_SPRG_SCRATCH5, r10 /* Save some working registers */ 27752ae92ccSChristophe Leroy mtspr SPRN_SPRG_SCRATCH6, r11 278ee43eb78SBenjamin Herrenschmidt mtspr SPRN_SPRG_SCRATCH3, r12 279ee43eb78SBenjamin Herrenschmidt mtspr SPRN_SPRG_SCRATCH4, r9 2803aacaa71SChristophe Leroy mfcr r12 281797f4016SChristophe Leroy mfspr r9, SPRN_PID 28252ae92ccSChristophe Leroy rlwimi r12, r9, 0, 0xff 28315f6527eSJosh Boyer mfspr r10, SPRN_DEAR /* Get faulting address */ 28415f6527eSJosh Boyer 28515f6527eSJosh Boyer /* If we are faulting a kernel address, we have to use the 28615f6527eSJosh Boyer * kernel page tables. 28715f6527eSJosh Boyer */ 2888a13c4f9SKumar Gala lis r11, PAGE_OFFSET@h 28915f6527eSJosh Boyer cmplw r10, r11 29015f6527eSJosh Boyer blt+ 3f 29115f6527eSJosh Boyer lis r11, swapper_pg_dir@h 29215f6527eSJosh Boyer ori r11, r11, swapper_pg_dir@l 29315f6527eSJosh Boyer li r9, 0 29415f6527eSJosh Boyer mtspr SPRN_PID, r9 /* TLB will have 0 TID */ 29515f6527eSJosh Boyer b 4f 29615f6527eSJosh Boyer 29715f6527eSJosh Boyer /* Get the PGD for the current thread. 29815f6527eSJosh Boyer */ 29915f6527eSJosh Boyer3: 300ee43eb78SBenjamin Herrenschmidt mfspr r11,SPRN_SPRG_THREAD 30115f6527eSJosh Boyer lwz r11,PGDIR(r11) 302fcf9bb6dSChristophe Leroy#ifdef CONFIG_PPC_KUAP 303fcf9bb6dSChristophe Leroy rlwinm. r9, r9, 0, 0xff 304fcf9bb6dSChristophe Leroy beq 5f /* Kuap fault */ 305fcf9bb6dSChristophe Leroy#endif 30615f6527eSJosh Boyer4: 30715f6527eSJosh Boyer tophys(r11, r11) 30815f6527eSJosh Boyer rlwimi r11, r10, 12, 20, 29 /* Create L1 (pgdir/pmd) address */ 309797f4016SChristophe Leroy lwz r11, 0(r11) /* Get L1 entry */ 310797f4016SChristophe Leroy andi. r9, r11, _PMD_PRESENT /* Check if it points to a PTE page */ 31115f6527eSJosh Boyer beq 2f /* Bail if no table */ 31215f6527eSJosh Boyer 313797f4016SChristophe Leroy rlwimi r11, r10, 22, 20, 29 /* Compute PTE address */ 314797f4016SChristophe Leroy lwz r11, 0(r11) /* Get Linux PTE */ 3152c74e258SChristophe Leroy li r9, _PAGE_PRESENT | _PAGE_ACCESSED 3162c74e258SChristophe Leroy andc. r9, r9, r11 /* Check permission */ 3172c74e258SChristophe Leroy bne 5f 31815f6527eSJosh Boyer 3192c74e258SChristophe Leroy rlwinm r9, r11, 1, _PAGE_RW /* dirty => rw */ 3202c74e258SChristophe Leroy and r9, r9, r11 /* hwwrite = dirty & rw */ 3212c74e258SChristophe Leroy rlwimi r11, r9, 0, _PAGE_RW /* replace rw by hwwrite */ 32215f6527eSJosh Boyer 32315f6527eSJosh Boyer /* Create TLB tag. This is the faulting address plus a static 32415f6527eSJosh Boyer * set of bits. These are size, valid, E, U0. 32515f6527eSJosh Boyer */ 326797f4016SChristophe Leroy li r9, 0x00c0 327797f4016SChristophe Leroy rlwimi r10, r9, 0, 20, 31 32815f6527eSJosh Boyer 32915f6527eSJosh Boyer b finish_tlb_load 33015f6527eSJosh Boyer 33115f6527eSJosh Boyer2: /* Check for possible large-page pmd entry */ 332797f4016SChristophe Leroy rlwinm. r9, r11, 2, 22, 24 33315f6527eSJosh Boyer beq 5f 33415f6527eSJosh Boyer 33515f6527eSJosh Boyer /* Create TLB tag. This is the faulting address, plus a static 33615f6527eSJosh Boyer * set of bits (valid, E, U0) plus the size from the PMD. 33715f6527eSJosh Boyer */ 33815f6527eSJosh Boyer ori r9, r9, 0x40 33915f6527eSJosh Boyer rlwimi r10, r9, 0, 20, 31 34015f6527eSJosh Boyer 34115f6527eSJosh Boyer b finish_tlb_load 34215f6527eSJosh Boyer 34315f6527eSJosh Boyer5: 34415f6527eSJosh Boyer /* The bailout. Restore registers to pre-exception conditions 34515f6527eSJosh Boyer * and call the heavyweights to help us out. 34615f6527eSJosh Boyer */ 34752ae92ccSChristophe Leroy mtspr SPRN_PID, r12 34852ae92ccSChristophe Leroy mtcrf 0x80, r12 349ee43eb78SBenjamin Herrenschmidt mfspr r9, SPRN_SPRG_SCRATCH4 350ee43eb78SBenjamin Herrenschmidt mfspr r12, SPRN_SPRG_SCRATCH3 35152ae92ccSChristophe Leroy mfspr r11, SPRN_SPRG_SCRATCH6 35252ae92ccSChristophe Leroy mfspr r10, SPRN_SPRG_SCRATCH5 3532c74e258SChristophe Leroy b DataStorage 35415f6527eSJosh Boyer 35515f6527eSJosh Boyer/* 0x1200 - Instruction TLB Miss Exception 35615f6527eSJosh Boyer * Nearly the same as above, except we get our information from different 35715f6527eSJosh Boyer * registers and bailout to a different point. 35815f6527eSJosh Boyer */ 35915f6527eSJosh Boyer START_EXCEPTION(0x1200, ITLBMiss) 36052ae92ccSChristophe Leroy mtspr SPRN_SPRG_SCRATCH5, r10 /* Save some working registers */ 36152ae92ccSChristophe Leroy mtspr SPRN_SPRG_SCRATCH6, r11 362ee43eb78SBenjamin Herrenschmidt mtspr SPRN_SPRG_SCRATCH3, r12 363ee43eb78SBenjamin Herrenschmidt mtspr SPRN_SPRG_SCRATCH4, r9 3643aacaa71SChristophe Leroy mfcr r12 365797f4016SChristophe Leroy mfspr r9, SPRN_PID 36652ae92ccSChristophe Leroy rlwimi r12, r9, 0, 0xff 36715f6527eSJosh Boyer mfspr r10, SPRN_SRR0 /* Get faulting address */ 36815f6527eSJosh Boyer 36915f6527eSJosh Boyer /* If we are faulting a kernel address, we have to use the 37015f6527eSJosh Boyer * kernel page tables. 37115f6527eSJosh Boyer */ 3728a13c4f9SKumar Gala lis r11, PAGE_OFFSET@h 37315f6527eSJosh Boyer cmplw r10, r11 37415f6527eSJosh Boyer blt+ 3f 37515f6527eSJosh Boyer lis r11, swapper_pg_dir@h 37615f6527eSJosh Boyer ori r11, r11, swapper_pg_dir@l 37715f6527eSJosh Boyer li r9, 0 37815f6527eSJosh Boyer mtspr SPRN_PID, r9 /* TLB will have 0 TID */ 37915f6527eSJosh Boyer b 4f 38015f6527eSJosh Boyer 38115f6527eSJosh Boyer /* Get the PGD for the current thread. 38215f6527eSJosh Boyer */ 38315f6527eSJosh Boyer3: 384ee43eb78SBenjamin Herrenschmidt mfspr r11,SPRN_SPRG_THREAD 38515f6527eSJosh Boyer lwz r11,PGDIR(r11) 386fcf9bb6dSChristophe Leroy#ifdef CONFIG_PPC_KUAP 387fcf9bb6dSChristophe Leroy rlwinm. r9, r9, 0, 0xff 388fcf9bb6dSChristophe Leroy beq 5f /* Kuap fault */ 389fcf9bb6dSChristophe Leroy#endif 39015f6527eSJosh Boyer4: 39115f6527eSJosh Boyer tophys(r11, r11) 39215f6527eSJosh Boyer rlwimi r11, r10, 12, 20, 29 /* Create L1 (pgdir/pmd) address */ 393797f4016SChristophe Leroy lwz r11, 0(r11) /* Get L1 entry */ 394797f4016SChristophe Leroy andi. r9, r11, _PMD_PRESENT /* Check if it points to a PTE page */ 39515f6527eSJosh Boyer beq 2f /* Bail if no table */ 39615f6527eSJosh Boyer 397797f4016SChristophe Leroy rlwimi r11, r10, 22, 20, 29 /* Compute PTE address */ 398797f4016SChristophe Leroy lwz r11, 0(r11) /* Get Linux PTE */ 3992c74e258SChristophe Leroy li r9, _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC 4002c74e258SChristophe Leroy andc. r9, r9, r11 /* Check permission */ 4012c74e258SChristophe Leroy bne 5f 40215f6527eSJosh Boyer 4032c74e258SChristophe Leroy rlwinm r9, r11, 1, _PAGE_RW /* dirty => rw */ 4042c74e258SChristophe Leroy and r9, r9, r11 /* hwwrite = dirty & rw */ 4052c74e258SChristophe Leroy rlwimi r11, r9, 0, _PAGE_RW /* replace rw by hwwrite */ 40615f6527eSJosh Boyer 40715f6527eSJosh Boyer /* Create TLB tag. This is the faulting address plus a static 40815f6527eSJosh Boyer * set of bits. These are size, valid, E, U0. 40915f6527eSJosh Boyer */ 410797f4016SChristophe Leroy li r9, 0x00c0 411797f4016SChristophe Leroy rlwimi r10, r9, 0, 20, 31 41215f6527eSJosh Boyer 41315f6527eSJosh Boyer b finish_tlb_load 41415f6527eSJosh Boyer 41515f6527eSJosh Boyer2: /* Check for possible large-page pmd entry */ 416797f4016SChristophe Leroy rlwinm. r9, r11, 2, 22, 24 41715f6527eSJosh Boyer beq 5f 41815f6527eSJosh Boyer 41915f6527eSJosh Boyer /* Create TLB tag. This is the faulting address, plus a static 42015f6527eSJosh Boyer * set of bits (valid, E, U0) plus the size from the PMD. 42115f6527eSJosh Boyer */ 42215f6527eSJosh Boyer ori r9, r9, 0x40 42315f6527eSJosh Boyer rlwimi r10, r9, 0, 20, 31 42415f6527eSJosh Boyer 42515f6527eSJosh Boyer b finish_tlb_load 42615f6527eSJosh Boyer 42715f6527eSJosh Boyer5: 42815f6527eSJosh Boyer /* The bailout. Restore registers to pre-exception conditions 42915f6527eSJosh Boyer * and call the heavyweights to help us out. 43015f6527eSJosh Boyer */ 43152ae92ccSChristophe Leroy mtspr SPRN_PID, r12 43252ae92ccSChristophe Leroy mtcrf 0x80, r12 433ee43eb78SBenjamin Herrenschmidt mfspr r9, SPRN_SPRG_SCRATCH4 434ee43eb78SBenjamin Herrenschmidt mfspr r12, SPRN_SPRG_SCRATCH3 43552ae92ccSChristophe Leroy mfspr r11, SPRN_SPRG_SCRATCH6 43652ae92ccSChristophe Leroy mfspr r10, SPRN_SPRG_SCRATCH5 43715f6527eSJosh Boyer b InstructionAccess 43815f6527eSJosh Boyer 439acc142b6SChristophe Leroy EXCEPTION(0x1300, Trap_13, unknown_exception) 440acc142b6SChristophe Leroy EXCEPTION(0x1400, Trap_14, unknown_exception) 441acc142b6SChristophe Leroy EXCEPTION(0x1500, Trap_15, unknown_exception) 442acc142b6SChristophe Leroy EXCEPTION(0x1600, Trap_16, unknown_exception) 443acc142b6SChristophe Leroy EXCEPTION(0x1700, Trap_17, unknown_exception) 444acc142b6SChristophe Leroy EXCEPTION(0x1800, Trap_18, unknown_exception) 445acc142b6SChristophe Leroy EXCEPTION(0x1900, Trap_19, unknown_exception) 446acc142b6SChristophe Leroy EXCEPTION(0x1A00, Trap_1A, unknown_exception) 447acc142b6SChristophe Leroy EXCEPTION(0x1B00, Trap_1B, unknown_exception) 448acc142b6SChristophe Leroy EXCEPTION(0x1C00, Trap_1C, unknown_exception) 449acc142b6SChristophe Leroy EXCEPTION(0x1D00, Trap_1D, unknown_exception) 450acc142b6SChristophe Leroy EXCEPTION(0x1E00, Trap_1E, unknown_exception) 451acc142b6SChristophe Leroy EXCEPTION(0x1F00, Trap_1F, unknown_exception) 45215f6527eSJosh Boyer 45315f6527eSJosh Boyer/* Check for a single step debug exception while in an exception 45415f6527eSJosh Boyer * handler before state has been saved. This is to catch the case 45515f6527eSJosh Boyer * where an instruction that we are trying to single step causes 45615f6527eSJosh Boyer * an exception (eg ITLB/DTLB miss) and thus the first instruction of 45715f6527eSJosh Boyer * the exception handler generates a single step debug exception. 45815f6527eSJosh Boyer * 45915f6527eSJosh Boyer * If we get a debug trap on the first instruction of an exception handler, 46015f6527eSJosh Boyer * we reset the MSR_DE in the _exception handler's_ MSR (the debug trap is 46115f6527eSJosh Boyer * a critical exception, so we are using SPRN_CSRR1 to manipulate the MSR). 46215f6527eSJosh Boyer * The exception handler was handling a non-critical interrupt, so it will 46315f6527eSJosh Boyer * save (and later restore) the MSR via SPRN_SRR1, which will still have 46415f6527eSJosh Boyer * the MSR_DE bit set. 46515f6527eSJosh Boyer */ 46615f6527eSJosh Boyer /* 0x2000 - Debug Exception */ 46715f6527eSJosh Boyer START_EXCEPTION(0x2000, DebugTrap) 468719e7e21SChristophe Leroy CRITICAL_EXCEPTION_PROLOG 0x2000 DebugTrap 46915f6527eSJosh Boyer 47015f6527eSJosh Boyer /* 47115f6527eSJosh Boyer * If this is a single step or branch-taken exception in an 47215f6527eSJosh Boyer * exception entry sequence, it was probably meant to apply to 47315f6527eSJosh Boyer * the code where the exception occurred (since exception entry 47415f6527eSJosh Boyer * doesn't turn off DE automatically). We simulate the effect 47515f6527eSJosh Boyer * of turning off DE on entry to an exception handler by turning 47615f6527eSJosh Boyer * off DE in the SRR3 value and clearing the debug status. 47715f6527eSJosh Boyer */ 47815f6527eSJosh Boyer mfspr r10,SPRN_DBSR /* check single-step/branch taken */ 47915f6527eSJosh Boyer andis. r10,r10,DBSR_IC@h 48015f6527eSJosh Boyer beq+ 2f 48115f6527eSJosh Boyer 48215f6527eSJosh Boyer andi. r10,r9,MSR_IR|MSR_PR /* check supervisor + MMU off */ 48315f6527eSJosh Boyer beq 1f /* branch and fix it up */ 48415f6527eSJosh Boyer 48515f6527eSJosh Boyer mfspr r10,SPRN_SRR2 /* Faulting instruction address */ 48615f6527eSJosh Boyer cmplwi r10,0x2100 48715f6527eSJosh Boyer bgt+ 2f /* address above exception vectors */ 48815f6527eSJosh Boyer 48915f6527eSJosh Boyer /* here it looks like we got an inappropriate debug exception. */ 49015f6527eSJosh Boyer1: rlwinm r9,r9,0,~MSR_DE /* clear DE in the SRR3 value */ 49115f6527eSJosh Boyer lis r10,DBSR_IC@h /* clear the IC event */ 49215f6527eSJosh Boyer mtspr SPRN_DBSR,r10 49315f6527eSJosh Boyer /* restore state and get out */ 49415f6527eSJosh Boyer lwz r10,_CCR(r11) 49515f6527eSJosh Boyer lwz r0,GPR0(r11) 49615f6527eSJosh Boyer lwz r1,GPR1(r11) 49715f6527eSJosh Boyer mtcrf 0x80,r10 49815f6527eSJosh Boyer mtspr SPRN_SRR2,r12 49915f6527eSJosh Boyer mtspr SPRN_SRR3,r9 50015f6527eSJosh Boyer lwz r9,GPR9(r11) 50115f6527eSJosh Boyer lwz r12,GPR12(r11) 50215f6527eSJosh Boyer lwz r10,crit_r10@l(0) 50315f6527eSJosh Boyer lwz r11,crit_r11@l(0) 50415f6527eSJosh Boyer rfci 50515f6527eSJosh Boyer b . 50615f6527eSJosh Boyer 50715f6527eSJosh Boyer /* continue normal handling for a critical exception... */ 50815f6527eSJosh Boyer2: mfspr r4,SPRN_DBSR 509755d6641SNicholas Piggin stw r4,_ESR(r11) /* DebugException takes DBSR in _ESR */ 5104c0104a8SChristophe Leroy prepare_transfer_to_handler 5114c0104a8SChristophe Leroy bl DebugException 5124c0104a8SChristophe Leroy b ret_from_crit_exc 51315f6527eSJosh Boyer 5141e18c17aSJason Gunthorpe /* Programmable Interval Timer (PIT) Exception. (from 0x1000) */ 515dc13b889SChristophe Leroy __HEAD 5161e18c17aSJason GunthorpeDecrementer: 517719e7e21SChristophe Leroy EXCEPTION_PROLOG 0x1000 Decrementer 5181e18c17aSJason Gunthorpe lis r0,TSR_PIS@h 5191e18c17aSJason Gunthorpe mtspr SPRN_TSR,r0 /* Clear the PIT exception */ 5204c0104a8SChristophe Leroy prepare_transfer_to_handler 5214c0104a8SChristophe Leroy bl timer_interrupt 5224c0104a8SChristophe Leroy b interrupt_return 5231e18c17aSJason Gunthorpe 5241e18c17aSJason Gunthorpe /* Fixed Interval Timer (FIT) Exception. (from 0x1010) */ 525dc13b889SChristophe Leroy __HEAD 5261e18c17aSJason GunthorpeFITException: 527719e7e21SChristophe Leroy EXCEPTION_PROLOG 0x1010 FITException 5284c0104a8SChristophe Leroy prepare_transfer_to_handler 5294c0104a8SChristophe Leroy bl unknown_exception 5304c0104a8SChristophe Leroy b interrupt_return 5311e18c17aSJason Gunthorpe 5321e18c17aSJason Gunthorpe /* Watchdog Timer (WDT) Exception. (from 0x1020) */ 533dc13b889SChristophe Leroy __HEAD 5341e18c17aSJason GunthorpeWDTException: 535719e7e21SChristophe Leroy CRITICAL_EXCEPTION_PROLOG 0x1020 WDTException 5364c0104a8SChristophe Leroy prepare_transfer_to_handler 5374c0104a8SChristophe Leroy bl WatchdogException 5384c0104a8SChristophe Leroy b ret_from_crit_exc 5391e18c17aSJason Gunthorpe 54015f6527eSJosh Boyer/* Other PowerPC processors, namely those derived from the 6xx-series 54115f6527eSJosh Boyer * have vectors from 0x2100 through 0x2F00 defined, but marked as reserved. 54215f6527eSJosh Boyer * However, for the 4xx-series processors these are neither defined nor 54315f6527eSJosh Boyer * reserved. 54415f6527eSJosh Boyer */ 54515f6527eSJosh Boyer 546dc13b889SChristophe Leroy __HEAD 54715f6527eSJosh Boyer /* Damn, I came up one instruction too many to fit into the 54815f6527eSJosh Boyer * exception space :-). Both the instruction and data TLB 54915f6527eSJosh Boyer * miss get to this point to load the TLB. 55015f6527eSJosh Boyer * r10 - TLB_TAG value 55115f6527eSJosh Boyer * r11 - Linux PTE 552797f4016SChristophe Leroy * r9 - available to use 55315f6527eSJosh Boyer * PID - loaded with proper value when we get here 55415f6527eSJosh Boyer * Upon exit, we reload everything and RFI. 55515f6527eSJosh Boyer * Actually, it will fit now, but oh well.....a common place 55615f6527eSJosh Boyer * to load the TLB. 55715f6527eSJosh Boyer */ 55815f6527eSJosh Boyertlb_4xx_index: 55915f6527eSJosh Boyer .long 0 56015f6527eSJosh Boyerfinish_tlb_load: 56115f6527eSJosh Boyer /* 56215f6527eSJosh Boyer * Clear out the software-only bits in the PTE to generate the 56315f6527eSJosh Boyer * TLB_DATA value. These are the bottom 2 bits of the RPM, the 56415f6527eSJosh Boyer * top 3 bits of the zone field, and M. 56515f6527eSJosh Boyer */ 566797f4016SChristophe Leroy li r9, 0x0ce2 567797f4016SChristophe Leroy andc r11, r11, r9 568797f4016SChristophe Leroy 569797f4016SChristophe Leroy /* load the next available TLB index. */ 570797f4016SChristophe Leroy lwz r9, tlb_4xx_index@l(0) 571797f4016SChristophe Leroy addi r9, r9, 1 572797f4016SChristophe Leroy andi. r9, r9, PPC40X_TLB_SIZE - 1 573797f4016SChristophe Leroy stw r9, tlb_4xx_index@l(0) 57415f6527eSJosh Boyer 57515f6527eSJosh Boyer tlbwe r11, r9, TLB_DATA /* Load TLB LO */ 57615f6527eSJosh Boyer tlbwe r10, r9, TLB_TAG /* Load TLB HI */ 57715f6527eSJosh Boyer 57815f6527eSJosh Boyer /* Done...restore registers and get out of here. 57915f6527eSJosh Boyer */ 58052ae92ccSChristophe Leroy mtspr SPRN_PID, r12 58152ae92ccSChristophe Leroy mtcrf 0x80, r12 582ee43eb78SBenjamin Herrenschmidt mfspr r9, SPRN_SPRG_SCRATCH4 583ee43eb78SBenjamin Herrenschmidt mfspr r12, SPRN_SPRG_SCRATCH3 58452ae92ccSChristophe Leroy mfspr r11, SPRN_SPRG_SCRATCH6 58552ae92ccSChristophe Leroy mfspr r10, SPRN_SPRG_SCRATCH5 58615f6527eSJosh Boyer rfi /* Should sync shadow TLBs */ 58715f6527eSJosh Boyer b . /* prevent prefetch past rfi */ 58815f6527eSJosh Boyer 58915f6527eSJosh Boyer/* This is where the main kernel code starts. 59015f6527eSJosh Boyer */ 59115f6527eSJosh Boyerstart_here: 59215f6527eSJosh Boyer 59315f6527eSJosh Boyer /* ptr to current */ 59415f6527eSJosh Boyer lis r2,init_task@h 59515f6527eSJosh Boyer ori r2,r2,init_task@l 59615f6527eSJosh Boyer 59715f6527eSJosh Boyer /* ptr to phys current thread */ 59815f6527eSJosh Boyer tophys(r4,r2) 59915f6527eSJosh Boyer addi r4,r4,THREAD /* init task's THREAD */ 600ee43eb78SBenjamin Herrenschmidt mtspr SPRN_SPRG_THREAD,r4 60115f6527eSJosh Boyer 60215f6527eSJosh Boyer /* stack */ 60315f6527eSJosh Boyer lis r1,init_thread_union@ha 60415f6527eSJosh Boyer addi r1,r1,init_thread_union@l 60515f6527eSJosh Boyer li r0,0 606*90f1b431SNicholas Piggin stwu r0,THREAD_SIZE-STACK_FRAME_MIN_SIZE(r1) 60715f6527eSJosh Boyer 60815f6527eSJosh Boyer bl early_init /* We have to do this with MMU on */ 60915f6527eSJosh Boyer 61015f6527eSJosh Boyer/* 61115f6527eSJosh Boyer * Decide what sort of machine this is and initialize the MMU. 61215f6527eSJosh Boyer */ 6132edb16efSChristophe Leroy#ifdef CONFIG_KASAN 6142edb16efSChristophe Leroy bl kasan_early_init 6152edb16efSChristophe Leroy#endif 6166dece0ebSScott Wood li r3,0 6176dece0ebSScott Wood mr r4,r31 61815f6527eSJosh Boyer bl machine_init 61915f6527eSJosh Boyer bl MMU_init 62015f6527eSJosh Boyer 62115f6527eSJosh Boyer/* Go back to running unmapped so we can load up new values 62215f6527eSJosh Boyer * and change to using our exception vectors. 62315f6527eSJosh Boyer * On the 4xx, all we have to do is invalidate the TLB to clear 62415f6527eSJosh Boyer * the old 16M byte TLB mappings. 62515f6527eSJosh Boyer */ 62615f6527eSJosh Boyer lis r4,2f@h 62715f6527eSJosh Boyer ori r4,r4,2f@l 62815f6527eSJosh Boyer tophys(r4,r4) 62915f6527eSJosh Boyer lis r3,(MSR_KERNEL & ~(MSR_IR|MSR_DR))@h 63015f6527eSJosh Boyer ori r3,r3,(MSR_KERNEL & ~(MSR_IR|MSR_DR))@l 63115f6527eSJosh Boyer mtspr SPRN_SRR0,r4 63215f6527eSJosh Boyer mtspr SPRN_SRR1,r3 63315f6527eSJosh Boyer rfi 63415f6527eSJosh Boyer b . /* prevent prefetch past rfi */ 63515f6527eSJosh Boyer 63615f6527eSJosh Boyer/* Load up the kernel context */ 63715f6527eSJosh Boyer2: 63815f6527eSJosh Boyer sync /* Flush to memory before changing TLB */ 63915f6527eSJosh Boyer tlbia 64015f6527eSJosh Boyer isync /* Flush shadow TLBs */ 64115f6527eSJosh Boyer 64215f6527eSJosh Boyer /* set up the PTE pointers for the Abatron bdiGDB. 64315f6527eSJosh Boyer */ 64415f6527eSJosh Boyer lis r6, swapper_pg_dir@h 64515f6527eSJosh Boyer ori r6, r6, swapper_pg_dir@l 64615f6527eSJosh Boyer lis r5, abatron_pteptrs@h 64715f6527eSJosh Boyer ori r5, r5, abatron_pteptrs@l 6488d8a629dSMichael Ellerman stw r5, 0xf0(0) /* Must match your Abatron config file */ 64915f6527eSJosh Boyer tophys(r5,r5) 65015f6527eSJosh Boyer stw r6, 0(r5) 65115f6527eSJosh Boyer 65215f6527eSJosh Boyer/* Now turn on the MMU for real! */ 65315f6527eSJosh Boyer lis r4,MSR_KERNEL@h 65415f6527eSJosh Boyer ori r4,r4,MSR_KERNEL@l 65515f6527eSJosh Boyer lis r3,start_kernel@h 65615f6527eSJosh Boyer ori r3,r3,start_kernel@l 65715f6527eSJosh Boyer mtspr SPRN_SRR0,r3 65815f6527eSJosh Boyer mtspr SPRN_SRR1,r4 65915f6527eSJosh Boyer rfi /* enable MMU and jump to start_kernel */ 66015f6527eSJosh Boyer b . /* prevent prefetch past rfi */ 66115f6527eSJosh Boyer 66215f6527eSJosh Boyer/* Set up the initial MMU state so we can do the first level of 66306e7cbc2SChristophe Leroy * kernel initialization. This maps the first 32 MBytes of memory 1:1 66415f6527eSJosh Boyer * virtual to physical and more importantly sets the cache mode. 66515f6527eSJosh Boyer */ 6662da37761SChristophe LeroySYM_FUNC_START_LOCAL(initial_mmu) 66715f6527eSJosh Boyer tlbia /* Invalidate all TLB entries */ 66815f6527eSJosh Boyer isync 66915f6527eSJosh Boyer 67015f6527eSJosh Boyer /* We should still be executing code at physical address 0x0000xxxx 67115f6527eSJosh Boyer * at this point. However, start_here is at virtual address 67215f6527eSJosh Boyer * 0xC000xxxx. So, set up a TLB mapping to cover this once 67315f6527eSJosh Boyer * translation is enabled. 67415f6527eSJosh Boyer */ 67515f6527eSJosh Boyer 67615f6527eSJosh Boyer lis r3,KERNELBASE@h /* Load the kernel virtual address */ 67715f6527eSJosh Boyer ori r3,r3,KERNELBASE@l 67815f6527eSJosh Boyer tophys(r4,r3) /* Load the kernel physical address */ 67915f6527eSJosh Boyer 68015f6527eSJosh Boyer iccci r0,r3 /* Invalidate the i-cache before use */ 68115f6527eSJosh Boyer 68215f6527eSJosh Boyer /* Load the kernel PID. 68315f6527eSJosh Boyer */ 68415f6527eSJosh Boyer li r0,0 68515f6527eSJosh Boyer mtspr SPRN_PID,r0 68615f6527eSJosh Boyer sync 68715f6527eSJosh Boyer 688cd3db0c4SBenjamin Herrenschmidt /* Configure and load one entry into TLB slots 63 */ 68915f6527eSJosh Boyer clrrwi r4,r4,10 /* Mask off the real page number */ 69015f6527eSJosh Boyer ori r4,r4,(TLB_WR | TLB_EX) /* Set the write and execute bits */ 69115f6527eSJosh Boyer 69215f6527eSJosh Boyer clrrwi r3,r3,10 /* Mask off the effective page number */ 69315f6527eSJosh Boyer ori r3,r3,(TLB_VALID | TLB_PAGESZ(PAGESZ_16M)) 69415f6527eSJosh Boyer 69515f6527eSJosh Boyer li r0,63 /* TLB slot 63 */ 69615f6527eSJosh Boyer 69715f6527eSJosh Boyer tlbwe r4,r0,TLB_DATA /* Load the data portion of the entry */ 69815f6527eSJosh Boyer tlbwe r3,r0,TLB_TAG /* Load the tag portion of the entry */ 69915f6527eSJosh Boyer 70006e7cbc2SChristophe Leroy li r0,62 /* TLB slot 62 */ 70106e7cbc2SChristophe Leroy addis r4,r4,SZ_16M@h 70206e7cbc2SChristophe Leroy addis r3,r3,SZ_16M@h 70306e7cbc2SChristophe Leroy tlbwe r4,r0,TLB_DATA /* Load the data portion of the entry */ 70406e7cbc2SChristophe Leroy tlbwe r3,r0,TLB_TAG /* Load the tag portion of the entry */ 70506e7cbc2SChristophe Leroy 70615f6527eSJosh Boyer isync 70715f6527eSJosh Boyer 70815f6527eSJosh Boyer /* Establish the exception vector base 70915f6527eSJosh Boyer */ 71015f6527eSJosh Boyer lis r4,KERNELBASE@h /* EVPR only uses the high 16-bits */ 71115f6527eSJosh Boyer tophys(r0,r4) /* Use the physical address */ 71215f6527eSJosh Boyer mtspr SPRN_EVPR,r0 71315f6527eSJosh Boyer 71415f6527eSJosh Boyer blr 7152da37761SChristophe LeroySYM_FUNC_END(initial_mmu) 71615f6527eSJosh Boyer 71715f6527eSJosh Boyer_GLOBAL(abort) 71815f6527eSJosh Boyer mfspr r13,SPRN_DBCR0 71915f6527eSJosh Boyer oris r13,r13,DBCR0_RST_SYSTEM@h 72015f6527eSJosh Boyer mtspr SPRN_DBCR0,r13 721