aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/include/asm/exception-64s.h
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/include/asm/exception-64s.h')
-rw-r--r--arch/powerpc/include/asm/exception-64s.h113
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 7778d6f0c878..f5dfe3411f64 100644
--- a/arch/powerpc/include/asm/exception-64s.h
+++ b/arch/powerpc/include/asm/exception-64s.h
@@ -46,6 +46,7 @@
46#define EX_CCR 60 46#define EX_CCR 60
47#define EX_R3 64 47#define EX_R3 64
48#define EX_LR 72 48#define EX_LR 72
49#define EX_CFAR 80
49 50
50/* 51/*
51 * We're short on space and time in the exception prolog, so we can't 52 * We're short on space and time in the exception prolog, so we can't
@@ -56,30 +57,40 @@
56#define LOAD_HANDLER(reg, label) \ 57#define LOAD_HANDLER(reg, label) \
57 addi reg,reg,(label)-_stext; /* virt addr of handler ... */ 58 addi reg,reg,(label)-_stext; /* virt addr of handler ... */
58 59
59#define EXCEPTION_PROLOG_1(area) \ 60/* Exception register prefixes */
60 mfspr r13,SPRN_SPRG_PACA; /* get paca address into r13 */ \ 61#define EXC_HV H
62#define EXC_STD
63
64#define EXCEPTION_PROLOG_1(area) \
65 GET_PACA(r13); \
61 std r9,area+EX_R9(r13); /* save r9 - r12 */ \ 66 std r9,area+EX_R9(r13); /* save r9 - r12 */ \
62 std r10,area+EX_R10(r13); \ 67 std r10,area+EX_R10(r13); \
63 std r11,area+EX_R11(r13); \ 68 std r11,area+EX_R11(r13); \
64 std r12,area+EX_R12(r13); \ 69 std r12,area+EX_R12(r13); \
65 mfspr r9,SPRN_SPRG_SCRATCH0; \ 70 BEGIN_FTR_SECTION_NESTED(66); \
71 mfspr r10,SPRN_CFAR; \
72 std r10,area+EX_CFAR(r13); \
73 END_FTR_SECTION_NESTED(CPU_FTR_CFAR, CPU_FTR_CFAR, 66); \
74 GET_SCRATCH0(r9); \
66 std r9,area+EX_R13(r13); \ 75 std r9,area+EX_R13(r13); \
67 mfcr r9 76 mfcr r9
68 77
69#define EXCEPTION_PROLOG_PSERIES_1(label) \ 78#define __EXCEPTION_PROLOG_PSERIES_1(label, h) \
70 ld r12,PACAKBASE(r13); /* get high part of &label */ \ 79 ld r12,PACAKBASE(r13); /* get high part of &label */ \
71 ld r10,PACAKMSR(r13); /* get MSR value for kernel */ \ 80 ld r10,PACAKMSR(r13); /* get MSR value for kernel */ \
72 mfspr r11,SPRN_SRR0; /* save SRR0 */ \ 81 mfspr r11,SPRN_##h##SRR0; /* save SRR0 */ \
73 LOAD_HANDLER(r12,label) \ 82 LOAD_HANDLER(r12,label) \
74 mtspr SPRN_SRR0,r12; \ 83 mtspr SPRN_##h##SRR0,r12; \
75 mfspr r12,SPRN_SRR1; /* and SRR1 */ \ 84 mfspr r12,SPRN_##h##SRR1; /* and SRR1 */ \
76 mtspr SPRN_SRR1,r10; \ 85 mtspr SPRN_##h##SRR1,r10; \
77 rfid; \ 86 h##rfid; \
78 b . /* prevent speculative execution */ 87 b . /* prevent speculative execution */
88#define EXCEPTION_PROLOG_PSERIES_1(label, h) \
89 __EXCEPTION_PROLOG_PSERIES_1(label, h)
79 90
80#define EXCEPTION_PROLOG_PSERIES(area, label) \ 91#define EXCEPTION_PROLOG_PSERIES(area, label, h) \
81 EXCEPTION_PROLOG_1(area); \ 92 EXCEPTION_PROLOG_1(area); \
82 EXCEPTION_PROLOG_PSERIES_1(label); 93 EXCEPTION_PROLOG_PSERIES_1(label, h);
83 94
84/* 95/*
85 * The common exception prolog is used for all except a few exceptions 96 * The common exception prolog is used for all except a few exceptions
@@ -98,10 +109,11 @@
98 beq- 1f; \ 109 beq- 1f; \
99 ld r1,PACAKSAVE(r13); /* kernel stack to use */ \ 110 ld r1,PACAKSAVE(r13); /* kernel stack to use */ \
1001: cmpdi cr1,r1,0; /* check if r1 is in userspace */ \ 1111: cmpdi cr1,r1,0; /* check if r1 is in userspace */ \
101 bge- cr1,2f; /* abort if it is */ \ 112 blt+ cr1,3f; /* abort if it is */ \
102 b 3f; \ 113 li r1,(n); /* will be reloaded later */ \
1032: li r1,(n); /* will be reloaded later */ \
104 sth r1,PACA_TRAP_SAVE(r13); \ 114 sth r1,PACA_TRAP_SAVE(r13); \
115 std r3,area+EX_R3(r13); \
116 addi r3,r13,area; /* r3 -> where regs are saved*/ \
105 b bad_stack; \ 117 b bad_stack; \
1063: std r9,_CCR(r1); /* save CR in stackframe */ \ 1183: std r9,_CCR(r1); /* save CR in stackframe */ \
107 std r11,_NIP(r1); /* save SRR0 in stackframe */ \ 119 std r11,_NIP(r1); /* save SRR0 in stackframe */ \
@@ -123,6 +135,10 @@
123 std r9,GPR11(r1); \ 135 std r9,GPR11(r1); \
124 std r10,GPR12(r1); \ 136 std r10,GPR12(r1); \
125 std r11,GPR13(r1); \ 137 std r11,GPR13(r1); \
138 BEGIN_FTR_SECTION_NESTED(66); \
139 ld r10,area+EX_CFAR(r13); \
140 std r10,ORIG_GPR3(r1); \
141 END_FTR_SECTION_NESTED(CPU_FTR_CFAR, CPU_FTR_CFAR, 66); \
126 ld r2,PACATOC(r13); /* get kernel TOC into r2 */ \ 142 ld r2,PACATOC(r13); /* get kernel TOC into r2 */ \
127 mflr r9; /* save LR in stackframe */ \ 143 mflr r9; /* save LR in stackframe */ \
128 std r9,_LINK(r1); \ 144 std r9,_LINK(r1); \
@@ -143,57 +159,62 @@
143/* 159/*
144 * Exception vectors. 160 * Exception vectors.
145 */ 161 */
146#define STD_EXCEPTION_PSERIES(n, label) \ 162#define STD_EXCEPTION_PSERIES(loc, vec, label) \
147 . = n; \ 163 . = loc; \
148 .globl label##_pSeries; \ 164 .globl label##_pSeries; \
149label##_pSeries: \ 165label##_pSeries: \
150 HMT_MEDIUM; \ 166 HMT_MEDIUM; \
151 DO_KVM n; \ 167 DO_KVM vec; \
152 mtspr SPRN_SPRG_SCRATCH0,r13; /* save r13 */ \ 168 SET_SCRATCH0(r13); /* save r13 */ \
153 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common) 169 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, EXC_STD)
154 170
155#define HSTD_EXCEPTION_PSERIES(n, label) \ 171#define STD_EXCEPTION_HV(loc, vec, label) \
156 . = n; \ 172 . = loc; \
157 .globl label##_pSeries; \ 173 .globl label##_hv; \
158label##_pSeries: \ 174label##_hv: \
159 HMT_MEDIUM; \ 175 HMT_MEDIUM; \
160 mtspr SPRN_SPRG_SCRATCH0,r20; /* save r20 */ \ 176 DO_KVM vec; \
161 mfspr r20,SPRN_HSRR0; /* copy HSRR0 to SRR0 */ \ 177 SET_SCRATCH0(r13); /* save r13 */ \
162 mtspr SPRN_SRR0,r20; \ 178 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common, EXC_HV)
163 mfspr r20,SPRN_HSRR1; /* copy HSRR0 to SRR0 */ \
164 mtspr SPRN_SRR1,r20; \
165 mfspr r20,SPRN_SPRG_SCRATCH0; /* restore r20 */ \
166 mtspr SPRN_SPRG_SCRATCH0,r13; /* save r13 */ \
167 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
168 179
169 180#define __MASKABLE_EXCEPTION_PSERIES(vec, label, h) \
170#define MASKABLE_EXCEPTION_PSERIES(n, label) \
171 . = n; \
172 .globl label##_pSeries; \
173label##_pSeries: \
174 HMT_MEDIUM; \ 181 HMT_MEDIUM; \
175 DO_KVM n; \ 182 DO_KVM vec; \
176 mtspr SPRN_SPRG_SCRATCH0,r13; /* save r13 */ \ 183 SET_SCRATCH0(r13); /* save r13 */ \
177 mfspr r13,SPRN_SPRG_PACA; /* get paca address into r13 */ \ 184 GET_PACA(r13); \
178 std r9,PACA_EXGEN+EX_R9(r13); /* save r9, r10 */ \ 185 std r9,PACA_EXGEN+EX_R9(r13); /* save r9, r10 */ \
179 std r10,PACA_EXGEN+EX_R10(r13); \ 186 std r10,PACA_EXGEN+EX_R10(r13); \
180 lbz r10,PACASOFTIRQEN(r13); \ 187 lbz r10,PACASOFTIRQEN(r13); \
181 mfcr r9; \ 188 mfcr r9; \
182 cmpwi r10,0; \ 189 cmpwi r10,0; \
183 beq masked_interrupt; \ 190 beq masked_##h##interrupt; \
184 mfspr r10,SPRN_SPRG_SCRATCH0; \ 191 GET_SCRATCH0(r10); \
185 std r10,PACA_EXGEN+EX_R13(r13); \ 192 std r10,PACA_EXGEN+EX_R13(r13); \
186 std r11,PACA_EXGEN+EX_R11(r13); \ 193 std r11,PACA_EXGEN+EX_R11(r13); \
187 std r12,PACA_EXGEN+EX_R12(r13); \ 194 std r12,PACA_EXGEN+EX_R12(r13); \
188 ld r12,PACAKBASE(r13); /* get high part of &label */ \ 195 ld r12,PACAKBASE(r13); /* get high part of &label */ \
189 ld r10,PACAKMSR(r13); /* get MSR value for kernel */ \ 196 ld r10,PACAKMSR(r13); /* get MSR value for kernel */ \
190 mfspr r11,SPRN_SRR0; /* save SRR0 */ \ 197 mfspr r11,SPRN_##h##SRR0; /* save SRR0 */ \
191 LOAD_HANDLER(r12,label##_common) \ 198 LOAD_HANDLER(r12,label##_common) \
192 mtspr SPRN_SRR0,r12; \ 199 mtspr SPRN_##h##SRR0,r12; \
193 mfspr r12,SPRN_SRR1; /* and SRR1 */ \ 200 mfspr r12,SPRN_##h##SRR1; /* and SRR1 */ \
194 mtspr SPRN_SRR1,r10; \ 201 mtspr SPRN_##h##SRR1,r10; \
195 rfid; \ 202 h##rfid; \
196 b . /* prevent speculative execution */ 203 b . /* prevent speculative execution */
204#define _MASKABLE_EXCEPTION_PSERIES(vec, label, h) \
205 __MASKABLE_EXCEPTION_PSERIES(vec, label, h)
206
207#define MASKABLE_EXCEPTION_PSERIES(loc, vec, label) \
208 . = loc; \
209 .globl label##_pSeries; \
210label##_pSeries: \
211 _MASKABLE_EXCEPTION_PSERIES(vec, label, EXC_STD)
212
213#define MASKABLE_EXCEPTION_HV(loc, vec, label) \
214 . = loc; \
215 .globl label##_hv; \
216label##_hv: \
217 _MASKABLE_EXCEPTION_PSERIES(vec, label, EXC_HV)
197 218
198#ifdef CONFIG_PPC_ISERIES 219#ifdef CONFIG_PPC_ISERIES
199#define DISABLE_INTS \ 220#define DISABLE_INTS \