Linux Audio

Check our new training course

Loading...
v4.6
 
  1#ifndef _ASM_POWERPC_EXCEPTION_H
  2#define _ASM_POWERPC_EXCEPTION_H
  3/*
  4 * Extracted from head_64.S
  5 *
  6 *  PowerPC version
  7 *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  8 *
  9 *  Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
 10 *    Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu>
 11 *  Adapted for Power Macintosh by Paul Mackerras.
 12 *  Low-level exception handlers and MMU support
 13 *  rewritten by Paul Mackerras.
 14 *    Copyright (C) 1996 Paul Mackerras.
 15 *
 16 *  Adapted for 64bit PowerPC by Dave Engebretsen, Peter Bergner, and
 17 *    Mike Corrigan {engebret|bergner|mikejc}@us.ibm.com
 18 *
 19 *  This file contains the low-level support and setup for the
 20 *  PowerPC-64 platform, including trap and interrupt dispatch.
 21 *
 22 *  This program is free software; you can redistribute it and/or
 23 *  modify it under the terms of the GNU General Public License
 24 *  as published by the Free Software Foundation; either version
 25 *  2 of the License, or (at your option) any later version.
 26 */
 27/*
 28 * The following macros define the code that appears as
 29 * the prologue to each of the exception handlers.  They
 30 * are split into two parts to allow a single kernel binary
 31 * to be used for pSeries and iSeries.
 32 *
 33 * We make as much of the exception code common between native
 34 * exception handlers (including pSeries LPAR) and iSeries LPAR
 35 * implementations as possible.
 36 */
 
 37
 38#define EX_R9		0
 39#define EX_R10		8
 40#define EX_R11		16
 41#define EX_R12		24
 42#define EX_R13		32
 43#define EX_SRR0		40
 44#define EX_DAR		48
 45#define EX_DSISR	56
 46#define EX_CCR		60
 47#define EX_R3		64
 48#define EX_LR		72
 49#define EX_CFAR		80
 50#define EX_PPR		88	/* SMT thread status register (priority) */
 51#define EX_CTR		96
 52
 53#ifdef CONFIG_RELOCATABLE
 54#define __EXCEPTION_RELON_PROLOG_PSERIES_1(label, h)			\
 55	ld	r12,PACAKBASE(r13);	/* get high part of &label */	\
 56	mfspr	r11,SPRN_##h##SRR0;	/* save SRR0 */			\
 57	LOAD_HANDLER(r12,label);					\
 58	mtctr	r12;							\
 59	mfspr	r12,SPRN_##h##SRR1;	/* and SRR1 */			\
 60	li	r10,MSR_RI;						\
 61	mtmsrd 	r10,1;			/* Set RI (EE=0) */		\
 62	bctr;
 63#else
 64/* If not relocatable, we can jump directly -- and save messing with LR */
 65#define __EXCEPTION_RELON_PROLOG_PSERIES_1(label, h)			\
 66	mfspr	r11,SPRN_##h##SRR0;	/* save SRR0 */			\
 67	mfspr	r12,SPRN_##h##SRR1;	/* and SRR1 */			\
 68	li	r10,MSR_RI;						\
 69	mtmsrd 	r10,1;			/* Set RI (EE=0) */		\
 70	b	label;
 71#endif
 72#define EXCEPTION_RELON_PROLOG_PSERIES_1(label, h)			\
 73	__EXCEPTION_RELON_PROLOG_PSERIES_1(label, h)			\
 74
 75/*
 76 * As EXCEPTION_PROLOG_PSERIES(), except we've already got relocation on
 77 * so no need to rfid.  Save lr in case we're CONFIG_RELOCATABLE, in which
 78 * case EXCEPTION_RELON_PROLOG_PSERIES_1 will be using lr.
 79 */
 80#define EXCEPTION_RELON_PROLOG_PSERIES(area, label, h, extra, vec)	\
 81	EXCEPTION_PROLOG_0(area);					\
 82	EXCEPTION_PROLOG_1(area, extra, vec);				\
 83	EXCEPTION_RELON_PROLOG_PSERIES_1(label, h)
 84
 85/*
 86 * We're short on space and time in the exception prolog, so we can't
 87 * use the normal SET_REG_IMMEDIATE macro. Normally we just need the
 88 * low halfword of the address, but for Kdump we need the whole low
 89 * word.
 90 */
 91#define LOAD_HANDLER(reg, label)					\
 92	/* Handlers must be within 64K of kbase, which must be 64k aligned */ \
 93	ori	reg,reg,(label)-_stext;	/* virt addr of handler ... */
 94
 95/* Exception register prefixes */
 96#define EXC_HV	H
 97#define EXC_STD
 98
 99#if defined(CONFIG_RELOCATABLE)
