diff options
Diffstat (limited to 'arch/powerpc/include/asm/exception-64s.h')
-rw-r--r-- | arch/powerpc/include/asm/exception-64s.h | 113 |
1 files changed, 67 insertions, 46 deletions
diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index 7778d6f0c87..f5dfe3411f6 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h @@ -46,6 +46,7 @@ #define EX_CCR 60 #define EX_R3 64 #define EX_LR 72 +#define EX_CFAR 80 /* * We're short on space and time in the exception prolog, so we can't @@ -56,30 +57,40 @@ #define LOAD_HANDLER(reg, label) \ addi reg,reg,(label)-_stext; /* virt addr of handler ... */ -#define EXCEPTION_PROLOG_1(area) \ - mfspr r13,SPRN_SPRG_PACA; /* get paca address into r13 */ \ +/* Exception register prefixes */ +#define EXC_HV H +#define EXC_STD + +#define EXCEPTION_PROLOG_1(area) \ + GET_PACA(r13); \ std r9,area+EX_R9(r13); /* save r9 - r12 */ \ std r10,area+EX_R10(r13); \ std r11,area+EX_R11(r13); \ std r12,area+EX_R12(r13); \ - mfspr r9,SPRN_SPRG_SCRATCH0; \ + BEGIN_FTR_SECTION_NESTED(66); \ + mfspr r10,SPRN_CFAR; \ + std r10,area+EX_CFAR(r13); \ + END_FTR_SECTION_NESTED(CPU_FTR_CFAR, CPU_FTR_CFAR, 66); \ + GET_SCRATCH0(r9); \ std r9,area+EX_R13(r13); \ mfcr r9 -#define EXCEPTION_PROLOG_PSERIES_1(label) \ +#define __EXCEPTION_PROLOG_PSERIES_1(label, h) \ ld r12,PACAKBASE(r13); /* get high part of &label */ \ ld r10,PACAKMSR(r13); /* get MSR value for kernel */ \ - mfspr r11,SPRN_SRR0; /* save SRR0 */ \ + mfspr r11,SPRN_##h##SRR0; /* save SRR0 */ \ LOAD_HANDLER(r12,label) \ - mtspr SPRN_SRR0,r12; \ - mfspr r12,SPRN_SRR1; /* and SRR1 */ \ - mtspr SPRN_SRR1,r10; \ - rfid; \ + mtspr SPRN_##h##SRR0,r12; \ + mfspr r12,SPRN_##h##SRR1; /* and SRR1 */ \ + mtspr SPRN_##h##SRR1,r10; \ + h##rfid; \ b . /* prevent speculative execution */ +#define EXCEPTION_PROLOG_PSERIES_1(label, h) \ + __EXCEPTION_PROLOG_PSERIES_1(label, h) -#define EXCEPTION_PROLOG_PSERIES(area, label) \ +#define EXCEPTION_PROLOG_PSERIES(area, label, h) \ EXCEPTION_PROLOG_1(area); \ - EXCEPTION_PROLOG_PSERIES_1(label); + EXCEPTION_PROLOG_PSERIES_1(label, h); /* * The common exception prolog is used for all except a few exceptions @@ -98,10 +109,11 @@ beq- 1f; \ ld r1,PACAKSAVE(r13); /* kernel stack to use */ \ 1: cmpdi cr1,r1,0; /* check if r1 is in userspace */ \ - bge- cr1,2f; /* abort if it is */ \ - b 3f; \ -2: li r1,(n); /* will be reloaded later */ \ + blt+ cr1,3f; /* abort if it is */ \ + li r1,(n); /* will be reloaded later */ \ sth r1,PACA_TRAP_SAVE(r13); \ + std r3,area+EX_R3(r13); \ + addi r3,r13,area; /* r3 -> where regs are saved*/ \ b bad_stack; \ 3: std r9,_CCR(r1); /* save CR in stackframe */ \ std r11,_NIP(r1); /* save SRR0 in stackframe */ \ @@ -123,6 +135,10 @@ std r9,GPR11(r1); \ std r10,GPR12(r1); \ std r11,GPR13(r1); \ + BEGIN_FTR_SECTION_NESTED(66); \ + ld r10,area+EX_CFAR(r13); \ + std r10,ORIG_GPR3(r1); \ + END_FTR_SECTION_NESTED(CPU_FTR_CFAR, CPU_FTR_CFAR, 66); \ ld r2,PACATOC(r13); /* get kernel TOC into r2 */ \ mflr r9; /* save LR in stackframe */ \ std r9,_LINK(r1); \ @@ -143,57 +159,62 @@ /* * Exception vectors. */ -#define STD_EXCEPTION_PSERIES(n, label) \ - . = n; \ +#define STD_EXCEPTION_PSERIES(loc, vec, label) \ + . = loc; \ .globl label##_pSeries; \ label##_pSeries: \ HMT_MEDIUM; \ - DO_KVM n; \ - mtspr SPRN_SPRG_SCRATCH0,r13; /* save r13 */ \ - EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common) + DO_KVM vec; \ + SET_SCRATCH0(r13); /* save r13 */ \ + EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, EXC_STD) -#define HSTD_EXCEPTION_PSERIES(n, label) \ - . = n; \ - .globl label##_pSeries; \ -label##_pSeries: \ +#define STD_EXCEPTION_HV(loc, vec, label) \ + . = loc; \ + .globl label##_hv; \ +label##_hv: \ HMT_MEDIUM; \ - mtspr SPRN_SPRG_SCRATCH0,r20; /* save r20 */ \ - mfspr r20,SPRN_HSRR0; /* copy HSRR0 to SRR0 */ \ - mtspr SPRN_SRR0,r20; \ - mfspr r20,SPRN_HSRR1; /* copy HSRR0 to SRR0 */ \ - mtspr SPRN_SRR1,r20; \ - mfspr r20,SPRN_SPRG_SCRATCH0; /* restore r20 */ \ - mtspr SPRN_SPRG_SCRATCH0,r13; /* save r13 */ \ - EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common) + DO_KVM vec; \ + SET_SCRATCH0(r13); /* save r13 */ \ + EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, EXC_HV) - -#define MASKABLE_EXCEPTION_PSERIES(n, label) \ - . = n; \ - .globl label##_pSeries; \ -label##_pSeries: \ +#define __MASKABLE_EXCEPTION_PSERIES(vec, label, h) \ HMT_MEDIUM; \ - DO_KVM n; \ - mtspr SPRN_SPRG_SCRATCH0,r13; /* save r13 */ \ - mfspr r13,SPRN_SPRG_PACA; /* get paca address into r13 */ \ + DO_KVM vec; \ + SET_SCRATCH0(r13); /* save r13 */ \ + GET_PACA(r13); \ std r9,PACA_EXGEN+EX_R9(r13); /* save r9, r10 */ \ std r10,PACA_EXGEN+EX_R10(r13); \ lbz r10,PACASOFTIRQEN(r13); \ mfcr r9; \ cmpwi r10,0; \ - beq masked_interrupt; \ - mfspr r10,SPRN_SPRG_SCRATCH0; \ + beq masked_##h##interrupt; \ + GET_SCRATCH0(r10); \ std r10,PACA_EXGEN+EX_R13(r13); \ std r11,PACA_EXGEN+EX_R11(r13); \ std r12,PACA_EXGEN+EX_R12(r13); \ ld r12,PACAKBASE(r13); /* get high part of &label */ \ ld r10,PACAKMSR(r13); /* get MSR value for kernel */ \ - mfspr r11,SPRN_SRR0; /* save SRR0 */ \ + mfspr r11,SPRN_##h##SRR0; /* save SRR0 */ \ LOAD_HANDLER(r12,label##_common) \ - mtspr SPRN_SRR0,r12; \ - mfspr r12,SPRN_SRR1; /* and SRR1 */ \ - mtspr SPRN_SRR1,r10; \ - rfid; \ + mtspr SPRN_##h##SRR0,r12; \ + mfspr r12,SPRN_##h##SRR1; /* and SRR1 */ \ + mtspr SPRN_##h##SRR1,r10; \ + h##rfid; \ b . /* prevent speculative execution */ +#define _MASKABLE_EXCEPTION_PSERIES(vec, label, h) \ + __MASKABLE_EXCEPTION_PSERIES(vec, label, h) + +#define MASKABLE_EXCEPTION_PSERIES(loc, vec, label) \ + . = loc; \ + .globl label##_pSeries; \ +label##_pSeries: \ + _MASKABLE_EXCEPTION_PSERIES(vec, label, EXC_STD) + +#define MASKABLE_EXCEPTION_HV(loc, vec, label) \ + . = loc; \ + .globl label##_hv; \ +label##_hv: \ + _MASKABLE_EXCEPTION_PSERIES(vec, label, EXC_HV) #ifdef CONFIG_PPC_ISERIES #define DISABLE_INTS \ |