1*8aa34ab8SBenjamin Herrenschmidt #ifndef _ASM_POWERPC_EXCEPTION_H 2*8aa34ab8SBenjamin Herrenschmidt #define _ASM_POWERPC_EXCEPTION_H 3*8aa34ab8SBenjamin Herrenschmidt /* 4*8aa34ab8SBenjamin Herrenschmidt * Extracted from head_64.S 5*8aa34ab8SBenjamin Herrenschmidt * 6*8aa34ab8SBenjamin Herrenschmidt * PowerPC version 7*8aa34ab8SBenjamin Herrenschmidt * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) 8*8aa34ab8SBenjamin Herrenschmidt * 9*8aa34ab8SBenjamin Herrenschmidt * Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP 10*8aa34ab8SBenjamin Herrenschmidt * Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu> 11*8aa34ab8SBenjamin Herrenschmidt * Adapted for Power Macintosh by Paul Mackerras. 12*8aa34ab8SBenjamin Herrenschmidt * Low-level exception handlers and MMU support 13*8aa34ab8SBenjamin Herrenschmidt * rewritten by Paul Mackerras. 14*8aa34ab8SBenjamin Herrenschmidt * Copyright (C) 1996 Paul Mackerras. 15*8aa34ab8SBenjamin Herrenschmidt * 16*8aa34ab8SBenjamin Herrenschmidt * Adapted for 64bit PowerPC by Dave Engebretsen, Peter Bergner, and 17*8aa34ab8SBenjamin Herrenschmidt * Mike Corrigan {engebret|bergner|mikejc}@us.ibm.com 18*8aa34ab8SBenjamin Herrenschmidt * 19*8aa34ab8SBenjamin Herrenschmidt * This file contains the low-level support and setup for the 20*8aa34ab8SBenjamin Herrenschmidt * PowerPC-64 platform, including trap and interrupt dispatch. 21*8aa34ab8SBenjamin Herrenschmidt * 22*8aa34ab8SBenjamin Herrenschmidt * This program is free software; you can redistribute it and/or 23*8aa34ab8SBenjamin Herrenschmidt * modify it under the terms of the GNU General Public License 24*8aa34ab8SBenjamin Herrenschmidt * as published by the Free Software Foundation; either version 25*8aa34ab8SBenjamin Herrenschmidt * 2 of the License, or (at your option) any later version. 26*8aa34ab8SBenjamin Herrenschmidt */ 27*8aa34ab8SBenjamin Herrenschmidt /* 28*8aa34ab8SBenjamin Herrenschmidt * The following macros define the code that appears as 29*8aa34ab8SBenjamin Herrenschmidt * the prologue to each of the exception handlers. They 30*8aa34ab8SBenjamin Herrenschmidt * are split into two parts to allow a single kernel binary 31*8aa34ab8SBenjamin Herrenschmidt * to be used for pSeries and iSeries. 32*8aa34ab8SBenjamin Herrenschmidt * 33*8aa34ab8SBenjamin Herrenschmidt * We make as much of the exception code common between native 34*8aa34ab8SBenjamin Herrenschmidt * exception handlers (including pSeries LPAR) and iSeries LPAR 35*8aa34ab8SBenjamin Herrenschmidt * implementations as possible. 36*8aa34ab8SBenjamin Herrenschmidt */ 37*8aa34ab8SBenjamin Herrenschmidt 38*8aa34ab8SBenjamin Herrenschmidt #define EX_R9 0 39*8aa34ab8SBenjamin Herrenschmidt #define EX_R10 8 40*8aa34ab8SBenjamin Herrenschmidt #define EX_R11 16 41*8aa34ab8SBenjamin Herrenschmidt #define EX_R12 24 42*8aa34ab8SBenjamin Herrenschmidt #define EX_R13 32 43*8aa34ab8SBenjamin Herrenschmidt #define EX_SRR0 40 44*8aa34ab8SBenjamin Herrenschmidt #define EX_DAR 48 45*8aa34ab8SBenjamin Herrenschmidt #define EX_DSISR 56 46*8aa34ab8SBenjamin Herrenschmidt #define EX_CCR 60 47*8aa34ab8SBenjamin Herrenschmidt #define EX_R3 64 48*8aa34ab8SBenjamin Herrenschmidt #define EX_LR 72 49*8aa34ab8SBenjamin Herrenschmidt 50*8aa34ab8SBenjamin Herrenschmidt /* 51*8aa34ab8SBenjamin Herrenschmidt * We're short on space and time in the exception prolog, so we can't 52*8aa34ab8SBenjamin Herrenschmidt * use the normal SET_REG_IMMEDIATE macro. Normally we just need the 53*8aa34ab8SBenjamin Herrenschmidt * low halfword of the address, but for Kdump we need the whole low 54*8aa34ab8SBenjamin Herrenschmidt * word. 55*8aa34ab8SBenjamin Herrenschmidt */ 56*8aa34ab8SBenjamin Herrenschmidt #define LOAD_HANDLER(reg, label) \ 57*8aa34ab8SBenjamin Herrenschmidt addi reg,reg,(label)-_stext; /* virt addr of handler ... */ 58*8aa34ab8SBenjamin Herrenschmidt 59*8aa34ab8SBenjamin Herrenschmidt #define EXCEPTION_PROLOG_1(area) \ 60*8aa34ab8SBenjamin Herrenschmidt mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \ 61*8aa34ab8SBenjamin Herrenschmidt std r9,area+EX_R9(r13); /* save r9 - r12 */ \ 62*8aa34ab8SBenjamin Herrenschmidt std r10,area+EX_R10(r13); \ 63*8aa34ab8SBenjamin Herrenschmidt std r11,area+EX_R11(r13); \ 64*8aa34ab8SBenjamin Herrenschmidt std r12,area+EX_R12(r13); \ 65*8aa34ab8SBenjamin Herrenschmidt mfspr r9,SPRN_SPRG1; \ 66*8aa34ab8SBenjamin Herrenschmidt std r9,area+EX_R13(r13); \ 67*8aa34ab8SBenjamin Herrenschmidt mfcr r9 68*8aa34ab8SBenjamin Herrenschmidt 69*8aa34ab8SBenjamin Herrenschmidt #define EXCEPTION_PROLOG_PSERIES(area, label) \ 70*8aa34ab8SBenjamin Herrenschmidt EXCEPTION_PROLOG_1(area); \ 71*8aa34ab8SBenjamin Herrenschmidt ld r12,PACAKBASE(r13); /* get high part of &label */ \ 72*8aa34ab8SBenjamin Herrenschmidt ld r10,PACAKMSR(r13); /* get MSR value for kernel */ \ 73*8aa34ab8SBenjamin Herrenschmidt mfspr r11,SPRN_SRR0; /* save SRR0 */ \ 74*8aa34ab8SBenjamin Herrenschmidt LOAD_HANDLER(r12,label) \ 75*8aa34ab8SBenjamin Herrenschmidt mtspr SPRN_SRR0,r12; \ 76*8aa34ab8SBenjamin Herrenschmidt mfspr r12,SPRN_SRR1; /* and SRR1 */ \ 77*8aa34ab8SBenjamin Herrenschmidt mtspr SPRN_SRR1,r10; \ 78*8aa34ab8SBenjamin Herrenschmidt rfid; \ 79*8aa34ab8SBenjamin Herrenschmidt b . /* prevent speculative execution */ 80*8aa34ab8SBenjamin Herrenschmidt 81*8aa34ab8SBenjamin Herrenschmidt /* 82*8aa34ab8SBenjamin Herrenschmidt * The common exception prolog is used for all except a few exceptions 83*8aa34ab8SBenjamin Herrenschmidt * such as a segment miss on a kernel address. We have to be prepared 84*8aa34ab8SBenjamin Herrenschmidt * to take another exception from the point where we first touch the 85*8aa34ab8SBenjamin Herrenschmidt * kernel stack onwards. 86*8aa34ab8SBenjamin Herrenschmidt * 87*8aa34ab8SBenjamin Herrenschmidt * On entry r13 points to the paca, r9-r13 are saved in the paca, 88*8aa34ab8SBenjamin Herrenschmidt * r9 contains the saved CR, r11 and r12 contain the saved SRR0 and 89*8aa34ab8SBenjamin Herrenschmidt * SRR1, and relocation is on. 90*8aa34ab8SBenjamin Herrenschmidt */ 91*8aa34ab8SBenjamin Herrenschmidt #define EXCEPTION_PROLOG_COMMON(n, area) \ 92*8aa34ab8SBenjamin Herrenschmidt andi. r10,r12,MSR_PR; /* See if coming from user */ \ 93*8aa34ab8SBenjamin Herrenschmidt mr r10,r1; /* Save r1 */ \ 94*8aa34ab8SBenjamin Herrenschmidt subi r1,r1,INT_FRAME_SIZE; /* alloc frame on kernel stack */ \ 95*8aa34ab8SBenjamin Herrenschmidt beq- 1f; \ 96*8aa34ab8SBenjamin Herrenschmidt ld r1,PACAKSAVE(r13); /* kernel stack to use */ \ 97*8aa34ab8SBenjamin Herrenschmidt 1: cmpdi cr1,r1,0; /* check if r1 is in userspace */ \ 98*8aa34ab8SBenjamin Herrenschmidt bge- cr1,2f; /* abort if it is */ \ 99*8aa34ab8SBenjamin Herrenschmidt b 3f; \ 100*8aa34ab8SBenjamin Herrenschmidt 2: li r1,(n); /* will be reloaded later */ \ 101*8aa34ab8SBenjamin Herrenschmidt sth r1,PACA_TRAP_SAVE(r13); \ 102*8aa34ab8SBenjamin Herrenschmidt b bad_stack; \ 103*8aa34ab8SBenjamin Herrenschmidt 3: std r9,_CCR(r1); /* save CR in stackframe */ \ 104*8aa34ab8SBenjamin Herrenschmidt std r11,_NIP(r1); /* save SRR0 in stackframe */ \ 105*8aa34ab8SBenjamin Herrenschmidt std r12,_MSR(r1); /* save SRR1 in stackframe */ \ 106*8aa34ab8SBenjamin Herrenschmidt std r10,0(r1); /* make stack chain pointer */ \ 107*8aa34ab8SBenjamin Herrenschmidt std r0,GPR0(r1); /* save r0 in stackframe */ \ 108*8aa34ab8SBenjamin Herrenschmidt std r10,GPR1(r1); /* save r1 in stackframe */ \ 109*8aa34ab8SBenjamin Herrenschmidt ACCOUNT_CPU_USER_ENTRY(r9, r10); \ 110*8aa34ab8SBenjamin Herrenschmidt std r2,GPR2(r1); /* save r2 in stackframe */ \ 111*8aa34ab8SBenjamin Herrenschmidt SAVE_4GPRS(3, r1); /* save r3 - r6 in stackframe */ \ 112*8aa34ab8SBenjamin Herrenschmidt SAVE_2GPRS(7, r1); /* save r7, r8 in stackframe */ \ 113*8aa34ab8SBenjamin Herrenschmidt ld r9,area+EX_R9(r13); /* move r9, r10 to stackframe */ \ 114*8aa34ab8SBenjamin Herrenschmidt ld r10,area+EX_R10(r13); \ 115*8aa34ab8SBenjamin Herrenschmidt std r9,GPR9(r1); \ 116*8aa34ab8SBenjamin Herrenschmidt std r10,GPR10(r1); \ 117*8aa34ab8SBenjamin Herrenschmidt ld r9,area+EX_R11(r13); /* move r11 - r13 to stackframe */ \ 118*8aa34ab8SBenjamin Herrenschmidt ld r10,area+EX_R12(r13); \ 119*8aa34ab8SBenjamin Herrenschmidt ld r11,area+EX_R13(r13); \ 120*8aa34ab8SBenjamin Herrenschmidt std r9,GPR11(r1); \ 121*8aa34ab8SBenjamin Herrenschmidt std r10,GPR12(r1); \ 122*8aa34ab8SBenjamin Herrenschmidt std r11,GPR13(r1); \ 123*8aa34ab8SBenjamin Herrenschmidt ld r2,PACATOC(r13); /* get kernel TOC into r2 */ \ 124*8aa34ab8SBenjamin Herrenschmidt mflr r9; /* save LR in stackframe */ \ 125*8aa34ab8SBenjamin Herrenschmidt std r9,_LINK(r1); \ 126*8aa34ab8SBenjamin Herrenschmidt mfctr r10; /* save CTR in stackframe */ \ 127*8aa34ab8SBenjamin Herrenschmidt std r10,_CTR(r1); \ 128*8aa34ab8SBenjamin Herrenschmidt lbz r10,PACASOFTIRQEN(r13); \ 129*8aa34ab8SBenjamin Herrenschmidt mfspr r11,SPRN_XER; /* save XER in stackframe */ \ 130*8aa34ab8SBenjamin Herrenschmidt std r10,SOFTE(r1); \ 131*8aa34ab8SBenjamin Herrenschmidt std r11,_XER(r1); \ 132*8aa34ab8SBenjamin Herrenschmidt li r9,(n)+1; \ 133*8aa34ab8SBenjamin Herrenschmidt std r9,_TRAP(r1); /* set trap number */ \ 134*8aa34ab8SBenjamin Herrenschmidt li r10,0; \ 135*8aa34ab8SBenjamin Herrenschmidt ld r11,exception_marker@toc(r2); \ 136*8aa34ab8SBenjamin Herrenschmidt std r10,RESULT(r1); /* clear regs->result */ \ 137*8aa34ab8SBenjamin Herrenschmidt std r11,STACK_FRAME_OVERHEAD-16(r1); /* mark the frame */ 138*8aa34ab8SBenjamin Herrenschmidt 139*8aa34ab8SBenjamin Herrenschmidt /* 140*8aa34ab8SBenjamin Herrenschmidt * Exception vectors. 141*8aa34ab8SBenjamin Herrenschmidt */ 142*8aa34ab8SBenjamin Herrenschmidt #define STD_EXCEPTION_PSERIES(n, label) \ 143*8aa34ab8SBenjamin Herrenschmidt . = n; \ 144*8aa34ab8SBenjamin Herrenschmidt .globl label##_pSeries; \ 145*8aa34ab8SBenjamin Herrenschmidt label##_pSeries: \ 146*8aa34ab8SBenjamin Herrenschmidt HMT_MEDIUM; \ 147*8aa34ab8SBenjamin Herrenschmidt mtspr SPRN_SPRG1,r13; /* save r13 */ \ 148*8aa34ab8SBenjamin Herrenschmidt EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common) 149*8aa34ab8SBenjamin Herrenschmidt 150*8aa34ab8SBenjamin Herrenschmidt #define HSTD_EXCEPTION_PSERIES(n, label) \ 151*8aa34ab8SBenjamin Herrenschmidt . = n; \ 152*8aa34ab8SBenjamin Herrenschmidt .globl label##_pSeries; \ 153*8aa34ab8SBenjamin Herrenschmidt label##_pSeries: \ 154*8aa34ab8SBenjamin Herrenschmidt HMT_MEDIUM; \ 155*8aa34ab8SBenjamin Herrenschmidt mtspr SPRN_SPRG1,r20; /* save r20 */ \ 156*8aa34ab8SBenjamin Herrenschmidt mfspr r20,SPRN_HSRR0; /* copy HSRR0 to SRR0 */ \ 157*8aa34ab8SBenjamin Herrenschmidt mtspr SPRN_SRR0,r20; \ 158*8aa34ab8SBenjamin Herrenschmidt mfspr r20,SPRN_HSRR1; /* copy HSRR0 to SRR0 */ \ 159*8aa34ab8SBenjamin Herrenschmidt mtspr SPRN_SRR1,r20; \ 160*8aa34ab8SBenjamin Herrenschmidt mfspr r20,SPRN_SPRG1; /* restore r20 */ \ 161*8aa34ab8SBenjamin Herrenschmidt mtspr SPRN_SPRG1,r13; /* save r13 */ \ 162*8aa34ab8SBenjamin Herrenschmidt EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common) 163*8aa34ab8SBenjamin Herrenschmidt 164*8aa34ab8SBenjamin Herrenschmidt 165*8aa34ab8SBenjamin Herrenschmidt #define MASKABLE_EXCEPTION_PSERIES(n, label) \ 166*8aa34ab8SBenjamin Herrenschmidt . = n; \ 167*8aa34ab8SBenjamin Herrenschmidt .globl label##_pSeries; \ 168*8aa34ab8SBenjamin Herrenschmidt label##_pSeries: \ 169*8aa34ab8SBenjamin Herrenschmidt HMT_MEDIUM; \ 170*8aa34ab8SBenjamin Herrenschmidt mtspr SPRN_SPRG1,r13; /* save r13 */ \ 171*8aa34ab8SBenjamin Herrenschmidt mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \ 172*8aa34ab8SBenjamin Herrenschmidt std r9,PACA_EXGEN+EX_R9(r13); /* save r9, r10 */ \ 173*8aa34ab8SBenjamin Herrenschmidt std r10,PACA_EXGEN+EX_R10(r13); \ 174*8aa34ab8SBenjamin Herrenschmidt lbz r10,PACASOFTIRQEN(r13); \ 175*8aa34ab8SBenjamin Herrenschmidt mfcr r9; \ 176*8aa34ab8SBenjamin Herrenschmidt cmpwi r10,0; \ 177*8aa34ab8SBenjamin Herrenschmidt beq masked_interrupt; \ 178*8aa34ab8SBenjamin Herrenschmidt mfspr r10,SPRN_SPRG1; \ 179*8aa34ab8SBenjamin Herrenschmidt std r10,PACA_EXGEN+EX_R13(r13); \ 180*8aa34ab8SBenjamin Herrenschmidt std r11,PACA_EXGEN+EX_R11(r13); \ 181*8aa34ab8SBenjamin Herrenschmidt std r12,PACA_EXGEN+EX_R12(r13); \ 182*8aa34ab8SBenjamin Herrenschmidt ld r12,PACAKBASE(r13); /* get high part of &label */ \ 183*8aa34ab8SBenjamin Herrenschmidt ld r10,PACAKMSR(r13); /* get MSR value for kernel */ \ 184*8aa34ab8SBenjamin Herrenschmidt mfspr r11,SPRN_SRR0; /* save SRR0 */ \ 185*8aa34ab8SBenjamin Herrenschmidt LOAD_HANDLER(r12,label##_common) \ 186*8aa34ab8SBenjamin Herrenschmidt mtspr SPRN_SRR0,r12; \ 187*8aa34ab8SBenjamin Herrenschmidt mfspr r12,SPRN_SRR1; /* and SRR1 */ \ 188*8aa34ab8SBenjamin Herrenschmidt mtspr SPRN_SRR1,r10; \ 189*8aa34ab8SBenjamin Herrenschmidt rfid; \ 190*8aa34ab8SBenjamin Herrenschmidt b . /* prevent speculative execution */ 191*8aa34ab8SBenjamin Herrenschmidt 192*8aa34ab8SBenjamin Herrenschmidt #ifdef CONFIG_PPC_ISERIES 193*8aa34ab8SBenjamin Herrenschmidt #define DISABLE_INTS \ 194*8aa34ab8SBenjamin Herrenschmidt li r11,0; \ 195*8aa34ab8SBenjamin Herrenschmidt stb r11,PACASOFTIRQEN(r13); \ 196*8aa34ab8SBenjamin Herrenschmidt BEGIN_FW_FTR_SECTION; \ 197*8aa34ab8SBenjamin Herrenschmidt stb r11,PACAHARDIRQEN(r13); \ 198*8aa34ab8SBenjamin Herrenschmidt END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES); \ 199*8aa34ab8SBenjamin Herrenschmidt TRACE_DISABLE_INTS; \ 200*8aa34ab8SBenjamin Herrenschmidt BEGIN_FW_FTR_SECTION; \ 201*8aa34ab8SBenjamin Herrenschmidt mfmsr r10; \ 202*8aa34ab8SBenjamin Herrenschmidt ori r10,r10,MSR_EE; \ 203*8aa34ab8SBenjamin Herrenschmidt mtmsrd r10,1; \ 204*8aa34ab8SBenjamin Herrenschmidt END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) 205*8aa34ab8SBenjamin Herrenschmidt #else 206*8aa34ab8SBenjamin Herrenschmidt #define DISABLE_INTS \ 207*8aa34ab8SBenjamin Herrenschmidt li r11,0; \ 208*8aa34ab8SBenjamin Herrenschmidt stb r11,PACASOFTIRQEN(r13); \ 209*8aa34ab8SBenjamin Herrenschmidt stb r11,PACAHARDIRQEN(r13); \ 210*8aa34ab8SBenjamin Herrenschmidt TRACE_DISABLE_INTS 211*8aa34ab8SBenjamin Herrenschmidt #endif /* CONFIG_PPC_ISERIES */ 212*8aa34ab8SBenjamin Herrenschmidt 213*8aa34ab8SBenjamin Herrenschmidt #define ENABLE_INTS \ 214*8aa34ab8SBenjamin Herrenschmidt ld r12,_MSR(r1); \ 215*8aa34ab8SBenjamin Herrenschmidt mfmsr r11; \ 216*8aa34ab8SBenjamin Herrenschmidt rlwimi r11,r12,0,MSR_EE; \ 217*8aa34ab8SBenjamin Herrenschmidt mtmsrd r11,1 218*8aa34ab8SBenjamin Herrenschmidt 219*8aa34ab8SBenjamin Herrenschmidt #define STD_EXCEPTION_COMMON(trap, label, hdlr) \ 220*8aa34ab8SBenjamin Herrenschmidt .align 7; \ 221*8aa34ab8SBenjamin Herrenschmidt .globl label##_common; \ 222*8aa34ab8SBenjamin Herrenschmidt label##_common: \ 223*8aa34ab8SBenjamin Herrenschmidt EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \ 224*8aa34ab8SBenjamin Herrenschmidt DISABLE_INTS; \ 225*8aa34ab8SBenjamin Herrenschmidt bl .save_nvgprs; \ 226*8aa34ab8SBenjamin Herrenschmidt addi r3,r1,STACK_FRAME_OVERHEAD; \ 227*8aa34ab8SBenjamin Herrenschmidt bl hdlr; \ 228*8aa34ab8SBenjamin Herrenschmidt b .ret_from_except 229*8aa34ab8SBenjamin Herrenschmidt 230*8aa34ab8SBenjamin Herrenschmidt /* 231*8aa34ab8SBenjamin Herrenschmidt * Like STD_EXCEPTION_COMMON, but for exceptions that can occur 232*8aa34ab8SBenjamin Herrenschmidt * in the idle task and therefore need the special idle handling. 233*8aa34ab8SBenjamin Herrenschmidt */ 234*8aa34ab8SBenjamin Herrenschmidt #define STD_EXCEPTION_COMMON_IDLE(trap, label, hdlr) \ 235*8aa34ab8SBenjamin Herrenschmidt .align 7; \ 236*8aa34ab8SBenjamin Herrenschmidt .globl label##_common; \ 237*8aa34ab8SBenjamin Herrenschmidt label##_common: \ 238*8aa34ab8SBenjamin Herrenschmidt EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \ 239*8aa34ab8SBenjamin Herrenschmidt FINISH_NAP; \ 240*8aa34ab8SBenjamin Herrenschmidt DISABLE_INTS; \ 241*8aa34ab8SBenjamin Herrenschmidt bl .save_nvgprs; \ 242*8aa34ab8SBenjamin Herrenschmidt addi r3,r1,STACK_FRAME_OVERHEAD; \ 243*8aa34ab8SBenjamin Herrenschmidt bl hdlr; \ 244*8aa34ab8SBenjamin Herrenschmidt b .ret_from_except 245*8aa34ab8SBenjamin Herrenschmidt 246*8aa34ab8SBenjamin Herrenschmidt #define STD_EXCEPTION_COMMON_LITE(trap, label, hdlr) \ 247*8aa34ab8SBenjamin Herrenschmidt .align 7; \ 248*8aa34ab8SBenjamin Herrenschmidt .globl label##_common; \ 249*8aa34ab8SBenjamin Herrenschmidt label##_common: \ 250*8aa34ab8SBenjamin Herrenschmidt EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \ 251*8aa34ab8SBenjamin Herrenschmidt FINISH_NAP; \ 252*8aa34ab8SBenjamin Herrenschmidt DISABLE_INTS; \ 253*8aa34ab8SBenjamin Herrenschmidt BEGIN_FTR_SECTION \ 254*8aa34ab8SBenjamin Herrenschmidt bl .ppc64_runlatch_on; \ 255*8aa34ab8SBenjamin Herrenschmidt END_FTR_SECTION_IFSET(CPU_FTR_CTRL) \ 256*8aa34ab8SBenjamin Herrenschmidt addi r3,r1,STACK_FRAME_OVERHEAD; \ 257*8aa34ab8SBenjamin Herrenschmidt bl hdlr; \ 258*8aa34ab8SBenjamin Herrenschmidt b .ret_from_except_lite 259*8aa34ab8SBenjamin Herrenschmidt 260*8aa34ab8SBenjamin Herrenschmidt /* 261*8aa34ab8SBenjamin Herrenschmidt * When the idle code in power4_idle puts the CPU into NAP mode, 262*8aa34ab8SBenjamin Herrenschmidt * it has to do so in a loop, and relies on the external interrupt 263*8aa34ab8SBenjamin Herrenschmidt * and decrementer interrupt entry code to get it out of the loop. 264*8aa34ab8SBenjamin Herrenschmidt * It sets the _TLF_NAPPING bit in current_thread_info()->local_flags 265*8aa34ab8SBenjamin Herrenschmidt * to signal that it is in the loop and needs help to get out. 266*8aa34ab8SBenjamin Herrenschmidt */ 267*8aa34ab8SBenjamin Herrenschmidt #ifdef CONFIG_PPC_970_NAP 268*8aa34ab8SBenjamin Herrenschmidt #define FINISH_NAP \ 269*8aa34ab8SBenjamin Herrenschmidt BEGIN_FTR_SECTION \ 270*8aa34ab8SBenjamin Herrenschmidt clrrdi r11,r1,THREAD_SHIFT; \ 271*8aa34ab8SBenjamin Herrenschmidt ld r9,TI_LOCAL_FLAGS(r11); \ 272*8aa34ab8SBenjamin Herrenschmidt andi. r10,r9,_TLF_NAPPING; \ 273*8aa34ab8SBenjamin Herrenschmidt bnel power4_fixup_nap; \ 274*8aa34ab8SBenjamin Herrenschmidt END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) 275*8aa34ab8SBenjamin Herrenschmidt #else 276*8aa34ab8SBenjamin Herrenschmidt #define FINISH_NAP 277*8aa34ab8SBenjamin Herrenschmidt #endif 278*8aa34ab8SBenjamin Herrenschmidt 279*8aa34ab8SBenjamin Herrenschmidt #endif /* _ASM_POWERPC_EXCEPTION_H */ 280