10ebc4cdaSBenjamin Herrenschmidt/* 20ebc4cdaSBenjamin Herrenschmidt * This file contains the 64-bit "server" PowerPC variant 30ebc4cdaSBenjamin Herrenschmidt * of the low level exception handling including exception 40ebc4cdaSBenjamin Herrenschmidt * vectors, exception return, part of the slb and stab 50ebc4cdaSBenjamin Herrenschmidt * handling and other fixed offset specific things. 60ebc4cdaSBenjamin Herrenschmidt * 70ebc4cdaSBenjamin Herrenschmidt * This file is meant to be #included from head_64.S due to 825985edcSLucas De Marchi * position dependent assembly. 90ebc4cdaSBenjamin Herrenschmidt * 100ebc4cdaSBenjamin Herrenschmidt * Most of this originates from head_64.S and thus has the same 110ebc4cdaSBenjamin Herrenschmidt * copyright history. 120ebc4cdaSBenjamin Herrenschmidt * 130ebc4cdaSBenjamin Herrenschmidt */ 140ebc4cdaSBenjamin Herrenschmidt 157230c564SBenjamin Herrenschmidt#include <asm/hw_irq.h> 168aa34ab8SBenjamin Herrenschmidt#include <asm/exception-64s.h> 1746f52210SStephen Rothwell#include <asm/ptrace.h> 187cba160aSShreyas B. Prabhu#include <asm/cpuidle.h> 19da2bc464SMichael Ellerman#include <asm/head-64.h> 208aa34ab8SBenjamin Herrenschmidt 210ebc4cdaSBenjamin Herrenschmidt/* 2257f26649SNicholas Piggin * There are a few constraints to be concerned with. 2357f26649SNicholas Piggin * - Real mode exceptions code/data must be located at their physical location. 2457f26649SNicholas Piggin * - Virtual mode exceptions must be mapped at their 0xc000... location. 2557f26649SNicholas Piggin * - Fixed location code must not call directly beyond the __end_interrupts 2657f26649SNicholas Piggin * area when built with CONFIG_RELOCATABLE. LOAD_HANDLER / bctr sequence 2757f26649SNicholas Piggin * must be used. 2857f26649SNicholas Piggin * - LOAD_HANDLER targets must be within first 64K of physical 0 / 2957f26649SNicholas Piggin * virtual 0xc00... 3057f26649SNicholas Piggin * - Conditional branch targets must be within +/-32K of caller. 3157f26649SNicholas Piggin * 3257f26649SNicholas Piggin * "Virtual exceptions" run with relocation on (MSR_IR=1, MSR_DR=1), and 3357f26649SNicholas Piggin * therefore don't have to run in physically located code or rfid to 3457f26649SNicholas Piggin * virtual mode kernel code. However on relocatable kernels they do have 3557f26649SNicholas Piggin * to branch to KERNELBASE offset because the rest of the kernel (outside 3657f26649SNicholas Piggin * the exception vectors) may be located elsewhere. 3757f26649SNicholas Piggin * 3857f26649SNicholas Piggin * Virtual exceptions correspond with physical, except their entry points 3957f26649SNicholas Piggin * are offset by 0xc000000000000000 and also tend to get an added 0x4000 4057f26649SNicholas Piggin * offset applied. Virtual exceptions are enabled with the Alternate 4157f26649SNicholas Piggin * Interrupt Location (AIL) bit set in the LPCR. However this does not 4257f26649SNicholas Piggin * guarantee they will be delivered virtually. Some conditions (see the ISA) 4357f26649SNicholas Piggin * cause exceptions to be delivered in real mode. 4457f26649SNicholas Piggin * 4557f26649SNicholas Piggin * It's impossible to receive interrupts below 0x300 via AIL. 4657f26649SNicholas Piggin * 4757f26649SNicholas Piggin * KVM: None of the virtual exceptions are from the guest. Anything that 4857f26649SNicholas Piggin * escalated to HV=1 from HV=0 is delivered via real mode handlers. 4957f26649SNicholas Piggin * 5057f26649SNicholas Piggin * 510ebc4cdaSBenjamin Herrenschmidt * We layout physical memory as follows: 520ebc4cdaSBenjamin Herrenschmidt * 0x0000 - 0x00ff : Secondary processor spin code 5357f26649SNicholas Piggin * 0x0100 - 0x18ff : Real mode pSeries interrupt vectors 5457f26649SNicholas Piggin * 0x1900 - 0x3fff : Real mode trampolines 5557f26649SNicholas Piggin * 0x4000 - 0x58ff : Relon (IR=1,DR=1) mode pSeries interrupt vectors 5657f26649SNicholas Piggin * 0x5900 - 0x6fff : Relon mode trampolines 570ebc4cdaSBenjamin Herrenschmidt * 0x7000 - 0x7fff : FWNMI data area 5857f26649SNicholas Piggin * 0x8000 - .... : Common interrupt handlers, remaining early 5957f26649SNicholas Piggin * setup code, rest of kernel. 600ebc4cdaSBenjamin Herrenschmidt */ 6157f26649SNicholas PigginOPEN_FIXED_SECTION(real_vectors, 0x0100, 0x1900) 6257f26649SNicholas PigginOPEN_FIXED_SECTION(real_trampolines, 0x1900, 0x4000) 6357f26649SNicholas PigginOPEN_FIXED_SECTION(virt_vectors, 0x4000, 0x5900) 6457f26649SNicholas PigginOPEN_FIXED_SECTION(virt_trampolines, 0x5900, 0x7000) 6557f26649SNicholas Piggin#if defined(CONFIG_PPC_PSERIES) || defined(CONFIG_PPC_POWERNV) 6657f26649SNicholas Piggin/* 6757f26649SNicholas Piggin * Data area reserved for FWNMI option. 6857f26649SNicholas Piggin * This address (0x7000) is fixed by the RPA. 6957f26649SNicholas Piggin * pseries and powernv need to keep the whole page from 7057f26649SNicholas Piggin * 0x7000 to 0x8000 free for use by the firmware 7157f26649SNicholas Piggin */ 7257f26649SNicholas PigginZERO_FIXED_SECTION(fwnmi_page, 0x7000, 0x8000) 7357f26649SNicholas PigginOPEN_TEXT_SECTION(0x8000) 7457f26649SNicholas Piggin#else 7557f26649SNicholas PigginOPEN_TEXT_SECTION(0x7000) 7657f26649SNicholas Piggin#endif 7757f26649SNicholas Piggin 7857f26649SNicholas PigginUSE_FIXED_SECTION(real_vectors) 7957f26649SNicholas Piggin 800ebc4cdaSBenjamin Herrenschmidt/* 810ebc4cdaSBenjamin Herrenschmidt * This is the start of the interrupt handlers for pSeries 820ebc4cdaSBenjamin Herrenschmidt * This code runs with relocation off. 830ebc4cdaSBenjamin Herrenschmidt * Code from here to __end_interrupts gets copied down to real 840ebc4cdaSBenjamin Herrenschmidt * address 0x100 when we are running a relocatable kernel. 850ebc4cdaSBenjamin Herrenschmidt * Therefore any relative branches in this section must only 860ebc4cdaSBenjamin Herrenschmidt * branch to labels in this section. 870ebc4cdaSBenjamin Herrenschmidt */ 880ebc4cdaSBenjamin Herrenschmidt .globl __start_interrupts 890ebc4cdaSBenjamin Herrenschmidt__start_interrupts: 900ebc4cdaSBenjamin Herrenschmidt 91da2bc464SMichael EllermanEXC_REAL_BEGIN(system_reset, 0x100, 0x200) 92948cf67cSBenjamin Herrenschmidt SET_SCRATCH0(r13) 93948cf67cSBenjamin Herrenschmidt#ifdef CONFIG_PPC_P7_NAP 94948cf67cSBenjamin HerrenschmidtBEGIN_FTR_SECTION 95948cf67cSBenjamin Herrenschmidt /* Running native on arch 2.06 or later, check if we are 9677b54e9fSShreyas B. Prabhu * waking up from nap/sleep/winkle. 97948cf67cSBenjamin Herrenschmidt */ 98948cf67cSBenjamin Herrenschmidt mfspr r13,SPRN_SRR1 99371fefd6SPaul Mackerras rlwinm. r13,r13,47-31,30,31 100371fefd6SPaul Mackerras beq 9f 101371fefd6SPaul Mackerras 1027cba160aSShreyas B. Prabhu cmpwi cr3,r13,2 103371fefd6SPaul Mackerras GET_PACA(r13) 1045fa6b6bdSShreyas B. Prabhu bl pnv_restore_hyp_resource 10577b54e9fSShreyas B. Prabhu 1067cba160aSShreyas B. Prabhu li r0,PNV_THREAD_RUNNING 1077cba160aSShreyas B. Prabhu stb r0,PACA_THREAD_IDLE_STATE(r13) /* Clear thread state */ 108371fefd6SPaul Mackerras 1093a167beaSAneesh Kumar K.V#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE 110f0888f70SPaul Mackerras li r0,KVM_HWTHREAD_IN_KERNEL 111f0888f70SPaul Mackerras stb r0,HSTATE_HWTHREAD_STATE(r13) 112f0888f70SPaul Mackerras /* Order setting hwthread_state vs. testing hwthread_req */ 113f0888f70SPaul Mackerras sync 114f0888f70SPaul Mackerras lbz r0,HSTATE_HWTHREAD_REQ(r13) 115f0888f70SPaul Mackerras cmpwi r0,0 116f0888f70SPaul Mackerras beq 1f 117371fefd6SPaul Mackerras b kvm_start_guest 118371fefd6SPaul Mackerras1: 119371fefd6SPaul Mackerras#endif 120371fefd6SPaul Mackerras 12156548fc0SPaul Mackerras /* Return SRR1 from power7_nap() */ 12256548fc0SPaul Mackerras mfspr r3,SPRN_SRR1 12317065671SShreyas B. Prabhu blt cr3,2f 1245fa6b6bdSShreyas B. Prabhu b pnv_wakeup_loss 1255fa6b6bdSShreyas B. Prabhu2: b pnv_wakeup_noloss 126aca79d2bSVaidyanathan Srinivasan 127371fefd6SPaul Mackerras9: 128969391c5SPaul MackerrasEND_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206) 129948cf67cSBenjamin Herrenschmidt#endif /* CONFIG_PPC_P7_NAP */ 130b01c8b54SPaul Mackerras EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common, EXC_STD, 131b01c8b54SPaul Mackerras NOTEST, 0x100) 132da2bc464SMichael EllermanEXC_REAL_END(system_reset, 0x100, 0x200) 133582baf44SNicholas PigginEXC_VIRT_NONE(0x4100, 0x4200) 134582baf44SNicholas PigginEXC_COMMON(system_reset_common, 0x100, system_reset_exception) 135582baf44SNicholas Piggin 136582baf44SNicholas Piggin#ifdef CONFIG_PPC_PSERIES 137582baf44SNicholas Piggin/* 138582baf44SNicholas Piggin * Vectors for the FWNMI option. Share common code. 139582baf44SNicholas Piggin */ 140582baf44SNicholas PigginTRAMP_REAL_BEGIN(system_reset_fwnmi) 141582baf44SNicholas Piggin SET_SCRATCH0(r13) /* save r13 */ 142582baf44SNicholas Piggin EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common, EXC_STD, 143582baf44SNicholas Piggin NOTEST, 0x100) 144582baf44SNicholas Piggin#endif /* CONFIG_PPC_PSERIES */ 145582baf44SNicholas Piggin 1460ebc4cdaSBenjamin Herrenschmidt 147da2bc464SMichael EllermanEXC_REAL_BEGIN(machine_check, 0x200, 0x300) 148b01c8b54SPaul Mackerras /* This is moved out of line as it can be patched by FW, but 149b01c8b54SPaul Mackerras * some code path might still want to branch into the original 150b01c8b54SPaul Mackerras * vector 151b01c8b54SPaul Mackerras */ 1521707dd16SPaul Mackerras SET_SCRATCH0(r13) /* save r13 */ 153bc14c491SMahesh Salgaonkar /* 154bc14c491SMahesh Salgaonkar * Running native on arch 2.06 or later, we may wakeup from winkle 155bc14c491SMahesh Salgaonkar * inside machine check. If yes, then last bit of HSPGR0 would be set 156bc14c491SMahesh Salgaonkar * to 1. Hence clear it unconditionally. 1571c51089fSMahesh Salgaonkar */ 158bc14c491SMahesh Salgaonkar GET_PACA(r13) 159bc14c491SMahesh Salgaonkar clrrdi r13,r13,1 160bc14c491SMahesh Salgaonkar SET_PACA(r13) 1611707dd16SPaul Mackerras EXCEPTION_PROLOG_0(PACA_EXMC) 1621e9b4507SMahesh SalgaonkarBEGIN_FTR_SECTION 1632513767dSMahesh Salgaonkar b machine_check_powernv_early 1641e9b4507SMahesh SalgaonkarFTR_SECTION_ELSE 1651707dd16SPaul Mackerras b machine_check_pSeries_0 1661e9b4507SMahesh SalgaonkarALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE) 167da2bc464SMichael EllermanEXC_REAL_END(machine_check, 0x200, 0x300) 168afcf0095SNicholas PigginEXC_VIRT_NONE(0x4200, 0x4300) 169afcf0095SNicholas PigginTRAMP_REAL_BEGIN(machine_check_powernv_early) 170afcf0095SNicholas PigginBEGIN_FTR_SECTION 171afcf0095SNicholas Piggin EXCEPTION_PROLOG_1(PACA_EXMC, NOTEST, 0x200) 172afcf0095SNicholas Piggin /* 173afcf0095SNicholas Piggin * Register contents: 174afcf0095SNicholas Piggin * R13 = PACA 175afcf0095SNicholas Piggin * R9 = CR 176afcf0095SNicholas Piggin * Original R9 to R13 is saved on PACA_EXMC 177afcf0095SNicholas Piggin * 178afcf0095SNicholas Piggin * Switch to mc_emergency stack and handle re-entrancy (we limit 179afcf0095SNicholas Piggin * the nested MCE upto level 4 to avoid stack overflow). 180afcf0095SNicholas Piggin * Save MCE registers srr1, srr0, dar and dsisr and then set ME=1 181afcf0095SNicholas Piggin * 182afcf0095SNicholas Piggin * We use paca->in_mce to check whether this is the first entry or 183afcf0095SNicholas Piggin * nested machine check. We increment paca->in_mce to track nested 184afcf0095SNicholas Piggin * machine checks. 185afcf0095SNicholas Piggin * 186afcf0095SNicholas Piggin * If this is the first entry then set stack pointer to 187afcf0095SNicholas Piggin * paca->mc_emergency_sp, otherwise r1 is already pointing to 188afcf0095SNicholas Piggin * stack frame on mc_emergency stack. 189afcf0095SNicholas Piggin * 190afcf0095SNicholas Piggin * NOTE: We are here with MSR_ME=0 (off), which means we risk a 191afcf0095SNicholas Piggin * checkstop if we get another machine check exception before we do 192afcf0095SNicholas Piggin * rfid with MSR_ME=1. 193afcf0095SNicholas Piggin */ 194afcf0095SNicholas Piggin mr r11,r1 /* Save r1 */ 195afcf0095SNicholas Piggin lhz r10,PACA_IN_MCE(r13) 196afcf0095SNicholas Piggin cmpwi r10,0 /* Are we in nested machine check */ 197afcf0095SNicholas Piggin bne 0f /* Yes, we are. */ 198afcf0095SNicholas Piggin /* First machine check entry */ 199afcf0095SNicholas Piggin ld r1,PACAMCEMERGSP(r13) /* Use MC emergency stack */ 200afcf0095SNicholas Piggin0: subi r1,r1,INT_FRAME_SIZE /* alloc stack frame */ 201afcf0095SNicholas Piggin addi r10,r10,1 /* increment paca->in_mce */ 202afcf0095SNicholas Piggin sth r10,PACA_IN_MCE(r13) 203afcf0095SNicholas Piggin /* Limit nested MCE to level 4 to avoid stack overflow */ 204afcf0095SNicholas Piggin cmpwi r10,4 205afcf0095SNicholas Piggin bgt 2f /* Check if we hit limit of 4 */ 206afcf0095SNicholas Piggin std r11,GPR1(r1) /* Save r1 on the stack. */ 207afcf0095SNicholas Piggin std r11,0(r1) /* make stack chain pointer */ 208afcf0095SNicholas Piggin mfspr r11,SPRN_SRR0 /* Save SRR0 */ 209afcf0095SNicholas Piggin std r11,_NIP(r1) 210afcf0095SNicholas Piggin mfspr r11,SPRN_SRR1 /* Save SRR1 */ 211afcf0095SNicholas Piggin std r11,_MSR(r1) 212afcf0095SNicholas Piggin mfspr r11,SPRN_DAR /* Save DAR */ 213afcf0095SNicholas Piggin std r11,_DAR(r1) 214afcf0095SNicholas Piggin mfspr r11,SPRN_DSISR /* Save DSISR */ 215afcf0095SNicholas Piggin std r11,_DSISR(r1) 216afcf0095SNicholas Piggin std r9,_CCR(r1) /* Save CR in stackframe */ 217afcf0095SNicholas Piggin /* Save r9 through r13 from EXMC save area to stack frame. */ 218afcf0095SNicholas Piggin EXCEPTION_PROLOG_COMMON_2(PACA_EXMC) 219afcf0095SNicholas Piggin mfmsr r11 /* get MSR value */ 220afcf0095SNicholas Piggin ori r11,r11,MSR_ME /* turn on ME bit */ 221afcf0095SNicholas Piggin ori r11,r11,MSR_RI /* turn on RI bit */ 222afcf0095SNicholas Piggin LOAD_HANDLER(r12, machine_check_handle_early) 223afcf0095SNicholas Piggin1: mtspr SPRN_SRR0,r12 224afcf0095SNicholas Piggin mtspr SPRN_SRR1,r11 225afcf0095SNicholas Piggin rfid 226afcf0095SNicholas Piggin b . /* prevent speculative execution */ 227afcf0095SNicholas Piggin2: 228afcf0095SNicholas Piggin /* Stack overflow. Stay on emergency stack and panic. 229afcf0095SNicholas Piggin * Keep the ME bit off while panic-ing, so that if we hit 230afcf0095SNicholas Piggin * another machine check we checkstop. 231afcf0095SNicholas Piggin */ 232afcf0095SNicholas Piggin addi r1,r1,INT_FRAME_SIZE /* go back to previous stack frame */ 233afcf0095SNicholas Piggin ld r11,PACAKMSR(r13) 234afcf0095SNicholas Piggin LOAD_HANDLER(r12, unrecover_mce) 235afcf0095SNicholas Piggin li r10,MSR_ME 236afcf0095SNicholas Piggin andc r11,r11,r10 /* Turn off MSR_ME */ 237afcf0095SNicholas Piggin b 1b 238afcf0095SNicholas Piggin b . /* prevent speculative execution */ 239afcf0095SNicholas PigginEND_FTR_SECTION_IFSET(CPU_FTR_HVMODE) 240afcf0095SNicholas Piggin 241afcf0095SNicholas PigginTRAMP_REAL_BEGIN(machine_check_pSeries) 242afcf0095SNicholas Piggin .globl machine_check_fwnmi 243afcf0095SNicholas Pigginmachine_check_fwnmi: 244afcf0095SNicholas Piggin SET_SCRATCH0(r13) /* save r13 */ 245afcf0095SNicholas Piggin EXCEPTION_PROLOG_0(PACA_EXMC) 246afcf0095SNicholas Pigginmachine_check_pSeries_0: 247afcf0095SNicholas Piggin EXCEPTION_PROLOG_1(PACA_EXMC, KVMTEST_PR, 0x200) 248afcf0095SNicholas Piggin /* 249afcf0095SNicholas Piggin * The following is essentially EXCEPTION_PROLOG_PSERIES_1 with the 250afcf0095SNicholas Piggin * difference that MSR_RI is not enabled, because PACA_EXMC is being 251afcf0095SNicholas Piggin * used, so nested machine check corrupts it. machine_check_common 252afcf0095SNicholas Piggin * enables MSR_RI. 253afcf0095SNicholas Piggin */ 254afcf0095SNicholas Piggin ld r10,PACAKMSR(r13) 255afcf0095SNicholas Piggin xori r10,r10,MSR_RI 256afcf0095SNicholas Piggin mfspr r11,SPRN_SRR0 257afcf0095SNicholas Piggin LOAD_HANDLER(r12, machine_check_common) 258afcf0095SNicholas Piggin mtspr SPRN_SRR0,r12 259afcf0095SNicholas Piggin mfspr r12,SPRN_SRR1 260afcf0095SNicholas Piggin mtspr SPRN_SRR1,r10 261afcf0095SNicholas Piggin rfid 262afcf0095SNicholas Piggin b . /* prevent speculative execution */ 263afcf0095SNicholas Piggin 264afcf0095SNicholas PigginTRAMP_KVM_SKIP(PACA_EXMC, 0x200) 265afcf0095SNicholas Piggin 266afcf0095SNicholas PigginEXC_COMMON_BEGIN(machine_check_common) 267afcf0095SNicholas Piggin /* 268afcf0095SNicholas Piggin * Machine check is different because we use a different 269afcf0095SNicholas Piggin * save area: PACA_EXMC instead of PACA_EXGEN. 270afcf0095SNicholas Piggin */ 271afcf0095SNicholas Piggin mfspr r10,SPRN_DAR 272afcf0095SNicholas Piggin std r10,PACA_EXMC+EX_DAR(r13) 273afcf0095SNicholas Piggin mfspr r10,SPRN_DSISR 274afcf0095SNicholas Piggin stw r10,PACA_EXMC+EX_DSISR(r13) 275afcf0095SNicholas Piggin EXCEPTION_PROLOG_COMMON(0x200, PACA_EXMC) 276afcf0095SNicholas Piggin FINISH_NAP 277afcf0095SNicholas Piggin RECONCILE_IRQ_STATE(r10, r11) 278afcf0095SNicholas Piggin ld r3,PACA_EXMC+EX_DAR(r13) 279afcf0095SNicholas Piggin lwz r4,PACA_EXMC+EX_DSISR(r13) 280afcf0095SNicholas Piggin /* Enable MSR_RI when finished with PACA_EXMC */ 281afcf0095SNicholas Piggin li r10,MSR_RI 282afcf0095SNicholas Piggin mtmsrd r10,1 283afcf0095SNicholas Piggin std r3,_DAR(r1) 284afcf0095SNicholas Piggin std r4,_DSISR(r1) 285afcf0095SNicholas Piggin bl save_nvgprs 286afcf0095SNicholas Piggin addi r3,r1,STACK_FRAME_OVERHEAD 287afcf0095SNicholas Piggin bl machine_check_exception 288afcf0095SNicholas Piggin b ret_from_except 289afcf0095SNicholas Piggin 290afcf0095SNicholas Piggin#define MACHINE_CHECK_HANDLER_WINDUP \ 291afcf0095SNicholas Piggin /* Clear MSR_RI before setting SRR0 and SRR1. */\ 292afcf0095SNicholas Piggin li r0,MSR_RI; \ 293afcf0095SNicholas Piggin mfmsr r9; /* get MSR value */ \ 294afcf0095SNicholas Piggin andc r9,r9,r0; \ 295afcf0095SNicholas Piggin mtmsrd r9,1; /* Clear MSR_RI */ \ 296afcf0095SNicholas Piggin /* Move original SRR0 and SRR1 into the respective regs */ \ 297afcf0095SNicholas Piggin ld r9,_MSR(r1); \ 298afcf0095SNicholas Piggin mtspr SPRN_SRR1,r9; \ 299afcf0095SNicholas Piggin ld r3,_NIP(r1); \ 300afcf0095SNicholas Piggin mtspr SPRN_SRR0,r3; \ 301afcf0095SNicholas Piggin ld r9,_CTR(r1); \ 302afcf0095SNicholas Piggin mtctr r9; \ 303afcf0095SNicholas Piggin ld r9,_XER(r1); \ 304afcf0095SNicholas Piggin mtxer r9; \ 305afcf0095SNicholas Piggin ld r9,_LINK(r1); \ 306afcf0095SNicholas Piggin mtlr r9; \ 307afcf0095SNicholas Piggin REST_GPR(0, r1); \ 308afcf0095SNicholas Piggin REST_8GPRS(2, r1); \ 309afcf0095SNicholas Piggin REST_GPR(10, r1); \ 310afcf0095SNicholas Piggin ld r11,_CCR(r1); \ 311afcf0095SNicholas Piggin mtcr r11; \ 312afcf0095SNicholas Piggin /* Decrement paca->in_mce. */ \ 313afcf0095SNicholas Piggin lhz r12,PACA_IN_MCE(r13); \ 314afcf0095SNicholas Piggin subi r12,r12,1; \ 315afcf0095SNicholas Piggin sth r12,PACA_IN_MCE(r13); \ 316afcf0095SNicholas Piggin REST_GPR(11, r1); \ 317afcf0095SNicholas Piggin REST_2GPRS(12, r1); \ 318afcf0095SNicholas Piggin /* restore original r1. */ \ 319afcf0095SNicholas Piggin ld r1,GPR1(r1) 320afcf0095SNicholas Piggin 321afcf0095SNicholas Piggin /* 322afcf0095SNicholas Piggin * Handle machine check early in real mode. We come here with 323afcf0095SNicholas Piggin * ME=1, MMU (IR=0 and DR=0) off and using MC emergency stack. 324afcf0095SNicholas Piggin */ 325afcf0095SNicholas PigginEXC_COMMON_BEGIN(machine_check_handle_early) 326afcf0095SNicholas Piggin std r0,GPR0(r1) /* Save r0 */ 327afcf0095SNicholas Piggin EXCEPTION_PROLOG_COMMON_3(0x200) 328afcf0095SNicholas Piggin bl save_nvgprs 329afcf0095SNicholas Piggin addi r3,r1,STACK_FRAME_OVERHEAD 330afcf0095SNicholas Piggin bl machine_check_early 331afcf0095SNicholas Piggin std r3,RESULT(r1) /* Save result */ 332afcf0095SNicholas Piggin ld r12,_MSR(r1) 333afcf0095SNicholas Piggin#ifdef CONFIG_PPC_P7_NAP 334afcf0095SNicholas Piggin /* 335afcf0095SNicholas Piggin * Check if thread was in power saving mode. We come here when any 336afcf0095SNicholas Piggin * of the following is true: 337afcf0095SNicholas Piggin * a. thread wasn't in power saving mode 338afcf0095SNicholas Piggin * b. thread was in power saving mode with no state loss, 339afcf0095SNicholas Piggin * supervisor state loss or hypervisor state loss. 340afcf0095SNicholas Piggin * 341afcf0095SNicholas Piggin * Go back to nap/sleep/winkle mode again if (b) is true. 342afcf0095SNicholas Piggin */ 343afcf0095SNicholas Piggin rlwinm. r11,r12,47-31,30,31 /* Was it in power saving mode? */ 344afcf0095SNicholas Piggin beq 4f /* No, it wasn;t */ 345afcf0095SNicholas Piggin /* Thread was in power saving mode. Go back to nap again. */ 346afcf0095SNicholas Piggin cmpwi r11,2 347afcf0095SNicholas Piggin blt 3f 348afcf0095SNicholas Piggin /* Supervisor/Hypervisor state loss */ 349afcf0095SNicholas Piggin li r0,1 350afcf0095SNicholas Piggin stb r0,PACA_NAPSTATELOST(r13) 351afcf0095SNicholas Piggin3: bl machine_check_queue_event 352afcf0095SNicholas Piggin MACHINE_CHECK_HANDLER_WINDUP 353afcf0095SNicholas Piggin GET_PACA(r13) 354afcf0095SNicholas Piggin ld r1,PACAR1(r13) 355afcf0095SNicholas Piggin /* 356afcf0095SNicholas Piggin * Check what idle state this CPU was in and go back to same mode 357afcf0095SNicholas Piggin * again. 358afcf0095SNicholas Piggin */ 359afcf0095SNicholas Piggin lbz r3,PACA_THREAD_IDLE_STATE(r13) 360afcf0095SNicholas Piggin cmpwi r3,PNV_THREAD_NAP 361afcf0095SNicholas Piggin bgt 10f 362afcf0095SNicholas Piggin IDLE_STATE_ENTER_SEQ(PPC_NAP) 363afcf0095SNicholas Piggin /* No return */ 364afcf0095SNicholas Piggin10: 365afcf0095SNicholas Piggin cmpwi r3,PNV_THREAD_SLEEP 366afcf0095SNicholas Piggin bgt 2f 367afcf0095SNicholas Piggin IDLE_STATE_ENTER_SEQ(PPC_SLEEP) 368afcf0095SNicholas Piggin /* No return */ 369afcf0095SNicholas Piggin 370afcf0095SNicholas Piggin2: 371afcf0095SNicholas Piggin /* 372afcf0095SNicholas Piggin * Go back to winkle. Please note that this thread was woken up in 373afcf0095SNicholas Piggin * machine check from winkle and have not restored the per-subcore 374afcf0095SNicholas Piggin * state. Hence before going back to winkle, set last bit of HSPGR0 375afcf0095SNicholas Piggin * to 1. This will make sure that if this thread gets woken up 376afcf0095SNicholas Piggin * again at reset vector 0x100 then it will get chance to restore 377afcf0095SNicholas Piggin * the subcore state. 378afcf0095SNicholas Piggin */ 379afcf0095SNicholas Piggin ori r13,r13,1 380afcf0095SNicholas Piggin SET_PACA(r13) 381afcf0095SNicholas Piggin IDLE_STATE_ENTER_SEQ(PPC_WINKLE) 382afcf0095SNicholas Piggin /* No return */ 383afcf0095SNicholas Piggin4: 384afcf0095SNicholas Piggin#endif 385afcf0095SNicholas Piggin /* 386afcf0095SNicholas Piggin * Check if we are coming from hypervisor userspace. If yes then we 387afcf0095SNicholas Piggin * continue in host kernel in V mode to deliver the MC event. 388afcf0095SNicholas Piggin */ 389afcf0095SNicholas Piggin rldicl. r11,r12,4,63 /* See if MC hit while in HV mode. */ 390afcf0095SNicholas Piggin beq 5f 391afcf0095SNicholas Piggin andi. r11,r12,MSR_PR /* See if coming from user. */ 392afcf0095SNicholas Piggin bne 9f /* continue in V mode if we are. */ 393afcf0095SNicholas Piggin 394afcf0095SNicholas Piggin5: 395afcf0095SNicholas Piggin#ifdef CONFIG_KVM_BOOK3S_64_HANDLER 396afcf0095SNicholas Piggin /* 397afcf0095SNicholas Piggin * We are coming from kernel context. Check if we are coming from 398afcf0095SNicholas Piggin * guest. if yes, then we can continue. We will fall through 399afcf0095SNicholas Piggin * do_kvm_200->kvmppc_interrupt to deliver the MC event to guest. 400afcf0095SNicholas Piggin */ 401afcf0095SNicholas Piggin lbz r11,HSTATE_IN_GUEST(r13) 402afcf0095SNicholas Piggin cmpwi r11,0 /* Check if coming from guest */ 403afcf0095SNicholas Piggin bne 9f /* continue if we are. */ 404afcf0095SNicholas Piggin#endif 405afcf0095SNicholas Piggin /* 406afcf0095SNicholas Piggin * At this point we are not sure about what context we come from. 407afcf0095SNicholas Piggin * Queue up the MCE event and return from the interrupt. 408afcf0095SNicholas Piggin * But before that, check if this is an un-recoverable exception. 409afcf0095SNicholas Piggin * If yes, then stay on emergency stack and panic. 410afcf0095SNicholas Piggin */ 411afcf0095SNicholas Piggin andi. r11,r12,MSR_RI 412afcf0095SNicholas Piggin bne 2f 413afcf0095SNicholas Piggin1: mfspr r11,SPRN_SRR0 414afcf0095SNicholas Piggin LOAD_HANDLER(r10,unrecover_mce) 415afcf0095SNicholas Piggin mtspr SPRN_SRR0,r10 416afcf0095SNicholas Piggin ld r10,PACAKMSR(r13) 417afcf0095SNicholas Piggin /* 418afcf0095SNicholas Piggin * We are going down. But there are chances that we might get hit by 419afcf0095SNicholas Piggin * another MCE during panic path and we may run into unstable state 420afcf0095SNicholas Piggin * with no way out. Hence, turn ME bit off while going down, so that 421afcf0095SNicholas Piggin * when another MCE is hit during panic path, system will checkstop 422afcf0095SNicholas Piggin * and hypervisor will get restarted cleanly by SP. 423afcf0095SNicholas Piggin */ 424afcf0095SNicholas Piggin li r3,MSR_ME 425afcf0095SNicholas Piggin andc r10,r10,r3 /* Turn off MSR_ME */ 426afcf0095SNicholas Piggin mtspr SPRN_SRR1,r10 427afcf0095SNicholas Piggin rfid 428afcf0095SNicholas Piggin b . 429afcf0095SNicholas Piggin2: 430afcf0095SNicholas Piggin /* 431afcf0095SNicholas Piggin * Check if we have successfully handled/recovered from error, if not 432afcf0095SNicholas Piggin * then stay on emergency stack and panic. 433afcf0095SNicholas Piggin */ 434afcf0095SNicholas Piggin ld r3,RESULT(r1) /* Load result */ 435afcf0095SNicholas Piggin cmpdi r3,0 /* see if we handled MCE successfully */ 436afcf0095SNicholas Piggin 437afcf0095SNicholas Piggin beq 1b /* if !handled then panic */ 438afcf0095SNicholas Piggin /* 439afcf0095SNicholas Piggin * Return from MC interrupt. 440afcf0095SNicholas Piggin * Queue up the MCE event so that we can log it later, while 441afcf0095SNicholas Piggin * returning from kernel or opal call. 442afcf0095SNicholas Piggin */ 443afcf0095SNicholas Piggin bl machine_check_queue_event 444afcf0095SNicholas Piggin MACHINE_CHECK_HANDLER_WINDUP 445afcf0095SNicholas Piggin rfid 446afcf0095SNicholas Piggin9: 447afcf0095SNicholas Piggin /* Deliver the machine check to host kernel in V mode. */ 448afcf0095SNicholas Piggin MACHINE_CHECK_HANDLER_WINDUP 449afcf0095SNicholas Piggin b machine_check_pSeries 450afcf0095SNicholas Piggin 451afcf0095SNicholas PigginEXC_COMMON_BEGIN(unrecover_mce) 452afcf0095SNicholas Piggin /* Invoke machine_check_exception to print MCE event and panic. */ 453afcf0095SNicholas Piggin addi r3,r1,STACK_FRAME_OVERHEAD 454afcf0095SNicholas Piggin bl machine_check_exception 455afcf0095SNicholas Piggin /* 456afcf0095SNicholas Piggin * We will not reach here. Even if we did, there is no way out. Call 457afcf0095SNicholas Piggin * unrecoverable_exception and die. 458afcf0095SNicholas Piggin */ 459afcf0095SNicholas Piggin1: addi r3,r1,STACK_FRAME_OVERHEAD 460afcf0095SNicholas Piggin bl unrecoverable_exception 461afcf0095SNicholas Piggin b 1b 462afcf0095SNicholas Piggin 4630ebc4cdaSBenjamin Herrenschmidt 464da2bc464SMichael EllermanEXC_REAL(data_access, 0x300, 0x380) 46580795e6cSNicholas PigginEXC_VIRT(data_access, 0x4300, 0x4380, 0x300) 46680795e6cSNicholas PigginTRAMP_KVM_SKIP(PACA_EXGEN, 0x300) 46780795e6cSNicholas Piggin 46880795e6cSNicholas PigginEXC_COMMON_BEGIN(data_access_common) 46980795e6cSNicholas Piggin /* 47080795e6cSNicholas Piggin * Here r13 points to the paca, r9 contains the saved CR, 47180795e6cSNicholas Piggin * SRR0 and SRR1 are saved in r11 and r12, 47280795e6cSNicholas Piggin * r9 - r13 are saved in paca->exgen. 47380795e6cSNicholas Piggin */ 47480795e6cSNicholas Piggin mfspr r10,SPRN_DAR 47580795e6cSNicholas Piggin std r10,PACA_EXGEN+EX_DAR(r13) 47680795e6cSNicholas Piggin mfspr r10,SPRN_DSISR 47780795e6cSNicholas Piggin stw r10,PACA_EXGEN+EX_DSISR(r13) 47880795e6cSNicholas Piggin EXCEPTION_PROLOG_COMMON(0x300, PACA_EXGEN) 47980795e6cSNicholas Piggin RECONCILE_IRQ_STATE(r10, r11) 48080795e6cSNicholas Piggin ld r12,_MSR(r1) 48180795e6cSNicholas Piggin ld r3,PACA_EXGEN+EX_DAR(r13) 48280795e6cSNicholas Piggin lwz r4,PACA_EXGEN+EX_DSISR(r13) 48380795e6cSNicholas Piggin li r5,0x300 48480795e6cSNicholas Piggin std r3,_DAR(r1) 48580795e6cSNicholas Piggin std r4,_DSISR(r1) 48680795e6cSNicholas PigginBEGIN_MMU_FTR_SECTION 48780795e6cSNicholas Piggin b do_hash_page /* Try to handle as hpte fault */ 48880795e6cSNicholas PigginMMU_FTR_SECTION_ELSE 48980795e6cSNicholas Piggin b handle_page_fault 49080795e6cSNicholas PigginALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX) 49180795e6cSNicholas Piggin 4920ebc4cdaSBenjamin Herrenschmidt 493da2bc464SMichael EllermanEXC_REAL_BEGIN(data_access_slb, 0x380, 0x400) 494673b189aSPaul Mackerras SET_SCRATCH0(r13) 4951707dd16SPaul Mackerras EXCEPTION_PROLOG_0(PACA_EXSLB) 496da2bc464SMichael Ellerman EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST_PR, 0x380) 4970ebc4cdaSBenjamin Herrenschmidt std r3,PACA_EXSLB+EX_R3(r13) 4980ebc4cdaSBenjamin Herrenschmidt mfspr r3,SPRN_DAR 499b01c8b54SPaul Mackerras mfspr r12,SPRN_SRR1 500f0f558b1SPaul Mackerras crset 4*cr6+eq 5010ebc4cdaSBenjamin Herrenschmidt#ifndef CONFIG_RELOCATABLE 502b1576fecSAnton Blanchard b slb_miss_realmode 5030ebc4cdaSBenjamin Herrenschmidt#else 5040ebc4cdaSBenjamin Herrenschmidt /* 505ad0289e4SAnton Blanchard * We can't just use a direct branch to slb_miss_realmode 5060ebc4cdaSBenjamin Herrenschmidt * because the distance from here to there depends on where 5070ebc4cdaSBenjamin Herrenschmidt * the kernel ends up being put. 5080ebc4cdaSBenjamin Herrenschmidt */ 5090ebc4cdaSBenjamin Herrenschmidt mfctr r11 510ad0289e4SAnton Blanchard LOAD_HANDLER(r10, slb_miss_realmode) 5110ebc4cdaSBenjamin Herrenschmidt mtctr r10 5120ebc4cdaSBenjamin Herrenschmidt bctr 5130ebc4cdaSBenjamin Herrenschmidt#endif 514da2bc464SMichael EllermanEXC_REAL_END(data_access_slb, 0x380, 0x400) 5150ebc4cdaSBenjamin Herrenschmidt 5162b9af6e4SNicholas PigginEXC_VIRT_BEGIN(data_access_slb, 0x4380, 0x4400) 5172b9af6e4SNicholas Piggin SET_SCRATCH0(r13) 5182b9af6e4SNicholas Piggin EXCEPTION_PROLOG_0(PACA_EXSLB) 5192b9af6e4SNicholas Piggin EXCEPTION_PROLOG_1(PACA_EXSLB, NOTEST, 0x380) 5202b9af6e4SNicholas Piggin std r3,PACA_EXSLB+EX_R3(r13) 5212b9af6e4SNicholas Piggin mfspr r3,SPRN_DAR 5222b9af6e4SNicholas Piggin mfspr r12,SPRN_SRR1 5232b9af6e4SNicholas Piggin crset 4*cr6+eq 5242b9af6e4SNicholas Piggin#ifndef CONFIG_RELOCATABLE 5252b9af6e4SNicholas Piggin b slb_miss_realmode 5262b9af6e4SNicholas Piggin#else 5272b9af6e4SNicholas Piggin /* 5282b9af6e4SNicholas Piggin * We can't just use a direct branch to slb_miss_realmode 5292b9af6e4SNicholas Piggin * because the distance from here to there depends on where 5302b9af6e4SNicholas Piggin * the kernel ends up being put. 5312b9af6e4SNicholas Piggin */ 5322b9af6e4SNicholas Piggin mfctr r11 5332b9af6e4SNicholas Piggin LOAD_HANDLER(r10, slb_miss_realmode) 5342b9af6e4SNicholas Piggin mtctr r10 5352b9af6e4SNicholas Piggin bctr 5362b9af6e4SNicholas Piggin#endif 5372b9af6e4SNicholas PigginEXC_VIRT_END(data_access_slb, 0x4380, 0x4400) 5382b9af6e4SNicholas PigginTRAMP_KVM_SKIP(PACA_EXSLB, 0x380) 5392b9af6e4SNicholas Piggin 5402b9af6e4SNicholas Piggin 541da2bc464SMichael EllermanEXC_REAL(instruction_access, 0x400, 0x480) 54227ce77dfSNicholas PigginEXC_VIRT(instruction_access, 0x4400, 0x4480, 0x400) 54327ce77dfSNicholas PigginTRAMP_KVM(PACA_EXGEN, 0x400) 54427ce77dfSNicholas Piggin 54527ce77dfSNicholas PigginEXC_COMMON_BEGIN(instruction_access_common) 54627ce77dfSNicholas Piggin EXCEPTION_PROLOG_COMMON(0x400, PACA_EXGEN) 54727ce77dfSNicholas Piggin RECONCILE_IRQ_STATE(r10, r11) 54827ce77dfSNicholas Piggin ld r12,_MSR(r1) 54927ce77dfSNicholas Piggin ld r3,_NIP(r1) 55027ce77dfSNicholas Piggin andis. r4,r12,0x5820 55127ce77dfSNicholas Piggin li r5,0x400 55227ce77dfSNicholas Piggin std r3,_DAR(r1) 55327ce77dfSNicholas Piggin std r4,_DSISR(r1) 55427ce77dfSNicholas PigginBEGIN_MMU_FTR_SECTION 55527ce77dfSNicholas Piggin b do_hash_page /* Try to handle as hpte fault */ 55627ce77dfSNicholas PigginMMU_FTR_SECTION_ELSE 55727ce77dfSNicholas Piggin b handle_page_fault 55827ce77dfSNicholas PigginALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX) 55927ce77dfSNicholas Piggin 5600ebc4cdaSBenjamin Herrenschmidt 561da2bc464SMichael EllermanEXC_REAL_BEGIN(instruction_access_slb, 0x480, 0x500) 562673b189aSPaul Mackerras SET_SCRATCH0(r13) 5631707dd16SPaul Mackerras EXCEPTION_PROLOG_0(PACA_EXSLB) 564da2bc464SMichael Ellerman EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST_PR, 0x480) 5650ebc4cdaSBenjamin Herrenschmidt std r3,PACA_EXSLB+EX_R3(r13) 5660ebc4cdaSBenjamin Herrenschmidt mfspr r3,SPRN_SRR0 /* SRR0 is faulting address */ 567b01c8b54SPaul Mackerras mfspr r12,SPRN_SRR1 568f0f558b1SPaul Mackerras crclr 4*cr6+eq 5690ebc4cdaSBenjamin Herrenschmidt#ifndef CONFIG_RELOCATABLE 570b1576fecSAnton Blanchard b slb_miss_realmode 5710ebc4cdaSBenjamin Herrenschmidt#else 5720ebc4cdaSBenjamin Herrenschmidt mfctr r11 573ad0289e4SAnton Blanchard LOAD_HANDLER(r10, slb_miss_realmode) 5740ebc4cdaSBenjamin Herrenschmidt mtctr r10 5750ebc4cdaSBenjamin Herrenschmidt bctr 5760ebc4cdaSBenjamin Herrenschmidt#endif 577da2bc464SMichael EllermanEXC_REAL_END(instruction_access_slb, 0x480, 0x500) 5780ebc4cdaSBenjamin Herrenschmidt 5798d04631aSNicholas PigginEXC_VIRT_BEGIN(instruction_access_slb, 0x4480, 0x4500) 5808d04631aSNicholas Piggin SET_SCRATCH0(r13) 5818d04631aSNicholas Piggin EXCEPTION_PROLOG_0(PACA_EXSLB) 5828d04631aSNicholas Piggin EXCEPTION_PROLOG_1(PACA_EXSLB, NOTEST, 0x480) 5838d04631aSNicholas Piggin std r3,PACA_EXSLB+EX_R3(r13) 5848d04631aSNicholas Piggin mfspr r3,SPRN_SRR0 /* SRR0 is faulting address */ 5858d04631aSNicholas Piggin mfspr r12,SPRN_SRR1 5868d04631aSNicholas Piggin crclr 4*cr6+eq 5878d04631aSNicholas Piggin#ifndef CONFIG_RELOCATABLE 5888d04631aSNicholas Piggin b slb_miss_realmode 5898d04631aSNicholas Piggin#else 5908d04631aSNicholas Piggin mfctr r11 5918d04631aSNicholas Piggin LOAD_HANDLER(r10, slb_miss_realmode) 5928d04631aSNicholas Piggin mtctr r10 5938d04631aSNicholas Piggin bctr 5948d04631aSNicholas Piggin#endif 5958d04631aSNicholas PigginEXC_VIRT_END(instruction_access_slb, 0x4480, 0x4500) 5968d04631aSNicholas PigginTRAMP_KVM(PACA_EXSLB, 0x480) 5978d04631aSNicholas Piggin 5988d04631aSNicholas Piggin 5998d04631aSNicholas Piggin/* This handler is used by both 0x380 and 0x480 slb miss interrupts */ 6008d04631aSNicholas PigginEXC_COMMON_BEGIN(slb_miss_realmode) 6018d04631aSNicholas Piggin /* 6028d04631aSNicholas Piggin * r13 points to the PACA, r9 contains the saved CR, 6038d04631aSNicholas Piggin * r12 contain the saved SRR1, SRR0 is still ready for return 6048d04631aSNicholas Piggin * r3 has the faulting address 6058d04631aSNicholas Piggin * r9 - r13 are saved in paca->exslb. 6068d04631aSNicholas Piggin * r3 is saved in paca->slb_r3 6078d04631aSNicholas Piggin * cr6.eq is set for a D-SLB miss, clear for a I-SLB miss 6088d04631aSNicholas Piggin * We assume we aren't going to take any exceptions during this 6098d04631aSNicholas Piggin * procedure. 6108d04631aSNicholas Piggin */ 6118d04631aSNicholas Piggin mflr r10 6128d04631aSNicholas Piggin#ifdef CONFIG_RELOCATABLE 6138d04631aSNicholas Piggin mtctr r11 6148d04631aSNicholas Piggin#endif 6158d04631aSNicholas Piggin 6168d04631aSNicholas Piggin stw r9,PACA_EXSLB+EX_CCR(r13) /* save CR in exc. frame */ 6178d04631aSNicholas Piggin std r10,PACA_EXSLB+EX_LR(r13) /* save LR */ 6188d04631aSNicholas Piggin std r3,PACA_EXSLB+EX_DAR(r13) 6198d04631aSNicholas Piggin 6208d04631aSNicholas Piggin crset 4*cr0+eq 6218d04631aSNicholas Piggin#ifdef CONFIG_PPC_STD_MMU_64 6228d04631aSNicholas PigginBEGIN_MMU_FTR_SECTION 6238d04631aSNicholas Piggin bl slb_allocate_realmode 6248d04631aSNicholas PigginEND_MMU_FTR_SECTION_IFCLR(MMU_FTR_TYPE_RADIX) 6258d04631aSNicholas Piggin#endif 6268d04631aSNicholas Piggin 6278d04631aSNicholas Piggin ld r10,PACA_EXSLB+EX_LR(r13) 6288d04631aSNicholas Piggin ld r3,PACA_EXSLB+EX_R3(r13) 6298d04631aSNicholas Piggin lwz r9,PACA_EXSLB+EX_CCR(r13) /* get saved CR */ 6308d04631aSNicholas Piggin mtlr r10 6318d04631aSNicholas Piggin 6328d04631aSNicholas Piggin beq 8f /* if bad address, make full stack frame */ 6338d04631aSNicholas Piggin 6348d04631aSNicholas Piggin andi. r10,r12,MSR_RI /* check for unrecoverable exception */ 6358d04631aSNicholas Piggin beq- 2f 6368d04631aSNicholas Piggin 6378d04631aSNicholas Piggin /* All done -- return from exception. */ 6388d04631aSNicholas Piggin 6398d04631aSNicholas Piggin.machine push 6408d04631aSNicholas Piggin.machine "power4" 6418d04631aSNicholas Piggin mtcrf 0x80,r9 6428d04631aSNicholas Piggin mtcrf 0x02,r9 /* I/D indication is in cr6 */ 6438d04631aSNicholas Piggin mtcrf 0x01,r9 /* slb_allocate uses cr0 and cr7 */ 6448d04631aSNicholas Piggin.machine pop 6458d04631aSNicholas Piggin 6468d04631aSNicholas Piggin RESTORE_PPR_PACA(PACA_EXSLB, r9) 6478d04631aSNicholas Piggin ld r9,PACA_EXSLB+EX_R9(r13) 6488d04631aSNicholas Piggin ld r10,PACA_EXSLB+EX_R10(r13) 6498d04631aSNicholas Piggin ld r11,PACA_EXSLB+EX_R11(r13) 6508d04631aSNicholas Piggin ld r12,PACA_EXSLB+EX_R12(r13) 6518d04631aSNicholas Piggin ld r13,PACA_EXSLB+EX_R13(r13) 6528d04631aSNicholas Piggin rfid 6538d04631aSNicholas Piggin b . /* prevent speculative execution */ 6548d04631aSNicholas Piggin 6558d04631aSNicholas Piggin2: mfspr r11,SPRN_SRR0 6568d04631aSNicholas Piggin LOAD_HANDLER(r10,unrecov_slb) 6578d04631aSNicholas Piggin mtspr SPRN_SRR0,r10 6588d04631aSNicholas Piggin ld r10,PACAKMSR(r13) 6598d04631aSNicholas Piggin mtspr SPRN_SRR1,r10 6608d04631aSNicholas Piggin rfid 6618d04631aSNicholas Piggin b . 6628d04631aSNicholas Piggin 6638d04631aSNicholas Piggin8: mfspr r11,SPRN_SRR0 6648d04631aSNicholas Piggin LOAD_HANDLER(r10,bad_addr_slb) 6658d04631aSNicholas Piggin mtspr SPRN_SRR0,r10 6668d04631aSNicholas Piggin ld r10,PACAKMSR(r13) 6678d04631aSNicholas Piggin mtspr SPRN_SRR1,r10 6688d04631aSNicholas Piggin rfid 6698d04631aSNicholas Piggin b . 6708d04631aSNicholas Piggin 6718d04631aSNicholas PigginEXC_COMMON_BEGIN(unrecov_slb) 6728d04631aSNicholas Piggin EXCEPTION_PROLOG_COMMON(0x4100, PACA_EXSLB) 6738d04631aSNicholas Piggin RECONCILE_IRQ_STATE(r10, r11) 6748d04631aSNicholas Piggin bl save_nvgprs 6758d04631aSNicholas Piggin1: addi r3,r1,STACK_FRAME_OVERHEAD 6768d04631aSNicholas Piggin bl unrecoverable_exception 6778d04631aSNicholas Piggin b 1b 6788d04631aSNicholas Piggin 6798d04631aSNicholas PigginEXC_COMMON_BEGIN(bad_addr_slb) 6808d04631aSNicholas Piggin EXCEPTION_PROLOG_COMMON(0x380, PACA_EXSLB) 6818d04631aSNicholas Piggin RECONCILE_IRQ_STATE(r10, r11) 6828d04631aSNicholas Piggin ld r3, PACA_EXSLB+EX_DAR(r13) 6838d04631aSNicholas Piggin std r3, _DAR(r1) 6848d04631aSNicholas Piggin beq cr6, 2f 6858d04631aSNicholas Piggin li r10, 0x480 /* fix trap number for I-SLB miss */ 6868d04631aSNicholas Piggin std r10, _TRAP(r1) 6878d04631aSNicholas Piggin2: bl save_nvgprs 6888d04631aSNicholas Piggin addi r3, r1, STACK_FRAME_OVERHEAD 6898d04631aSNicholas Piggin bl slb_miss_bad_addr 6908d04631aSNicholas Piggin b ret_from_except 6918d04631aSNicholas Piggin 692da2bc464SMichael EllermanEXC_REAL_BEGIN(hardware_interrupt, 0x500, 0x600) 693b3e6b5dfSBenjamin Herrenschmidt .globl hardware_interrupt_hv; 694b3e6b5dfSBenjamin Herrenschmidthardware_interrupt_hv: 695a5d4f3adSBenjamin Herrenschmidt BEGIN_FTR_SECTION 696da2bc464SMichael Ellerman _MASKABLE_EXCEPTION_PSERIES(0x500, hardware_interrupt_common, 697b01c8b54SPaul Mackerras EXC_HV, SOFTEN_TEST_HV) 698da2bc464SMichael Ellermando_kvm_H0x500: 699b01c8b54SPaul Mackerras KVM_HANDLER(PACA_EXGEN, EXC_HV, 0x502) 700de56a948SPaul Mackerras FTR_SECTION_ELSE 701da2bc464SMichael Ellerman _MASKABLE_EXCEPTION_PSERIES(0x500, hardware_interrupt_common, 70231a40e2bSPaul Mackerras EXC_STD, SOFTEN_TEST_PR) 703da2bc464SMichael Ellermando_kvm_0x500: 704de56a948SPaul Mackerras KVM_HANDLER(PACA_EXGEN, EXC_STD, 0x500) 705969391c5SPaul Mackerras ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206) 706da2bc464SMichael EllermanEXC_REAL_END(hardware_interrupt, 0x500, 0x600) 707a5d4f3adSBenjamin Herrenschmidt 708c138e588SNicholas PigginEXC_VIRT_BEGIN(hardware_interrupt, 0x4500, 0x4600) 709c138e588SNicholas Piggin .globl hardware_interrupt_relon_hv; 710c138e588SNicholas Pigginhardware_interrupt_relon_hv: 711c138e588SNicholas Piggin BEGIN_FTR_SECTION 712c138e588SNicholas Piggin _MASKABLE_RELON_EXCEPTION_PSERIES(0x500, hardware_interrupt_common, EXC_HV, SOFTEN_TEST_HV) 713c138e588SNicholas Piggin FTR_SECTION_ELSE 714c138e588SNicholas Piggin _MASKABLE_RELON_EXCEPTION_PSERIES(0x500, hardware_interrupt_common, EXC_STD, SOFTEN_TEST_PR) 715c138e588SNicholas Piggin ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE) 716c138e588SNicholas PigginEXC_VIRT_END(hardware_interrupt, 0x4500, 0x4600) 717c138e588SNicholas Piggin 718c138e588SNicholas PigginEXC_COMMON_ASYNC(hardware_interrupt_common, 0x500, do_IRQ) 719c138e588SNicholas Piggin 720c138e588SNicholas Piggin 721da2bc464SMichael EllermanEXC_REAL(alignment, 0x600, 0x700) 722f9aa6714SNicholas PigginEXC_VIRT(alignment, 0x4600, 0x4700, 0x600) 723da2bc464SMichael EllermanTRAMP_KVM(PACA_EXGEN, 0x600) 724f9aa6714SNicholas PigginEXC_COMMON_BEGIN(alignment_common) 725f9aa6714SNicholas Piggin mfspr r10,SPRN_DAR 726f9aa6714SNicholas Piggin std r10,PACA_EXGEN+EX_DAR(r13) 727f9aa6714SNicholas Piggin mfspr r10,SPRN_DSISR 728f9aa6714SNicholas Piggin stw r10,PACA_EXGEN+EX_DSISR(r13) 729f9aa6714SNicholas Piggin EXCEPTION_PROLOG_COMMON(0x600, PACA_EXGEN) 730f9aa6714SNicholas Piggin ld r3,PACA_EXGEN+EX_DAR(r13) 731f9aa6714SNicholas Piggin lwz r4,PACA_EXGEN+EX_DSISR(r13) 732f9aa6714SNicholas Piggin std r3,_DAR(r1) 733f9aa6714SNicholas Piggin std r4,_DSISR(r1) 734f9aa6714SNicholas Piggin bl save_nvgprs 735f9aa6714SNicholas Piggin RECONCILE_IRQ_STATE(r10, r11) 736f9aa6714SNicholas Piggin addi r3,r1,STACK_FRAME_OVERHEAD 737f9aa6714SNicholas Piggin bl alignment_exception 738f9aa6714SNicholas Piggin b ret_from_except 739f9aa6714SNicholas Piggin 740b01c8b54SPaul Mackerras 741da2bc464SMichael EllermanEXC_REAL(program_check, 0x700, 0x800) 74211e87346SNicholas PigginEXC_VIRT(program_check, 0x4700, 0x4800, 0x700) 743da2bc464SMichael EllermanTRAMP_KVM(PACA_EXGEN, 0x700) 74411e87346SNicholas PigginEXC_COMMON_BEGIN(program_check_common) 74511e87346SNicholas Piggin EXCEPTION_PROLOG_COMMON(0x700, PACA_EXGEN) 74611e87346SNicholas Piggin bl save_nvgprs 74711e87346SNicholas Piggin RECONCILE_IRQ_STATE(r10, r11) 74811e87346SNicholas Piggin addi r3,r1,STACK_FRAME_OVERHEAD 74911e87346SNicholas Piggin bl program_check_exception 75011e87346SNicholas Piggin b ret_from_except 75111e87346SNicholas Piggin 752a485c709SPaul Mackerras 753da2bc464SMichael EllermanEXC_REAL(fp_unavailable, 0x800, 0x900) 754c78d9b97SNicholas PigginEXC_VIRT(fp_unavailable, 0x4800, 0x4900, 0x800) 755da2bc464SMichael EllermanTRAMP_KVM(PACA_EXGEN, 0x800) 756c78d9b97SNicholas PigginEXC_COMMON_BEGIN(fp_unavailable_common) 757c78d9b97SNicholas Piggin EXCEPTION_PROLOG_COMMON(0x800, PACA_EXGEN) 758c78d9b97SNicholas Piggin bne 1f /* if from user, just load it up */ 759c78d9b97SNicholas Piggin bl save_nvgprs 760c78d9b97SNicholas Piggin RECONCILE_IRQ_STATE(r10, r11) 761c78d9b97SNicholas Piggin addi r3,r1,STACK_FRAME_OVERHEAD 762c78d9b97SNicholas Piggin bl kernel_fp_unavailable_exception 763c78d9b97SNicholas Piggin BUG_OPCODE 764c78d9b97SNicholas Piggin1: 765c78d9b97SNicholas Piggin#ifdef CONFIG_PPC_TRANSACTIONAL_MEM 766c78d9b97SNicholas PigginBEGIN_FTR_SECTION 767c78d9b97SNicholas Piggin /* Test if 2 TM state bits are zero. If non-zero (ie. userspace was in 768c78d9b97SNicholas Piggin * transaction), go do TM stuff 769c78d9b97SNicholas Piggin */ 770c78d9b97SNicholas Piggin rldicl. r0, r12, (64-MSR_TS_LG), (64-2) 771c78d9b97SNicholas Piggin bne- 2f 772c78d9b97SNicholas PigginEND_FTR_SECTION_IFSET(CPU_FTR_TM) 773c78d9b97SNicholas Piggin#endif 774c78d9b97SNicholas Piggin bl load_up_fpu 775c78d9b97SNicholas Piggin b fast_exception_return 776c78d9b97SNicholas Piggin#ifdef CONFIG_PPC_TRANSACTIONAL_MEM 777c78d9b97SNicholas Piggin2: /* User process was in a transaction */ 778c78d9b97SNicholas Piggin bl save_nvgprs 779c78d9b97SNicholas Piggin RECONCILE_IRQ_STATE(r10, r11) 780c78d9b97SNicholas Piggin addi r3,r1,STACK_FRAME_OVERHEAD 781c78d9b97SNicholas Piggin bl fp_unavailable_tm 782c78d9b97SNicholas Piggin b ret_from_except 783c78d9b97SNicholas Piggin#endif 784c78d9b97SNicholas Piggin 785b01c8b54SPaul Mackerras 786da2bc464SMichael EllermanEXC_REAL_MASKABLE(decrementer, 0x900, 0x980) 78739c0da57SNicholas PigginEXC_VIRT_MASKABLE(decrementer, 0x4900, 0x4980, 0x900) 78839c0da57SNicholas PigginTRAMP_KVM(PACA_EXGEN, 0x900) 78939c0da57SNicholas PigginEXC_COMMON_ASYNC(decrementer_common, 0x900, timer_interrupt) 79039c0da57SNicholas Piggin 7910ebc4cdaSBenjamin Herrenschmidt 792da2bc464SMichael EllermanEXC_REAL_HV(hdecrementer, 0x980, 0xa00) 793facc6d74SNicholas PigginEXC_VIRT_HV(hdecrementer, 0x4980, 0x4a00, 0x980) 794facc6d74SNicholas PigginTRAMP_KVM_HV(PACA_EXGEN, 0x980) 795facc6d74SNicholas PigginEXC_COMMON(hdecrementer_common, 0x980, hdec_interrupt) 796facc6d74SNicholas Piggin 797da2bc464SMichael Ellerman 798da2bc464SMichael EllermanEXC_REAL_MASKABLE(doorbell_super, 0xa00, 0xb00) 799ca243163SNicholas PigginEXC_VIRT_MASKABLE(doorbell_super, 0x4a00, 0x4b00, 0xa00) 800da2bc464SMichael EllermanTRAMP_KVM(PACA_EXGEN, 0xa00) 801ca243163SNicholas Piggin#ifdef CONFIG_PPC_DOORBELL 802ca243163SNicholas PigginEXC_COMMON_ASYNC(doorbell_super_common, 0xa00, doorbell_exception) 803ca243163SNicholas Piggin#else 804ca243163SNicholas PigginEXC_COMMON_ASYNC(doorbell_super_common, 0xa00, unknown_exception) 805ca243163SNicholas Piggin#endif 806ca243163SNicholas Piggin 807da2bc464SMichael Ellerman 808da2bc464SMichael EllermanEXC_REAL(trap_0b, 0xb00, 0xc00) 809341215dcSNicholas PigginEXC_VIRT(trap_0b, 0x4b00, 0x4c00, 0xb00) 810da2bc464SMichael EllermanTRAMP_KVM(PACA_EXGEN, 0xb00) 811341215dcSNicholas PigginEXC_COMMON(trap_0b_common, 0xb00, unknown_exception) 812341215dcSNicholas Piggin 813da2bc464SMichael Ellerman 814d807ad37SNicholas Piggin#define LOAD_SYSCALL_HANDLER(reg) \ 815d807ad37SNicholas Piggin ld reg,PACAKBASE(r13); \ 816d807ad37SNicholas Piggin ori reg,reg,(ABS_ADDR(system_call_common))@l; 817d807ad37SNicholas Piggin 818d807ad37SNicholas Piggin/* Syscall routine is used twice, in reloc-off and reloc-on paths */ 819d807ad37SNicholas Piggin#define SYSCALL_PSERIES_1 \ 820d807ad37SNicholas PigginBEGIN_FTR_SECTION \ 821d807ad37SNicholas Piggin cmpdi r0,0x1ebe ; \ 822d807ad37SNicholas Piggin beq- 1f ; \ 823d807ad37SNicholas PigginEND_FTR_SECTION_IFSET(CPU_FTR_REAL_LE) \ 824d807ad37SNicholas Piggin mr r9,r13 ; \ 825d807ad37SNicholas Piggin GET_PACA(r13) ; \ 826d807ad37SNicholas Piggin mfspr r11,SPRN_SRR0 ; \ 827d807ad37SNicholas Piggin0: 828d807ad37SNicholas Piggin 829d807ad37SNicholas Piggin#define SYSCALL_PSERIES_2_RFID \ 830d807ad37SNicholas Piggin mfspr r12,SPRN_SRR1 ; \ 831d807ad37SNicholas Piggin LOAD_SYSCALL_HANDLER(r10) ; \ 832d807ad37SNicholas Piggin mtspr SPRN_SRR0,r10 ; \ 833d807ad37SNicholas Piggin ld r10,PACAKMSR(r13) ; \ 834d807ad37SNicholas Piggin mtspr SPRN_SRR1,r10 ; \ 835d807ad37SNicholas Piggin rfid ; \ 836d807ad37SNicholas Piggin b . ; /* prevent speculative execution */ 837d807ad37SNicholas Piggin 838d807ad37SNicholas Piggin#define SYSCALL_PSERIES_3 \ 839d807ad37SNicholas Piggin /* Fast LE/BE switch system call */ \ 840d807ad37SNicholas Piggin1: mfspr r12,SPRN_SRR1 ; \ 841d807ad37SNicholas Piggin xori r12,r12,MSR_LE ; \ 842d807ad37SNicholas Piggin mtspr SPRN_SRR1,r12 ; \ 843d807ad37SNicholas Piggin rfid ; /* return to userspace */ \ 844d807ad37SNicholas Piggin b . ; /* prevent speculative execution */ 845d807ad37SNicholas Piggin 846d807ad37SNicholas Piggin#if defined(CONFIG_RELOCATABLE) 847d807ad37SNicholas Piggin /* 848d807ad37SNicholas Piggin * We can't branch directly so we do it via the CTR which 849d807ad37SNicholas Piggin * is volatile across system calls. 850d807ad37SNicholas Piggin */ 851d807ad37SNicholas Piggin#define SYSCALL_PSERIES_2_DIRECT \ 852d807ad37SNicholas Piggin LOAD_SYSCALL_HANDLER(r12) ; \ 853d807ad37SNicholas Piggin mtctr r12 ; \ 854d807ad37SNicholas Piggin mfspr r12,SPRN_SRR1 ; \ 855d807ad37SNicholas Piggin li r10,MSR_RI ; \ 856d807ad37SNicholas Piggin mtmsrd r10,1 ; \ 857d807ad37SNicholas Piggin bctr ; 858d807ad37SNicholas Piggin#else 859d807ad37SNicholas Piggin /* We can branch directly */ 860d807ad37SNicholas Piggin#define SYSCALL_PSERIES_2_DIRECT \ 861d807ad37SNicholas Piggin mfspr r12,SPRN_SRR1 ; \ 862d807ad37SNicholas Piggin li r10,MSR_RI ; \ 863d807ad37SNicholas Piggin mtmsrd r10,1 ; /* Set RI (EE=0) */ \ 864d807ad37SNicholas Piggin b system_call_common ; 865d807ad37SNicholas Piggin#endif 866d807ad37SNicholas Piggin 867da2bc464SMichael EllermanEXC_REAL_BEGIN(system_call, 0xc00, 0xd00) 8688b91a255SSuresh E. Warrier /* 8698b91a255SSuresh E. Warrier * If CONFIG_KVM_BOOK3S_64_HANDLER is set, save the PPR (on systems 8708b91a255SSuresh E. Warrier * that support it) before changing to HMT_MEDIUM. That allows the KVM 8718b91a255SSuresh E. Warrier * code to save that value into the guest state (it is the guest's PPR 8728b91a255SSuresh E. Warrier * value). Otherwise just change to HMT_MEDIUM as userspace has 8738b91a255SSuresh E. Warrier * already saved the PPR. 8748b91a255SSuresh E. Warrier */ 875b01c8b54SPaul Mackerras#ifdef CONFIG_KVM_BOOK3S_64_HANDLER 876b01c8b54SPaul Mackerras SET_SCRATCH0(r13) 877b01c8b54SPaul Mackerras GET_PACA(r13) 878b01c8b54SPaul Mackerras std r9,PACA_EXGEN+EX_R9(r13) 8798b91a255SSuresh E. Warrier OPT_GET_SPR(r9, SPRN_PPR, CPU_FTR_HAS_PPR); 8808b91a255SSuresh E. Warrier HMT_MEDIUM; 881b01c8b54SPaul Mackerras std r10,PACA_EXGEN+EX_R10(r13) 8828b91a255SSuresh E. Warrier OPT_SAVE_REG_TO_PACA(PACA_EXGEN+EX_PPR, r9, CPU_FTR_HAS_PPR); 883b01c8b54SPaul Mackerras mfcr r9 884da2bc464SMichael Ellerman KVMTEST_PR(0xc00) 885b01c8b54SPaul Mackerras GET_SCRATCH0(r13) 8868b91a255SSuresh E. Warrier#else 8878b91a255SSuresh E. Warrier HMT_MEDIUM; 888b01c8b54SPaul Mackerras#endif 889742415d6SMichael Neuling SYSCALL_PSERIES_1 890742415d6SMichael Neuling SYSCALL_PSERIES_2_RFID 891742415d6SMichael Neuling SYSCALL_PSERIES_3 892da2bc464SMichael EllermanEXC_REAL_END(system_call, 0xc00, 0xd00) 893b01c8b54SPaul Mackerras 894d807ad37SNicholas PigginEXC_VIRT_BEGIN(system_call, 0x4c00, 0x4d00) 895d807ad37SNicholas Piggin HMT_MEDIUM 896d807ad37SNicholas Piggin SYSCALL_PSERIES_1 897d807ad37SNicholas Piggin SYSCALL_PSERIES_2_DIRECT 898d807ad37SNicholas Piggin SYSCALL_PSERIES_3 899d807ad37SNicholas PigginEXC_VIRT_END(system_call, 0x4c00, 0x4d00) 900d807ad37SNicholas Piggin 901da2bc464SMichael EllermanTRAMP_KVM(PACA_EXGEN, 0xc00) 902da2bc464SMichael Ellerman 903d807ad37SNicholas Piggin 904da2bc464SMichael EllermanEXC_REAL(single_step, 0xd00, 0xe00) 905bc6675c6SNicholas PigginEXC_VIRT(single_step, 0x4d00, 0x4e00, 0xd00) 906da2bc464SMichael EllermanTRAMP_KVM(PACA_EXGEN, 0xd00) 907bc6675c6SNicholas PigginEXC_COMMON(single_step_common, 0xd00, single_step_exception) 908da2bc464SMichael Ellerman 909b3e6b5dfSBenjamin Herrenschmidt 910da2bc464SMichael Ellerman__EXC_REAL_OOL_HV(h_data_storage, 0xe00, 0xe20) 911f5c32c1dSNicholas Piggin__TRAMP_REAL_REAL_OOL_HV(h_data_storage, 0xe00) 912f5c32c1dSNicholas PigginEXC_VIRT_BEGIN(unused, 0x4e00, 0x4e20) 913f5c32c1dSNicholas Piggin b . /* Can't happen, see v2.07 Book III-S section 6.5 */ 914f5c32c1dSNicholas PigginEXC_VIRT_END(unused, 0x4e00, 0x4e20) 915f5c32c1dSNicholas PigginTRAMP_KVM_HV_SKIP(PACA_EXGEN, 0xe00) 916f5c32c1dSNicholas PigginEXC_COMMON_BEGIN(h_data_storage_common) 917f5c32c1dSNicholas Piggin mfspr r10,SPRN_HDAR 918f5c32c1dSNicholas Piggin std r10,PACA_EXGEN+EX_DAR(r13) 919f5c32c1dSNicholas Piggin mfspr r10,SPRN_HDSISR 920f5c32c1dSNicholas Piggin stw r10,PACA_EXGEN+EX_DSISR(r13) 921f5c32c1dSNicholas Piggin EXCEPTION_PROLOG_COMMON(0xe00, PACA_EXGEN) 922f5c32c1dSNicholas Piggin bl save_nvgprs 923f5c32c1dSNicholas Piggin RECONCILE_IRQ_STATE(r10, r11) 924f5c32c1dSNicholas Piggin addi r3,r1,STACK_FRAME_OVERHEAD 925f5c32c1dSNicholas Piggin bl unknown_exception 926f5c32c1dSNicholas Piggin b ret_from_except 927f5c32c1dSNicholas PigginEXC_COMMON(trap_0e_common, 0xe00, unknown_exception) 928f5c32c1dSNicholas Piggin 9291707dd16SPaul Mackerras 930da2bc464SMichael Ellerman__EXC_REAL_OOL_HV(h_instr_storage, 0xe20, 0xe40) 93182517cabSNicholas Piggin__TRAMP_REAL_REAL_OOL_HV(h_instr_storage, 0xe20) 93282517cabSNicholas PigginEXC_VIRT_BEGIN(unused, 0x4e20, 0x4e40) 93382517cabSNicholas Piggin b . /* Can't happen, see v2.07 Book III-S section 6.5 */ 93482517cabSNicholas PigginEXC_VIRT_END(unused, 0x4e20, 0x4e40) 93582517cabSNicholas PigginTRAMP_KVM_HV(PACA_EXGEN, 0xe20) 93682517cabSNicholas PigginEXC_COMMON(h_instr_storage_common, 0xe20, unknown_exception) 93782517cabSNicholas Piggin 9381707dd16SPaul Mackerras 939da2bc464SMichael Ellerman__EXC_REAL_OOL_HV(emulation_assist, 0xe40, 0xe60) 940031b4026SNicholas Piggin__TRAMP_REAL_REAL_OOL_HV(emulation_assist, 0xe40) 941031b4026SNicholas Piggin__EXC_VIRT_OOL_HV(emulation_assist, 0x4e40, 0x4e60) 942031b4026SNicholas Piggin__TRAMP_REAL_VIRT_OOL_HV(emulation_assist, 0xe40) 943031b4026SNicholas PigginTRAMP_KVM_HV(PACA_EXGEN, 0xe40) 944031b4026SNicholas PigginEXC_COMMON(emulation_assist_common, 0xe40, emulation_assist_interrupt) 945031b4026SNicholas Piggin 9461707dd16SPaul Mackerras 947da2bc464SMichael Ellerman__EXC_REAL_OOL_HV_DIRECT(hmi_exception, 0xe60, 0xe80, hmi_exception_early) 94862f9b03bSNicholas Piggin__TRAMP_REAL_REAL_OOL_MASKABLE_HV(hmi_exception, 0xe60) 94962f9b03bSNicholas PigginEXC_VIRT_BEGIN(unused, 0x4e60, 0x4e80) 95062f9b03bSNicholas Piggin b . /* Can't happen, see v2.07 Book III-S section 6.5 */ 95162f9b03bSNicholas PigginEXC_VIRT_END(unused, 0x4e60, 0x4e80) 95262f9b03bSNicholas PigginTRAMP_KVM_HV(PACA_EXGEN, 0xe60) 95362f9b03bSNicholas PigginTRAMP_REAL_BEGIN(hmi_exception_early) 95462f9b03bSNicholas Piggin EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST_HV, 0xe60) 95562f9b03bSNicholas Piggin mr r10,r1 /* Save r1 */ 95662f9b03bSNicholas Piggin ld r1,PACAEMERGSP(r13) /* Use emergency stack */ 95762f9b03bSNicholas Piggin subi r1,r1,INT_FRAME_SIZE /* alloc stack frame */ 95862f9b03bSNicholas Piggin std r9,_CCR(r1) /* save CR in stackframe */ 95962f9b03bSNicholas Piggin mfspr r11,SPRN_HSRR0 /* Save HSRR0 */ 96062f9b03bSNicholas Piggin std r11,_NIP(r1) /* save HSRR0 in stackframe */ 96162f9b03bSNicholas Piggin mfspr r12,SPRN_HSRR1 /* Save SRR1 */ 96262f9b03bSNicholas Piggin std r12,_MSR(r1) /* save SRR1 in stackframe */ 96362f9b03bSNicholas Piggin std r10,0(r1) /* make stack chain pointer */ 96462f9b03bSNicholas Piggin std r0,GPR0(r1) /* save r0 in stackframe */ 96562f9b03bSNicholas Piggin std r10,GPR1(r1) /* save r1 in stackframe */ 96662f9b03bSNicholas Piggin EXCEPTION_PROLOG_COMMON_2(PACA_EXGEN) 96762f9b03bSNicholas Piggin EXCEPTION_PROLOG_COMMON_3(0xe60) 96862f9b03bSNicholas Piggin addi r3,r1,STACK_FRAME_OVERHEAD 96962f9b03bSNicholas Piggin bl hmi_exception_realmode 97062f9b03bSNicholas Piggin /* Windup the stack. */ 97162f9b03bSNicholas Piggin /* Move original HSRR0 and HSRR1 into the respective regs */ 97262f9b03bSNicholas Piggin ld r9,_MSR(r1) 97362f9b03bSNicholas Piggin mtspr SPRN_HSRR1,r9 97462f9b03bSNicholas Piggin ld r3,_NIP(r1) 97562f9b03bSNicholas Piggin mtspr SPRN_HSRR0,r3 97662f9b03bSNicholas Piggin ld r9,_CTR(r1) 97762f9b03bSNicholas Piggin mtctr r9 97862f9b03bSNicholas Piggin ld r9,_XER(r1) 97962f9b03bSNicholas Piggin mtxer r9 98062f9b03bSNicholas Piggin ld r9,_LINK(r1) 98162f9b03bSNicholas Piggin mtlr r9 98262f9b03bSNicholas Piggin REST_GPR(0, r1) 98362f9b03bSNicholas Piggin REST_8GPRS(2, r1) 98462f9b03bSNicholas Piggin REST_GPR(10, r1) 98562f9b03bSNicholas Piggin ld r11,_CCR(r1) 98662f9b03bSNicholas Piggin mtcr r11 98762f9b03bSNicholas Piggin REST_GPR(11, r1) 98862f9b03bSNicholas Piggin REST_2GPRS(12, r1) 98962f9b03bSNicholas Piggin /* restore original r1. */ 99062f9b03bSNicholas Piggin ld r1,GPR1(r1) 99162f9b03bSNicholas Piggin 99262f9b03bSNicholas Piggin /* 99362f9b03bSNicholas Piggin * Go to virtual mode and pull the HMI event information from 99462f9b03bSNicholas Piggin * firmware. 99562f9b03bSNicholas Piggin */ 99662f9b03bSNicholas Piggin .globl hmi_exception_after_realmode 99762f9b03bSNicholas Pigginhmi_exception_after_realmode: 99862f9b03bSNicholas Piggin SET_SCRATCH0(r13) 99962f9b03bSNicholas Piggin EXCEPTION_PROLOG_0(PACA_EXGEN) 100062f9b03bSNicholas Piggin b tramp_real_hmi_exception 100162f9b03bSNicholas Piggin 100262f9b03bSNicholas PigginEXC_COMMON_ASYNC(hmi_exception_common, 0xe60, handle_hmi_exception) 100362f9b03bSNicholas Piggin 10041707dd16SPaul Mackerras 1005da2bc464SMichael Ellerman__EXC_REAL_OOL_MASKABLE_HV(h_doorbell, 0xe80, 0xea0) 10069bcb81bfSNicholas Piggin__TRAMP_REAL_REAL_OOL_MASKABLE_HV(h_doorbell, 0xe80) 10079bcb81bfSNicholas Piggin__EXC_VIRT_OOL_MASKABLE_HV(h_doorbell, 0x4e80, 0x4ea0) 10089bcb81bfSNicholas Piggin__TRAMP_REAL_VIRT_OOL_MASKABLE_HV(h_doorbell, 0xe80) 10099bcb81bfSNicholas PigginTRAMP_KVM_HV(PACA_EXGEN, 0xe80) 10109bcb81bfSNicholas Piggin#ifdef CONFIG_PPC_DOORBELL 10119bcb81bfSNicholas PigginEXC_COMMON_ASYNC(h_doorbell_common, 0xe80, doorbell_exception) 10129bcb81bfSNicholas Piggin#else 10139bcb81bfSNicholas PigginEXC_COMMON_ASYNC(h_doorbell_common, 0xe80, unknown_exception) 10149bcb81bfSNicholas Piggin#endif 10159bcb81bfSNicholas Piggin 10160ebc4cdaSBenjamin Herrenschmidt 1017da2bc464SMichael Ellerman__EXC_REAL_OOL_MASKABLE_HV(h_virt_irq, 0xea0, 0xec0) 1018*74408776SNicholas Piggin__TRAMP_REAL_REAL_OOL_MASKABLE_HV(h_virt_irq, 0xea0) 1019*74408776SNicholas Piggin__EXC_VIRT_OOL_MASKABLE_HV(h_virt_irq, 0x4ea0, 0x4ec0) 1020*74408776SNicholas Piggin__TRAMP_REAL_VIRT_OOL_MASKABLE_HV(h_virt_irq, 0xea0) 1021*74408776SNicholas PigginTRAMP_KVM_HV(PACA_EXGEN, 0xea0) 1022*74408776SNicholas PigginEXC_COMMON_ASYNC(h_virt_irq_common, 0xea0, do_IRQ) 1023*74408776SNicholas Piggin 10249baaef0aSBenjamin Herrenschmidt 1025da2bc464SMichael EllermanEXC_REAL_NONE(0xec0, 0xf00) 10260ebc4cdaSBenjamin Herrenschmidt 1027da2bc464SMichael Ellerman__EXC_REAL_OOL(performance_monitor, 0xf00, 0xf20) 10280ebc4cdaSBenjamin Herrenschmidt 1029da2bc464SMichael Ellerman__EXC_REAL_OOL(altivec_unavailable, 0xf20, 0xf40) 10300ebc4cdaSBenjamin Herrenschmidt 1031da2bc464SMichael Ellerman__EXC_REAL_OOL(vsx_unavailable, 0xf40, 0xf60) 1032d0c0c9a1SMichael Neuling 1033da2bc464SMichael Ellerman__EXC_REAL_OOL(facility_unavailable, 0xf60, 0xf80) 1034da2bc464SMichael Ellerman 1035da2bc464SMichael Ellerman__EXC_REAL_OOL_HV(h_facility_unavailable, 0xf80, 0xfa0) 1036da2bc464SMichael Ellerman 1037da2bc464SMichael EllermanEXC_REAL_NONE(0xfa0, 0x1200) 1038da2bc464SMichael Ellerman 10390ebc4cdaSBenjamin Herrenschmidt#ifdef CONFIG_CBE_RAS 1040da2bc464SMichael EllermanEXC_REAL_HV(cbe_system_error, 0x1200, 0x1300) 1041b01c8b54SPaul Mackerras 1042da2bc464SMichael EllermanTRAMP_KVM_HV_SKIP(PACA_EXGEN, 0x1200) 1043b01c8b54SPaul Mackerras 1044da2bc464SMichael Ellerman#else /* CONFIG_CBE_RAS */ 1045da2bc464SMichael EllermanEXC_REAL_NONE(0x1200, 0x1300) 1046da2bc464SMichael Ellerman#endif 1047da2bc464SMichael Ellerman 1048da2bc464SMichael EllermanEXC_REAL(instruction_breakpoint, 0x1300, 0x1400) 1049da2bc464SMichael Ellerman 1050da2bc464SMichael EllermanTRAMP_KVM_SKIP(PACA_EXGEN, 0x1300) 1051da2bc464SMichael Ellerman 1052da2bc464SMichael EllermanEXC_REAL_BEGIN(denorm_exception_hv, 0x1500, 0x1600) 1053b92a66a6SMichael Neuling mtspr SPRN_SPRG_HSCRATCH0,r13 10541707dd16SPaul Mackerras EXCEPTION_PROLOG_0(PACA_EXGEN) 1055630573c1SPaul Mackerras EXCEPTION_PROLOG_1(PACA_EXGEN, NOTEST, 0x1500) 1056b92a66a6SMichael Neuling 1057b92a66a6SMichael Neuling#ifdef CONFIG_PPC_DENORMALISATION 1058b92a66a6SMichael Neuling mfspr r10,SPRN_HSRR1 1059b92a66a6SMichael Neuling mfspr r11,SPRN_HSRR0 /* save HSRR0 */ 1060b92a66a6SMichael Neuling andis. r10,r10,(HSRR1_DENORM)@h /* denorm? */ 1061b92a66a6SMichael Neuling addi r11,r11,-4 /* HSRR0 is next instruction */ 1062b92a66a6SMichael Neuling bne+ denorm_assist 1063b92a66a6SMichael Neuling#endif 1064b92a66a6SMichael Neuling 1065da2bc464SMichael Ellerman KVMTEST_PR(0x1500) 1066b92a66a6SMichael Neuling EXCEPTION_PROLOG_PSERIES_1(denorm_common, EXC_HV) 1067da2bc464SMichael EllermanEXC_REAL_END(denorm_exception_hv, 0x1500, 0x1600) 1068da2bc464SMichael Ellerman 1069da2bc464SMichael EllermanTRAMP_KVM_SKIP(PACA_EXGEN, 0x1500) 1070b92a66a6SMichael Neuling 10710ebc4cdaSBenjamin Herrenschmidt#ifdef CONFIG_CBE_RAS 1072da2bc464SMichael EllermanEXC_REAL_HV(cbe_maintenance, 0x1600, 0x1700) 1073b01c8b54SPaul Mackerras 1074da2bc464SMichael EllermanTRAMP_KVM_HV_SKIP(PACA_EXGEN, 0x1600) 1075da2bc464SMichael Ellerman 1076da2bc464SMichael Ellerman#else /* CONFIG_CBE_RAS */ 1077da2bc464SMichael EllermanEXC_REAL_NONE(0x1600, 0x1700) 1078da2bc464SMichael Ellerman#endif 1079da2bc464SMichael Ellerman 1080da2bc464SMichael EllermanEXC_REAL(altivec_assist, 0x1700, 0x1800) 1081da2bc464SMichael Ellerman 1082da2bc464SMichael EllermanTRAMP_KVM(PACA_EXGEN, 0x1700) 1083b01c8b54SPaul Mackerras 10840ebc4cdaSBenjamin Herrenschmidt#ifdef CONFIG_CBE_RAS 1085da2bc464SMichael EllermanEXC_REAL_HV(cbe_thermal, 0x1800, 0x1900) 1086da2bc464SMichael Ellerman 1087da2bc464SMichael EllermanTRAMP_KVM_HV_SKIP(PACA_EXGEN, 0x1800) 1088da2bc464SMichael Ellerman 1089da2bc464SMichael Ellerman#else /* CONFIG_CBE_RAS */ 1090da2bc464SMichael EllermanEXC_REAL_NONE(0x1800, 0x1900) 1091da2bc464SMichael Ellerman#endif 10920ebc4cdaSBenjamin Herrenschmidt 10930ebc4cdaSBenjamin Herrenschmidt 1094b3e6b5dfSBenjamin Herrenschmidt/*** Out of line interrupts support ***/ 1095b3e6b5dfSBenjamin Herrenschmidt 1096b01c8b54SPaul Mackerras /* moved from 0x200 */ 1097b01c8b54SPaul Mackerras 1098b92a66a6SMichael Neuling#ifdef CONFIG_PPC_DENORMALISATION 1099da2bc464SMichael EllermanTRAMP_REAL_BEGIN(denorm_assist) 1100b92a66a6SMichael NeulingBEGIN_FTR_SECTION 1101b92a66a6SMichael Neuling/* 1102b92a66a6SMichael Neuling * To denormalise we need to move a copy of the register to itself. 1103b92a66a6SMichael Neuling * For POWER6 do that here for all FP regs. 1104b92a66a6SMichael Neuling */ 1105b92a66a6SMichael Neuling mfmsr r10 1106b92a66a6SMichael Neuling ori r10,r10,(MSR_FP|MSR_FE0|MSR_FE1) 1107b92a66a6SMichael Neuling xori r10,r10,(MSR_FE0|MSR_FE1) 1108b92a66a6SMichael Neuling mtmsrd r10 1109b92a66a6SMichael Neuling sync 1110d7c67fb1SMichael Neuling 1111d7c67fb1SMichael Neuling#define FMR2(n) fmr (n), (n) ; fmr n+1, n+1 1112d7c67fb1SMichael Neuling#define FMR4(n) FMR2(n) ; FMR2(n+2) 1113d7c67fb1SMichael Neuling#define FMR8(n) FMR4(n) ; FMR4(n+4) 1114d7c67fb1SMichael Neuling#define FMR16(n) FMR8(n) ; FMR8(n+8) 1115d7c67fb1SMichael Neuling#define FMR32(n) FMR16(n) ; FMR16(n+16) 1116d7c67fb1SMichael Neuling FMR32(0) 1117d7c67fb1SMichael Neuling 1118b92a66a6SMichael NeulingFTR_SECTION_ELSE 1119b92a66a6SMichael Neuling/* 1120b92a66a6SMichael Neuling * To denormalise we need to move a copy of the register to itself. 1121b92a66a6SMichael Neuling * For POWER7 do that here for the first 32 VSX registers only. 1122b92a66a6SMichael Neuling */ 1123b92a66a6SMichael Neuling mfmsr r10 1124b92a66a6SMichael Neuling oris r10,r10,MSR_VSX@h 1125b92a66a6SMichael Neuling mtmsrd r10 1126b92a66a6SMichael Neuling sync 1127d7c67fb1SMichael Neuling 1128d7c67fb1SMichael Neuling#define XVCPSGNDP2(n) XVCPSGNDP(n,n,n) ; XVCPSGNDP(n+1,n+1,n+1) 1129d7c67fb1SMichael Neuling#define XVCPSGNDP4(n) XVCPSGNDP2(n) ; XVCPSGNDP2(n+2) 1130d7c67fb1SMichael Neuling#define XVCPSGNDP8(n) XVCPSGNDP4(n) ; XVCPSGNDP4(n+4) 1131d7c67fb1SMichael Neuling#define XVCPSGNDP16(n) XVCPSGNDP8(n) ; XVCPSGNDP8(n+8) 1132d7c67fb1SMichael Neuling#define XVCPSGNDP32(n) XVCPSGNDP16(n) ; XVCPSGNDP16(n+16) 1133d7c67fb1SMichael Neuling XVCPSGNDP32(0) 1134d7c67fb1SMichael Neuling 1135b92a66a6SMichael NeulingALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_206) 1136fb0fce3eSMichael Neuling 1137fb0fce3eSMichael NeulingBEGIN_FTR_SECTION 1138fb0fce3eSMichael Neuling b denorm_done 1139fb0fce3eSMichael NeulingEND_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S) 1140fb0fce3eSMichael Neuling/* 1141fb0fce3eSMichael Neuling * To denormalise we need to move a copy of the register to itself. 1142fb0fce3eSMichael Neuling * For POWER8 we need to do that for all 64 VSX registers 1143fb0fce3eSMichael Neuling */ 1144fb0fce3eSMichael Neuling XVCPSGNDP32(32) 1145fb0fce3eSMichael Neulingdenorm_done: 1146b92a66a6SMichael Neuling mtspr SPRN_HSRR0,r11 1147b92a66a6SMichael Neuling mtcrf 0x80,r9 1148b92a66a6SMichael Neuling ld r9,PACA_EXGEN+EX_R9(r13) 114944e9309fSHaren Myneni RESTORE_PPR_PACA(PACA_EXGEN, r10) 1150630573c1SPaul MackerrasBEGIN_FTR_SECTION 1151630573c1SPaul Mackerras ld r10,PACA_EXGEN+EX_CFAR(r13) 1152630573c1SPaul Mackerras mtspr SPRN_CFAR,r10 1153630573c1SPaul MackerrasEND_FTR_SECTION_IFSET(CPU_FTR_CFAR) 1154b92a66a6SMichael Neuling ld r10,PACA_EXGEN+EX_R10(r13) 1155b92a66a6SMichael Neuling ld r11,PACA_EXGEN+EX_R11(r13) 1156b92a66a6SMichael Neuling ld r12,PACA_EXGEN+EX_R12(r13) 1157b92a66a6SMichael Neuling ld r13,PACA_EXGEN+EX_R13(r13) 1158b92a66a6SMichael Neuling HRFID 1159b92a66a6SMichael Neuling b . 1160b92a66a6SMichael Neuling#endif 1161b92a66a6SMichael Neuling 11620ebc4cdaSBenjamin Herrenschmidt /* moved from 0xf00 */ 1163da2bc464SMichael Ellerman__TRAMP_REAL_REAL_OOL(performance_monitor, 0xf00) 1164da2bc464SMichael EllermanTRAMP_KVM(PACA_EXGEN, 0xf00) 1165da2bc464SMichael Ellerman 1166da2bc464SMichael Ellerman__TRAMP_REAL_REAL_OOL(altivec_unavailable, 0xf20) 1167da2bc464SMichael EllermanTRAMP_KVM(PACA_EXGEN, 0xf20) 1168da2bc464SMichael Ellerman 1169da2bc464SMichael Ellerman__TRAMP_REAL_REAL_OOL(vsx_unavailable, 0xf40) 1170da2bc464SMichael EllermanTRAMP_KVM(PACA_EXGEN, 0xf40) 1171da2bc464SMichael Ellerman 1172da2bc464SMichael Ellerman__TRAMP_REAL_REAL_OOL(facility_unavailable, 0xf60) 1173da2bc464SMichael EllermanTRAMP_KVM(PACA_EXGEN, 0xf60) 1174da2bc464SMichael Ellerman 1175da2bc464SMichael Ellerman__TRAMP_REAL_REAL_OOL_HV(h_facility_unavailable, 0xf80) 1176da2bc464SMichael EllermanTRAMP_KVM_HV(PACA_EXGEN, 0xf80) 11770ebc4cdaSBenjamin Herrenschmidt 11780ebc4cdaSBenjamin Herrenschmidt/* 1179fe9e1d54SIan Munsie * An interrupt came in while soft-disabled. We set paca->irq_happened, then: 1180fe9e1d54SIan Munsie * - If it was a decrementer interrupt, we bump the dec to max and and return. 1181fe9e1d54SIan Munsie * - If it was a doorbell we return immediately since doorbells are edge 1182fe9e1d54SIan Munsie * triggered and won't automatically refire. 11830869b6fdSMahesh Salgaonkar * - If it was a HMI we return immediately since we handled it in realmode 11840869b6fdSMahesh Salgaonkar * and it won't refire. 1185fe9e1d54SIan Munsie * - else we hard disable and return. 1186fe9e1d54SIan Munsie * This is called with r10 containing the value to OR to the paca field. 11870ebc4cdaSBenjamin Herrenschmidt */ 11887230c564SBenjamin Herrenschmidt#define MASKED_INTERRUPT(_H) \ 11897230c564SBenjamin Herrenschmidtmasked_##_H##interrupt: \ 11907230c564SBenjamin Herrenschmidt std r11,PACA_EXGEN+EX_R11(r13); \ 11917230c564SBenjamin Herrenschmidt lbz r11,PACAIRQHAPPENED(r13); \ 11927230c564SBenjamin Herrenschmidt or r11,r11,r10; \ 11937230c564SBenjamin Herrenschmidt stb r11,PACAIRQHAPPENED(r13); \ 1194fe9e1d54SIan Munsie cmpwi r10,PACA_IRQ_DEC; \ 1195fe9e1d54SIan Munsie bne 1f; \ 11967230c564SBenjamin Herrenschmidt lis r10,0x7fff; \ 11977230c564SBenjamin Herrenschmidt ori r10,r10,0xffff; \ 11987230c564SBenjamin Herrenschmidt mtspr SPRN_DEC,r10; \ 11997230c564SBenjamin Herrenschmidt b 2f; \ 1200fe9e1d54SIan Munsie1: cmpwi r10,PACA_IRQ_DBELL; \ 1201fe9e1d54SIan Munsie beq 2f; \ 12020869b6fdSMahesh Salgaonkar cmpwi r10,PACA_IRQ_HMI; \ 12030869b6fdSMahesh Salgaonkar beq 2f; \ 1204fe9e1d54SIan Munsie mfspr r10,SPRN_##_H##SRR1; \ 12057230c564SBenjamin Herrenschmidt rldicl r10,r10,48,1; /* clear MSR_EE */ \ 12067230c564SBenjamin Herrenschmidt rotldi r10,r10,16; \ 12077230c564SBenjamin Herrenschmidt mtspr SPRN_##_H##SRR1,r10; \ 12087230c564SBenjamin Herrenschmidt2: mtcrf 0x80,r9; \ 12097230c564SBenjamin Herrenschmidt ld r9,PACA_EXGEN+EX_R9(r13); \ 12107230c564SBenjamin Herrenschmidt ld r10,PACA_EXGEN+EX_R10(r13); \ 12117230c564SBenjamin Herrenschmidt ld r11,PACA_EXGEN+EX_R11(r13); \ 12127230c564SBenjamin Herrenschmidt GET_SCRATCH0(r13); \ 12137230c564SBenjamin Herrenschmidt ##_H##rfid; \ 12140ebc4cdaSBenjamin Herrenschmidt b . 12150ebc4cdaSBenjamin Herrenschmidt 121657f26649SNicholas Piggin/* 121757f26649SNicholas Piggin * Real mode exceptions actually use this too, but alternate 121857f26649SNicholas Piggin * instruction code patches (which end up in the common .text area) 121957f26649SNicholas Piggin * cannot reach these if they are put there. 122057f26649SNicholas Piggin */ 122157f26649SNicholas PigginUSE_FIXED_SECTION(virt_trampolines) 12227230c564SBenjamin Herrenschmidt MASKED_INTERRUPT() 12237230c564SBenjamin Herrenschmidt MASKED_INTERRUPT(H) 12247230c564SBenjamin Herrenschmidt 12257230c564SBenjamin Herrenschmidt/* 12267230c564SBenjamin Herrenschmidt * Called from arch_local_irq_enable when an interrupt needs 1227fe9e1d54SIan Munsie * to be resent. r3 contains 0x500, 0x900, 0xa00 or 0xe80 to indicate 1228fe9e1d54SIan Munsie * which kind of interrupt. MSR:EE is already off. We generate a 12297230c564SBenjamin Herrenschmidt * stackframe like if a real interrupt had happened. 12307230c564SBenjamin Herrenschmidt * 12317230c564SBenjamin Herrenschmidt * Note: While MSR:EE is off, we need to make sure that _MSR 12327230c564SBenjamin Herrenschmidt * in the generated frame has EE set to 1 or the exception 12337230c564SBenjamin Herrenschmidt * handler will not properly re-enable them. 12347230c564SBenjamin Herrenschmidt */ 123557f26649SNicholas PigginUSE_TEXT_SECTION() 12367230c564SBenjamin Herrenschmidt_GLOBAL(__replay_interrupt) 12377230c564SBenjamin Herrenschmidt /* We are going to jump to the exception common code which 12387230c564SBenjamin Herrenschmidt * will retrieve various register values from the PACA which 12397230c564SBenjamin Herrenschmidt * we don't give a damn about, so we don't bother storing them. 12407230c564SBenjamin Herrenschmidt */ 12417230c564SBenjamin Herrenschmidt mfmsr r12 12427230c564SBenjamin Herrenschmidt mflr r11 12437230c564SBenjamin Herrenschmidt mfcr r9 12447230c564SBenjamin Herrenschmidt ori r12,r12,MSR_EE 1245fe9e1d54SIan Munsie cmpwi r3,0x900 1246fe9e1d54SIan Munsie beq decrementer_common 1247fe9e1d54SIan Munsie cmpwi r3,0x500 1248fe9e1d54SIan Munsie beq hardware_interrupt_common 1249fe9e1d54SIan MunsieBEGIN_FTR_SECTION 1250fe9e1d54SIan Munsie cmpwi r3,0xe80 1251fe9e1d54SIan Munsie beq h_doorbell_common 12529baaef0aSBenjamin Herrenschmidt cmpwi r3,0xea0 12539baaef0aSBenjamin Herrenschmidt beq h_virt_irq_common 1254fd7bacbcSMahesh Salgaonkar cmpwi r3,0xe60 1255fd7bacbcSMahesh Salgaonkar beq hmi_exception_common 1256fe9e1d54SIan MunsieFTR_SECTION_ELSE 1257fe9e1d54SIan Munsie cmpwi r3,0xa00 1258fe9e1d54SIan Munsie beq doorbell_super_common 1259fe9e1d54SIan MunsieALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE) 1260fe9e1d54SIan Munsie blr 1261a5d4f3adSBenjamin Herrenschmidt 12624f6c11dbSPaul Mackerras#ifdef CONFIG_KVM_BOOK3S_64_HANDLER 1263da2bc464SMichael EllermanTRAMP_REAL_BEGIN(kvmppc_skip_interrupt) 12644f6c11dbSPaul Mackerras /* 12654f6c11dbSPaul Mackerras * Here all GPRs are unchanged from when the interrupt happened 12664f6c11dbSPaul Mackerras * except for r13, which is saved in SPRG_SCRATCH0. 12674f6c11dbSPaul Mackerras */ 12684f6c11dbSPaul Mackerras mfspr r13, SPRN_SRR0 12694f6c11dbSPaul Mackerras addi r13, r13, 4 12704f6c11dbSPaul Mackerras mtspr SPRN_SRR0, r13 12714f6c11dbSPaul Mackerras GET_SCRATCH0(r13) 12724f6c11dbSPaul Mackerras rfid 12734f6c11dbSPaul Mackerras b . 12744f6c11dbSPaul Mackerras 1275da2bc464SMichael EllermanTRAMP_REAL_BEGIN(kvmppc_skip_Hinterrupt) 12764f6c11dbSPaul Mackerras /* 12774f6c11dbSPaul Mackerras * Here all GPRs are unchanged from when the interrupt happened 12784f6c11dbSPaul Mackerras * except for r13, which is saved in SPRG_SCRATCH0. 12794f6c11dbSPaul Mackerras */ 12804f6c11dbSPaul Mackerras mfspr r13, SPRN_HSRR0 12814f6c11dbSPaul Mackerras addi r13, r13, 4 12824f6c11dbSPaul Mackerras mtspr SPRN_HSRR0, r13 12834f6c11dbSPaul Mackerras GET_SCRATCH0(r13) 12844f6c11dbSPaul Mackerras hrfid 12854f6c11dbSPaul Mackerras b . 12864f6c11dbSPaul Mackerras#endif 12874f6c11dbSPaul Mackerras 12880ebc4cdaSBenjamin Herrenschmidt/* 1289057b6d7eSHari Bathini * Ensure that any handlers that get invoked from the exception prologs 1290057b6d7eSHari Bathini * above are below the first 64KB (0x10000) of the kernel image because 1291057b6d7eSHari Bathini * the prologs assemble the addresses of these handlers using the 1292057b6d7eSHari Bathini * LOAD_HANDLER macro, which uses an ori instruction. 12930ebc4cdaSBenjamin Herrenschmidt */ 12940ebc4cdaSBenjamin Herrenschmidt 12950ebc4cdaSBenjamin Herrenschmidt/*** Common interrupt handlers ***/ 12960ebc4cdaSBenjamin Herrenschmidt 12970ebc4cdaSBenjamin Herrenschmidt 1298da2bc464SMichael EllermanEXC_COMMON_ASYNC(performance_monitor_common, 0xf00, performance_monitor_exception) 1299da2bc464SMichael EllermanEXC_COMMON(instruction_breakpoint_common, 0x1300, instruction_breakpoint_exception) 1300da2bc464SMichael EllermanEXC_COMMON_HV(denorm_common, 0x1500, unknown_exception) 13010ebc4cdaSBenjamin Herrenschmidt#ifdef CONFIG_ALTIVEC 1302da2bc464SMichael EllermanEXC_COMMON(altivec_assist_common, 0x1700, altivec_assist_exception) 13030ebc4cdaSBenjamin Herrenschmidt#else 1304da2bc464SMichael EllermanEXC_COMMON(altivec_assist_common, 0x1700, unknown_exception) 13050ebc4cdaSBenjamin Herrenschmidt#endif 13060ebc4cdaSBenjamin Herrenschmidt 1307c1fb6816SMichael Neuling /* 1308c1fb6816SMichael Neuling * Relocation-on interrupts: A subset of the interrupts can be delivered 1309c1fb6816SMichael Neuling * with IR=1/DR=1, if AIL==2 and MSR.HV won't be changed by delivering 1310c1fb6816SMichael Neuling * it. Addresses are the same as the original interrupt addresses, but 1311c1fb6816SMichael Neuling * offset by 0xc000000000004000. 1312c1fb6816SMichael Neuling * It's impossible to receive interrupts below 0x300 via this mechanism. 1313c1fb6816SMichael Neuling * KVM: None of these traps are from the guest ; anything that escalated 1314c1fb6816SMichael Neuling * to HV=1 from HV=0 is delivered via real mode handlers. 1315c1fb6816SMichael Neuling */ 1316c1fb6816SMichael Neuling 1317c1fb6816SMichael Neuling /* 1318c1fb6816SMichael Neuling * This uses the standard macro, since the original 0x300 vector 1319c1fb6816SMichael Neuling * only has extra guff for STAB-based processors -- which never 1320c1fb6816SMichael Neuling * come here. 1321c1fb6816SMichael Neuling */ 1322da2bc464SMichael Ellerman 1323da2bc464SMichael EllermanEXC_VIRT_NONE(0x4ec0, 0x4f00) 1324c1fb6816SMichael Neuling 1325da2bc464SMichael Ellerman__EXC_VIRT_OOL(performance_monitor, 0x4f00, 0x4f20) 1326c1fb6816SMichael Neuling 1327da2bc464SMichael Ellerman__EXC_VIRT_OOL(altivec_unavailable, 0x4f20, 0x4f40) 1328c1fb6816SMichael Neuling 1329da2bc464SMichael Ellerman__EXC_VIRT_OOL(vsx_unavailable, 0x4f40, 0x4f60) 1330d0c0c9a1SMichael Neuling 1331da2bc464SMichael Ellerman__EXC_VIRT_OOL(facility_unavailable, 0x4f60, 0x4f80) 1332b14b6260SMichael Ellerman 1333da2bc464SMichael Ellerman__EXC_VIRT_OOL_HV(h_facility_unavailable, 0x4f80, 0x4fa0) 1334da2bc464SMichael Ellerman 1335da2bc464SMichael EllermanEXC_VIRT_NONE(0x4fa0, 0x5200) 1336da2bc464SMichael Ellerman 1337da2bc464SMichael EllermanEXC_VIRT_NONE(0x5200, 0x5300) 1338da2bc464SMichael Ellerman 1339da2bc464SMichael EllermanEXC_VIRT(instruction_breakpoint, 0x5300, 0x5400, 0x1300) 1340da2bc464SMichael Ellerman 1341c1fb6816SMichael Neuling#ifdef CONFIG_PPC_DENORMALISATION 1342da2bc464SMichael EllermanEXC_VIRT_BEGIN(denorm_exception, 0x5500, 0x5600) 1343da2bc464SMichael Ellerman b exc_real_0x1500_denorm_exception_hv 1344da2bc464SMichael EllermanEXC_VIRT_END(denorm_exception, 0x5500, 0x5600) 1345da2bc464SMichael Ellerman#else 1346da2bc464SMichael EllermanEXC_VIRT_NONE(0x5500, 0x5600) 1347c1fb6816SMichael Neuling#endif 1348c1fb6816SMichael Neuling 1349da2bc464SMichael EllermanEXC_VIRT_NONE(0x5600, 0x5700) 1350da2bc464SMichael Ellerman 1351da2bc464SMichael EllermanEXC_VIRT(altivec_assist, 0x5700, 0x5800, 0x1700) 1352da2bc464SMichael Ellerman 1353da2bc464SMichael EllermanEXC_VIRT_NONE(0x5800, 0x5900) 1354da2bc464SMichael Ellerman 135557f26649SNicholas PigginEXC_COMMON_BEGIN(ppc64_runlatch_on_trampoline) 1356b1576fecSAnton Blanchard b __ppc64_runlatch_on 1357fe1952fcSBenjamin Herrenschmidt 1358da2bc464SMichael EllermanEXC_COMMON_BEGIN(altivec_unavailable_common) 13590ebc4cdaSBenjamin Herrenschmidt EXCEPTION_PROLOG_COMMON(0xf20, PACA_EXGEN) 13600ebc4cdaSBenjamin Herrenschmidt#ifdef CONFIG_ALTIVEC 13610ebc4cdaSBenjamin HerrenschmidtBEGIN_FTR_SECTION 13620ebc4cdaSBenjamin Herrenschmidt beq 1f 1363bc2a9408SMichael Neuling#ifdef CONFIG_PPC_TRANSACTIONAL_MEM 1364bc2a9408SMichael Neuling BEGIN_FTR_SECTION_NESTED(69) 1365bc2a9408SMichael Neuling /* Test if 2 TM state bits are zero. If non-zero (ie. userspace was in 1366bc2a9408SMichael Neuling * transaction), go do TM stuff 1367bc2a9408SMichael Neuling */ 1368bc2a9408SMichael Neuling rldicl. r0, r12, (64-MSR_TS_LG), (64-2) 1369bc2a9408SMichael Neuling bne- 2f 1370bc2a9408SMichael Neuling END_FTR_SECTION_NESTED(CPU_FTR_TM, CPU_FTR_TM, 69) 1371bc2a9408SMichael Neuling#endif 1372b1576fecSAnton Blanchard bl load_up_altivec 13730ebc4cdaSBenjamin Herrenschmidt b fast_exception_return 1374bc2a9408SMichael Neuling#ifdef CONFIG_PPC_TRANSACTIONAL_MEM 1375bc2a9408SMichael Neuling2: /* User process was in a transaction */ 1376b1576fecSAnton Blanchard bl save_nvgprs 13779daf112bSMichael Ellerman RECONCILE_IRQ_STATE(r10, r11) 1378bc2a9408SMichael Neuling addi r3,r1,STACK_FRAME_OVERHEAD 1379b1576fecSAnton Blanchard bl altivec_unavailable_tm 1380b1576fecSAnton Blanchard b ret_from_except 1381bc2a9408SMichael Neuling#endif 13820ebc4cdaSBenjamin Herrenschmidt1: 13830ebc4cdaSBenjamin HerrenschmidtEND_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) 13840ebc4cdaSBenjamin Herrenschmidt#endif 1385b1576fecSAnton Blanchard bl save_nvgprs 13869daf112bSMichael Ellerman RECONCILE_IRQ_STATE(r10, r11) 13870ebc4cdaSBenjamin Herrenschmidt addi r3,r1,STACK_FRAME_OVERHEAD 1388b1576fecSAnton Blanchard bl altivec_unavailable_exception 1389b1576fecSAnton Blanchard b ret_from_except 13900ebc4cdaSBenjamin Herrenschmidt 1391da2bc464SMichael EllermanEXC_COMMON_BEGIN(vsx_unavailable_common) 13920ebc4cdaSBenjamin Herrenschmidt EXCEPTION_PROLOG_COMMON(0xf40, PACA_EXGEN) 13930ebc4cdaSBenjamin Herrenschmidt#ifdef CONFIG_VSX 13940ebc4cdaSBenjamin HerrenschmidtBEGIN_FTR_SECTION 13957230c564SBenjamin Herrenschmidt beq 1f 1396bc2a9408SMichael Neuling#ifdef CONFIG_PPC_TRANSACTIONAL_MEM 1397bc2a9408SMichael Neuling BEGIN_FTR_SECTION_NESTED(69) 1398bc2a9408SMichael Neuling /* Test if 2 TM state bits are zero. If non-zero (ie. userspace was in 1399bc2a9408SMichael Neuling * transaction), go do TM stuff 1400bc2a9408SMichael Neuling */ 1401bc2a9408SMichael Neuling rldicl. r0, r12, (64-MSR_TS_LG), (64-2) 1402bc2a9408SMichael Neuling bne- 2f 1403bc2a9408SMichael Neuling END_FTR_SECTION_NESTED(CPU_FTR_TM, CPU_FTR_TM, 69) 1404bc2a9408SMichael Neuling#endif 1405b1576fecSAnton Blanchard b load_up_vsx 1406bc2a9408SMichael Neuling#ifdef CONFIG_PPC_TRANSACTIONAL_MEM 1407bc2a9408SMichael Neuling2: /* User process was in a transaction */ 1408b1576fecSAnton Blanchard bl save_nvgprs 14099daf112bSMichael Ellerman RECONCILE_IRQ_STATE(r10, r11) 1410bc2a9408SMichael Neuling addi r3,r1,STACK_FRAME_OVERHEAD 1411b1576fecSAnton Blanchard bl vsx_unavailable_tm 1412b1576fecSAnton Blanchard b ret_from_except 1413bc2a9408SMichael Neuling#endif 14140ebc4cdaSBenjamin Herrenschmidt1: 14150ebc4cdaSBenjamin HerrenschmidtEND_FTR_SECTION_IFSET(CPU_FTR_VSX) 14160ebc4cdaSBenjamin Herrenschmidt#endif 1417b1576fecSAnton Blanchard bl save_nvgprs 14189daf112bSMichael Ellerman RECONCILE_IRQ_STATE(r10, r11) 14190ebc4cdaSBenjamin Herrenschmidt addi r3,r1,STACK_FRAME_OVERHEAD 1420b1576fecSAnton Blanchard bl vsx_unavailable_exception 1421b1576fecSAnton Blanchard b ret_from_except 14220ebc4cdaSBenjamin Herrenschmidt 142361383407SBenjamin Herrenschmidt /* Equivalents to the above handlers for relocation-on interrupt vectors */ 1424da2bc464SMichael Ellerman__TRAMP_REAL_VIRT_OOL(performance_monitor, 0xf00) 1425da2bc464SMichael Ellerman__TRAMP_REAL_VIRT_OOL(altivec_unavailable, 0xf20) 1426da2bc464SMichael Ellerman__TRAMP_REAL_VIRT_OOL(vsx_unavailable, 0xf40) 1427da2bc464SMichael Ellerman__TRAMP_REAL_VIRT_OOL(facility_unavailable, 0xf60) 1428da2bc464SMichael Ellerman__TRAMP_REAL_VIRT_OOL_HV(h_facility_unavailable, 0xf80) 142961383407SBenjamin Herrenschmidt 143057f26649SNicholas PigginUSE_FIXED_SECTION(virt_trampolines) 14318ed8ab40SHari Bathini /* 14328ed8ab40SHari Bathini * The __end_interrupts marker must be past the out-of-line (OOL) 14338ed8ab40SHari Bathini * handlers, so that they are copied to real address 0x100 when running 14348ed8ab40SHari Bathini * a relocatable kernel. This ensures they can be reached from the short 14358ed8ab40SHari Bathini * trampoline handlers (like 0x4f00, 0x4f20, etc.) which branch 14368ed8ab40SHari Bathini * directly, without using LOAD_HANDLER(). 14378ed8ab40SHari Bathini */ 14388ed8ab40SHari Bathini .align 7 14398ed8ab40SHari Bathini .globl __end_interrupts 14408ed8ab40SHari Bathini__end_interrupts: 144157f26649SNicholas PigginDEFINE_FIXED_SYMBOL(__end_interrupts) 144261383407SBenjamin Herrenschmidt 1443da2bc464SMichael EllermanEXC_COMMON(facility_unavailable_common, 0xf60, facility_unavailable_exception) 1444da2bc464SMichael EllermanEXC_COMMON(h_facility_unavailable_common, 0xf80, facility_unavailable_exception) 1445b88d4bceSBenjamin Herrenschmidt 1446b88d4bceSBenjamin Herrenschmidt#ifdef CONFIG_CBE_RAS 1447da2bc464SMichael EllermanEXC_COMMON(cbe_system_error_common, 0x1200, cbe_system_error_exception) 1448da2bc464SMichael EllermanEXC_COMMON(cbe_maintenance_common, 0x1600, cbe_maintenance_exception) 1449da2bc464SMichael EllermanEXC_COMMON(cbe_thermal_common, 0x1800, cbe_thermal_exception) 1450b88d4bceSBenjamin Herrenschmidt#endif /* CONFIG_CBE_RAS */ 1451b88d4bceSBenjamin Herrenschmidt 1452da2bc464SMichael Ellerman 1453087aa036SChen Gang#ifdef CONFIG_PPC_970_NAP 1454da2bc464SMichael EllermanTRAMP_REAL_BEGIN(power4_fixup_nap) 1455087aa036SChen Gang andc r9,r9,r10 1456087aa036SChen Gang std r9,TI_LOCAL_FLAGS(r11) 1457087aa036SChen Gang ld r10,_LINK(r1) /* make idle task do the */ 1458087aa036SChen Gang std r10,_NIP(r1) /* equivalent of a blr */ 1459087aa036SChen Gang blr 1460087aa036SChen Gang#endif 1461087aa036SChen Gang 146257f26649SNicholas PigginCLOSE_FIXED_SECTION(real_vectors); 146357f26649SNicholas PigginCLOSE_FIXED_SECTION(real_trampolines); 146457f26649SNicholas PigginCLOSE_FIXED_SECTION(virt_vectors); 146557f26649SNicholas PigginCLOSE_FIXED_SECTION(virt_trampolines); 146657f26649SNicholas Piggin 146757f26649SNicholas PigginUSE_TEXT_SECTION() 146857f26649SNicholas Piggin 1469087aa036SChen Gang/* 14700ebc4cdaSBenjamin Herrenschmidt * Hash table stuff 14710ebc4cdaSBenjamin Herrenschmidt */ 14720ebc4cdaSBenjamin Herrenschmidt .align 7 14736a3bab90SAnton Blancharddo_hash_page: 1474caca285eSAneesh Kumar K.V#ifdef CONFIG_PPC_STD_MMU_64 14759c7cc234SK.Prasad andis. r0,r4,0xa410 /* weird error? */ 14760ebc4cdaSBenjamin Herrenschmidt bne- handle_page_fault /* if not, try to insert a HPTE */ 14779c7cc234SK.Prasad andis. r0,r4,DSISR_DABRMATCH@h 14789c7cc234SK.Prasad bne- handle_dabr_fault 14799778b696SStuart Yoder CURRENT_THREAD_INFO(r11, r1) 14809c1e1052SPaul Mackerras lwz r0,TI_PREEMPT(r11) /* If we're in an "NMI" */ 14819c1e1052SPaul Mackerras andis. r0,r0,NMI_MASK@h /* (i.e. an irq when soft-disabled) */ 14829c1e1052SPaul Mackerras bne 77f /* then don't call hash_page now */ 14830ebc4cdaSBenjamin Herrenschmidt 14840ebc4cdaSBenjamin Herrenschmidt /* 14850ebc4cdaSBenjamin Herrenschmidt * r3 contains the faulting address 1486106713a1SAneesh Kumar K.V * r4 msr 14870ebc4cdaSBenjamin Herrenschmidt * r5 contains the trap number 1488aefa5688SAneesh Kumar K.V * r6 contains dsisr 14890ebc4cdaSBenjamin Herrenschmidt * 14907230c564SBenjamin Herrenschmidt * at return r3 = 0 for success, 1 for page fault, negative for error 14910ebc4cdaSBenjamin Herrenschmidt */ 1492106713a1SAneesh Kumar K.V mr r4,r12 1493aefa5688SAneesh Kumar K.V ld r6,_DSISR(r1) 1494106713a1SAneesh Kumar K.V bl __hash_page /* build HPTE if possible */ 1495106713a1SAneesh Kumar K.V cmpdi r3,0 /* see if __hash_page succeeded */ 14960ebc4cdaSBenjamin Herrenschmidt 14977230c564SBenjamin Herrenschmidt /* Success */ 14980ebc4cdaSBenjamin Herrenschmidt beq fast_exc_return_irq /* Return from exception on success */ 14990ebc4cdaSBenjamin Herrenschmidt 15007230c564SBenjamin Herrenschmidt /* Error */ 15017230c564SBenjamin Herrenschmidt blt- 13f 1502caca285eSAneesh Kumar K.V#endif /* CONFIG_PPC_STD_MMU_64 */ 15030ebc4cdaSBenjamin Herrenschmidt 1504a546498fSBenjamin Herrenschmidt/* Here we have a page fault that hash_page can't handle. */ 1505a546498fSBenjamin Herrenschmidthandle_page_fault: 1506a546498fSBenjamin Herrenschmidt11: ld r4,_DAR(r1) 1507a546498fSBenjamin Herrenschmidt ld r5,_DSISR(r1) 1508a546498fSBenjamin Herrenschmidt addi r3,r1,STACK_FRAME_OVERHEAD 1509b1576fecSAnton Blanchard bl do_page_fault 1510a546498fSBenjamin Herrenschmidt cmpdi r3,0 1511a546498fSBenjamin Herrenschmidt beq+ 12f 1512b1576fecSAnton Blanchard bl save_nvgprs 1513a546498fSBenjamin Herrenschmidt mr r5,r3 1514a546498fSBenjamin Herrenschmidt addi r3,r1,STACK_FRAME_OVERHEAD 1515a546498fSBenjamin Herrenschmidt lwz r4,_DAR(r1) 1516b1576fecSAnton Blanchard bl bad_page_fault 1517b1576fecSAnton Blanchard b ret_from_except 15180ebc4cdaSBenjamin Herrenschmidt 15199c7cc234SK.Prasad/* We have a data breakpoint exception - handle it */ 15209c7cc234SK.Prasadhandle_dabr_fault: 1521b1576fecSAnton Blanchard bl save_nvgprs 15229c7cc234SK.Prasad ld r4,_DAR(r1) 15239c7cc234SK.Prasad ld r5,_DSISR(r1) 15249c7cc234SK.Prasad addi r3,r1,STACK_FRAME_OVERHEAD 1525b1576fecSAnton Blanchard bl do_break 1526b1576fecSAnton Blanchard12: b ret_from_except_lite 15279c7cc234SK.Prasad 15280ebc4cdaSBenjamin Herrenschmidt 1529caca285eSAneesh Kumar K.V#ifdef CONFIG_PPC_STD_MMU_64 15300ebc4cdaSBenjamin Herrenschmidt/* We have a page fault that hash_page could handle but HV refused 15310ebc4cdaSBenjamin Herrenschmidt * the PTE insertion 15320ebc4cdaSBenjamin Herrenschmidt */ 1533b1576fecSAnton Blanchard13: bl save_nvgprs 15340ebc4cdaSBenjamin Herrenschmidt mr r5,r3 15350ebc4cdaSBenjamin Herrenschmidt addi r3,r1,STACK_FRAME_OVERHEAD 15360ebc4cdaSBenjamin Herrenschmidt ld r4,_DAR(r1) 1537b1576fecSAnton Blanchard bl low_hash_fault 1538b1576fecSAnton Blanchard b ret_from_except 1539caca285eSAneesh Kumar K.V#endif 15400ebc4cdaSBenjamin Herrenschmidt 15419c1e1052SPaul Mackerras/* 15429c1e1052SPaul Mackerras * We come here as a result of a DSI at a point where we don't want 15439c1e1052SPaul Mackerras * to call hash_page, such as when we are accessing memory (possibly 15449c1e1052SPaul Mackerras * user memory) inside a PMU interrupt that occurred while interrupts 15459c1e1052SPaul Mackerras * were soft-disabled. We want to invoke the exception handler for 15469c1e1052SPaul Mackerras * the access, or panic if there isn't a handler. 15479c1e1052SPaul Mackerras */ 1548b1576fecSAnton Blanchard77: bl save_nvgprs 15499c1e1052SPaul Mackerras mr r4,r3 15509c1e1052SPaul Mackerras addi r3,r1,STACK_FRAME_OVERHEAD 15519c1e1052SPaul Mackerras li r5,SIGSEGV 1552b1576fecSAnton Blanchard bl bad_page_fault 1553b1576fecSAnton Blanchard b ret_from_except 15544e2bf01bSMichael Ellerman 15554e2bf01bSMichael Ellerman/* 15564e2bf01bSMichael Ellerman * Here we have detected that the kernel stack pointer is bad. 15574e2bf01bSMichael Ellerman * R9 contains the saved CR, r13 points to the paca, 15584e2bf01bSMichael Ellerman * r10 contains the (bad) kernel stack pointer, 15594e2bf01bSMichael Ellerman * r11 and r12 contain the saved SRR0 and SRR1. 15604e2bf01bSMichael Ellerman * We switch to using an emergency stack, save the registers there, 15614e2bf01bSMichael Ellerman * and call kernel_bad_stack(), which panics. 15624e2bf01bSMichael Ellerman */ 15634e2bf01bSMichael Ellermanbad_stack: 15644e2bf01bSMichael Ellerman ld r1,PACAEMERGSP(r13) 15654e2bf01bSMichael Ellerman subi r1,r1,64+INT_FRAME_SIZE 15664e2bf01bSMichael Ellerman std r9,_CCR(r1) 15674e2bf01bSMichael Ellerman std r10,GPR1(r1) 15684e2bf01bSMichael Ellerman std r11,_NIP(r1) 15694e2bf01bSMichael Ellerman std r12,_MSR(r1) 15704e2bf01bSMichael Ellerman mfspr r11,SPRN_DAR 15714e2bf01bSMichael Ellerman mfspr r12,SPRN_DSISR 15724e2bf01bSMichael Ellerman std r11,_DAR(r1) 15734e2bf01bSMichael Ellerman std r12,_DSISR(r1) 15744e2bf01bSMichael Ellerman mflr r10 15754e2bf01bSMichael Ellerman mfctr r11 15764e2bf01bSMichael Ellerman mfxer r12 15774e2bf01bSMichael Ellerman std r10,_LINK(r1) 15784e2bf01bSMichael Ellerman std r11,_CTR(r1) 15794e2bf01bSMichael Ellerman std r12,_XER(r1) 15804e2bf01bSMichael Ellerman SAVE_GPR(0,r1) 15814e2bf01bSMichael Ellerman SAVE_GPR(2,r1) 15824e2bf01bSMichael Ellerman ld r10,EX_R3(r3) 15834e2bf01bSMichael Ellerman std r10,GPR3(r1) 15844e2bf01bSMichael Ellerman SAVE_GPR(4,r1) 15854e2bf01bSMichael Ellerman SAVE_4GPRS(5,r1) 15864e2bf01bSMichael Ellerman ld r9,EX_R9(r3) 15874e2bf01bSMichael Ellerman ld r10,EX_R10(r3) 15884e2bf01bSMichael Ellerman SAVE_2GPRS(9,r1) 15894e2bf01bSMichael Ellerman ld r9,EX_R11(r3) 15904e2bf01bSMichael Ellerman ld r10,EX_R12(r3) 15914e2bf01bSMichael Ellerman ld r11,EX_R13(r3) 15924e2bf01bSMichael Ellerman std r9,GPR11(r1) 15934e2bf01bSMichael Ellerman std r10,GPR12(r1) 15944e2bf01bSMichael Ellerman std r11,GPR13(r1) 15954e2bf01bSMichael EllermanBEGIN_FTR_SECTION 15964e2bf01bSMichael Ellerman ld r10,EX_CFAR(r3) 15974e2bf01bSMichael Ellerman std r10,ORIG_GPR3(r1) 15984e2bf01bSMichael EllermanEND_FTR_SECTION_IFSET(CPU_FTR_CFAR) 15994e2bf01bSMichael Ellerman SAVE_8GPRS(14,r1) 16004e2bf01bSMichael Ellerman SAVE_10GPRS(22,r1) 16014e2bf01bSMichael Ellerman lhz r12,PACA_TRAP_SAVE(r13) 16024e2bf01bSMichael Ellerman std r12,_TRAP(r1) 16034e2bf01bSMichael Ellerman addi r11,r1,INT_FRAME_SIZE 16044e2bf01bSMichael Ellerman std r11,0(r1) 16054e2bf01bSMichael Ellerman li r12,0 16064e2bf01bSMichael Ellerman std r12,0(r11) 16074e2bf01bSMichael Ellerman ld r2,PACATOC(r13) 16084e2bf01bSMichael Ellerman ld r11,exception_marker@toc(r2) 16094e2bf01bSMichael Ellerman std r12,RESULT(r1) 16104e2bf01bSMichael Ellerman std r11,STACK_FRAME_OVERHEAD-16(r1) 16114e2bf01bSMichael Ellerman1: addi r3,r1,STACK_FRAME_OVERHEAD 16124e2bf01bSMichael Ellerman bl kernel_bad_stack 16134e2bf01bSMichael Ellerman b 1b 1614