100/*
101 * If we support interrupts with relocation on AND we're a relocatable kernel,
102 * we need to use CTR to get to the 2nd level handler.  So, save/restore it
103 * when required.
104 */
105#define SAVE_CTR(reg, area)	mfctr	reg ; 	std	reg,area+EX_CTR(r13)
106#define GET_CTR(reg, area) 			ld	reg,area+EX_CTR(r13)
107#define RESTORE_CTR(reg, area)	ld	reg,area+EX_CTR(r13) ; mtctr reg
108#else
109/* ...else CTR is unused and in register. */
110#define SAVE_CTR(reg, area)
111#define GET_CTR(reg, area) 	mfctr	reg
112#define RESTORE_CTR(reg, area)
113#endif
114
115/*
116 * PPR save/restore macros used in exceptions_64s.S  
117 * Used for P7 or later processors
118 */
119#define SAVE_PPR(area, ra, rb)						\
120BEGIN_FTR_SECTION_NESTED(940)						\
121	ld	ra,PACACURRENT(r13);					\
122	ld	rb,area+EX_PPR(r13);	/* Read PPR from paca */	\
123	std	rb,TASKTHREADPPR(ra);					\
124END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,940)
125
126#define RESTORE_PPR_PACA(area, ra)					\
127BEGIN_FTR_SECTION_NESTED(941)						\
128	ld	ra,area+EX_PPR(r13);					\
129	mtspr	SPRN_PPR,ra;						\
130END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,941)
131
132/*
133 * Get an SPR into a register if the CPU has the given feature
134 */
135#define OPT_GET_SPR(ra, spr, ftr)					\
136BEGIN_FTR_SECTION_NESTED(943)						\
137	mfspr	ra,spr;							\
138END_FTR_SECTION_NESTED(ftr,ftr,943)
139
140/*
141 * Set an SPR from a register if the CPU has the given feature
142 */
143#define OPT_SET_SPR(ra, spr, ftr)					\
144BEGIN_FTR_SECTION_NESTED(943)						\
145	mtspr	spr,ra;							\
146END_FTR_SECTION_NESTED(ftr,ftr,943)
147
148/*
149 * Save a register to the PACA if the CPU has the given feature
150 */
151#define OPT_SAVE_REG_TO_PACA(offset, ra, ftr)				\
152BEGIN_FTR_SECTION_NESTED(943)						\
153	std	ra,offset(r13);						\
154END_FTR_SECTION_NESTED(ftr,ftr,943)
155
156#define EXCEPTION_PROLOG_0(area)					\
157	GET_PACA(r13);							\
158	std	r9,area+EX_R9(r13);	/* save r9 */			\
159	OPT_GET_SPR(r9, SPRN_PPR, CPU_FTR_HAS_PPR);			\
160	HMT_MEDIUM;							\
161	std	r10,area+EX_R10(r13);	/* save r10 - r12 */		\
162	OPT_GET_SPR(r10, SPRN_CFAR, CPU_FTR_CFAR)
163
164#define __EXCEPTION_PROLOG_1(area, extra, vec)				\
165	OPT_SAVE_REG_TO_PACA(area+EX_PPR, r9, CPU_FTR_HAS_PPR);		\
166	OPT_SAVE_REG_TO_PACA(area+EX_CFAR, r10, CPU_FTR_CFAR);		\
167	SAVE_CTR(r10, area);						\
168	mfcr	r9;							\
169	extra(vec);							\
170	std	r11,area+EX_R11(r13);					\
171	std	r12,area+EX_R12(r13);					\
172	GET_SCRATCH0(r10);						\
173	std	r10,area+EX_R13(r13)
174#define EXCEPTION_PROLOG_1(area, extra, vec)				\
175	__EXCEPTION_PROLOG_1(area, extra, vec)
176
177#define __EXCEPTION_PROLOG_PSERIES_1(label, h)				\
178	ld	r12,PACAKBASE(r13);	/* get high part of &label */	\
179	ld	r10,PACAKMSR(r13);	/* get MSR value for kernel */	\
180	mfspr	r11,SPRN_##h##SRR0;	/* save SRR0 */			\
181	LOAD_HANDLER(r12,label)						\
182	mtspr	SPRN_##h##SRR0,r12;					\
183	mfspr	r12,SPRN_##h##SRR1;	/* and SRR1 */			\
184	mtspr	SPRN_##h##SRR1,r10;					\
185	h##rfid;							\
186	b	.	/* prevent speculative execution */
187#define EXCEPTION_PROLOG_PSERIES_1(label, h)				\
188	__EXCEPTION_PROLOG_PSERIES_1(label, h)
189
190#define EXCEPTION_PROLOG_PSERIES(area, label, h, extra, vec)		\
191	EXCEPTION_PROLOG_0(area);					\
192	EXCEPTION_PROLOG_1(area, extra, vec);				\
193	EXCEPTION_PROLOG_PSERIES_1(label, h);
194
195#define __KVMTEST(n)							\
196	lbz	r10,HSTATE_IN_GUEST(r13);			\
197	cmpwi	r10,0;							\
198	bne	do_kvm_##n
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
199
200#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
201/*
202 * If hv is possible, interrupts come into to the hv version
203 * of the kvmppc_interrupt code, which then jumps to the PR handler,
204 * kvmppc_interrupt_pr, if the guest is a PR guest.
205 */
206#define kvmppc_interrupt kvmppc_interrupt_hv
207#else
208#define kvmppc_interrupt kvmppc_interrupt_pr
209#endif
210
211#define __KVM_HANDLER(area, h, n)					\
212do_kvm_##n:								\
213	BEGIN_FTR_SECTION_NESTED(947)					\
214	ld	r10,area+EX_CFAR(r13);					\
215	std	r10,HSTATE_CFAR(r13);					\
216	END_FTR_SECTION_NESTED(CPU_FTR_CFAR,CPU_FTR_CFAR,947);		\
217	BEGIN_FTR_SECTION_NESTED(948)					\
218	ld	r10,area+EX_PPR(r13);					\
219	std	r10,HSTATE_PPR(r13);					\
220	END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,948);	\
221	ld	r10,area+EX_R10(r13);					\
222	stw	r9,HSTATE_SCRATCH1(r13);				\
223	ld	r9,area+EX_R9(r13);					\
224	std	r12,HSTATE_SCRATCH0(r13);				\
225	li	r12,n;							\
226	b	kvmppc_interrupt
227
228#define __KVM_HANDLER_SKIP(area, h, n)					\
229do_kvm_##n:								\
230	cmpwi	r10,KVM_GUEST_MODE_SKIP;				\
231	ld	r10,area+EX_R10(r13);					\
232	beq	89f;							\
233	stw	r9,HSTATE_SCRATCH1(r13);			\
234	BEGIN_FTR_SECTION_NESTED(948)					\
235	ld	r9,area+EX_PPR(r13);					\
236	std	r9,HSTATE_PPR(r13);					\
237	END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,948);	\
238	ld	r9,area+EX_R9(r13);					\
239	std	r12,HSTATE_SCRATCH0(r13);			\
240	li	r12,n;							\
241	b	kvmppc_interrupt;					\
24289:	mtocrf	0x80,r9;						\
243	ld	r9,area+EX_R9(r13);					\
244	b	kvmppc_skip_##h##interrupt
245
246#ifdef CONFIG_KVM_BOOK3S_64_HANDLER
247#define KVMTEST(n)			__KVMTEST(n)
248#define KVM_HANDLER(area, h, n)		__KVM_HANDLER(area, h, n)
249#define KVM_HANDLER_SKIP(area, h, n)	__KVM_HANDLER_SKIP(area, h, n)
250
251#else
252#define KVMTEST(n)
253#define KVM_HANDLER(area, h, n)
254#define KVM_HANDLER_SKIP(area, h, n)
255#endif
256
257#define NOTEST(n)
258
259/*
260 * The common exception prolog is used for all except a few exceptions
261 * such as a segment miss on a kernel address.  We have to be prepared
262 * to take another exception from the point where we first touch the
263 * kernel stack onwards.
264 *
265 * On entry r13 points to the paca, r9-r13 are saved in the paca,
266 * r9 contains the saved CR, r11 and r12 contain the saved SRR0 and
267 * SRR1, and relocation is on.
268 */
269#define EXCEPTION_PROLOG_COMMON(n, area)				   \
270	andi.	r10,r12,MSR_PR;		/* See if coming from user	*/ \
271	mr	r10,r1;			/* Save r1			*/ \
272	subi	r1,r1,INT_FRAME_SIZE;	/* alloc frame on kernel stack	*/ \
273	beq-	1f;							   \
274	ld	r1,PACAKSAVE(r13);	/* kernel stack to use		*/ \
2751:	cmpdi	cr1,r1,-INT_FRAME_SIZE;	/* check if r1 is in userspace	*/ \
276	blt+	cr1,3f;			/* abort if it is		*/ \
277	li	r1,(n);			/* will be reloaded later	*/ \
278	sth	r1,PACA_TRAP_SAVE(r13);					   \
279	std	r3,area+EX_R3(r13);					   \
280	addi	r3,r13,area;		/* r3 -> where regs are saved*/	   \
281	RESTORE_CTR(r1, area);						   \
282	b	bad_stack;						   \
2833:	std	r9,_CCR(r1);		/* save CR in stackframe	*/ \
284	std	r11,_NIP(r1);		/* save SRR0 in stackframe	*/ \
285	std	r12,_MSR(r1);		/* save SRR1 in stackframe	*/ \
286	std	r10,0(r1);		/* make stack chain pointer	*/ \
287	std	r0,GPR0(r1);		/* save r0 in stackframe	*/ \
288	std	r10,GPR1(r1);		/* save r1 in stackframe	*/ \
289	beq	4f;			/* if from kernel mode		*/ \
290	ACCOUNT_CPU_USER_ENTRY(r9, r10);				   \
291	SAVE_PPR(area, r9, r10);					   \
2924:	EXCEPTION_PROLOG_COMMON_2(area)					   \
293	EXCEPTION_PROLOG_COMMON_3(n)					   \
294	ACCOUNT_STOLEN_TIME
295
296/* Save original regs values from save area to stack frame. */
297#define EXCEPTION_PROLOG_COMMON_2(area)					   \
298	ld	r9,area+EX_R9(r13);	/* move r9, r10 to stackframe	*/ \
299	ld	r10,area+EX_R10(r13);					   \
300	std	r9,GPR9(r1);						   \
301	std	r10,GPR10(r1);						   \
302	ld	r9,area+EX_R11(r13);	/* move r11 - r13 to stackframe	*/ \
303	ld	r10,area+EX_R12(r13);					   \
304	ld	r11,area+EX_R13(r13);					   \
305	std	r9,GPR11(r1);						   \
306	std	r10,GPR12(r1);						   \
307	std	r11,GPR13(r1);						   \
308	BEGIN_FTR_SECTION_NESTED(66);					   \
309	ld	r10,area+EX_CFAR(r13);					   \
310	std	r10,ORIG_GPR3(r1);					   \
311	END_FTR_SECTION_NESTED(CPU_FTR_CFAR, CPU_FTR_CFAR, 66);		   \
312	GET_CTR(r10, area);						   \
313	std	r10,_CTR(r1);
314
315#define EXCEPTION_PROLOG_COMMON_3(n)					   \
316	std	r2,GPR2(r1);		/* save r2 in stackframe	*/ \
317	SAVE_4GPRS(3, r1);		/* save r3 - r6 in stackframe   */ \
318	SAVE_2GPRS(7, r1);		/* save r7, r8 in stackframe	*/ \
319	mflr	r9;			/* Get LR, later save to stack	*/ \
320	ld	r2,PACATOC(r13);	/* get kernel TOC into r2	*/ \
321	std	r9,_LINK(r1);						   \
322	lbz	r10,PACASOFTIRQEN(r13);				   \
323	mfspr	r11,SPRN_XER;		/* save XER in stackframe	*/ \
324	std	r10,SOFTE(r1);						   \
325	std	r11,_XER(r1);						   \
326	li	r9,(n)+1;						   \
327	std	r9,_TRAP(r1);		/* set trap number		*/ \
328	li	r10,0;							   \
329	ld	r11,exception_marker@toc(r2);				   \
330	std	r10,RESULT(r1);		/* clear regs->result		*/ \
331	std	r11,STACK_FRAME_OVERHEAD-16(r1); /* mark the frame	*/
332
333/*
334 * Exception vectors.
335 */
336#define STD_EXCEPTION_PSERIES(vec, label)		\
337	. = vec;					\
338	.globl label##_pSeries;				\
339label##_pSeries:					\
340	SET_SCRATCH0(r13);		/* save r13 */		\
341	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common,	\
342				 EXC_STD, KVMTEST, vec)
343
344/* Version of above for when we have to branch out-of-line */
345#define STD_EXCEPTION_PSERIES_OOL(vec, label)			\
346	.globl label##_pSeries;					\
347label##_pSeries:						\
348	EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST, vec);	\
349	EXCEPTION_PROLOG_PSERIES_1(label##_common, EXC_STD)
350
351#define STD_EXCEPTION_HV(loc, vec, label)		\
352	. = loc;					\
353	.globl label##_hv;				\
354label##_hv:						\
355	SET_SCRATCH0(r13);	/* save r13 */			\
356	EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common,	\
357				 EXC_HV, KVMTEST, vec)
358
359/* Version of above for when we have to branch out-of-line */
360#define STD_EXCEPTION_HV_OOL(vec, label)		\
361	.globl label##_hv;				\
362label##_hv:						\
363	EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST, vec);	\
364	EXCEPTION_PROLOG_PSERIES_1(label##_common, EXC_HV)
365
366#define STD_RELON_EXCEPTION_PSERIES(loc, vec, label)	\
367	. = loc;					\
368	.globl label##_relon_pSeries;			\
369label##_relon_pSeries:					\
370	/* No guest interrupts come through here */	\
371	SET_SCRATCH0(r13);		/* save r13 */	\
372	EXCEPTION_RELON_PROLOG_PSERIES(PACA_EXGEN, label##_common, \
373				       EXC_STD, NOTEST, vec)
374
375#define STD_RELON_EXCEPTION_PSERIES_OOL(vec, label)		\
376	.globl label##_relon_pSeries;				\
377label##_relon_pSeries:						\
378	EXCEPTION_PROLOG_1(PACA_EXGEN, NOTEST, vec);		\
379	EXCEPTION_RELON_PROLOG_PSERIES_1(label##_common, EXC_STD)
380
381#define STD_RELON_EXCEPTION_HV(loc, vec, label)		\
382	. = loc;					\
383	.globl label##_relon_hv;			\
384label##_relon_hv:					\
385	/* No guest interrupts come through here */	\
386	SET_SCRATCH0(r13);	/* save r13 */		\
387	EXCEPTION_RELON_PROLOG_PSERIES(PACA_EXGEN, label##_common, \
388				       EXC_HV, NOTEST, vec)
389
390#define STD_RELON_EXCEPTION_HV_OOL(vec, label)			\
391	.globl label##_relon_hv;				\
392label##_relon_hv:						\
393	EXCEPTION_PROLOG_1(PACA_EXGEN, NOTEST, vec);		\
394	EXCEPTION_RELON_PROLOG_PSERIES_1(label##_common, EXC_HV)
395
396/* This associate vector numbers with bits in paca->irq_happened */
397#define SOFTEN_VALUE_0x500	PACA_IRQ_EE
398#define SOFTEN_VALUE_0x502	PACA_IRQ_EE
399#define SOFTEN_VALUE_0x900	PACA_IRQ_DEC
400#define SOFTEN_VALUE_0x982	PACA_IRQ_DEC
401#define SOFTEN_VALUE_0xa00	PACA_IRQ_DBELL
402#define SOFTEN_VALUE_0xe80	PACA_IRQ_DBELL
403#define SOFTEN_VALUE_0xe82	PACA_IRQ_DBELL
404#define SOFTEN_VALUE_0xe60	PACA_IRQ_HMI
405#define SOFTEN_VALUE_0xe62	PACA_IRQ_HMI
406
407#define __SOFTEN_TEST(h, vec)						\
408	lbz	r10,PACASOFTIRQEN(r13);					\
409	cmpwi	r10,0;							\
410	li	r10,SOFTEN_VALUE_##vec;					\
411	beq	masked_##h##interrupt
412#define _SOFTEN_TEST(h, vec)	__SOFTEN_TEST(h, vec)
413
414#define SOFTEN_TEST_PR(vec)						\
415	KVMTEST(vec);							\
416	_SOFTEN_TEST(EXC_STD, vec)
417
418#define SOFTEN_TEST_HV(vec)						\
419	KVMTEST(vec);							\
420	_SOFTEN_TEST(EXC_HV, vec)
421
422#define SOFTEN_NOTEST_PR(vec)		_SOFTEN_TEST(EXC_STD, vec)
423#define SOFTEN_NOTEST_HV(vec)		_SOFTEN_TEST(EXC_HV, vec)
424
425#define __MASKABLE_EXCEPTION_PSERIES(vec, label, h, extra)		\
426	SET_SCRATCH0(r13);    /* save r13 */				\
427	EXCEPTION_PROLOG_0(PACA_EXGEN);					\
428	__EXCEPTION_PROLOG_1(PACA_EXGEN, extra, vec);			\
429	EXCEPTION_PROLOG_PSERIES_1(label##_common, h);
430
431#define _MASKABLE_EXCEPTION_PSERIES(vec, label, h, extra)		\
432	__MASKABLE_EXCEPTION_PSERIES(vec, label, h, extra)
433
434#define MASKABLE_EXCEPTION_PSERIES(loc, vec, label)			\
435	. = loc;							\
436	.globl label##_pSeries;						\
437label##_pSeries:							\
438	_MASKABLE_EXCEPTION_PSERIES(vec, label,				\
439				    EXC_STD, SOFTEN_TEST_PR)
440
441#define MASKABLE_EXCEPTION_HV(loc, vec, label)				\
442	. = loc;							\
443	.globl label##_hv;						\
444label##_hv:								\
445	_MASKABLE_EXCEPTION_PSERIES(vec, label,				\
446				    EXC_HV, SOFTEN_TEST_HV)
447
448#define MASKABLE_EXCEPTION_HV_OOL(vec, label)				\
449	.globl label##_hv;						\
450label##_hv:								\
451	EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_TEST_HV, vec);		\
452	EXCEPTION_PROLOG_PSERIES_1(label##_common, EXC_HV);
453
454#define __MASKABLE_RELON_EXCEPTION_PSERIES(vec, label, h, extra)	\
455	SET_SCRATCH0(r13);    /* save r13 */				\
456	EXCEPTION_PROLOG_0(PACA_EXGEN);					\
457	__EXCEPTION_PROLOG_1(PACA_EXGEN, extra, vec);		\
458	EXCEPTION_RELON_PROLOG_PSERIES_1(label##_common, h);
459#define _MASKABLE_RELON_EXCEPTION_PSERIES(vec, label, h, extra)	\
460	__MASKABLE_RELON_EXCEPTION_PSERIES(vec, label, h, extra)
461
462#define MASKABLE_RELON_EXCEPTION_PSERIES(loc, vec, label)		\
463	. = loc;							\
464	.globl label##_relon_pSeries;					\
465label##_relon_pSeries:							\
466	_MASKABLE_RELON_EXCEPTION_PSERIES(vec, label,			\
467					  EXC_STD, SOFTEN_NOTEST_PR)
468
469#define MASKABLE_RELON_EXCEPTION_HV(loc, vec, label)			\
470	. = loc;							\
471	.globl label##_relon_hv;					\
472label##_relon_hv:							\
473	_MASKABLE_RELON_EXCEPTION_PSERIES(vec, label,			\
474					  EXC_HV, SOFTEN_NOTEST_HV)
475
476#define MASKABLE_RELON_EXCEPTION_HV_OOL(vec, label)			\
477	.globl label##_relon_hv;					\
478label##_relon_hv:							\
479	EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_NOTEST_HV, vec);		\
480	EXCEPTION_PROLOG_PSERIES_1(label##_common, EXC_HV);
481
482/*
483 * Our exception common code can be passed various "additions"
484 * to specify the behaviour of interrupts, whether to kick the
485 * runlatch, etc...
486 */
487
488/*
489 * This addition reconciles our actual IRQ state with the various software
490 * flags that track it. This may call C code.
491 */
492#define ADD_RECONCILE	RECONCILE_IRQ_STATE(r10,r11)
493
494#define ADD_NVGPRS				\
495	bl	save_nvgprs
496
497#define RUNLATCH_ON				\
498BEGIN_FTR_SECTION				\
499	CURRENT_THREAD_INFO(r3, r1);		\
500	ld	r4,TI_LOCAL_FLAGS(r3);		\
501	andi.	r0,r4,_TLF_RUNLATCH;		\
502	beql	ppc64_runlatch_on_trampoline;	\
503END_FTR_SECTION_IFSET(CPU_FTR_CTRL)
504
505#define EXCEPTION_COMMON(trap, label, hdlr, ret, additions)	\
506	.align	7;						\
507	.globl label##_common;					\
508label##_common:							\
509	EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN);		\
510	/* Volatile regs are potentially clobbered here */	\
511	additions;						\
512	addi	r3,r1,STACK_FRAME_OVERHEAD;			\
513	bl	hdlr;						\
514	b	ret
515
516#define STD_EXCEPTION_COMMON(trap, label, hdlr)			\
517	EXCEPTION_COMMON(trap, label, hdlr, ret_from_except,	\
518			 ADD_NVGPRS;ADD_RECONCILE)
519
520/*
521 * Like STD_EXCEPTION_COMMON, but for exceptions that can occur
522 * in the idle task and therefore need the special idle handling
523 * (finish nap and runlatch)
524 */
525#define STD_EXCEPTION_COMMON_ASYNC(trap, label, hdlr)		  \
526	EXCEPTION_COMMON(trap, label, hdlr, ret_from_except_lite, \
527			 FINISH_NAP;ADD_RECONCILE;RUNLATCH_ON)
528
529/*
530 * When the idle code in power4_idle puts the CPU into NAP mode,
531 * it has to do so in a loop, and relies on the external interrupt
532 * and decrementer interrupt entry code to get it out of the loop.
533 * It sets the _TLF_NAPPING bit in current_thread_info()->local_flags
534 * to signal that it is in the loop and needs help to get out.
535 */
536#ifdef CONFIG_PPC_970_NAP
537#define FINISH_NAP				\
538BEGIN_FTR_SECTION				\
539	CURRENT_THREAD_INFO(r11, r1);		\
540	ld	r9,TI_LOCAL_FLAGS(r11);		\
541	andi.	r10,r9,_TLF_NAPPING;		\
542	bnel	power4_fixup_nap;		\
543END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
544#else
545#define FINISH_NAP
546#endif
547
548#endif	/* _ASM_POWERPC_EXCEPTION_H */
v5.4
  1/* SPDX-License-Identifier: GPL-2.0-or-later */
  2#ifndef _ASM_POWERPC_EXCEPTION_H
  3#define _ASM_POWERPC_EXCEPTION_H
  4/*
  5 * Extracted from head_64.S
  6 *
  7 *  PowerPC version
  8 *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
  9 *
 10 *  Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP
 11 *    Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu>
 12 *  Adapted for Power Macintosh by Paul Mackerras.
 13 *  Low-level exception handlers and MMU support
 14 *  rewritten by Paul Mackerras.
 15 *    Copyright (C) 1996 Paul Mackerras.
 16 *
 17 *  Adapted for 64bit PowerPC by Dave Engebretsen, Peter Bergner, and
 18 *    Mike Corrigan {engebret|bergner|mikejc}@us.ibm.com
 19 *
 20 *  This file contains the low-level support and setup for the
 21 *  PowerPC-64 platform, including trap and interrupt dispatch.
 
 
 
 
 
 22 */
 23/*
 24 * The following macros define the code that appears as
 25 * the prologue to each of the exception handlers.  They
 26 * are split into two parts to allow a single kernel binary
 27 * to be used for pSeries and iSeries.
 28 *
 29 * We make as much of the exception code common between native
 30 * exception handlers (including pSeries LPAR) and iSeries LPAR
 31 * implementations as possible.
 32 */
 33#include <asm/feature-fixups.h>
 34
 35/* PACA save area size in u64 units (exgen, exmc, etc) */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 36#if defined(CONFIG_RELOCATABLE)
 37#define EX_SIZE		10
 
 
 
 
 
 
 
 38#else
 39#define EX_SIZE		9
 
 
 
 40#endif
 41
 42/*
 43 * maximum recursive depth of MCE exceptions
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 44 */
 45#define MAX_MCE_DEPTH	4
 
 
 
 46
 47#ifdef __ASSEMBLY__
 
 
 
 
 
 
 48
 49#define STF_ENTRY_BARRIER_SLOT						\
 50	STF_ENTRY_BARRIER_FIXUP_SECTION;				\
 51	nop;								\
 52	nop;								\
 53	nop
 54
 55#define STF_EXIT_BARRIER_SLOT						\
 56	STF_EXIT_BARRIER_FIXUP_SECTION;					\
 57	nop;								\
 58	nop;								\
 59	nop;								\
 60	nop;								\
 61	nop;								\
 62	nop
 63
 64/*
 65 * r10 must be free to use, r13 must be paca
 66 */
 67#define INTERRUPT_TO_KERNEL						\
 68	STF_ENTRY_BARRIER_SLOT
 69
 70/*
 71 * Macros for annotating the expected destination of (h)rfid
 72 *
 73 * The nop instructions allow us to insert one or more instructions to flush the
 74 * L1-D cache when returning to userspace or a guest.
 75 */
 76#define RFI_FLUSH_SLOT							\
 77	RFI_FLUSH_FIXUP_SECTION;					\
 78	nop;								\
 79	nop;								\
 80	nop
 81
 82#define RFI_TO_KERNEL							\
 83	rfid
 84
 85#define RFI_TO_USER							\
 86	STF_EXIT_BARRIER_SLOT;						\
 87	RFI_FLUSH_SLOT;							\
 88	rfid;								\
 89	b	rfi_flush_fallback
 90
 91#define RFI_TO_USER_OR_KERNEL						\
 92	STF_EXIT_BARRIER_SLOT;						\
 93	RFI_FLUSH_SLOT;							\
 94	rfid;								\
 95	b	rfi_flush_fallback
 96
 97#define RFI_TO_GUEST							\
 98	STF_EXIT_BARRIER_SLOT;						\
 99	RFI_FLUSH_SLOT;							\
100	rfid;								\
101	b	rfi_flush_fallback
102
103#define HRFI_TO_KERNEL							\
104	hrfid
105
106#define HRFI_TO_USER							\
107	STF_EXIT_BARRIER_SLOT;						\
108	RFI_FLUSH_SLOT;							\
109	hrfid;								\
110	b	hrfi_flush_fallback
111
112#define HRFI_TO_USER_OR_KERNEL						\
113	STF_EXIT_BARRIER_SLOT;						\
114	RFI_FLUSH_SLOT;							\
115	hrfid;								\
116	b	hrfi_flush_fallback
117
118#define HRFI_TO_GUEST							\
119	STF_EXIT_BARRIER_SLOT;						\
120	RFI_FLUSH_SLOT;							\
121	hrfid;								\
122	b	hrfi_flush_fallback
123
124#define HRFI_TO_UNKNOWN							\
125	STF_EXIT_BARRIER_SLOT;						\
126	RFI_FLUSH_SLOT;							\
127	hrfid;								\
128	b	hrfi_flush_fallback
129
130#endif /* __ASSEMBLY__ */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
132#endif	/* _ASM_POWERPC_EXCEPTION_H */