12874c5fdSThomas Gleixner/* SPDX-License-Identifier: GPL-2.0-or-later */ 22d27cfd3SBenjamin Herrenschmidt/* 32d27cfd3SBenjamin Herrenschmidt * Boot code and exception vectors for Book3E processors 42d27cfd3SBenjamin Herrenschmidt * 52d27cfd3SBenjamin Herrenschmidt * Copyright (C) 2007 Ben. Herrenschmidt (benh@kernel.crashing.org), IBM Corp. 62d27cfd3SBenjamin Herrenschmidt */ 72d27cfd3SBenjamin Herrenschmidt 82d27cfd3SBenjamin Herrenschmidt#include <linux/linkage.h> 92d27cfd3SBenjamin Herrenschmidt#include <linux/threads.h> 102d27cfd3SBenjamin Herrenschmidt#include <asm/reg.h> 112d27cfd3SBenjamin Herrenschmidt#include <asm/page.h> 122d27cfd3SBenjamin Herrenschmidt#include <asm/ppc_asm.h> 132d27cfd3SBenjamin Herrenschmidt#include <asm/asm-offsets.h> 142d27cfd3SBenjamin Herrenschmidt#include <asm/cputable.h> 152d27cfd3SBenjamin Herrenschmidt#include <asm/setup.h> 16a0496d45SJack Miller#include <asm/thread_info.h> 172d27cfd3SBenjamin Herrenschmidt#include <asm/reg_a2.h> 182d27cfd3SBenjamin Herrenschmidt#include <asm/exception-64e.h> 192d27cfd3SBenjamin Herrenschmidt#include <asm/bug.h> 202d27cfd3SBenjamin Herrenschmidt#include <asm/irqflags.h> 212d27cfd3SBenjamin Herrenschmidt#include <asm/ptrace.h> 222d27cfd3SBenjamin Herrenschmidt#include <asm/ppc-opcode.h> 237230c564SBenjamin Herrenschmidt#include <asm/mmu.h> 24fecff0f7SMihai Caraman#include <asm/hw_irq.h> 25fecff0f7SMihai Caraman#include <asm/kvm_asm.h> 262c86cd18SChristophe Leroy#include <asm/kvm_booke_hv_asm.h> 276cc0c16dSNicholas Piggin#include <asm/feature-fixups.h> 282d27cfd3SBenjamin Herrenschmidt#include <asm/context_tracking.h> 291df7d5e4SNicholas Piggin 301df7d5e4SNicholas Piggin/* 64e interrupt returns always use SRR registers */ 311df7d5e4SNicholas Piggin#define fast_interrupt_return fast_interrupt_return_srr 321df7d5e4SNicholas Piggin#define interrupt_return interrupt_return_srr 332d27cfd3SBenjamin Herrenschmidt 342d27cfd3SBenjamin Herrenschmidt/* XXX This will ultimately add space for a special exception save 352d27cfd3SBenjamin Herrenschmidt * structure used to save things like SRR0/SRR1, SPRGs, MAS, etc... 362d27cfd3SBenjamin Herrenschmidt * when taking special interrupts. For now we don't support that, 372d27cfd3SBenjamin Herrenschmidt * special interrupts from within a non-standard level will probably 382d27cfd3SBenjamin Herrenschmidt * blow you up 39609af38fSScott Wood */ 40609af38fSScott Wood#define SPECIAL_EXC_SRR0 0 41609af38fSScott Wood#define SPECIAL_EXC_SRR1 1 42609af38fSScott Wood#define SPECIAL_EXC_SPRG_GEN 2 43609af38fSScott Wood#define SPECIAL_EXC_SPRG_TLB 3 44609af38fSScott Wood#define SPECIAL_EXC_MAS0 4 45609af38fSScott Wood#define SPECIAL_EXC_MAS1 5 46609af38fSScott Wood#define SPECIAL_EXC_MAS2 6 47609af38fSScott Wood#define SPECIAL_EXC_MAS3 7 48609af38fSScott Wood#define SPECIAL_EXC_MAS6 8 49609af38fSScott Wood#define SPECIAL_EXC_MAS7 9 50609af38fSScott Wood#define SPECIAL_EXC_MAS5 10 /* E.HV only */ 51609af38fSScott Wood#define SPECIAL_EXC_MAS8 11 /* E.HV only */ 52609af38fSScott Wood#define SPECIAL_EXC_IRQHAPPENED 12 53609af38fSScott Wood#define SPECIAL_EXC_DEAR 13 54609af38fSScott Wood#define SPECIAL_EXC_ESR 14 55609af38fSScott Wood#define SPECIAL_EXC_SOFTE 15 56609af38fSScott Wood#define SPECIAL_EXC_CSRR0 16 57609af38fSScott Wood#define SPECIAL_EXC_CSRR1 17 58609af38fSScott Wood/* must be even to keep 16-byte stack alignment */ 592d27cfd3SBenjamin Herrenschmidt#define SPECIAL_EXC_END 18 60609af38fSScott Wood 61609af38fSScott Wood#define SPECIAL_EXC_FRAME_SIZE (INT_FRAME_SIZE + SPECIAL_EXC_END * 8) 6219007b34STiejun Chen#define SPECIAL_EXC_FRAME_OFFS (INT_FRAME_SIZE - 288) 63609af38fSScott Wood 64609af38fSScott Wood#define SPECIAL_EXC_STORE(reg, name) \ 65609af38fSScott Wood std reg, (SPECIAL_EXC_##name * 8 + SPECIAL_EXC_FRAME_OFFS)(r1) 66609af38fSScott Wood 67609af38fSScott Wood#define SPECIAL_EXC_LOAD(reg, name) \ 68609af38fSScott Wood ld reg, (SPECIAL_EXC_##name * 8 + SPECIAL_EXC_FRAME_OFFS)(r1) 69609af38fSScott Wood 70609af38fSScott WoodSYM_CODE_START_LOCAL(special_reg_save) 71609af38fSScott Wood /* 72609af38fSScott Wood * We only need (or have stack space) to save this stuff if 73609af38fSScott Wood * we interrupted the kernel. 74609af38fSScott Wood */ 75609af38fSScott Wood ld r3,_MSR(r1) 76609af38fSScott Wood andi. r3,r3,MSR_PR 77609af38fSScott Wood bnelr 78609af38fSScott Wood 79609af38fSScott Wood /* 80609af38fSScott Wood * Advance to the next TLB exception frame for handler 81609af38fSScott Wood * types that don't do it automatically. 82609af38fSScott Wood */ 83609af38fSScott Wood LOAD_REG_ADDR(r11,extlb_level_exc) 84609af38fSScott Wood lwz r12,0(r11) 85609af38fSScott Wood mfspr r10,SPRN_SPRG_TLB_EXFRAME 86609af38fSScott Wood add r10,r10,r12 87609af38fSScott Wood mtspr SPRN_SPRG_TLB_EXFRAME,r10 88609af38fSScott Wood 89609af38fSScott Wood /* 90609af38fSScott Wood * Save registers needed to allow nesting of certain exceptions 91609af38fSScott Wood * (such as TLB misses) inside special exception levels 92609af38fSScott Wood */ 93609af38fSScott Wood mfspr r10,SPRN_SRR0 94609af38fSScott Wood SPECIAL_EXC_STORE(r10,SRR0) 95609af38fSScott Wood mfspr r10,SPRN_SRR1 96609af38fSScott Wood SPECIAL_EXC_STORE(r10,SRR1) 97609af38fSScott Wood mfspr r10,SPRN_SPRG_GEN_SCRATCH 98609af38fSScott Wood SPECIAL_EXC_STORE(r10,SPRG_GEN) 99609af38fSScott Wood mfspr r10,SPRN_SPRG_TLB_SCRATCH 100609af38fSScott Wood SPECIAL_EXC_STORE(r10,SPRG_TLB) 101609af38fSScott Wood mfspr r10,SPRN_MAS0 102609af38fSScott Wood SPECIAL_EXC_STORE(r10,MAS0) 103609af38fSScott Wood mfspr r10,SPRN_MAS1 104609af38fSScott Wood SPECIAL_EXC_STORE(r10,MAS1) 105609af38fSScott Wood mfspr r10,SPRN_MAS2 106609af38fSScott Wood SPECIAL_EXC_STORE(r10,MAS2) 107609af38fSScott Wood mfspr r10,SPRN_MAS3 108609af38fSScott Wood SPECIAL_EXC_STORE(r10,MAS3) 109609af38fSScott Wood mfspr r10,SPRN_MAS6 110609af38fSScott Wood SPECIAL_EXC_STORE(r10,MAS6) 111609af38fSScott Wood mfspr r10,SPRN_MAS7 112609af38fSScott Wood SPECIAL_EXC_STORE(r10,MAS7) 113609af38fSScott WoodBEGIN_FTR_SECTION 114609af38fSScott Wood mfspr r10,SPRN_MAS5 115609af38fSScott Wood SPECIAL_EXC_STORE(r10,MAS5) 116609af38fSScott Wood mfspr r10,SPRN_MAS8 117609af38fSScott Wood SPECIAL_EXC_STORE(r10,MAS8) 118609af38fSScott Wood 119609af38fSScott Wood /* MAS5/8 could have inappropriate values if we interrupted KVM code */ 120609af38fSScott Wood li r10,0 121609af38fSScott Wood mtspr SPRN_MAS5,r10 122609af38fSScott Wood mtspr SPRN_MAS8,r10 123609af38fSScott WoodEND_FTR_SECTION_IFSET(CPU_FTR_EMB_HV) 124609af38fSScott Wood mfspr r10,SPRN_DEAR 125609af38fSScott Wood SPECIAL_EXC_STORE(r10,DEAR) 126609af38fSScott Wood mfspr r10,SPRN_ESR 127609af38fSScott Wood SPECIAL_EXC_STORE(r10,ESR) 128609af38fSScott Wood 129609af38fSScott Wood ld r10,_NIP(r1) 130609af38fSScott Wood SPECIAL_EXC_STORE(r10,CSRR0) 131609af38fSScott Wood ld r10,_MSR(r1) 132609af38fSScott Wood SPECIAL_EXC_STORE(r10,CSRR1) 133609af38fSScott Wood 134609af38fSScott Wood blr 135609af38fSScott WoodSYM_CODE_END(special_reg_save) 136609af38fSScott Wood 137609af38fSScott WoodSYM_CODE_START_LOCAL(ret_from_level_except) 138609af38fSScott Wood ld r3,_MSR(r1) 1390c2472deSNicholas Piggin andi. r3,r3,MSR_PR 1400c2472deSNicholas Piggin beq 1f 141609af38fSScott Wood REST_NVGPRS(r1) 142609af38fSScott Wood b interrupt_return 143609af38fSScott Wood1: 144609af38fSScott Wood 145609af38fSScott Wood LOAD_REG_ADDR(r11,extlb_level_exc) 146609af38fSScott Wood lwz r12,0(r11) 147609af38fSScott Wood mfspr r10,SPRN_SPRG_TLB_EXFRAME 148609af38fSScott Wood sub r10,r10,r12 149609af38fSScott Wood mtspr SPRN_SPRG_TLB_EXFRAME,r10 150609af38fSScott Wood 151609af38fSScott Wood /* 152609af38fSScott Wood * It's possible that the special level exception interrupted a 153609af38fSScott Wood * TLB miss handler, and inserted the same entry that the 154609af38fSScott Wood * interrupted handler was about to insert. On CPUs without TLB 155609af38fSScott Wood * write conditional, this can result in a duplicate TLB entry. 156609af38fSScott Wood * Wipe all non-bolted entries to be safe. 157609af38fSScott Wood * 158609af38fSScott Wood * Note that this doesn't protect against any TLB misses 159609af38fSScott Wood * we may take accessing the stack from here to the end of 160609af38fSScott Wood * the special level exception. It's not clear how we can 161609af38fSScott Wood * reasonably protect against that, but only CPUs with 162609af38fSScott Wood * neither TLB write conditional nor bolted kernel memory 163609af38fSScott Wood * are affected. Do any such CPUs even exist? 164609af38fSScott Wood */ 165609af38fSScott Wood PPC_TLBILX_ALL(0,R0) 166609af38fSScott Wood 167609af38fSScott Wood REST_NVGPRS(r1) 168609af38fSScott Wood 169609af38fSScott Wood SPECIAL_EXC_LOAD(r10,SRR0) 170609af38fSScott Wood mtspr SPRN_SRR0,r10 171609af38fSScott Wood SPECIAL_EXC_LOAD(r10,SRR1) 172609af38fSScott Wood mtspr SPRN_SRR1,r10 173609af38fSScott Wood SPECIAL_EXC_LOAD(r10,SPRG_GEN) 174609af38fSScott Wood mtspr SPRN_SPRG_GEN_SCRATCH,r10 175609af38fSScott Wood SPECIAL_EXC_LOAD(r10,SPRG_TLB) 176609af38fSScott Wood mtspr SPRN_SPRG_TLB_SCRATCH,r10 177609af38fSScott Wood SPECIAL_EXC_LOAD(r10,MAS0) 178609af38fSScott Wood mtspr SPRN_MAS0,r10 179609af38fSScott Wood SPECIAL_EXC_LOAD(r10,MAS1) 180609af38fSScott Wood mtspr SPRN_MAS1,r10 181609af38fSScott Wood SPECIAL_EXC_LOAD(r10,MAS2) 182609af38fSScott Wood mtspr SPRN_MAS2,r10 183609af38fSScott Wood SPECIAL_EXC_LOAD(r10,MAS3) 184609af38fSScott Wood mtspr SPRN_MAS3,r10 185609af38fSScott Wood SPECIAL_EXC_LOAD(r10,MAS6) 186609af38fSScott Wood mtspr SPRN_MAS6,r10 187609af38fSScott Wood SPECIAL_EXC_LOAD(r10,MAS7) 188609af38fSScott Wood mtspr SPRN_MAS7,r10 189609af38fSScott WoodBEGIN_FTR_SECTION 190609af38fSScott Wood SPECIAL_EXC_LOAD(r10,MAS5) 191609af38fSScott Wood mtspr SPRN_MAS5,r10 192609af38fSScott Wood SPECIAL_EXC_LOAD(r10,MAS8) 193609af38fSScott Wood mtspr SPRN_MAS8,r10 194609af38fSScott WoodEND_FTR_SECTION_IFSET(CPU_FTR_EMB_HV) 195609af38fSScott Wood 196609af38fSScott Wood SPECIAL_EXC_LOAD(r10,DEAR) 197609af38fSScott Wood mtspr SPRN_DEAR,r10 198609af38fSScott Wood SPECIAL_EXC_LOAD(r10,ESR) 199609af38fSScott Wood mtspr SPRN_ESR,r10 200609af38fSScott Wood 201aebd1fb4SNicholas Piggin stdcx. r0,0,r1 /* to clear the reservation */ 202609af38fSScott Wood 203609af38fSScott Wood REST_GPRS(2, 9, r1) 204609af38fSScott Wood 205609af38fSScott Wood ld r10,_CTR(r1) 206609af38fSScott Wood ld r11,_XER(r1) 207609af38fSScott Wood mtctr r10 208609af38fSScott Wood mtxer r11 209609af38fSScott Wood 210609af38fSScott Wood blr 211609af38fSScott WoodSYM_CODE_END(ret_from_level_except) 212609af38fSScott Wood 213609af38fSScott Wood.macro ret_from_level srr0 srr1 paca_ex scratch 214609af38fSScott Wood bl ret_from_level_except 215609af38fSScott Wood 216609af38fSScott Wood ld r10,_LINK(r1) 217609af38fSScott Wood ld r11,_CCR(r1) 218609af38fSScott Wood ld r0,GPR13(r1) 21953ecaa67SRohan McLure mtlr r10 220609af38fSScott Wood mtcr r11 221609af38fSScott Wood 222609af38fSScott Wood REST_GPRS(10, 12, r1) 223609af38fSScott Wood mtspr \scratch,r0 224609af38fSScott Wood 225609af38fSScott Wood std r10,\paca_ex+EX_R10(r13); 22653ecaa67SRohan McLure std r11,\paca_ex+EX_R11(r13); 22753ecaa67SRohan McLure ld r10,_NIP(r1) 228609af38fSScott Wood ld r11,_MSR(r1) 229609af38fSScott Wood REST_GPR(0, r1) 230609af38fSScott Wood REST_GPR(1, r1) 231609af38fSScott Wood mtspr \srr0,r10 232609af38fSScott Wood mtspr \srr1,r11 233609af38fSScott Wood ld r10,\paca_ex+EX_R10(r13) 234609af38fSScott Wood ld r11,\paca_ex+EX_R11(r13) 235609af38fSScott Wood mfspr r13,\scratch 236609af38fSScott Wood.endm 237609af38fSScott Wood 238609af38fSScott WoodSYM_CODE_START_LOCAL(ret_from_crit_except) 239609af38fSScott Wood ret_from_level SPRN_CSRR0 SPRN_CSRR1 PACA_EXCRIT SPRN_SPRG_CRIT_SCRATCH 240609af38fSScott Wood rfci 241609af38fSScott WoodSYM_CODE_END(ret_from_crit_except) 24219007b34STiejun Chen 2432d27cfd3SBenjamin HerrenschmidtSYM_CODE_START_LOCAL(ret_from_mc_except) 244fecff0f7SMihai Caraman ret_from_level SPRN_MCSRR0 SPRN_MCSRR1 PACA_EXMC SPRN_SPRG_MC_SCRATCH 2452d27cfd3SBenjamin Herrenschmidt rfmci 2462d27cfd3SBenjamin HerrenschmidtSYM_CODE_END(ret_from_mc_except) 2472d27cfd3SBenjamin Herrenschmidt 2482d27cfd3SBenjamin Herrenschmidt/* Exception prolog code for all exceptions */ 2492d27cfd3SBenjamin Herrenschmidt#define EXCEPTION_PROLOG(n, intnum, type, addition) \ 250fecff0f7SMihai Caraman mtspr SPRN_SPRG_##type##_SCRATCH,r13; /* get spare registers */ \ 251fecff0f7SMihai Caraman mfspr r13,SPRN_SPRG_PACA; /* get PACA */ \ 25279b5c8dbSMihai Caraman std r10,PACA_EX##type+EX_R10(r13); \ 2532d27cfd3SBenjamin Herrenschmidt std r11,PACA_EX##type+EX_R11(r13); \ 2542d27cfd3SBenjamin Herrenschmidt mfcr r10; /* save CR */ \ 2552d27cfd3SBenjamin Herrenschmidt mfspr r11,SPRN_##type##_SRR1;/* what are we coming from */ \ 2562d27cfd3SBenjamin Herrenschmidt DO_KVM intnum,SPRN_##type##_SRR1; /* KVM hook */ \ 2572d27cfd3SBenjamin Herrenschmidt stw r10,PACA_EX##type+EX_CR(r13); /* save old CR in the PACA */ \ 2582d27cfd3SBenjamin Herrenschmidt addition; /* additional code for that exc. */ \ 25910c5e83aSDiana Craciun std r1,PACA_EX##type+EX_R1(r13); /* save old r1 in the PACA */ \ 26010c5e83aSDiana Craciun type##_SET_KSTACK; /* get special stack if necessary */\ 2612d27cfd3SBenjamin Herrenschmidt andi. r10,r11,MSR_PR; /* save stack pointer */ \ 2622d27cfd3SBenjamin Herrenschmidt beq 1f; /* branch around if supervisor */ \ 2632d27cfd3SBenjamin Herrenschmidt ld r1,PACAKSAVE(r13); /* get kernel stack coming from usr */\ 2642d27cfd3SBenjamin Herrenschmidt1: type##_BTB_FLUSH \ 2652d27cfd3SBenjamin Herrenschmidt cmpdi cr1,r1,0; /* check if SP makes sense */ \ 2662d27cfd3SBenjamin Herrenschmidt bge- cr1,exc_##n##_bad_stack;/* bad stack (TODO: out of line) */ \ 2672d27cfd3SBenjamin Herrenschmidt mfspr r10,SPRN_##type##_SRR0; /* read SRR0 before touching stack */ 2682d27cfd3SBenjamin Herrenschmidt 2692d27cfd3SBenjamin Herrenschmidt/* Exception type-specific macros */ 2705473eb1cSMihai Caraman#define GEN_SET_KSTACK \ 2715473eb1cSMihai Caraman subi r1,r1,INT_FRAME_SIZE; /* alloc frame on kernel stack */ 2725473eb1cSMihai Caraman#define SPRN_GEN_SRR0 SPRN_SRR0 2735473eb1cSMihai Caraman#define SPRN_GEN_SRR1 SPRN_SRR1 2742d27cfd3SBenjamin Herrenschmidt 2752d27cfd3SBenjamin Herrenschmidt#define GDBELL_SET_KSTACK GEN_SET_KSTACK 276609af38fSScott Wood#define SPRN_GDBELL_SRR0 SPRN_GSRR0 2772d27cfd3SBenjamin Herrenschmidt#define SPRN_GDBELL_SRR1 SPRN_GSRR1 2782d27cfd3SBenjamin Herrenschmidt 2792d27cfd3SBenjamin Herrenschmidt#define CRIT_SET_KSTACK \ 2802d27cfd3SBenjamin Herrenschmidt ld r1,PACA_CRIT_STACK(r13); \ 2812d27cfd3SBenjamin Herrenschmidt subi r1,r1,SPECIAL_EXC_FRAME_SIZE 282609af38fSScott Wood#define SPRN_CRIT_SRR0 SPRN_CSRR0 2832d27cfd3SBenjamin Herrenschmidt#define SPRN_CRIT_SRR1 SPRN_CSRR1 2842d27cfd3SBenjamin Herrenschmidt 2852d27cfd3SBenjamin Herrenschmidt#define DBG_SET_KSTACK \ 2862d27cfd3SBenjamin Herrenschmidt ld r1,PACA_DBG_STACK(r13); \ 2872d27cfd3SBenjamin Herrenschmidt subi r1,r1,SPECIAL_EXC_FRAME_SIZE 288609af38fSScott Wood#define SPRN_DBG_SRR0 SPRN_DSRR0 2892d27cfd3SBenjamin Herrenschmidt#define SPRN_DBG_SRR1 SPRN_DSRR1 2902d27cfd3SBenjamin Herrenschmidt 2912d27cfd3SBenjamin Herrenschmidt#define MC_SET_KSTACK \ 29210c5e83aSDiana Craciun ld r1,PACA_MC_STACK(r13); \ 29310c5e83aSDiana Craciun subi r1,r1,SPECIAL_EXC_FRAME_SIZE 29410c5e83aSDiana Craciun#define SPRN_MC_SRR0 SPRN_MCSRR0 29510c5e83aSDiana Craciun#define SPRN_MC_SRR1 SPRN_MCSRR1 29610c5e83aSDiana Craciun 29710c5e83aSDiana Craciun#define GEN_BTB_FLUSH \ 29810c5e83aSDiana Craciun START_BTB_FLUSH_SECTION \ 29910c5e83aSDiana Craciun beq 1f; \ 30010c5e83aSDiana Craciun BTB_FLUSH(r10) \ 30110c5e83aSDiana Craciun 1: \ 30210c5e83aSDiana Craciun END_BTB_FLUSH_SECTION 30310c5e83aSDiana Craciun 30410c5e83aSDiana Craciun#define CRIT_BTB_FLUSH \ 30510c5e83aSDiana Craciun START_BTB_FLUSH_SECTION \ 30610c5e83aSDiana Craciun BTB_FLUSH(r10) \ 30710c5e83aSDiana Craciun END_BTB_FLUSH_SECTION 308fecff0f7SMihai Caraman 309fecff0f7SMihai Caraman#define DBG_BTB_FLUSH CRIT_BTB_FLUSH 3102d27cfd3SBenjamin Herrenschmidt#define MC_BTB_FLUSH CRIT_BTB_FLUSH 311fecff0f7SMihai Caraman#define GDBELL_BTB_FLUSH GEN_BTB_FLUSH 312fecff0f7SMihai Caraman 3132d27cfd3SBenjamin Herrenschmidt#define NORMAL_EXCEPTION_PROLOG(n, intnum, addition) \ 314fecff0f7SMihai Caraman EXCEPTION_PROLOG(n, intnum, GEN, addition##_GEN(n)) 315fecff0f7SMihai Caraman 3162d27cfd3SBenjamin Herrenschmidt#define CRIT_EXCEPTION_PROLOG(n, intnum, addition) \ 317fecff0f7SMihai Caraman EXCEPTION_PROLOG(n, intnum, CRIT, addition##_CRIT(n)) 318fecff0f7SMihai Caraman 3192d27cfd3SBenjamin Herrenschmidt#define DBG_EXCEPTION_PROLOG(n, intnum, addition) \ 320fecff0f7SMihai Caraman EXCEPTION_PROLOG(n, intnum, DBG, addition##_DBG(n)) 321fecff0f7SMihai Caraman 3222d27cfd3SBenjamin Herrenschmidt#define MC_EXCEPTION_PROLOG(n, intnum, addition) \ 3232d27cfd3SBenjamin Herrenschmidt EXCEPTION_PROLOG(n, intnum, MC, addition##_MC(n)) 3242d27cfd3SBenjamin Herrenschmidt 3257230c564SBenjamin Herrenschmidt#define GDBELL_EXCEPTION_PROLOG(n, intnum, addition) \ 3265473eb1cSMihai Caraman EXCEPTION_PROLOG(n, intnum, GDBELL, addition##_GDBELL(n)) 3277230c564SBenjamin Herrenschmidt 3287230c564SBenjamin Herrenschmidt/* Variants of the "addition" argument for the prolog 3297230c564SBenjamin Herrenschmidt */ 3302d27cfd3SBenjamin Herrenschmidt#define PROLOG_ADDITION_NONE_GEN(n) 3317230c564SBenjamin Herrenschmidt#define PROLOG_ADDITION_NONE_GDBELL(n) 3324e26bc4aSMadhavan Srinivasan#define PROLOG_ADDITION_NONE_CRIT(n) 33301417c6cSMadhavan Srinivasan#define PROLOG_ADDITION_NONE_DBG(n) 3349b69d48cSNicholas Piggin#define PROLOG_ADDITION_NONE_MC(n) 3352d27cfd3SBenjamin Herrenschmidt 336c6ac667bSNicholas Piggin#define PROLOG_ADDITION_MASKABLE_GEN(n) \ 337c6ac667bSNicholas Piggin lbz r10,PACAIRQSOFTMASK(r13); /* are irqs soft-masked? */ \ 338c6ac667bSNicholas Piggin andi. r10,r10,IRQS_DISABLED; /* yes -> go out of line */ \ 339c6ac667bSNicholas Piggin bne masked_interrupt_book3e_##n 340c6ac667bSNicholas Piggin 341c6ac667bSNicholas Piggin/* 3427230c564SBenjamin Herrenschmidt * Additional regs must be re-loaded from paca before EXCEPTION_COMMON* is 3432d27cfd3SBenjamin Herrenschmidt * called, because that does SAVE_NVGPRS which must see the original register 3442d27cfd3SBenjamin Herrenschmidt * values, otherwise the scratch values might be restored when exiting the 3452d27cfd3SBenjamin Herrenschmidt * interrupt. 3467230c564SBenjamin Herrenschmidt */ 3472d27cfd3SBenjamin Herrenschmidt#define PROLOG_ADDITION_2REGS_GEN(n) \ 3482d27cfd3SBenjamin Herrenschmidt std r14,PACA_EXGEN+EX_R14(r13); \ 3497230c564SBenjamin Herrenschmidt std r15,PACA_EXGEN+EX_R15(r13) 3502d27cfd3SBenjamin Herrenschmidt 3512d27cfd3SBenjamin Herrenschmidt#define PROLOG_ADDITION_1REG_GEN(n) \ 3522d27cfd3SBenjamin Herrenschmidt std r14,PACA_EXGEN+EX_R14(r13); 3537230c564SBenjamin Herrenschmidt 3542d27cfd3SBenjamin Herrenschmidt#define PROLOG_ADDITION_2REGS_CRIT(n) \ 3552d27cfd3SBenjamin Herrenschmidt std r14,PACA_EXCRIT+EX_R14(r13); \ 3562d27cfd3SBenjamin Herrenschmidt std r15,PACA_EXCRIT+EX_R15(r13) 3577230c564SBenjamin Herrenschmidt 3582d27cfd3SBenjamin Herrenschmidt#define PROLOG_ADDITION_2REGS_DBG(n) \ 3592d27cfd3SBenjamin Herrenschmidt std r14,PACA_EXDBG+EX_R14(r13); \ 3602d27cfd3SBenjamin Herrenschmidt std r15,PACA_EXDBG+EX_R15(r13) 3613d97a619SScott Wood 36231f71248SScott Wood#define PROLOG_ADDITION_2REGS_MC(n) \ 36331f71248SScott Wood std r14,PACA_EXMC+EX_R14(r13); \ 3647230c564SBenjamin Herrenschmidt std r15,PACA_EXMC+EX_R15(r13) 36553ecaa67SRohan McLure 36653ecaa67SRohan McLure/* Core exception code for all exceptions except TLB misses. */ 3672d27cfd3SBenjamin Herrenschmidt#define EXCEPTION_COMMON_LVL(n, scratch, excf) \ 3682d27cfd3SBenjamin Herrenschmidtexc_##n##_common: \ 3695d75b264SHaren Myneni SAVE_GPR(0, r1); /* save r0 in stackframe */ \ 3705d75b264SHaren Myneni SAVE_GPRS(2, 9, r1); /* save r2 - r9 in stackframe */ \ 3712d27cfd3SBenjamin Herrenschmidt std r10,_NIP(r1); /* save SRR0 to stackframe */ \ 37231f71248SScott Wood std r11,_MSR(r1); /* save SRR1 to stackframe */ \ 37353ecaa67SRohan McLure beq 2f; /* if from kernel mode */ \ 3748e93fb33SNicholas Piggin2: ld r3,excf+EX_R10(r13); /* get back r10 */ \ 3752d27cfd3SBenjamin Herrenschmidt ld r4,excf+EX_R11(r13); /* get back r11 */ \ 3762d27cfd3SBenjamin Herrenschmidt mfspr r5,scratch; /* get back r13 */ \ 3772d27cfd3SBenjamin Herrenschmidt SAVE_GPR(12, r1); /* save r12 in stackframe */ \ 3782d27cfd3SBenjamin Herrenschmidt LOAD_PACA_TOC(); /* get kernel TOC into r2 */ \ 3792d27cfd3SBenjamin Herrenschmidt mflr r6; /* save LR in stackframe */ \ 3804e26bc4aSMadhavan Srinivasan mfctr r7; /* save CTR in stackframe */ \ 38117773afdSNicholas Piggin mfspr r8,SPRN_XER; /* save XER in stackframe */ \ 38253ecaa67SRohan McLure ld r9,excf+EX_R1(r13); /* load orig r1 back from PACA */ \ 3832d27cfd3SBenjamin Herrenschmidt lwz r10,excf+EX_CR(r13); /* load orig CR back from PACA */ \ 3842d27cfd3SBenjamin Herrenschmidt lbz r11,PACAIRQSOFTMASK(r13); /* get current IRQ softe */ \ 3852d27cfd3SBenjamin Herrenschmidt LOAD_REG_IMMEDIATE(r12, STACK_FRAME_REGS_MARKER); \ 3862d27cfd3SBenjamin Herrenschmidt ZEROIZE_GPR(0); \ 3872d27cfd3SBenjamin Herrenschmidt std r3,GPR10(r1); /* save r10 to stackframe */ \ 3882d27cfd3SBenjamin Herrenschmidt std r4,GPR11(r1); /* save r11 to stackframe */ \ 3894228b2c3SNicholas Piggin std r5,GPR13(r1); /* save it to stackframe */ \ 3902d27cfd3SBenjamin Herrenschmidt std r6,_LINK(r1); \ 3912d27cfd3SBenjamin Herrenschmidt std r7,_CTR(r1); \ 3922d27cfd3SBenjamin Herrenschmidt std r8,_XER(r1); \ 3932d27cfd3SBenjamin Herrenschmidt li r3,(n); /* regs.trap vector */ \ 3942d27cfd3SBenjamin Herrenschmidt std r9,0(r1); /* store stack frame back link */ \ 3952d27cfd3SBenjamin Herrenschmidt std r10,_CCR(r1); /* store orig CR in stackframe */ \ 3964228b2c3SNicholas Piggin std r9,GPR1(r1); /* store stack frame back link */ \ 3974228b2c3SNicholas Piggin std r11,SOFTE(r1); /* and save it to stackframe */ \ 3982d27cfd3SBenjamin Herrenschmidt std r12,STACK_INT_FRAME_MARKER(r1); /* mark the frame */ \ 39931f71248SScott Wood std r3,_TRAP(r1); /* set trap number */ \ 40031f71248SScott Wood std r0,RESULT(r1); /* clear regs->result */ \ 40131f71248SScott Wood SAVE_NVGPRS(r1); \ 40231f71248SScott Wood SANITIZE_NVGPRS(); /* minimise speculation influence */ 40331f71248SScott Wood 40431f71248SScott Wood#define EXCEPTION_COMMON(n) \ 40531f71248SScott Wood EXCEPTION_COMMON_LVL(n, SPRN_SPRG_GEN_SCRATCH, PACA_EXGEN) 40631f71248SScott Wood#define EXCEPTION_COMMON_CRIT(n) \ 40731f71248SScott Wood EXCEPTION_COMMON_LVL(n, SPRN_SPRG_CRIT_SCRATCH, PACA_EXCRIT) 4082d27cfd3SBenjamin Herrenschmidt#define EXCEPTION_COMMON_MC(n) \ 4092d27cfd3SBenjamin Herrenschmidt EXCEPTION_COMMON_LVL(n, SPRN_SPRG_MC_SCRATCH, PACA_EXMC) 4102d27cfd3SBenjamin Herrenschmidt#define EXCEPTION_COMMON_DBG(n) \ 4112d27cfd3SBenjamin Herrenschmidt EXCEPTION_COMMON_LVL(n, SPRN_SPRG_DBG_SCRATCH, PACA_EXDBG) 4122d27cfd3SBenjamin Herrenschmidt 4132d27cfd3SBenjamin Herrenschmidt/* XXX FIXME: Restore r14/r15 when necessary */ 4142d27cfd3SBenjamin Herrenschmidt#define BAD_STACK_TRAMPOLINE(n) \ 415027dfac6SMichael Ellermanexc_##n##_bad_stack: \ 416ff82c319SBenjamin Herrenschmidt li r1,(n); /* get exception number */ \ 417ff82c319SBenjamin Herrenschmidt sth r1,PACA_TRAP_SAVE(r13); /* store trap */ \ 418ff82c319SBenjamin Herrenschmidt b bad_stack_book3e; /* bad stack error */ 419ff82c319SBenjamin Herrenschmidt 420ff82c319SBenjamin Herrenschmidt/* WARNING: If you change the layout of this stub, make sure you check 4212d27cfd3SBenjamin Herrenschmidt * the debug exception handler which handles single stepping 4222d27cfd3SBenjamin Herrenschmidt * into exceptions from userspace, and the MM code in 4232d27cfd3SBenjamin Herrenschmidt * arch/powerpc/mm/tlb_nohash.c which patches the branch here 4242d27cfd3SBenjamin Herrenschmidt * and would need to be updated if that branch is moved 4252d27cfd3SBenjamin Herrenschmidt */ 4262d27cfd3SBenjamin Herrenschmidt#define EXCEPTION_STUB(loc, label) \ 4272d27cfd3SBenjamin Herrenschmidt . = interrupt_base_book3e + loc; \ 4282d27cfd3SBenjamin Herrenschmidt nop; /* To make debug interrupts happy */ \ 4292d27cfd3SBenjamin Herrenschmidt b exc_##label##_book3e; 4302d27cfd3SBenjamin Herrenschmidt 4312d27cfd3SBenjamin Herrenschmidt#define ACK_NONE(r) 4322d27cfd3SBenjamin Herrenschmidt#define ACK_DEC(r) \ 4332d27cfd3SBenjamin Herrenschmidt lis r,TSR_DIS@h; \ 43434d97e07SBenjamin Herrenschmidt mtspr SPRN_TSR,r 43534d97e07SBenjamin Herrenschmidt#define ACK_FIT(r) \ 43634d97e07SBenjamin Herrenschmidt lis r,TSR_FIS@h; \ 43734d97e07SBenjamin Herrenschmidt mtspr SPRN_TSR,r 43834d97e07SBenjamin Herrenschmidt 43934d97e07SBenjamin Herrenschmidt/* Used by asynchronous interrupt that may happen in the idle loop. 44034d97e07SBenjamin Herrenschmidt * 441c911d2e1SChristophe Leroy * This check if the thread was in the idle loop, and if yes, returns 44234d97e07SBenjamin Herrenschmidt * to the caller rather than the PC. This is to avoid a race if 44334d97e07SBenjamin Herrenschmidt * interrupts happen before the wait instruction. 44434d97e07SBenjamin Herrenschmidt */ 44534d97e07SBenjamin Herrenschmidt#define CHECK_NAPPING() \ 44634d97e07SBenjamin Herrenschmidt ld r11, PACA_THREAD_INFO(r13); \ 44734d97e07SBenjamin Herrenschmidt ld r10,TI_LOCAL_FLAGS(r11); \ 44834d97e07SBenjamin Herrenschmidt andi. r9,r10,_TLF_NAPPING; \ 44934d97e07SBenjamin Herrenschmidt beq+ 1f; \ 45034d97e07SBenjamin Herrenschmidt ld r8,_LINK(r1); \ 45134d97e07SBenjamin Herrenschmidt rlwinm r7,r10,0,~_TLF_NAPPING; \ 452fecff0f7SMihai Caraman std r8,_NIP(r1); \ 4532d27cfd3SBenjamin Herrenschmidt std r7,TI_LOCAL_FLAGS(r11); \ 454fecff0f7SMihai Caraman1: 45531f71248SScott Wood 4562d27cfd3SBenjamin Herrenschmidt 45734d97e07SBenjamin Herrenschmidt#define MASKABLE_EXCEPTION(trapnum, intnum, label, hdlr, ack) \ 4582d27cfd3SBenjamin Herrenschmidt START_EXCEPTION(label); \ 4592d27cfd3SBenjamin Herrenschmidt NORMAL_EXCEPTION_PROLOG(trapnum, intnum, PROLOG_ADDITION_MASKABLE)\ 4600c2472deSNicholas Piggin EXCEPTION_COMMON(trapnum) \ 4612d27cfd3SBenjamin Herrenschmidt ack(r8); \ 4622d27cfd3SBenjamin Herrenschmidt CHECK_NAPPING(); \ 4632d27cfd3SBenjamin Herrenschmidt addi r3,r1,STACK_INT_FRAME_REGS; \ 4642d27cfd3SBenjamin Herrenschmidt bl hdlr; \ 4652d27cfd3SBenjamin Herrenschmidt b interrupt_return 4662d27cfd3SBenjamin Herrenschmidt 4672d27cfd3SBenjamin Herrenschmidt/* 4682d27cfd3SBenjamin Herrenschmidt * And here we have the exception vectors ! 4692d27cfd3SBenjamin Herrenschmidt */ 470c4787d1eSScott Wood 471c4787d1eSScott Wood .text 4722d27cfd3SBenjamin Herrenschmidt .balign 0x1000 4732d27cfd3SBenjamin Herrenschmidt .globl interrupt_base_book3e 4742d27cfd3SBenjamin Herrenschmidtinterrupt_base_book3e: /* fake trap */ 4752d27cfd3SBenjamin Herrenschmidt EXCEPTION_STUB(0x000, machine_check) 4762d27cfd3SBenjamin Herrenschmidt EXCEPTION_STUB(0x020, critical_input) /* 0x0100 */ 4772d27cfd3SBenjamin Herrenschmidt EXCEPTION_STUB(0x040, debug_crit) /* 0x0d00 */ 4782d27cfd3SBenjamin Herrenschmidt EXCEPTION_STUB(0x060, data_storage) /* 0x0300 */ 4792d27cfd3SBenjamin Herrenschmidt EXCEPTION_STUB(0x080, instruction_storage) /* 0x0400 */ 4802d27cfd3SBenjamin Herrenschmidt EXCEPTION_STUB(0x0a0, external_input) /* 0x0500 */ 4812d27cfd3SBenjamin Herrenschmidt EXCEPTION_STUB(0x0c0, alignment) /* 0x0600 */ 4822d27cfd3SBenjamin Herrenschmidt EXCEPTION_STUB(0x0e0, program) /* 0x0700 */ 4832d27cfd3SBenjamin Herrenschmidt EXCEPTION_STUB(0x100, fp_unavailable) /* 0x0800 */ 4842d27cfd3SBenjamin Herrenschmidt EXCEPTION_STUB(0x120, system_call) /* 0x0c00 */ 4852d27cfd3SBenjamin Herrenschmidt EXCEPTION_STUB(0x140, ap_unavailable) /* 0x0f20 */ 486c4787d1eSScott Wood EXCEPTION_STUB(0x160, decrementer) /* 0x0900 */ 487c4787d1eSScott Wood EXCEPTION_STUB(0x180, fixed_interval) /* 0x0980 */ 4883a6e9bd7SScott Wood EXCEPTION_STUB(0x1a0, watchdog) /* 0x09f0 */ 48989c81797SBenjamin Herrenschmidt EXCEPTION_STUB(0x1c0, data_tlb_miss) 49089c81797SBenjamin Herrenschmidt EXCEPTION_STUB(0x1e0, instruction_tlb_miss) 4913a6e9bd7SScott Wood EXCEPTION_STUB(0x200, altivec_unavailable) 4923a6e9bd7SScott Wood EXCEPTION_STUB(0x220, altivec_assist) 4933a6e9bd7SScott Wood EXCEPTION_STUB(0x260, perfmon) 4943a6e9bd7SScott Wood EXCEPTION_STUB(0x280, doorbell) 495228b1a47SMihai Caraman EXCEPTION_STUB(0x2a0, doorbell_crit) 4962d27cfd3SBenjamin Herrenschmidt EXCEPTION_STUB(0x2c0, guest_doorbell) 49768d10140STiejun Chen EXCEPTION_STUB(0x2e0, guest_doorbell_crit) 49868d10140STiejun Chen EXCEPTION_STUB(0x300, hypercall) 4992d27cfd3SBenjamin Herrenschmidt EXCEPTION_STUB(0x320, ehpriv) 5002d27cfd3SBenjamin Herrenschmidt EXCEPTION_STUB(0x340, lrat_error) 5012d27cfd3SBenjamin Herrenschmidt 502fecff0f7SMihai Caraman .globl __end_interrupts 503fecff0f7SMihai Caraman__end_interrupts: 504609af38fSScott Wood 505609af38fSScott Wood/* Critical Input Interrupt */ 506609af38fSScott Wood START_EXCEPTION(critical_input); 507609af38fSScott Wood CRIT_EXCEPTION_PROLOG(0x100, BOOKE_INTERRUPT_CRITICAL, 5083db8aa10SNicholas Piggin PROLOG_ADDITION_NONE) 509609af38fSScott Wood EXCEPTION_COMMON_CRIT(0x100) 5102d27cfd3SBenjamin Herrenschmidt bl special_reg_save 5112d27cfd3SBenjamin Herrenschmidt CHECK_NAPPING(); 5122d27cfd3SBenjamin Herrenschmidt addi r3,r1,STACK_INT_FRAME_REGS 513c4787d1eSScott Wood bl unknown_nmi_exception 514fecff0f7SMihai Caraman b ret_from_crit_except 515609af38fSScott Wood 516609af38fSScott Wood/* Machine Check Interrupt */ 517609af38fSScott Wood START_EXCEPTION(machine_check); 518609af38fSScott Wood MC_EXCEPTION_PROLOG(0x000, BOOKE_INTERRUPT_MACHINE_CHECK, 519b1576fecSAnton Blanchard PROLOG_ADDITION_NONE) 520609af38fSScott Wood EXCEPTION_COMMON_MC(0x000) 5212d27cfd3SBenjamin Herrenschmidt bl special_reg_save 5222d27cfd3SBenjamin Herrenschmidt CHECK_NAPPING(); 5232d27cfd3SBenjamin Herrenschmidt addi r3,r1,STACK_INT_FRAME_REGS 524fecff0f7SMihai Caraman bl machine_check_exception 525fecff0f7SMihai Caraman b ret_from_mc_except 5262d27cfd3SBenjamin Herrenschmidt 5272d27cfd3SBenjamin Herrenschmidt/* Data Storage Interrupt */ 528d9db6e42SXiongwei Song START_EXCEPTION(data_storage) 529cfa47772SXiongwei Song NORMAL_EXCEPTION_PROLOG(0x300, BOOKE_INTERRUPT_DATA_STORAGE, 530c6ac667bSNicholas Piggin PROLOG_ADDITION_2REGS) 531c6ac667bSNicholas Piggin mfspr r14,SPRN_DEAR 53231f71248SScott Wood mfspr r15,SPRN_ESR 5332d27cfd3SBenjamin Herrenschmidt std r14,_DEAR(r1) 5342d27cfd3SBenjamin Herrenschmidt std r15,_ESR(r1) 5352d27cfd3SBenjamin Herrenschmidt ld r14,PACA_EXGEN+EX_R14(r13) 5362d27cfd3SBenjamin Herrenschmidt ld r15,PACA_EXGEN+EX_R15(r13) 537fecff0f7SMihai Caraman EXCEPTION_COMMON(0x300) 538fecff0f7SMihai Caraman b storage_fault_common 5392d27cfd3SBenjamin Herrenschmidt 5402d27cfd3SBenjamin Herrenschmidt/* Instruction Storage Interrupt */ 541d9db6e42SXiongwei Song START_EXCEPTION(instruction_storage); 542cfa47772SXiongwei Song NORMAL_EXCEPTION_PROLOG(0x400, BOOKE_INTERRUPT_INST_STORAGE, 543c6ac667bSNicholas Piggin PROLOG_ADDITION_2REGS) 544c6ac667bSNicholas Piggin li r15,0 54531f71248SScott Wood mr r14,r10 5462d27cfd3SBenjamin Herrenschmidt std r14,_DEAR(r1) 5472d27cfd3SBenjamin Herrenschmidt std r15,_ESR(r1) 5482d27cfd3SBenjamin Herrenschmidt ld r14,PACA_EXGEN+EX_R14(r13) 549fecff0f7SMihai Caraman ld r15,PACA_EXGEN+EX_R15(r13) 55035425501SAnton Blanchard EXCEPTION_COMMON(0x400) 5512d27cfd3SBenjamin Herrenschmidt b storage_fault_common 5522d27cfd3SBenjamin Herrenschmidt 5532d27cfd3SBenjamin Herrenschmidt/* External Input Interrupt */ 554fecff0f7SMihai Caraman MASKABLE_EXCEPTION(0x500, BOOKE_INTERRUPT_EXTERNAL, 555fecff0f7SMihai Caraman external_input, do_IRQ, ACK_NONE) 5562d27cfd3SBenjamin Herrenschmidt 5572d27cfd3SBenjamin Herrenschmidt/* Alignment */ 558d9db6e42SXiongwei Song START_EXCEPTION(alignment); 559cfa47772SXiongwei Song NORMAL_EXCEPTION_PROLOG(0x600, BOOKE_INTERRUPT_ALIGNMENT, 560c6ac667bSNicholas Piggin PROLOG_ADDITION_2REGS) 561c6ac667bSNicholas Piggin mfspr r14,SPRN_DEAR 56231f71248SScott Wood mfspr r15,SPRN_ESR 5632d27cfd3SBenjamin Herrenschmidt std r14,_DEAR(r1) 5642d27cfd3SBenjamin Herrenschmidt std r15,_ESR(r1) 5652d27cfd3SBenjamin Herrenschmidt ld r14,PACA_EXGEN+EX_R14(r13) 5662d27cfd3SBenjamin Herrenschmidt ld r15,PACA_EXGEN+EX_R15(r13) 567fecff0f7SMihai Caraman EXCEPTION_COMMON(0x600) 568fecff0f7SMihai Caraman b alignment_more /* no room, go out of line */ 5692d27cfd3SBenjamin Herrenschmidt 570cfa47772SXiongwei Song/* Program Interrupt */ 5712d27cfd3SBenjamin Herrenschmidt START_EXCEPTION(program); 572c6ac667bSNicholas Piggin NORMAL_EXCEPTION_PROLOG(0x700, BOOKE_INTERRUPT_PROGRAM, 573c6ac667bSNicholas Piggin PROLOG_ADDITION_1REG) 574b1576fecSAnton Blanchard mfspr r14,SPRN_ESR 5750c2472deSNicholas Piggin std r14,_ESR(r1) 5760c2472deSNicholas Piggin ld r14,PACA_EXGEN+EX_R14(r13) 5772d27cfd3SBenjamin Herrenschmidt EXCEPTION_COMMON(0x700) 5782d27cfd3SBenjamin Herrenschmidt addi r3,r1,STACK_INT_FRAME_REGS 5792d27cfd3SBenjamin Herrenschmidt bl program_check_exception 580fecff0f7SMihai Caraman REST_NVGPRS(r1) 581fecff0f7SMihai Caraman b interrupt_return 5822d27cfd3SBenjamin Herrenschmidt 58331f71248SScott Wood/* Floating Point Unavailable Interrupt */ 5849424fabfSBenjamin Herrenschmidt START_EXCEPTION(fp_unavailable); 5859424fabfSBenjamin Herrenschmidt NORMAL_EXCEPTION_PROLOG(0x800, BOOKE_INTERRUPT_FP_UNAVAIL, 5869424fabfSBenjamin Herrenschmidt PROLOG_ADDITION_NONE) 587b1576fecSAnton Blanchard /* we can probably do a shorter exception entry for that one... */ 5880c2472deSNicholas Piggin EXCEPTION_COMMON(0x800) 589097157e1SNicholas Piggin ld r12,_MSR(r1) 590b1576fecSAnton Blanchard andi. r0,r12,MSR_PR; 5910c2472deSNicholas Piggin beq- 1f 5922d27cfd3SBenjamin Herrenschmidt bl load_up_fpu 593cd66cc2eSKumar Gala b fast_interrupt_return 594cd66cc2eSKumar Gala1: addi r3,r1,STACK_INT_FRAME_REGS 5952b2695a8SMihai Caraman bl kernel_fp_unavailable_exception 596cd66cc2eSKumar Gala b interrupt_return 597cd66cc2eSKumar Gala 59831f71248SScott Wood/* Altivec Unavailable Interrupt */ 599cd66cc2eSKumar Gala START_EXCEPTION(altivec_unavailable); 600cd66cc2eSKumar Gala NORMAL_EXCEPTION_PROLOG(0x200, BOOKE_INTERRUPT_ALTIVEC_UNAVAIL, 601cd66cc2eSKumar Gala PROLOG_ADDITION_NONE) 602cd66cc2eSKumar Gala /* we can probably do a shorter exception entry for that one... */ 603cd66cc2eSKumar Gala EXCEPTION_COMMON(0x200) 604b1576fecSAnton Blanchard#ifdef CONFIG_ALTIVEC 6050c2472deSNicholas PigginBEGIN_FTR_SECTION 606cd66cc2eSKumar Gala ld r12,_MSR(r1) 607cd66cc2eSKumar Gala andi. r0,r12,MSR_PR; 608cd66cc2eSKumar Gala beq- 1f 609cd66cc2eSKumar Gala bl load_up_altivec 610b1576fecSAnton Blanchard b fast_interrupt_return 6110c2472deSNicholas Piggin1: 612cd66cc2eSKumar GalaEND_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) 613cd66cc2eSKumar Gala#endif 614cd66cc2eSKumar Gala addi r3,r1,STACK_INT_FRAME_REGS 6156b310fc5SMihai Caraman bl altivec_unavailable_exception 6162b2695a8SMihai Caraman b interrupt_return 617cd66cc2eSKumar Gala 61831f71248SScott Wood/* AltiVec Assist */ 619cd66cc2eSKumar Gala START_EXCEPTION(altivec_assist); 620cd66cc2eSKumar Gala NORMAL_EXCEPTION_PROLOG(0x220, 621cd66cc2eSKumar Gala BOOKE_INTERRUPT_ALTIVEC_ASSIST, 622b1576fecSAnton Blanchard PROLOG_ADDITION_NONE) 623cd66cc2eSKumar Gala EXCEPTION_COMMON(0x220) 6240c2472deSNicholas Piggin addi r3,r1,STACK_INT_FRAME_REGS 625cd66cc2eSKumar Gala#ifdef CONFIG_ALTIVEC 626b1576fecSAnton BlanchardBEGIN_FTR_SECTION 627cd66cc2eSKumar Gala bl altivec_assist_exception 6280c2472deSNicholas PigginEND_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) 629cd66cc2eSKumar Gala REST_NVGPRS(r1) 630cd66cc2eSKumar Gala#else 6312d27cfd3SBenjamin Herrenschmidt bl unknown_exception 632fecff0f7SMihai Caraman#endif 63335425501SAnton Blanchard b interrupt_return 6342d27cfd3SBenjamin Herrenschmidt 6352d27cfd3SBenjamin Herrenschmidt 636fecff0f7SMihai Caraman/* Decrementer Interrupt */ 63735425501SAnton Blanchard MASKABLE_EXCEPTION(0x900, BOOKE_INTERRUPT_DECREMENTER, 6382d27cfd3SBenjamin Herrenschmidt decrementer, timer_interrupt, ACK_DEC) 6392d27cfd3SBenjamin Herrenschmidt 6402d27cfd3SBenjamin Herrenschmidt/* Fixed Interval Timer Interrupt */ 641fecff0f7SMihai Caraman MASKABLE_EXCEPTION(0x980, BOOKE_INTERRUPT_FIT, 642fecff0f7SMihai Caraman fixed_interval, unknown_exception, ACK_FIT) 643609af38fSScott Wood 644609af38fSScott Wood/* Watchdog Timer Interrupt */ 645609af38fSScott Wood START_EXCEPTION(watchdog); 646609af38fSScott Wood CRIT_EXCEPTION_PROLOG(0x9f0, BOOKE_INTERRUPT_WATCHDOG, 647609af38fSScott Wood PROLOG_ADDITION_NONE) 648b1576fecSAnton Blanchard EXCEPTION_COMMON_CRIT(0x9f0) 649609af38fSScott Wood bl special_reg_save 6503db8aa10SNicholas Piggin CHECK_NAPPING(); 651609af38fSScott Wood addi r3,r1,STACK_INT_FRAME_REGS 652609af38fSScott Wood#ifdef CONFIG_BOOKE_WDT 6532d27cfd3SBenjamin Herrenschmidt bl WatchdogException 6542d27cfd3SBenjamin Herrenschmidt#else 6552d27cfd3SBenjamin Herrenschmidt bl unknown_nmi_exception 6562d27cfd3SBenjamin Herrenschmidt#endif 6572d27cfd3SBenjamin Herrenschmidt b ret_from_crit_except 6582d27cfd3SBenjamin Herrenschmidt 6592d27cfd3SBenjamin Herrenschmidt/* System Call Interrupt */ 6602d27cfd3SBenjamin Herrenschmidt START_EXCEPTION(system_call) 6612d27cfd3SBenjamin Herrenschmidt mr r9,r13 /* keep a copy of userland r13 */ 66225985edcSLucas De Marchi mfspr r11,SPRN_SRR0 /* get return address */ 6632d27cfd3SBenjamin Herrenschmidt mfspr r12,SPRN_SRR1 /* get previous MSR */ 664fecff0f7SMihai Caraman mfspr r13,SPRN_SPRG_PACA /* get our PACA */ 665fecff0f7SMihai Caraman b system_call_common 66631f71248SScott Wood 6679f2f79e3SBenjamin Herrenschmidt/* Auxiliary Processor Unavailable Interrupt */ 668b1576fecSAnton Blanchard START_EXCEPTION(ap_unavailable); 6690c2472deSNicholas Piggin NORMAL_EXCEPTION_PROLOG(0xf20, BOOKE_INTERRUPT_AP_UNAVAIL, 6702d27cfd3SBenjamin Herrenschmidt PROLOG_ADDITION_NONE) 6712d27cfd3SBenjamin Herrenschmidt EXCEPTION_COMMON(0xf20) 6722d27cfd3SBenjamin Herrenschmidt addi r3,r1,STACK_INT_FRAME_REGS 673fecff0f7SMihai Caraman bl unknown_exception 674fecff0f7SMihai Caraman b interrupt_return 6752d27cfd3SBenjamin Herrenschmidt 6762d27cfd3SBenjamin Herrenschmidt/* Debug exception as a critical interrupt*/ 6772d27cfd3SBenjamin Herrenschmidt START_EXCEPTION(debug_crit); 6782d27cfd3SBenjamin Herrenschmidt CRIT_EXCEPTION_PROLOG(0xd00, BOOKE_INTERRUPT_DEBUG, 6792d27cfd3SBenjamin Herrenschmidt PROLOG_ADDITION_2REGS) 6802d27cfd3SBenjamin Herrenschmidt 6812d27cfd3SBenjamin Herrenschmidt /* 6822d27cfd3SBenjamin Herrenschmidt * If there is a single step or branch-taken exception in an 6832d27cfd3SBenjamin Herrenschmidt * exception entry sequence, it was probably meant to apply to 6842d27cfd3SBenjamin Herrenschmidt * the code where the exception occurred (since exception entry 6852d27cfd3SBenjamin Herrenschmidt * doesn't turn off DE automatically). We simulate the effect 6866cecf76bSScott Wood * of turning off DE on entry to an exception handler by turning 6872d27cfd3SBenjamin Herrenschmidt * off DE in the CSRR1 value and clearing the debug status. 6882d27cfd3SBenjamin Herrenschmidt */ 689fd615f69SLiuHailong 6908e93fb33SNicholas Piggin mfspr r14,SPRN_DBSR /* check single-step/branch taken */ 6913569d84bSNicholas Piggin andis. r15,r14,(DBSR_IC|DBSR_BT)@h 6923569d84bSNicholas Piggin beq+ 1f 6932d27cfd3SBenjamin Herrenschmidt 6942d27cfd3SBenjamin Herrenschmidt#ifdef CONFIG_RELOCATABLE 695d7fb5b18SChristophe Leroy __LOAD_PACA_TOC(r15) 696d7fb5b18SChristophe Leroy LOAD_REG_ADDR_ALTTOC(r14, r15, interrupt_base_book3e) 697d7fb5b18SChristophe Leroy LOAD_REG_ADDR_ALTTOC(r15, r15, __end_interrupts) 698d7fb5b18SChristophe Leroy cmpld cr0,r10,r14 699d7fb5b18SChristophe Leroy cmpld cr1,r10,r15 700d7fb5b18SChristophe Leroy#else 7012d27cfd3SBenjamin Herrenschmidt LOAD_REG_IMMEDIATE_SYM(r14, r15, interrupt_base_book3e) 7022d27cfd3SBenjamin Herrenschmidt cmpld cr0, r10, r14 7032d27cfd3SBenjamin Herrenschmidt LOAD_REG_IMMEDIATE_SYM(r14, r15, __end_interrupts) 7042d27cfd3SBenjamin Herrenschmidt cmpld cr1, r10, r14 7056cecf76bSScott Wood#endif 7062d27cfd3SBenjamin Herrenschmidt blt+ cr0,1f 7072d27cfd3SBenjamin Herrenschmidt bge+ cr1,1f 7082d27cfd3SBenjamin Herrenschmidt 7092d27cfd3SBenjamin Herrenschmidt /* here it looks like we got an inappropriate debug exception. */ 7102d27cfd3SBenjamin Herrenschmidt lis r14,(DBSR_IC|DBSR_BT)@h /* clear the event */ 7112d27cfd3SBenjamin Herrenschmidt rlwinm r11,r11,0,~MSR_DE /* clear DE in the CSRR1 value */ 7122d27cfd3SBenjamin Herrenschmidt mtspr SPRN_DBSR,r14 7132d27cfd3SBenjamin Herrenschmidt mtspr SPRN_CSRR1,r11 7142d27cfd3SBenjamin Herrenschmidt lwz r10,PACA_EXCRIT+EX_CR(r13) /* restore registers */ 7152d27cfd3SBenjamin Herrenschmidt ld r1,PACA_EXCRIT+EX_R1(r13) 7169d378dfaSScott Wood ld r14,PACA_EXCRIT+EX_R14(r13) 7172d27cfd3SBenjamin Herrenschmidt ld r15,PACA_EXCRIT+EX_R15(r13) 7182d27cfd3SBenjamin Herrenschmidt mtcr r10 7192d27cfd3SBenjamin Herrenschmidt ld r10,PACA_EXCRIT+EX_R10(r13) /* restore registers */ 7202d27cfd3SBenjamin Herrenschmidt ld r11,PACA_EXCRIT+EX_R11(r13) 7212d27cfd3SBenjamin Herrenschmidt mfspr r13,SPRN_SPRG_CRIT_SCRATCH 7222d27cfd3SBenjamin Herrenschmidt rfci 7232d27cfd3SBenjamin Herrenschmidt 7242d27cfd3SBenjamin Herrenschmidt /* Normal debug exception */ 7252d27cfd3SBenjamin Herrenschmidt /* XXX We only handle coming from userspace for now since we can't 7262d27cfd3SBenjamin Herrenschmidt * quite save properly an interrupted kernel state yet 7272d27cfd3SBenjamin Herrenschmidt */ 7282d27cfd3SBenjamin Herrenschmidt1: andi. r14,r11,MSR_PR; /* check for userspace again */ 7292d27cfd3SBenjamin Herrenschmidt beq kernel_dbg_exc; /* if from kernel mode */ 7302d27cfd3SBenjamin Herrenschmidt 7312d27cfd3SBenjamin Herrenschmidt /* Now we mash up things to make it look like we are coming on a 7322d27cfd3SBenjamin Herrenschmidt * normal exception 733c6ac667bSNicholas Piggin */ 734c6ac667bSNicholas Piggin mfspr r14,SPRN_DBSR 735b1576fecSAnton Blanchard std r14,_DSISR(r1) 7360c2472deSNicholas Piggin ld r14,PACA_EXCRIT+EX_R14(r13) 7370c2472deSNicholas Piggin ld r15,PACA_EXCRIT+EX_R15(r13) 7382d27cfd3SBenjamin Herrenschmidt EXCEPTION_COMMON_CRIT(0xd00) 7392d27cfd3SBenjamin Herrenschmidt addi r3,r1,STACK_INT_FRAME_REGS 7402d27cfd3SBenjamin Herrenschmidt bl DebugException 7412d27cfd3SBenjamin Herrenschmidt REST_NVGPRS(r1) 742d36b4c4fSKumar Gala b interrupt_return 743d36b4c4fSKumar Gala 744fecff0f7SMihai Caramankernel_dbg_exc: 745fecff0f7SMihai Caraman b . /* NYI */ 746d36b4c4fSKumar Gala 747d36b4c4fSKumar Gala/* Debug exception as a debug interrupt*/ 748d36b4c4fSKumar Gala START_EXCEPTION(debug_debug); 749d36b4c4fSKumar Gala DBG_EXCEPTION_PROLOG(0xd00, BOOKE_INTERRUPT_DEBUG, 750d36b4c4fSKumar Gala PROLOG_ADDITION_2REGS) 751d36b4c4fSKumar Gala 752d36b4c4fSKumar Gala /* 753d36b4c4fSKumar Gala * If there is a single step or branch-taken exception in an 754d36b4c4fSKumar Gala * exception entry sequence, it was probably meant to apply to 755d36b4c4fSKumar Gala * the code where the exception occurred (since exception entry 756d36b4c4fSKumar Gala * doesn't turn off DE automatically). We simulate the effect 7576cecf76bSScott Wood * of turning off DE on entry to an exception handler by turning 758d36b4c4fSKumar Gala * off DE in the DSRR1 value and clearing the debug status. 759d36b4c4fSKumar Gala */ 760fd615f69SLiuHailong 7618e93fb33SNicholas Piggin mfspr r14,SPRN_DBSR /* check single-step/branch taken */ 7623569d84bSNicholas Piggin andis. r15,r14,(DBSR_IC|DBSR_BT)@h 7633569d84bSNicholas Piggin beq+ 1f 764d36b4c4fSKumar Gala 765d36b4c4fSKumar Gala#ifdef CONFIG_RELOCATABLE 766d7fb5b18SChristophe Leroy __LOAD_PACA_TOC(r15) 767d7fb5b18SChristophe Leroy LOAD_REG_ADDR_ALTTOC(r14, r15, interrupt_base_book3e) 768d7fb5b18SChristophe Leroy LOAD_REG_ADDR_ALTTOC(r15, r15, __end_interrupts) 769d7fb5b18SChristophe Leroy cmpld cr0,r10,r14 770d7fb5b18SChristophe Leroy cmpld cr1,r10,r15 771d7fb5b18SChristophe Leroy#else 772d36b4c4fSKumar Gala LOAD_REG_IMMEDIATE_SYM(r14, r15, interrupt_base_book3e) 773d36b4c4fSKumar Gala cmpld cr0, r10, r14 774d36b4c4fSKumar Gala LOAD_REG_IMMEDIATE_SYM(r14, r15,__end_interrupts) 775d36b4c4fSKumar Gala cmpld cr1, r10, r14 7766cecf76bSScott Wood#endif 777d36b4c4fSKumar Gala blt+ cr0,1f 778d36b4c4fSKumar Gala bge+ cr1,1f 779d36b4c4fSKumar Gala 780d36b4c4fSKumar Gala /* here it looks like we got an inappropriate debug exception. */ 781d36b4c4fSKumar Gala lis r14,(DBSR_IC|DBSR_BT)@h /* clear the event */ 782d36b4c4fSKumar Gala rlwinm r11,r11,0,~MSR_DE /* clear DE in the DSRR1 value */ 783d36b4c4fSKumar Gala mtspr SPRN_DBSR,r14 784d36b4c4fSKumar Gala mtspr SPRN_DSRR1,r11 785d36b4c4fSKumar Gala lwz r10,PACA_EXDBG+EX_CR(r13) /* restore registers */ 786d36b4c4fSKumar Gala ld r1,PACA_EXDBG+EX_R1(r13) 787d36b4c4fSKumar Gala ld r14,PACA_EXDBG+EX_R14(r13) 788d36b4c4fSKumar Gala ld r15,PACA_EXDBG+EX_R15(r13) 789d36b4c4fSKumar Gala mtcr r10 790d36b4c4fSKumar Gala ld r10,PACA_EXDBG+EX_R10(r13) /* restore registers */ 791d36b4c4fSKumar Gala ld r11,PACA_EXDBG+EX_R11(r13) 792d36b4c4fSKumar Gala mfspr r13,SPRN_SPRG_DBG_SCRATCH 793d36b4c4fSKumar Gala rfdi 794d36b4c4fSKumar Gala 795d36b4c4fSKumar Gala /* Normal debug exception */ 796d36b4c4fSKumar Gala /* XXX We only handle coming from userspace for now since we can't 797d36b4c4fSKumar Gala * quite save properly an interrupted kernel state yet 798d36b4c4fSKumar Gala */ 799d36b4c4fSKumar Gala1: andi. r14,r11,MSR_PR; /* check for userspace again */ 800d36b4c4fSKumar Gala beq kernel_dbg_exc; /* if from kernel mode */ 801d36b4c4fSKumar Gala 802d36b4c4fSKumar Gala /* Now we mash up things to make it look like we are coming on a 803d36b4c4fSKumar Gala * normal exception 804c6ac667bSNicholas Piggin */ 805c6ac667bSNicholas Piggin mfspr r14,SPRN_DBSR 806b1576fecSAnton Blanchard std r14,_DSISR(r1) 8070c2472deSNicholas Piggin ld r14,PACA_EXDBG+EX_R14(r13) 8080c2472deSNicholas Piggin ld r15,PACA_EXDBG+EX_R15(r13) 809d36b4c4fSKumar Gala EXCEPTION_COMMON_DBG(0xd08) 8107230c564SBenjamin Herrenschmidt addi r3,r1,STACK_INT_FRAME_REGS 811fecff0f7SMihai Caraman bl DebugException 812fecff0f7SMihai Caraman REST_NVGPRS(r1) 81331f71248SScott Wood b interrupt_return 814e4867336SKevin Hao 8157230c564SBenjamin Herrenschmidt START_EXCEPTION(perfmon); 816*a073672eSNicholas Piggin NORMAL_EXCEPTION_PROLOG(0x260, BOOKE_INTERRUPT_PERFORMANCE_MONITOR, 817*a073672eSNicholas Piggin PROLOG_ADDITION_NONE) 818*a073672eSNicholas Piggin EXCEPTION_COMMON(0x260) 819*a073672eSNicholas Piggin CHECK_NAPPING() 820*a073672eSNicholas Piggin addi r3,r1,STACK_INT_FRAME_REGS 821*a073672eSNicholas Piggin /* 822*a073672eSNicholas Piggin * XXX: Returning from performance_monitor_exception taken as a 823b1576fecSAnton Blanchard * soft-NMI (Linux irqs disabled) may be risky to use interrupt_return 8240c2472deSNicholas Piggin * and could cause bugs in return or elsewhere. That case should just 8253a6e9bd7SScott Wood * restore registers and return. There is a workaround for one known 82689c81797SBenjamin Herrenschmidt * problem in interrupt_exit_kernel_prepare(). 827fecff0f7SMihai Caraman */ 82835425501SAnton Blanchard bl performance_monitor_exception 82989c81797SBenjamin Herrenschmidt b interrupt_return 83089c81797SBenjamin Herrenschmidt 83189c81797SBenjamin Herrenschmidt/* Doorbell interrupt */ 832fecff0f7SMihai Caraman MASKABLE_EXCEPTION(0x280, BOOKE_INTERRUPT_DOORBELL, 833fecff0f7SMihai Caraman doorbell, doorbell_exception, ACK_NONE) 834609af38fSScott Wood 835609af38fSScott Wood/* Doorbell critical Interrupt */ 836609af38fSScott Wood START_EXCEPTION(doorbell_crit); 837609af38fSScott Wood CRIT_EXCEPTION_PROLOG(0x2a0, BOOKE_INTERRUPT_DOORBELL_CRITICAL, 8383db8aa10SNicholas Piggin PROLOG_ADDITION_NONE) 839609af38fSScott Wood EXCEPTION_COMMON_CRIT(0x2a0) 84089c81797SBenjamin Herrenschmidt bl special_reg_save 8415473eb1cSMihai Caraman CHECK_NAPPING(); 8425473eb1cSMihai Caraman addi r3,r1,STACK_INT_FRAME_REGS 8435473eb1cSMihai Caraman bl unknown_nmi_exception 8445473eb1cSMihai Caraman b ret_from_crit_except 8455473eb1cSMihai Caraman 846fecff0f7SMihai Caraman/* 847fecff0f7SMihai Caraman * Guest doorbell interrupt 84831f71248SScott Wood * This general exception use GSRRx save/restore registers 8495473eb1cSMihai Caraman */ 850b1576fecSAnton Blanchard START_EXCEPTION(guest_doorbell); 8510c2472deSNicholas Piggin GDBELL_EXCEPTION_PROLOG(0x2c0, BOOKE_INTERRUPT_GUEST_DBELL, 8523a6e9bd7SScott Wood PROLOG_ADDITION_NONE) 8537230c564SBenjamin Herrenschmidt EXCEPTION_COMMON(0x2c0) 8547230c564SBenjamin Herrenschmidt addi r3,r1,STACK_INT_FRAME_REGS 855fecff0f7SMihai Caraman bl unknown_exception 856fecff0f7SMihai Caraman b interrupt_return 857609af38fSScott Wood 858609af38fSScott Wood/* Guest Doorbell critical Interrupt */ 859609af38fSScott Wood START_EXCEPTION(guest_doorbell_crit); 860609af38fSScott Wood CRIT_EXCEPTION_PROLOG(0x2e0, BOOKE_INTERRUPT_GUEST_DBELL_CRIT, 8613db8aa10SNicholas Piggin PROLOG_ADDITION_NONE) 862609af38fSScott Wood EXCEPTION_COMMON_CRIT(0x2e0) 8637230c564SBenjamin Herrenschmidt bl special_reg_save 8647230c564SBenjamin Herrenschmidt CHECK_NAPPING(); 8657230c564SBenjamin Herrenschmidt addi r3,r1,STACK_INT_FRAME_REGS 866fecff0f7SMihai Caraman bl unknown_nmi_exception 867fecff0f7SMihai Caraman b ret_from_crit_except 86831f71248SScott Wood 8697230c564SBenjamin Herrenschmidt/* Hypervisor call */ 870b1576fecSAnton Blanchard START_EXCEPTION(hypercall); 8710c2472deSNicholas Piggin NORMAL_EXCEPTION_PROLOG(0x310, BOOKE_INTERRUPT_HV_SYSCALL, 8727230c564SBenjamin Herrenschmidt PROLOG_ADDITION_NONE) 8737230c564SBenjamin Herrenschmidt EXCEPTION_COMMON(0x310) 8747230c564SBenjamin Herrenschmidt addi r3,r1,STACK_INT_FRAME_REGS 875fecff0f7SMihai Caraman bl unknown_exception 876fecff0f7SMihai Caraman b interrupt_return 87731f71248SScott Wood 8787230c564SBenjamin Herrenschmidt/* Embedded Hypervisor priviledged */ 879b1576fecSAnton Blanchard START_EXCEPTION(ehpriv); 8800c2472deSNicholas Piggin NORMAL_EXCEPTION_PROLOG(0x320, BOOKE_INTERRUPT_HV_PRIV, 8812d27cfd3SBenjamin Herrenschmidt PROLOG_ADDITION_NONE) 882228b1a47SMihai Caraman EXCEPTION_COMMON(0x320) 883228b1a47SMihai Caraman addi r3,r1,STACK_INT_FRAME_REGS 884228b1a47SMihai Caraman bl unknown_exception 885228b1a47SMihai Caraman b interrupt_return 88631f71248SScott Wood 887228b1a47SMihai Caraman/* LRAT Error interrupt */ 888ae88f7b9SNicholas Piggin START_EXCEPTION(lrat_error); 8890c2472deSNicholas Piggin NORMAL_EXCEPTION_PROLOG(0x340, BOOKE_INTERRUPT_LRAT_ERROR, 890228b1a47SMihai Caraman PROLOG_ADDITION_NONE) 891f23699c9SNicholas Piggin EXCEPTION_COMMON(0x340) 892fce01acfSNicholas Piggin addi r3,r1,STACK_INT_FRAME_REGS 8938e93fb33SNicholas Piggin bl unknown_exception 8943569d84bSNicholas Piggin b interrupt_return 8953569d84bSNicholas Piggin 896fce01acfSNicholas Piggin.macro SEARCH_RESTART_TABLE 897f23699c9SNicholas Piggin#ifdef CONFIG_RELOCATABLE 898f23699c9SNicholas Piggin __LOAD_PACA_TOC(r11) 899fce01acfSNicholas Piggin LOAD_REG_ADDR_ALTTOC(r14, r11, __start___restart_table) 900f23699c9SNicholas Piggin LOAD_REG_ADDR_ALTTOC(r15, r11, __stop___restart_table) 901f23699c9SNicholas Piggin#else 902f23699c9SNicholas Piggin LOAD_REG_IMMEDIATE_SYM(r14, r11, __start___restart_table) 903f23699c9SNicholas Piggin LOAD_REG_IMMEDIATE_SYM(r15, r11, __stop___restart_table) 904f23699c9SNicholas Piggin#endif 905f23699c9SNicholas Piggin300: 906f23699c9SNicholas Piggin cmpd r14,r15 907f23699c9SNicholas Piggin beq 302f 908f23699c9SNicholas Piggin ld r11,0(r14) 909f23699c9SNicholas Piggin cmpld r10,r11 910f23699c9SNicholas Piggin blt 301f 911f23699c9SNicholas Piggin ld r11,8(r14) 912f23699c9SNicholas Piggin cmpld r10,r11 913f23699c9SNicholas Piggin bge 301f 914f23699c9SNicholas Piggin ld r11,16(r14) 915f23699c9SNicholas Piggin b 303f 916f23699c9SNicholas Piggin301: 917f23699c9SNicholas Piggin addi r14,r14,24 918f23699c9SNicholas Piggin b 300b 9192d27cfd3SBenjamin Herrenschmidt302: 9207230c564SBenjamin Herrenschmidt li r11,0 9217230c564SBenjamin Herrenschmidt303: 9226cc3f91bSNicholas Piggin.endm 9236cc3f91bSNicholas Piggin 9242d27cfd3SBenjamin Herrenschmidt/* 9253d97a619SScott Wood * An interrupt came in while soft-disabled; We mark paca->irq_happened 92679b5c8dbSMihai Caraman * accordingly and if the interrupt is level sensitive, we hard disable 927f23699c9SNicholas Piggin * hard disable (full_mask) corresponds to PACA_IRQ_MUST_HARD_MASK, so 928f23699c9SNicholas Piggin * keep these in synch. 929f23699c9SNicholas Piggin */ 9307230c564SBenjamin Herrenschmidt 9319b81c021SNicholas Piggin.macro masked_interrupt_book3e paca_irq full_mask 9329b81c021SNicholas Piggin std r14,PACA_EXGEN+EX_R14(r13) 9339b81c021SNicholas Piggin std r15,PACA_EXGEN+EX_R15(r13) 93479b5c8dbSMihai Caraman 9359b81c021SNicholas Piggin lbz r10,PACAIRQHAPPENED(r13) 9367230c564SBenjamin Herrenschmidt .if \full_mask == 1 93779b5c8dbSMihai Caraman ori r10,r10,\paca_irq | PACA_IRQ_HARD_DIS 93879b5c8dbSMihai Caraman .else 939f23699c9SNicholas Piggin ori r10,r10,\paca_irq 94079b5c8dbSMihai Caraman .endif 94179b5c8dbSMihai Caraman stb r10,PACAIRQHAPPENED(r13) 94279b5c8dbSMihai Caraman 943f23699c9SNicholas Piggin .if \full_mask == 1 944f23699c9SNicholas Piggin xori r11,r11,MSR_EE /* clear MSR_EE */ 945f23699c9SNicholas Piggin mtspr SPRN_SRR1,r11 946f23699c9SNicholas Piggin .endif 947f23699c9SNicholas Piggin 948f23699c9SNicholas Piggin mfspr r10,SPRN_SRR0 949f23699c9SNicholas Piggin SEARCH_RESTART_TABLE 95079b5c8dbSMihai Caraman cmpdi r11,0 95179b5c8dbSMihai Caraman beq 1f 95279b5c8dbSMihai Caraman mtspr SPRN_SRR0,r11 /* return to restart address */ 95379b5c8dbSMihai Caraman1: 954f23699c9SNicholas Piggin 955f23699c9SNicholas Piggin lwz r11,PACA_EXGEN+EX_CR(r13) 95679b5c8dbSMihai Caraman mtcr r11 9572d27cfd3SBenjamin Herrenschmidt ld r10,PACA_EXGEN+EX_R10(r13) 9582d27cfd3SBenjamin Herrenschmidt ld r11,PACA_EXGEN+EX_R11(r13) 95979b5c8dbSMihai Caraman ld r14,PACA_EXGEN+EX_R14(r13) 96079b5c8dbSMihai Caraman ld r15,PACA_EXGEN+EX_R15(r13) 96179b5c8dbSMihai Caraman mfspr r13,SPRN_SPRG_GEN_SCRATCH 96279b5c8dbSMihai Caraman rfi 96379b5c8dbSMihai Caraman b . 96479b5c8dbSMihai Caraman.endm 96579b5c8dbSMihai Caraman 96679b5c8dbSMihai Caramanmasked_interrupt_book3e_0x500: 96779b5c8dbSMihai Caraman masked_interrupt_book3e PACA_IRQ_EE 1 96879b5c8dbSMihai Caraman 96979b5c8dbSMihai Caramanmasked_interrupt_book3e_0x900: 97079b5c8dbSMihai Caraman ACK_DEC(r10); 97179b5c8dbSMihai Caraman masked_interrupt_book3e PACA_IRQ_DEC 0 97279b5c8dbSMihai Caraman 97379b5c8dbSMihai Caramanmasked_interrupt_book3e_0x980: 97479b5c8dbSMihai Caraman ACK_FIT(r10); 97579b5c8dbSMihai Caraman masked_interrupt_book3e PACA_IRQ_DEC 0 9767230c564SBenjamin Herrenschmidt 9772d27cfd3SBenjamin Herrenschmidtmasked_interrupt_book3e_0x280: 9782d27cfd3SBenjamin Herrenschmidtmasked_interrupt_book3e_0x2c0: 9792d27cfd3SBenjamin Herrenschmidt masked_interrupt_book3e PACA_IRQ_DBELL 0 9802d27cfd3SBenjamin Herrenschmidt 9812d27cfd3SBenjamin Herrenschmidt/* 9822d27cfd3SBenjamin Herrenschmidt * This is called from 0x300 and 0x400 handlers after the prologs with 983b1576fecSAnton Blanchard * r14 and r15 containing the fault address and error code, with the 9840c2472deSNicholas Piggin * original values stashed away in the PACA 9852d27cfd3SBenjamin Herrenschmidt */ 9862d27cfd3SBenjamin HerrenschmidtSYM_CODE_START_LOCAL(storage_fault_common) 9872d27cfd3SBenjamin Herrenschmidt addi r3,r1,STACK_INT_FRAME_REGS 9882d27cfd3SBenjamin Herrenschmidt bl do_page_fault 9892d27cfd3SBenjamin Herrenschmidt b interrupt_return 9902d27cfd3SBenjamin HerrenschmidtSYM_CODE_END(storage_fault_common) 9912d27cfd3SBenjamin Herrenschmidt 992b1576fecSAnton Blanchard/* 9936cc0c16dSNicholas Piggin * Alignment exception doesn't fit entirely in the 0x100 bytes so it 9940c2472deSNicholas Piggin * continues here. 9956cc0c16dSNicholas Piggin */ 9966cc0c16dSNicholas PigginSYM_CODE_START_LOCAL(alignment_more) 9972d27cfd3SBenjamin Herrenschmidt addi r3,r1,STACK_INT_FRAME_REGS 9982d27cfd3SBenjamin Herrenschmidt bl alignment_exception 9992d27cfd3SBenjamin Herrenschmidt REST_NVGPRS(r1) 10002d27cfd3SBenjamin Herrenschmidt b interrupt_return 10012d27cfd3SBenjamin HerrenschmidtSYM_CODE_END(alignment_more) 10022d27cfd3SBenjamin Herrenschmidt 10032d27cfd3SBenjamin Herrenschmidt/* 10042d27cfd3SBenjamin Herrenschmidt * Trampolines used when spotting a bad kernel stack pointer in 10052d27cfd3SBenjamin Herrenschmidt * the exception entry code. 1006cd66cc2eSKumar Gala * 10073a6e9bd7SScott Wood * TODO: move some bits like SRR0 read to trampoline, pass PACA 10087230c564SBenjamin Herrenschmidt * index around, etc... to handle crit & mcheck 10097230c564SBenjamin Herrenschmidt */ 10103a6e9bd7SScott WoodBAD_STACK_TRAMPOLINE(0x000) 10113a6e9bd7SScott WoodBAD_STACK_TRAMPOLINE(0x100) 10122d27cfd3SBenjamin HerrenschmidtBAD_STACK_TRAMPOLINE(0x200) 10133a6e9bd7SScott WoodBAD_STACK_TRAMPOLINE(0x220) 10143a6e9bd7SScott WoodBAD_STACK_TRAMPOLINE(0x260) 1015228b1a47SMihai CaramanBAD_STACK_TRAMPOLINE(0x280) 10162d27cfd3SBenjamin HerrenschmidtBAD_STACK_TRAMPOLINE(0x2a0) 10172d27cfd3SBenjamin HerrenschmidtBAD_STACK_TRAMPOLINE(0x2c0) 10182d27cfd3SBenjamin HerrenschmidtBAD_STACK_TRAMPOLINE(0x2e0) 10192d27cfd3SBenjamin HerrenschmidtBAD_STACK_TRAMPOLINE(0x300) 10202d27cfd3SBenjamin HerrenschmidtBAD_STACK_TRAMPOLINE(0x310) 10212d27cfd3SBenjamin HerrenschmidtBAD_STACK_TRAMPOLINE(0x320) 10222d27cfd3SBenjamin HerrenschmidtBAD_STACK_TRAMPOLINE(0x340) 10232d27cfd3SBenjamin HerrenschmidtBAD_STACK_TRAMPOLINE(0x400) 10242d27cfd3SBenjamin HerrenschmidtBAD_STACK_TRAMPOLINE(0x500) 10252d27cfd3SBenjamin HerrenschmidtBAD_STACK_TRAMPOLINE(0x600) 10262d27cfd3SBenjamin HerrenschmidtBAD_STACK_TRAMPOLINE(0x700) 10272d27cfd3SBenjamin HerrenschmidtBAD_STACK_TRAMPOLINE(0x800) 10287230c564SBenjamin HerrenschmidtBAD_STACK_TRAMPOLINE(0x900) 10292d27cfd3SBenjamin HerrenschmidtBAD_STACK_TRAMPOLINE(0x980) 10302d27cfd3SBenjamin HerrenschmidtBAD_STACK_TRAMPOLINE(0x9f0) 10312d27cfd3SBenjamin HerrenschmidtBAD_STACK_TRAMPOLINE(0xa00) 10322d27cfd3SBenjamin HerrenschmidtBAD_STACK_TRAMPOLINE(0xb00) 10332d27cfd3SBenjamin HerrenschmidtBAD_STACK_TRAMPOLINE(0xc00) 10342d27cfd3SBenjamin HerrenschmidtBAD_STACK_TRAMPOLINE(0xd00) 10352d27cfd3SBenjamin HerrenschmidtBAD_STACK_TRAMPOLINE(0xd08) 10362d27cfd3SBenjamin HerrenschmidtBAD_STACK_TRAMPOLINE(0xe00) 10372d27cfd3SBenjamin HerrenschmidtBAD_STACK_TRAMPOLINE(0xf00) 10382d27cfd3SBenjamin HerrenschmidtBAD_STACK_TRAMPOLINE(0xf20) 10392d27cfd3SBenjamin Herrenschmidt 10402d27cfd3SBenjamin Herrenschmidt_GLOBAL(bad_stack_book3e) 10412d27cfd3SBenjamin Herrenschmidt /* XXX: Needs to make SPRN_SPRG_GEN depend on exception type */ 10422d27cfd3SBenjamin Herrenschmidt mfspr r10,SPRN_SRR0; /* read SRR0 before touching stack */ 10432d27cfd3SBenjamin Herrenschmidt ld r1,PACAEMERGSP(r13) 10442d27cfd3SBenjamin Herrenschmidt subi r1,r1,64+INT_FRAME_SIZE 10452d27cfd3SBenjamin Herrenschmidt std r10,_NIP(r1) 10462d27cfd3SBenjamin Herrenschmidt std r11,_MSR(r1) 1047d9db6e42SXiongwei Song ld r10,PACA_EXGEN+EX_R1(r13) /* FIXME for crit & mcheck */ 1048cfa47772SXiongwei Song lwz r11,PACA_EXGEN+EX_CR(r13) /* FIXME for crit & mcheck */ 104953ecaa67SRohan McLure std r10,GPR1(r1) 105053ecaa67SRohan McLure std r11,_CCR(r1) 10512d27cfd3SBenjamin Herrenschmidt mfspr r10,SPRN_DEAR 10522d27cfd3SBenjamin Herrenschmidt mfspr r11,SPRN_ESR 10532d27cfd3SBenjamin Herrenschmidt std r10,_DEAR(r1) 10542d27cfd3SBenjamin Herrenschmidt std r11,_ESR(r1) 10552d27cfd3SBenjamin Herrenschmidt SAVE_GPR(0, r1); /* save r0 in stackframe */ \ 105653ecaa67SRohan McLure SAVE_GPRS(2, 9, r1); /* save r2 - r9 in stackframe */ \ 10572d27cfd3SBenjamin Herrenschmidt ld r3,PACA_EXGEN+EX_R10(r13);/* get back r10 */ \ 10582d27cfd3SBenjamin Herrenschmidt ld r4,PACA_EXGEN+EX_R11(r13);/* get back r11 */ \ 10592d27cfd3SBenjamin Herrenschmidt mfspr r5,SPRN_SPRG_GEN_SCRATCH;/* get back r13 XXX can be wrong */ \ 10602d27cfd3SBenjamin Herrenschmidt std r3,GPR10(r1); /* save r10 to stackframe */ \ 10612d27cfd3SBenjamin Herrenschmidt std r4,GPR11(r1); /* save r11 to stackframe */ \ 10622d27cfd3SBenjamin Herrenschmidt SAVE_GPR(12, r1); /* save r12 in stackframe */ \ 10632d27cfd3SBenjamin Herrenschmidt std r5,GPR13(r1); /* save it to stackframe */ \ 106453ecaa67SRohan McLure mflr r10 10652d27cfd3SBenjamin Herrenschmidt mfctr r11 10662d27cfd3SBenjamin Herrenschmidt mfxer r12 10672d27cfd3SBenjamin Herrenschmidt std r10,_LINK(r1) 10682d27cfd3SBenjamin Herrenschmidt std r11,_CTR(r1) 106953ecaa67SRohan McLure std r12,_XER(r1) 10702d27cfd3SBenjamin Herrenschmidt SAVE_NVGPRS(r1) 10718e93fb33SNicholas Piggin lhz r12,PACA_TRAP_SAVE(r13) 10722d27cfd3SBenjamin Herrenschmidt std r12,_TRAP(r1) 1073b1576fecSAnton Blanchard addi r11,r1,INT_FRAME_SIZE 10742d27cfd3SBenjamin Herrenschmidt std r11,0(r1) 10752d27cfd3SBenjamin Herrenschmidt ZEROIZE_GPR(12) 10762d27cfd3SBenjamin Herrenschmidt std r12,0(r11) 10772d27cfd3SBenjamin Herrenschmidt LOAD_PACA_TOC() 10782d27cfd3SBenjamin Herrenschmidt1: addi r3,r1,STACK_INT_FRAME_REGS 10792d27cfd3SBenjamin Herrenschmidt bl kernel_bad_stack 10802d27cfd3SBenjamin Herrenschmidt b 1b 10812d27cfd3SBenjamin Herrenschmidt 10822d27cfd3SBenjamin Herrenschmidt/* 1083bb1af71eSKumar Gala * Setup the initial TLB for a core. This current implementation 1084bb1af71eSKumar Gala * assume that whatever we are running off will not conflict with 1085bb1af71eSKumar Gala * the new mapping at PAGE_OFFSET. 1086bb1af71eSKumar Gala */ 1087bb1af71eSKumar Gala_GLOBAL(initial_tlb_book3e) 1088bb1af71eSKumar Gala 1089bb1af71eSKumar Gala /* Look for the first TLB with IPROT set */ 1090bb1af71eSKumar Gala mfspr r4,SPRN_TLB0CFG 1091bb1af71eSKumar Gala andi. r3,r4,TLBnCFG_IPROT 1092bb1af71eSKumar Gala lis r3,MAS0_TLBSEL(0)@h 1093bb1af71eSKumar Gala bne found_iprot 1094bb1af71eSKumar Gala 1095bb1af71eSKumar Gala mfspr r4,SPRN_TLB1CFG 1096bb1af71eSKumar Gala andi. r3,r4,TLBnCFG_IPROT 1097bb1af71eSKumar Gala lis r3,MAS0_TLBSEL(1)@h 1098bb1af71eSKumar Gala bne found_iprot 1099bb1af71eSKumar Gala 1100bb1af71eSKumar Gala mfspr r4,SPRN_TLB2CFG 1101bb1af71eSKumar Gala andi. r3,r4,TLBnCFG_IPROT 1102bb1af71eSKumar Gala lis r3,MAS0_TLBSEL(2)@h 1103bb1af71eSKumar Gala bne found_iprot 1104bb1af71eSKumar Gala 1105bb1af71eSKumar Gala lis r3,MAS0_TLBSEL(3)@h 1106bb1af71eSKumar Gala mfspr r4,SPRN_TLB3CFG 1107bb1af71eSKumar Gala /* fall through */ 1108bb1af71eSKumar Gala 1109bb1af71eSKumar Galafound_iprot: 1110bb1af71eSKumar Gala andi. r5,r4,TLBnCFG_HES 1111bb1af71eSKumar Gala bne have_hes 1112bb1af71eSKumar Gala 1113f5007dbfSChristophe Leroy mflr r8 /* save LR */ 1114bb1af71eSKumar Gala/* 1. Find the index of the entry we're executing in 1115bb1af71eSKumar Gala * 1116bb1af71eSKumar Gala * r3 = MAS0_TLBSEL (for the iprot array) 1117bb1af71eSKumar Gala * r4 = SPRN_TLBnCFG 1118bb1af71eSKumar Gala */ 1119bb1af71eSKumar Gala bcl 20,31,$+4 /* Find our address */ 1120bb1af71eSKumar Galainvstr: mflr r6 /* Make it accessible */ 1121bb1af71eSKumar Gala mfmsr r7 1122bb1af71eSKumar Gala rlwinm r5,r7,27,31,31 /* extract MSR[IS] */ 1123bb1af71eSKumar Gala mfspr r7,SPRN_PID 1124bb1af71eSKumar Gala slwi r7,r7,16 1125bb1af71eSKumar Gala or r7,r7,r5 1126bb1af71eSKumar Gala mtspr SPRN_MAS6,r7 1127bb1af71eSKumar Gala tlbsx 0,r6 /* search MSR[IS], SPID=PID */ 1128bb1af71eSKumar Gala 1129bb1af71eSKumar Gala mfspr r3,SPRN_MAS0 1130bb1af71eSKumar Gala rlwinm r5,r3,16,20,31 /* Extract MAS0(Entry) */ 1131bb1af71eSKumar Gala 1132bb1af71eSKumar Gala mfspr r7,SPRN_MAS1 /* Insure IPROT set */ 1133bb1af71eSKumar Gala oris r7,r7,MAS1_IPROT@h 1134bb1af71eSKumar Gala mtspr SPRN_MAS1,r7 1135bb1af71eSKumar Gala tlbwe 1136bb1af71eSKumar Gala 1137bb1af71eSKumar Gala/* 2. Invalidate all entries except the entry we're executing in 1138bb1af71eSKumar Gala * 1139bb1af71eSKumar Gala * r3 = MAS0 w/TLBSEL & ESEL for the entry we are running in 1140bb1af71eSKumar Gala * r4 = SPRN_TLBnCFG 1141bb1af71eSKumar Gala * r5 = ESEL of entry we are running in 1142bb1af71eSKumar Gala */ 1143bb1af71eSKumar Gala andi. r4,r4,TLBnCFG_N_ENTRY /* Extract # entries */ 1144bb1af71eSKumar Gala li r6,0 /* Set Entry counter to 0 */ 1145bb1af71eSKumar Gala1: mr r7,r3 /* Set MAS0(TLBSEL) */ 1146bb1af71eSKumar Gala rlwimi r7,r6,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r6) */ 1147bb1af71eSKumar Gala mtspr SPRN_MAS0,r7 1148bb1af71eSKumar Gala tlbre 1149bb1af71eSKumar Gala mfspr r7,SPRN_MAS1 1150bb1af71eSKumar Gala rlwinm r7,r7,0,2,31 /* Clear MAS1 Valid and IPROT */ 1151bb1af71eSKumar Gala cmpw r5,r6 1152bb1af71eSKumar Gala beq skpinv /* Dont update the current execution TLB */ 1153bb1af71eSKumar Gala mtspr SPRN_MAS1,r7 1154bb1af71eSKumar Gala tlbwe 1155962cffbdSMichael Neuling isync 1156bb1af71eSKumar Galaskpinv: addi r6,r6,1 /* Increment */ 1157bb1af71eSKumar Gala cmpw r6,r4 /* Are we done? */ 1158bb1af71eSKumar Gala bne 1b /* If not, repeat */ 1159bb1af71eSKumar Gala 1160bb1af71eSKumar Gala /* Invalidate all TLBs */ 1161bb1af71eSKumar Gala PPC_TLBILX_ALL(0,R0) 1162bb1af71eSKumar Gala sync 1163bb1af71eSKumar Gala isync 1164bb1af71eSKumar Gala 1165bb1af71eSKumar Gala/* 3. Setup a temp mapping and jump to it 1166bb1af71eSKumar Gala * 1167bb1af71eSKumar Gala * r3 = MAS0 w/TLBSEL & ESEL for the entry we are running in 1168bb1af71eSKumar Gala * r5 = ESEL of entry we are running in 1169bb1af71eSKumar Gala */ 1170bb1af71eSKumar Gala andi. r7,r5,0x1 /* Find an entry not used and is non-zero */ 1171bb1af71eSKumar Gala addi r7,r7,0x1 1172bb1af71eSKumar Gala mr r4,r3 /* Set MAS0(TLBSEL) = 1 */ 1173bb1af71eSKumar Gala mtspr SPRN_MAS0,r4 1174bb1af71eSKumar Gala tlbre 1175bb1af71eSKumar Gala 1176bb1af71eSKumar Gala rlwimi r4,r7,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r7) */ 1177bb1af71eSKumar Gala mtspr SPRN_MAS0,r4 1178bb1af71eSKumar Gala 1179bb1af71eSKumar Gala mfspr r7,SPRN_MAS1 1180bb1af71eSKumar Gala xori r6,r7,MAS1_TS /* Setup TMP mapping in the other Address space */ 1181bb1af71eSKumar Gala mtspr SPRN_MAS1,r6 1182f5007dbfSChristophe Leroy 1183bb1af71eSKumar Gala tlbwe 1184bb1af71eSKumar Gala 1185bb1af71eSKumar Gala mfmsr r6 1186bb1af71eSKumar Gala xori r6,r6,MSR_IS 1187bb1af71eSKumar Gala mtspr SPRN_SRR1,r6 1188bb1af71eSKumar Gala bcl 20,31,$+4 /* Find our address */ 1189bb1af71eSKumar Gala1: mflr r6 1190bb1af71eSKumar Gala addi r6,r6,(2f - 1b) 1191bb1af71eSKumar Gala mtspr SPRN_SRR0,r6 1192bb1af71eSKumar Gala rfi 1193bb1af71eSKumar Gala2: 1194bb1af71eSKumar Gala 1195bb1af71eSKumar Gala/* 4. Clear out PIDs & Search info 1196bb1af71eSKumar Gala * 1197bb1af71eSKumar Gala * r3 = MAS0 w/TLBSEL & ESEL for the entry we started in 1198bb1af71eSKumar Gala * r4 = MAS0 w/TLBSEL & ESEL for the temp mapping 1199bb1af71eSKumar Gala * r5 = MAS3 1200bb1af71eSKumar Gala */ 1201bb1af71eSKumar Gala li r6,0 1202bb1af71eSKumar Gala mtspr SPRN_MAS6,r6 1203bb1af71eSKumar Gala mtspr SPRN_PID,r6 1204bb1af71eSKumar Gala 1205bb1af71eSKumar Gala/* 5. Invalidate mapping we started in 1206bb1af71eSKumar Gala * 1207bb1af71eSKumar Gala * r3 = MAS0 w/TLBSEL & ESEL for the entry we started in 1208ed2ddc56SDiana Craciun * r4 = MAS0 w/TLBSEL & ESEL for the temp mapping 1209bb1af71eSKumar Gala * r5 = MAS3 1210bb1af71eSKumar Gala */ 1211bb1af71eSKumar Gala mtspr SPRN_MAS0,r3 1212bb1af71eSKumar Gala tlbre 1213bb1af71eSKumar Gala mfspr r6,SPRN_MAS1 1214bb1af71eSKumar Gala rlwinm r6,r6,0,2,31 /* clear IPROT and VALID */ 1215bb1af71eSKumar Gala mtspr SPRN_MAS1,r6 1216bb1af71eSKumar Gala tlbwe 1217bb1af71eSKumar Gala sync 1218bb1af71eSKumar Gala isync 1219bb1af71eSKumar Gala 1220bb1af71eSKumar Gala/* 6. Setup KERNELBASE mapping in TLB[0] 1221bb1af71eSKumar Gala * 1222bb1af71eSKumar Gala * r3 = MAS0 w/TLBSEL & ESEL for the entry we started in 1223bb1af71eSKumar Gala * r4 = MAS0 w/TLBSEL & ESEL for the temp mapping 1224bb1af71eSKumar Gala * r5 = MAS3 1225bb1af71eSKumar Gala */ 12268054df05SJason Yan rlwinm r3,r3,0,16,3 /* clear ESEL */ 1227bb1af71eSKumar Gala mtspr SPRN_MAS0,r3 1228bb1af71eSKumar Gala lis r6,(MAS1_VALID|MAS1_IPROT)@h 1229bb1af71eSKumar Gala ori r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_1GB))@l 1230bb1af71eSKumar Gala mtspr SPRN_MAS1,r6 1231bb1af71eSKumar Gala 1232bb1af71eSKumar Gala LOAD_REG_IMMEDIATE(r6, PAGE_OFFSET | MAS2_M_IF_NEEDED) 1233bb1af71eSKumar Gala mtspr SPRN_MAS2,r6 1234bb1af71eSKumar Gala 1235bb1af71eSKumar Gala rlwinm r5,r5,0,0,25 1236bb1af71eSKumar Gala ori r5,r5,MAS3_SR | MAS3_SW | MAS3_SX 1237bb1af71eSKumar Gala mtspr SPRN_MAS3,r5 1238bb1af71eSKumar Gala li r5,-1 1239bb1af71eSKumar Gala rlwinm r5,r5,0,0,25 1240bb1af71eSKumar Gala 1241bb1af71eSKumar Gala tlbwe 1242f5007dbfSChristophe Leroy 12431cb6e064STiejun Chen/* 7. Jump to KERNELBASE mapping 12441cb6e064STiejun Chen * 12451cb6e064STiejun Chen * r4 = MAS0 w/TLBSEL & ESEL for the temp mapping 1246bb1af71eSKumar Gala */ 1247bb1af71eSKumar Gala /* Now we branch the new virtual address mapped by this entry */ 1248bb1af71eSKumar Gala bcl 20,31,$+4 /* Find our address */ 1249bb1af71eSKumar Gala1: mflr r6 1250bb1af71eSKumar Gala addi r6,r6,(2f - 1b) 1251bb1af71eSKumar Gala tovirt(r6,r6) 1252bb1af71eSKumar Gala lis r7,MSR_KERNEL@h 1253bb1af71eSKumar Gala ori r7,r7,MSR_KERNEL@l 1254bb1af71eSKumar Gala mtspr SPRN_SRR0,r6 1255bb1af71eSKumar Gala mtspr SPRN_SRR1,r7 1256bb1af71eSKumar Gala rfi /* start execution out of TLB1[0] entry */ 1257bb1af71eSKumar Gala2: 1258bb1af71eSKumar Gala 1259bb1af71eSKumar Gala/* 8. Clear out the temp mapping 1260ed2ddc56SDiana Craciun * 1261bb1af71eSKumar Gala * r4 = MAS0 w/TLBSEL & ESEL for the entry we are running in 1262bb1af71eSKumar Gala */ 1263bb1af71eSKumar Gala mtspr SPRN_MAS0,r4 1264bb1af71eSKumar Gala tlbre 1265bb1af71eSKumar Gala mfspr r5,SPRN_MAS1 1266bb1af71eSKumar Gala rlwinm r5,r5,0,2,31 /* clear IPROT and VALID */ 1267bb1af71eSKumar Gala mtspr SPRN_MAS1,r5 1268bb1af71eSKumar Gala tlbwe 1269bb1af71eSKumar Gala sync 1270bb1af71eSKumar Gala isync 1271bb1af71eSKumar Gala 12722d27cfd3SBenjamin Herrenschmidt /* We translate LR and return */ 12732d27cfd3SBenjamin Herrenschmidt tovirt(r8,r8) 12742d27cfd3SBenjamin Herrenschmidt mtlr r8 12752d27cfd3SBenjamin Herrenschmidt blr 12762d27cfd3SBenjamin Herrenschmidt 1277a1d0d98dSDavid Gibsonhave_hes: 1278a1d0d98dSDavid Gibson /* Setup MAS 0,1,2,3 and 7 for tlbwe of a 1G entry that maps the 1279a1d0d98dSDavid Gibson * kernel linear mapping. We also set MAS8 once for all here though 1280a1d0d98dSDavid Gibson * that will have to be made dependent on whether we are running under 1281a1d0d98dSDavid Gibson * a hypervisor I suppose. 1282a1d0d98dSDavid Gibson */ 1283a1d0d98dSDavid Gibson 1284a1d0d98dSDavid Gibson /* BEWARE, MAGIC 1285a1d0d98dSDavid Gibson * This code is called as an ordinary function on the boot CPU. But to 1286a1d0d98dSDavid Gibson * avoid duplication, this code is also used in SCOM bringup of 1287a1d0d98dSDavid Gibson * secondary CPUs. We read the code between the initial_tlb_code_start 1288a1d0d98dSDavid Gibson * and initial_tlb_code_end labels one instruction at a time and RAM it 1289a1d0d98dSDavid Gibson * into the new core via SCOM. That doesn't process branches, so there 1290a1d0d98dSDavid Gibson * must be none between those two labels. It also means if this code 12911a51dde1SBenjamin Herrenschmidt * ever takes any parameters, the SCOM code must also be updated to 12921a51dde1SBenjamin Herrenschmidt * provide them. 12931a51dde1SBenjamin Herrenschmidt */ 12942d27cfd3SBenjamin Herrenschmidt_GLOBAL(a2_tlbinit_code_start) 12952d27cfd3SBenjamin Herrenschmidt 12962d27cfd3SBenjamin Herrenschmidt ori r11,r3,MAS0_WQ_ALLWAYS 12972d27cfd3SBenjamin Herrenschmidt oris r11,r11,MAS0_ESEL(3)@h /* Use way 3: workaround A2 erratum 376 */ 12982d27cfd3SBenjamin Herrenschmidt mtspr SPRN_MAS0,r11 12992d27cfd3SBenjamin Herrenschmidt lis r3,(MAS1_VALID | MAS1_IPROT)@h 13002d27cfd3SBenjamin Herrenschmidt ori r3,r3,BOOK3E_PAGESZ_1GB << MAS1_TSIZE_SHIFT 13012d27cfd3SBenjamin Herrenschmidt mtspr SPRN_MAS1,r3 13022d27cfd3SBenjamin Herrenschmidt LOAD_REG_IMMEDIATE(r3, PAGE_OFFSET | MAS2_M) 13032d27cfd3SBenjamin Herrenschmidt mtspr SPRN_MAS2,r3 13042d27cfd3SBenjamin Herrenschmidt li r3,MAS3_SR | MAS3_SW | MAS3_SX 13052d27cfd3SBenjamin Herrenschmidt mtspr SPRN_MAS7_MAS3,r3 13062d27cfd3SBenjamin Herrenschmidt li r3,0 1307a1d0d98dSDavid Gibson mtspr SPRN_MAS8,r3 1308a1d0d98dSDavid Gibson 1309a1d0d98dSDavid Gibson /* Write the TLB entry */ 13102d27cfd3SBenjamin Herrenschmidt tlbwe 1311fce01acfSNicholas Piggin 13128e93fb33SNicholas Piggin .globl a2_tlbinit_after_linear_map 13133569d84bSNicholas Piggina2_tlbinit_after_linear_map: 1314fce01acfSNicholas Piggin 1315d7fb5b18SChristophe Leroy /* Now we branch the new virtual address mapped by this entry */ 1316fce01acfSNicholas Piggin#ifdef CONFIG_RELOCATABLE 13172d27cfd3SBenjamin Herrenschmidt __LOAD_PACA_TOC(r5) 13182d27cfd3SBenjamin Herrenschmidt LOAD_REG_ADDR_ALTTOC(r3, r5, 1f) 13192d27cfd3SBenjamin Herrenschmidt#else 13202d27cfd3SBenjamin Herrenschmidt LOAD_REG_IMMEDIATE_SYM(r3, r5, 1f) 1321f0aae323SJack Miller#endif 1322f0aae323SJack Miller mtctr r3 1323f0aae323SJack Miller bctr 13242d27cfd3SBenjamin Herrenschmidt 1325f0aae323SJack Miller1: /* We are now running at PAGE_OFFSET, clean the TLB of everything 1326f0aae323SJack Miller * else (including IPROTed things left by firmware) 1327f0aae323SJack Miller * r4 = TLBnCFG 1328f0aae323SJack Miller * r3 = current address (more or less) 1329f0aae323SJack Miller */ 1330f0aae323SJack Miller 1331f0aae323SJack Miller li r5,0 1332f0aae323SJack Miller mtspr SPRN_MAS6,r5 1333f0aae323SJack Miller tlbsx 0,r3 1334f0aae323SJack Miller 1335f0aae323SJack Miller rlwinm r9,r4,0,TLBnCFG_N_ENTRY 1336f0aae323SJack Miller rlwinm r10,r4,8,0xff 1337f0aae323SJack Miller addi r10,r10,-1 /* Get inner loop mask */ 1338f0aae323SJack Miller 1339f0aae323SJack Miller li r3,1 1340f0aae323SJack Miller 1341f0aae323SJack Miller mfspr r5,SPRN_MAS1 1342f0aae323SJack Miller rlwinm r5,r5,0,(~(MAS1_VALID|MAS1_IPROT)) 1343f0aae323SJack Miller 1344f0aae323SJack Miller mfspr r6,SPRN_MAS2 1345f0aae323SJack Miller rldicr r6,r6,0,51 /* Extract EPN */ 1346f0aae323SJack Miller 1347f0aae323SJack Miller mfspr r7,SPRN_MAS0 1348f0aae323SJack Miller rlwinm r7,r7,0,0xffff0fff /* Clear HES and WQ */ 1349f0aae323SJack Miller 1350f0aae323SJack Miller rlwinm r8,r7,16,0xfff /* Extract ESEL */ 1351f0aae323SJack Miller 1352f0aae323SJack Miller2: add r4,r3,r8 1353f0aae323SJack Miller and r4,r4,r10 1354f0aae323SJack Miller 1355f0aae323SJack Miller rlwimi r7,r4,16,MAS0_ESEL_MASK 1356f0aae323SJack Miller 1357f0aae323SJack Miller mtspr SPRN_MAS0,r7 1358f0aae323SJack Miller mtspr SPRN_MAS1,r5 1359f0aae323SJack Miller mtspr SPRN_MAS2,r6 1360f0aae323SJack Miller tlbwe 1361f0aae323SJack Miller 1362f0aae323SJack Miller addi r3,r3,1 1363f0aae323SJack Miller and. r4,r3,r10 1364f0aae323SJack Miller 1365f0aae323SJack Miller bne 3f 1366a1d0d98dSDavid Gibson addis r6,r6,(1<<30)@h 1367a1d0d98dSDavid Gibson3: 1368a1d0d98dSDavid Gibson cmpw r3,r9 1369962cffbdSMichael Neuling blt 2b 13702d27cfd3SBenjamin Herrenschmidt 13712d27cfd3SBenjamin Herrenschmidt .globl a2_tlbinit_after_iprot_flush 13722d27cfd3SBenjamin Herrenschmidta2_tlbinit_after_iprot_flush: 1373a1d0d98dSDavid Gibson 1374a1d0d98dSDavid Gibson PPC_TLBILX(0,0,R0) 1375a1d0d98dSDavid Gibson sync 13762d27cfd3SBenjamin Herrenschmidt isync 13772d27cfd3SBenjamin Herrenschmidt 13782d27cfd3SBenjamin Herrenschmidt .globl a2_tlbinit_code_end 13792d27cfd3SBenjamin Herrenschmidta2_tlbinit_code_end: 13802d27cfd3SBenjamin Herrenschmidt 13812d27cfd3SBenjamin Herrenschmidt /* We translate LR and return */ 13822d27cfd3SBenjamin Herrenschmidt mflr r3 13832d27cfd3SBenjamin Herrenschmidt tovirt(r3,r3) 13842d27cfd3SBenjamin Herrenschmidt mtlr r3 13852d27cfd3SBenjamin Herrenschmidt blr 13862d27cfd3SBenjamin Herrenschmidt 13872d27cfd3SBenjamin Herrenschmidt/* 13882d27cfd3SBenjamin Herrenschmidt * Main entry (boot CPU, thread 0) 13892d27cfd3SBenjamin Herrenschmidt * 13902d27cfd3SBenjamin Herrenschmidt * We enter here from head_64.S, possibly after the prom_init trampoline 13912d27cfd3SBenjamin Herrenschmidt * with r3 and r4 already saved to r31 and 30 respectively and in 64 bits 13922d27cfd3SBenjamin Herrenschmidt * mode. Anything else is as it was left by the bootloader 13932d27cfd3SBenjamin Herrenschmidt * 13942d27cfd3SBenjamin Herrenschmidt * Initial requirements of this port: 13952d27cfd3SBenjamin Herrenschmidt * 13962d27cfd3SBenjamin Herrenschmidt * - Kernel loaded at 0 physical 13972d27cfd3SBenjamin Herrenschmidt * - A good lump of memory mapped 0:0 by UTLB entry 0 13982d27cfd3SBenjamin Herrenschmidt * - MSR:IS & MSR:DS set to 0 13992d27cfd3SBenjamin Herrenschmidt * 14002d27cfd3SBenjamin Herrenschmidt * Note that some of the above requirements will be relaxed in the future 14012d27cfd3SBenjamin Herrenschmidt * as the kernel becomes smarter at dealing with different initial conditions 14022d27cfd3SBenjamin Herrenschmidt * but for now you have to be careful 14032d27cfd3SBenjamin Herrenschmidt */ 14042d27cfd3SBenjamin Herrenschmidt_GLOBAL(start_initialization_book3e) 14052d27cfd3SBenjamin Herrenschmidt mflr r28 14062d27cfd3SBenjamin Herrenschmidt 1407b1576fecSAnton Blanchard /* First, we need to setup some initial TLBs to map the kernel 14082d27cfd3SBenjamin Herrenschmidt * text, data and bss at PAGE_OFFSET. We don't have a real mode 14092d27cfd3SBenjamin Herrenschmidt * and always use AS 0, so we just set it up to match our link 1410b1576fecSAnton Blanchard * address and never use 0 based addresses. 14112d27cfd3SBenjamin Herrenschmidt */ 14122d27cfd3SBenjamin Herrenschmidt bl initial_tlb_book3e 1413b1576fecSAnton Blanchard 14142d27cfd3SBenjamin Herrenschmidt /* Init global core bits */ 14152d27cfd3SBenjamin Herrenschmidt bl init_core_book3e 14162d27cfd3SBenjamin Herrenschmidt 14172d27cfd3SBenjamin Herrenschmidt /* Init per-thread bits */ 14182d27cfd3SBenjamin Herrenschmidt bl init_thread_book3e 14192d27cfd3SBenjamin Herrenschmidt 14202d27cfd3SBenjamin Herrenschmidt /* Return to common init code */ 14212d27cfd3SBenjamin Herrenschmidt tovirt(r28,r28) 14222d27cfd3SBenjamin Herrenschmidt mtlr r28 14232d27cfd3SBenjamin Herrenschmidt blr 14242d27cfd3SBenjamin Herrenschmidt 14252d27cfd3SBenjamin Herrenschmidt 14262d27cfd3SBenjamin Herrenschmidt/* 14272d27cfd3SBenjamin Herrenschmidt * Secondary core/processor entry 14282d27cfd3SBenjamin Herrenschmidt * 14292d27cfd3SBenjamin Herrenschmidt * This is entered for thread 0 of a secondary core, all other threads 14302d27cfd3SBenjamin Herrenschmidt * are expected to be stopped. It's similar to start_initialization_book3e 14312d27cfd3SBenjamin Herrenschmidt * except that it's generally entered from the holding loop in head_64.S 14322d27cfd3SBenjamin Herrenschmidt * after CPUs have been gathered by Open Firmware. 14332d27cfd3SBenjamin Herrenschmidt * 1434b1576fecSAnton Blanchard * We assume we are in 32 bits mode running with whatever TLB entry was 14352d27cfd3SBenjamin Herrenschmidt * set for us by the firmware or POR engine. 14362d27cfd3SBenjamin Herrenschmidt */ 14372d27cfd3SBenjamin Herrenschmidt_GLOBAL(book3e_secondary_core_init_tlb_set) 14382d27cfd3SBenjamin Herrenschmidt li r4,1 14392d27cfd3SBenjamin Herrenschmidt b generic_secondary_smp_init 14402d27cfd3SBenjamin Herrenschmidt 14412d27cfd3SBenjamin Herrenschmidt_GLOBAL(book3e_secondary_core_init) 14422d27cfd3SBenjamin Herrenschmidt mflr r28 14432d27cfd3SBenjamin Herrenschmidt 1444b1576fecSAnton Blanchard /* Do we need to setup initial TLB entry ? */ 14452d27cfd3SBenjamin Herrenschmidt cmplwi r4,0 14462d27cfd3SBenjamin Herrenschmidt bne 2f 14472d27cfd3SBenjamin Herrenschmidt 14482d27cfd3SBenjamin Herrenschmidt /* Setup TLB for this core */ 1449b1576fecSAnton Blanchard bl initial_tlb_book3e 14502d27cfd3SBenjamin Herrenschmidt 14512d27cfd3SBenjamin Herrenschmidt /* We can return from the above running at a different 1452b1576fecSAnton Blanchard * address, so recalculate r2 (TOC) 14532d27cfd3SBenjamin Herrenschmidt */ 14542d27cfd3SBenjamin Herrenschmidt bl relative_toc 1455b1576fecSAnton Blanchard 14562d27cfd3SBenjamin Herrenschmidt /* Init global core bits */ 14572d27cfd3SBenjamin Herrenschmidt2: bl init_core_book3e 14582d27cfd3SBenjamin Herrenschmidt 14592d27cfd3SBenjamin Herrenschmidt /* Init per-thread bits */ 14602d27cfd3SBenjamin Herrenschmidt3: bl init_thread_book3e 14612d27cfd3SBenjamin Herrenschmidt 14622d27cfd3SBenjamin Herrenschmidt /* Return to common init code at proper virtual address. 14632d27cfd3SBenjamin Herrenschmidt * 14642d27cfd3SBenjamin Herrenschmidt * Due to various previous assumptions, we know we entered this 14652d27cfd3SBenjamin Herrenschmidt * function at either the final PAGE_OFFSET mapping or using a 14662d27cfd3SBenjamin Herrenschmidt * 1:1 mapping at 0, so we don't bother doing a complicated check 14672d27cfd3SBenjamin Herrenschmidt * here, we just ensure the return address has the right top bits. 14682d27cfd3SBenjamin Herrenschmidt * 14692d27cfd3SBenjamin Herrenschmidt * Note that if we ever want to be smarter about where we can be 14702d27cfd3SBenjamin Herrenschmidt * started from, we have to be careful that by the time we reach 14712d27cfd3SBenjamin Herrenschmidt * the code below we may already be running at a different location 14722d27cfd3SBenjamin Herrenschmidt * than the one we were called from since initial_tlb_book3e can 14732d27cfd3SBenjamin Herrenschmidt * have moved us already. 14742d27cfd3SBenjamin Herrenschmidt */ 14752d27cfd3SBenjamin Herrenschmidt cmpdi cr0,r28,0 14762d27cfd3SBenjamin Herrenschmidt blt 1f 14772d27cfd3SBenjamin Herrenschmidt lis r3,PAGE_OFFSET@highest 14782d27cfd3SBenjamin Herrenschmidt sldi r3,r3,32 14792d27cfd3SBenjamin Herrenschmidt or r28,r28,r3 14802d27cfd3SBenjamin Herrenschmidt1: mtlr r28 14812d27cfd3SBenjamin Herrenschmidt blr 14821cb6e064STiejun Chen 14836a3bab90SAnton Blanchard_GLOBAL(book3e_secondary_thread_init) 14842d27cfd3SBenjamin Herrenschmidt mflr r28 14851cb6e064STiejun Chen b 3b 14861cb6e064STiejun Chen 14872d27cfd3SBenjamin Herrenschmidt_GLOBAL(init_core_book3e) 14882d27cfd3SBenjamin Herrenschmidt /* Establish the interrupt vector base */ 14892d27cfd3SBenjamin Herrenschmidt tovirt(r2,r2) 14902d27cfd3SBenjamin Herrenschmidt LOAD_REG_ADDR(r3, interrupt_base_book3e) 14916a3bab90SAnton Blanchard mtspr SPRN_IVPR,r3 14922d27cfd3SBenjamin Herrenschmidt sync 14932d27cfd3SBenjamin Herrenschmidt blr 14942d27cfd3SBenjamin Herrenschmidt 14952d27cfd3SBenjamin HerrenschmidtSYM_CODE_START_LOCAL(init_thread_book3e) 14962d27cfd3SBenjamin Herrenschmidt lis r3,(SPRN_EPCR_ICM | SPRN_EPCR_GICM)@h 14972d27cfd3SBenjamin Herrenschmidt mtspr SPRN_EPCR,r3 14986c188829SKumar Gala 14996c188829SKumar Gala /* Make sure interrupts are off */ 15002d27cfd3SBenjamin Herrenschmidt wrteei 0 15016c188829SKumar Gala 15026c188829SKumar Gala /* disable all timers and clear out status */ 15032d27cfd3SBenjamin Herrenschmidt li r3,0 15042d27cfd3SBenjamin Herrenschmidt mtspr SPRN_TCR,r3 15052d27cfd3SBenjamin Herrenschmidt mfspr r3,SPRN_TSR 15064b98d9e7SKumar Gala mtspr SPRN_TSR,r3 15074b98d9e7SKumar Gala 15084b98d9e7SKumar Gala blr 15094b98d9e7SKumar GalaSYM_CODE_END(init_thread_book3e) 15104b98d9e7SKumar Gala 15114b98d9e7SKumar Gala_GLOBAL(__setup_base_ivors) 15124b98d9e7SKumar Gala SET_IVOR(0, 0x020) /* Critical Input */ 15134b98d9e7SKumar Gala SET_IVOR(1, 0x000) /* Machine Check */ 15144b98d9e7SKumar Gala SET_IVOR(2, 0x060) /* Data Storage */ 15154b98d9e7SKumar Gala SET_IVOR(3, 0x080) /* Instruction Storage */ 15164b98d9e7SKumar Gala SET_IVOR(4, 0x0a0) /* External Input */ 15174b98d9e7SKumar Gala SET_IVOR(5, 0x0c0) /* Alignment */ 15184b98d9e7SKumar Gala SET_IVOR(6, 0x0e0) /* Program */ 15194b98d9e7SKumar Gala SET_IVOR(7, 0x100) /* FP Unavailable */ 15204b98d9e7SKumar Gala SET_IVOR(8, 0x120) /* System Call */ 15214b98d9e7SKumar Gala SET_IVOR(9, 0x140) /* Auxiliary Processor Unavailable */ 15224b98d9e7SKumar Gala SET_IVOR(10, 0x160) /* Decrementer */ 15232d27cfd3SBenjamin Herrenschmidt SET_IVOR(11, 0x180) /* Fixed Interval Timer */ 15244b98d9e7SKumar Gala SET_IVOR(12, 0x1a0) /* Watchdog Timer */ 15252d27cfd3SBenjamin Herrenschmidt SET_IVOR(13, 0x1c0) /* Data TLB Error */ 15264b98d9e7SKumar Gala SET_IVOR(14, 0x1e0) /* Instruction TLB Error */ 15273a6e9bd7SScott Wood SET_IVOR(15, 0x040) /* Debug */ 1528cd66cc2eSKumar Gala 1529cd66cc2eSKumar Gala sync 1530cd66cc2eSKumar Gala 1531cd66cc2eSKumar Gala blr 1532cd66cc2eSKumar Gala 15333a6e9bd7SScott Wood_GLOBAL(setup_altivec_ivors) 15343a6e9bd7SScott Wood SET_IVOR(32, 0x200) /* AltiVec Unavailable */ 15353a6e9bd7SScott Wood SET_IVOR(33, 0x220) /* AltiVec Assist */ 15363a6e9bd7SScott Wood blr 15373a6e9bd7SScott Wood 15383a6e9bd7SScott Wood_GLOBAL(setup_perfmon_ivor) 15393a6e9bd7SScott Wood SET_IVOR(35, 0x260) /* Performance Monitor */ 15403a6e9bd7SScott Wood blr 15413a6e9bd7SScott Wood 15423a6e9bd7SScott Wood_GLOBAL(setup_doorbell_ivors) 15433a6e9bd7SScott Wood SET_IVOR(36, 0x280) /* Processor Doorbell */ 15443a6e9bd7SScott Wood SET_IVOR(37, 0x2a0) /* Processor Doorbell Crit */ 15450778407fSVarun Sethi blr 15460778407fSVarun Sethi 15473a6e9bd7SScott Wood_GLOBAL(setup_ehv_ivors) 1548228b1a47SMihai Caraman SET_IVOR(40, 0x300) /* Embedded Hypervisor System Call */ 1549228b1a47SMihai Caraman SET_IVOR(41, 0x320) /* Embedded Hypervisor Privilege */ 1550228b1a47SMihai Caraman SET_IVOR(38, 0x2c0) /* Guest Processor Doorbell */ 1551228b1a47SMihai Caraman SET_IVOR(39, 0x2e0) /* Guest Processor Doorbell Crit/MC */ 1552 blr 1553 1554_GLOBAL(setup_lrat_ivor) 1555 SET_IVOR(42, 0x340) /* LRAT Error */ 1556 blr 1557