cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

exceptions-64e.S (43055B)


      1/* SPDX-License-Identifier: GPL-2.0-or-later */
      2/*
      3 *  Boot code and exception vectors for Book3E processors
      4 *
      5 *  Copyright (C) 2007 Ben. Herrenschmidt (benh@kernel.crashing.org), IBM Corp.
      6 */
      7
      8#include <linux/threads.h>
      9#include <asm/reg.h>
     10#include <asm/page.h>
     11#include <asm/ppc_asm.h>
     12#include <asm/asm-offsets.h>
     13#include <asm/cputable.h>
     14#include <asm/setup.h>
     15#include <asm/thread_info.h>
     16#include <asm/reg_a2.h>
     17#include <asm/exception-64e.h>
     18#include <asm/bug.h>
     19#include <asm/irqflags.h>
     20#include <asm/ptrace.h>
     21#include <asm/ppc-opcode.h>
     22#include <asm/mmu.h>
     23#include <asm/hw_irq.h>
     24#include <asm/kvm_asm.h>
     25#include <asm/kvm_booke_hv_asm.h>
     26#include <asm/feature-fixups.h>
     27#include <asm/context_tracking.h>
     28
     29/* 64e interrupt returns always use SRR registers */
     30#define fast_interrupt_return fast_interrupt_return_srr
     31#define interrupt_return interrupt_return_srr
     32
     33/* XXX This will ultimately add space for a special exception save
     34 *     structure used to save things like SRR0/SRR1, SPRGs, MAS, etc...
     35 *     when taking special interrupts. For now we don't support that,
     36 *     special interrupts from within a non-standard level will probably
     37 *     blow you up
     38 */
     39#define SPECIAL_EXC_SRR0	0
     40#define SPECIAL_EXC_SRR1	1
     41#define SPECIAL_EXC_SPRG_GEN	2
     42#define SPECIAL_EXC_SPRG_TLB	3
     43#define SPECIAL_EXC_MAS0	4
     44#define SPECIAL_EXC_MAS1	5
     45#define SPECIAL_EXC_MAS2	6
     46#define SPECIAL_EXC_MAS3	7
     47#define SPECIAL_EXC_MAS6	8
     48#define SPECIAL_EXC_MAS7	9
     49#define SPECIAL_EXC_MAS5	10	/* E.HV only */
     50#define SPECIAL_EXC_MAS8	11	/* E.HV only */
     51#define SPECIAL_EXC_IRQHAPPENED	12
     52#define SPECIAL_EXC_DEAR	13
     53#define SPECIAL_EXC_ESR		14
     54#define SPECIAL_EXC_SOFTE	15
     55#define SPECIAL_EXC_CSRR0	16
     56#define SPECIAL_EXC_CSRR1	17
     57/* must be even to keep 16-byte stack alignment */
     58#define SPECIAL_EXC_END		18
     59
     60#define SPECIAL_EXC_FRAME_SIZE	(INT_FRAME_SIZE + SPECIAL_EXC_END * 8)
     61#define SPECIAL_EXC_FRAME_OFFS  (INT_FRAME_SIZE - 288)
     62
     63#define SPECIAL_EXC_STORE(reg, name) \
     64	std	reg, (SPECIAL_EXC_##name * 8 + SPECIAL_EXC_FRAME_OFFS)(r1)
     65
     66#define SPECIAL_EXC_LOAD(reg, name) \
     67	ld	reg, (SPECIAL_EXC_##name * 8 + SPECIAL_EXC_FRAME_OFFS)(r1)
     68
     69special_reg_save:
     70	/*
     71	 * We only need (or have stack space) to save this stuff if
     72	 * we interrupted the kernel.
     73	 */
     74	ld	r3,_MSR(r1)
     75	andi.	r3,r3,MSR_PR
     76	bnelr
     77
     78	/*
     79	 * Advance to the next TLB exception frame for handler
     80	 * types that don't do it automatically.
     81	 */
     82	LOAD_REG_ADDR(r11,extlb_level_exc)
     83	lwz	r12,0(r11)
     84	mfspr	r10,SPRN_SPRG_TLB_EXFRAME
     85	add	r10,r10,r12
     86	mtspr	SPRN_SPRG_TLB_EXFRAME,r10
     87
     88	/*
     89	 * Save registers needed to allow nesting of certain exceptions
     90	 * (such as TLB misses) inside special exception levels
     91	 */
     92	mfspr	r10,SPRN_SRR0
     93	SPECIAL_EXC_STORE(r10,SRR0)
     94	mfspr	r10,SPRN_SRR1
     95	SPECIAL_EXC_STORE(r10,SRR1)
     96	mfspr	r10,SPRN_SPRG_GEN_SCRATCH
     97	SPECIAL_EXC_STORE(r10,SPRG_GEN)
     98	mfspr	r10,SPRN_SPRG_TLB_SCRATCH
     99	SPECIAL_EXC_STORE(r10,SPRG_TLB)
    100	mfspr	r10,SPRN_MAS0
    101	SPECIAL_EXC_STORE(r10,MAS0)
    102	mfspr	r10,SPRN_MAS1
    103	SPECIAL_EXC_STORE(r10,MAS1)
    104	mfspr	r10,SPRN_MAS2
    105	SPECIAL_EXC_STORE(r10,MAS2)
    106	mfspr	r10,SPRN_MAS3
    107	SPECIAL_EXC_STORE(r10,MAS3)
    108	mfspr	r10,SPRN_MAS6
    109	SPECIAL_EXC_STORE(r10,MAS6)
    110	mfspr	r10,SPRN_MAS7
    111	SPECIAL_EXC_STORE(r10,MAS7)
    112BEGIN_FTR_SECTION
    113	mfspr	r10,SPRN_MAS5
    114	SPECIAL_EXC_STORE(r10,MAS5)
    115	mfspr	r10,SPRN_MAS8
    116	SPECIAL_EXC_STORE(r10,MAS8)
    117
    118	/* MAS5/8 could have inappropriate values if we interrupted KVM code */
    119	li	r10,0
    120	mtspr	SPRN_MAS5,r10
    121	mtspr	SPRN_MAS8,r10
    122END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV)
    123	mfspr	r10,SPRN_DEAR
    124	SPECIAL_EXC_STORE(r10,DEAR)
    125	mfspr	r10,SPRN_ESR
    126	SPECIAL_EXC_STORE(r10,ESR)
    127
    128	ld	r10,_NIP(r1)
    129	SPECIAL_EXC_STORE(r10,CSRR0)
    130	ld	r10,_MSR(r1)
    131	SPECIAL_EXC_STORE(r10,CSRR1)
    132
    133	blr
    134
    135ret_from_level_except:
    136	ld	r3,_MSR(r1)
    137	andi.	r3,r3,MSR_PR
    138	beq	1f
    139	REST_NVGPRS(r1)
    140	b	interrupt_return
    1411:
    142
    143	LOAD_REG_ADDR(r11,extlb_level_exc)
    144	lwz	r12,0(r11)
    145	mfspr	r10,SPRN_SPRG_TLB_EXFRAME
    146	sub	r10,r10,r12
    147	mtspr	SPRN_SPRG_TLB_EXFRAME,r10
    148
    149	/*
    150	 * It's possible that the special level exception interrupted a
    151	 * TLB miss handler, and inserted the same entry that the
    152	 * interrupted handler was about to insert.  On CPUs without TLB
    153	 * write conditional, this can result in a duplicate TLB entry.
    154	 * Wipe all non-bolted entries to be safe.
    155	 *
    156	 * Note that this doesn't protect against any TLB misses
    157	 * we may take accessing the stack from here to the end of
    158	 * the special level exception.  It's not clear how we can
    159	 * reasonably protect against that, but only CPUs with
    160	 * neither TLB write conditional nor bolted kernel memory
    161	 * are affected.  Do any such CPUs even exist?
    162	 */
    163	PPC_TLBILX_ALL(0,R0)
    164
    165	REST_NVGPRS(r1)
    166
    167	SPECIAL_EXC_LOAD(r10,SRR0)
    168	mtspr	SPRN_SRR0,r10
    169	SPECIAL_EXC_LOAD(r10,SRR1)
    170	mtspr	SPRN_SRR1,r10
    171	SPECIAL_EXC_LOAD(r10,SPRG_GEN)
    172	mtspr	SPRN_SPRG_GEN_SCRATCH,r10
    173	SPECIAL_EXC_LOAD(r10,SPRG_TLB)
    174	mtspr	SPRN_SPRG_TLB_SCRATCH,r10
    175	SPECIAL_EXC_LOAD(r10,MAS0)
    176	mtspr	SPRN_MAS0,r10
    177	SPECIAL_EXC_LOAD(r10,MAS1)
    178	mtspr	SPRN_MAS1,r10
    179	SPECIAL_EXC_LOAD(r10,MAS2)
    180	mtspr	SPRN_MAS2,r10
    181	SPECIAL_EXC_LOAD(r10,MAS3)
    182	mtspr	SPRN_MAS3,r10
    183	SPECIAL_EXC_LOAD(r10,MAS6)
    184	mtspr	SPRN_MAS6,r10
    185	SPECIAL_EXC_LOAD(r10,MAS7)
    186	mtspr	SPRN_MAS7,r10
    187BEGIN_FTR_SECTION
    188	SPECIAL_EXC_LOAD(r10,MAS5)
    189	mtspr	SPRN_MAS5,r10
    190	SPECIAL_EXC_LOAD(r10,MAS8)
    191	mtspr	SPRN_MAS8,r10
    192END_FTR_SECTION_IFSET(CPU_FTR_EMB_HV)
    193
    194	SPECIAL_EXC_LOAD(r10,DEAR)
    195	mtspr	SPRN_DEAR,r10
    196	SPECIAL_EXC_LOAD(r10,ESR)
    197	mtspr	SPRN_ESR,r10
    198
    199	stdcx.	r0,0,r1		/* to clear the reservation */
    200
    201	REST_GPRS(2, 9, r1)
    202
    203	ld	r10,_CTR(r1)
    204	ld	r11,_XER(r1)
    205	mtctr	r10
    206	mtxer	r11
    207
    208	blr
    209
    210.macro ret_from_level srr0 srr1 paca_ex scratch
    211	bl	ret_from_level_except
    212
    213	ld	r10,_LINK(r1)
    214	ld	r11,_CCR(r1)
    215	ld	r0,GPR13(r1)
    216	mtlr	r10
    217	mtcr	r11
    218
    219	ld	r10,GPR10(r1)
    220	ld	r11,GPR11(r1)
    221	ld	r12,GPR12(r1)
    222	mtspr	\scratch,r0
    223
    224	std	r10,\paca_ex+EX_R10(r13);
    225	std	r11,\paca_ex+EX_R11(r13);
    226	ld	r10,_NIP(r1)
    227	ld	r11,_MSR(r1)
    228	ld	r0,GPR0(r1)
    229	ld	r1,GPR1(r1)
    230	mtspr	\srr0,r10
    231	mtspr	\srr1,r11
    232	ld	r10,\paca_ex+EX_R10(r13)
    233	ld	r11,\paca_ex+EX_R11(r13)
    234	mfspr	r13,\scratch
    235.endm
    236
    237ret_from_crit_except:
    238	ret_from_level SPRN_CSRR0 SPRN_CSRR1 PACA_EXCRIT SPRN_SPRG_CRIT_SCRATCH
    239	rfci
    240
    241ret_from_mc_except:
    242	ret_from_level SPRN_MCSRR0 SPRN_MCSRR1 PACA_EXMC SPRN_SPRG_MC_SCRATCH
    243	rfmci
    244
    245/* Exception prolog code for all exceptions */
    246#define EXCEPTION_PROLOG(n, intnum, type, addition)	    		    \
    247	mtspr	SPRN_SPRG_##type##_SCRATCH,r13;	/* get spare registers */   \
    248	mfspr	r13,SPRN_SPRG_PACA;	/* get PACA */			    \
    249	std	r10,PACA_EX##type+EX_R10(r13);				    \
    250	std	r11,PACA_EX##type+EX_R11(r13);				    \
    251	mfcr	r10;			/* save CR */			    \
    252	mfspr	r11,SPRN_##type##_SRR1;/* what are we coming from */	    \
    253	DO_KVM	intnum,SPRN_##type##_SRR1;    /* KVM hook */		    \
    254	stw	r10,PACA_EX##type+EX_CR(r13); /* save old CR in the PACA */ \
    255	addition;			/* additional code for that exc. */ \
    256	std	r1,PACA_EX##type+EX_R1(r13); /* save old r1 in the PACA */  \
    257	type##_SET_KSTACK;		/* get special stack if necessary */\
    258	andi.	r10,r11,MSR_PR;		/* save stack pointer */	    \
    259	beq	1f;			/* branch around if supervisor */   \
    260	ld	r1,PACAKSAVE(r13);	/* get kernel stack coming from usr */\
    2611:	type##_BTB_FLUSH		\
    262	cmpdi	cr1,r1,0;		/* check if SP makes sense */	    \
    263	bge-	cr1,exc_##n##_bad_stack;/* bad stack (TODO: out of line) */ \
    264	mfspr	r10,SPRN_##type##_SRR0;	/* read SRR0 before touching stack */
    265
    266/* Exception type-specific macros */
    267#define	GEN_SET_KSTACK							    \
    268	subi	r1,r1,INT_FRAME_SIZE;	/* alloc frame on kernel stack */
    269#define SPRN_GEN_SRR0	SPRN_SRR0
    270#define SPRN_GEN_SRR1	SPRN_SRR1
    271
    272#define	GDBELL_SET_KSTACK	GEN_SET_KSTACK
    273#define SPRN_GDBELL_SRR0	SPRN_GSRR0
    274#define SPRN_GDBELL_SRR1	SPRN_GSRR1
    275
    276#define CRIT_SET_KSTACK						            \
    277	ld	r1,PACA_CRIT_STACK(r13);				    \
    278	subi	r1,r1,SPECIAL_EXC_FRAME_SIZE
    279#define SPRN_CRIT_SRR0	SPRN_CSRR0
    280#define SPRN_CRIT_SRR1	SPRN_CSRR1
    281
    282#define DBG_SET_KSTACK						            \
    283	ld	r1,PACA_DBG_STACK(r13);					    \
    284	subi	r1,r1,SPECIAL_EXC_FRAME_SIZE
    285#define SPRN_DBG_SRR0	SPRN_DSRR0
    286#define SPRN_DBG_SRR1	SPRN_DSRR1
    287
    288#define MC_SET_KSTACK						            \
    289	ld	r1,PACA_MC_STACK(r13);					    \
    290	subi	r1,r1,SPECIAL_EXC_FRAME_SIZE
    291#define SPRN_MC_SRR0	SPRN_MCSRR0
    292#define SPRN_MC_SRR1	SPRN_MCSRR1
    293
    294#ifdef CONFIG_PPC_FSL_BOOK3E
    295#define GEN_BTB_FLUSH			\
    296	START_BTB_FLUSH_SECTION		\
    297		beq 1f;			\
    298		BTB_FLUSH(r10)			\
    299		1:		\
    300	END_BTB_FLUSH_SECTION
    301
    302#define CRIT_BTB_FLUSH			\
    303	START_BTB_FLUSH_SECTION		\
    304		BTB_FLUSH(r10)		\
    305	END_BTB_FLUSH_SECTION
    306
    307#define DBG_BTB_FLUSH CRIT_BTB_FLUSH
    308#define MC_BTB_FLUSH CRIT_BTB_FLUSH
    309#define GDBELL_BTB_FLUSH GEN_BTB_FLUSH
    310#else
    311#define GEN_BTB_FLUSH
    312#define CRIT_BTB_FLUSH
    313#define DBG_BTB_FLUSH
    314#define MC_BTB_FLUSH
    315#define GDBELL_BTB_FLUSH
    316#endif
    317
    318#define NORMAL_EXCEPTION_PROLOG(n, intnum, addition)			    \
    319	EXCEPTION_PROLOG(n, intnum, GEN, addition##_GEN(n))
    320
    321#define CRIT_EXCEPTION_PROLOG(n, intnum, addition)			    \
    322	EXCEPTION_PROLOG(n, intnum, CRIT, addition##_CRIT(n))
    323
    324#define DBG_EXCEPTION_PROLOG(n, intnum, addition)			    \
    325	EXCEPTION_PROLOG(n, intnum, DBG, addition##_DBG(n))
    326
    327#define MC_EXCEPTION_PROLOG(n, intnum, addition)			    \
    328	EXCEPTION_PROLOG(n, intnum, MC, addition##_MC(n))
    329
    330#define GDBELL_EXCEPTION_PROLOG(n, intnum, addition)			    \
    331	EXCEPTION_PROLOG(n, intnum, GDBELL, addition##_GDBELL(n))
    332
    333/* Variants of the "addition" argument for the prolog
    334 */
    335#define PROLOG_ADDITION_NONE_GEN(n)
    336#define PROLOG_ADDITION_NONE_GDBELL(n)
    337#define PROLOG_ADDITION_NONE_CRIT(n)
    338#define PROLOG_ADDITION_NONE_DBG(n)
    339#define PROLOG_ADDITION_NONE_MC(n)
    340
    341#define PROLOG_ADDITION_MASKABLE_GEN(n)					    \
    342	lbz	r10,PACAIRQSOFTMASK(r13);	/* are irqs soft-masked? */ \
    343	andi.	r10,r10,IRQS_DISABLED;	/* yes -> go out of line */ \
    344	bne	masked_interrupt_book3e_##n
    345
    346/*
    347 * Additional regs must be re-loaded from paca before EXCEPTION_COMMON* is
    348 * called, because that does SAVE_NVGPRS which must see the original register
    349 * values, otherwise the scratch values might be restored when exiting the
    350 * interrupt.
    351 */
    352#define PROLOG_ADDITION_2REGS_GEN(n)					    \
    353	std	r14,PACA_EXGEN+EX_R14(r13);				    \
    354	std	r15,PACA_EXGEN+EX_R15(r13)
    355
    356#define PROLOG_ADDITION_1REG_GEN(n)					    \
    357	std	r14,PACA_EXGEN+EX_R14(r13);
    358
    359#define PROLOG_ADDITION_2REGS_CRIT(n)					    \
    360	std	r14,PACA_EXCRIT+EX_R14(r13);				    \
    361	std	r15,PACA_EXCRIT+EX_R15(r13)
    362
    363#define PROLOG_ADDITION_2REGS_DBG(n)					    \
    364	std	r14,PACA_EXDBG+EX_R14(r13);				    \
    365	std	r15,PACA_EXDBG+EX_R15(r13)
    366
    367#define PROLOG_ADDITION_2REGS_MC(n)					    \
    368	std	r14,PACA_EXMC+EX_R14(r13);				    \
    369	std	r15,PACA_EXMC+EX_R15(r13)
    370
    371
    372/* Core exception code for all exceptions except TLB misses. */
    373#define EXCEPTION_COMMON_LVL(n, scratch, excf)				    \
    374exc_##n##_common:							    \
    375	std	r0,GPR0(r1);		/* save r0 in stackframe */	    \
    376	std	r2,GPR2(r1);		/* save r2 in stackframe */	    \
    377	SAVE_GPRS(3, 9, r1);		/* save r3 - r9 in stackframe */    \
    378	std	r10,_NIP(r1);		/* save SRR0 to stackframe */	    \
    379	std	r11,_MSR(r1);		/* save SRR1 to stackframe */	    \
    380	beq	2f;			/* if from kernel mode */	    \
    3812:	ld	r3,excf+EX_R10(r13);	/* get back r10 */		    \
    382	ld	r4,excf+EX_R11(r13);	/* get back r11 */		    \
    383	mfspr	r5,scratch;		/* get back r13 */		    \
    384	std	r12,GPR12(r1);		/* save r12 in stackframe */	    \
    385	ld	r2,PACATOC(r13);	/* get kernel TOC into r2 */	    \
    386	mflr	r6;			/* save LR in stackframe */	    \
    387	mfctr	r7;			/* save CTR in stackframe */	    \
    388	mfspr	r8,SPRN_XER;		/* save XER in stackframe */	    \
    389	ld	r9,excf+EX_R1(r13);	/* load orig r1 back from PACA */   \
    390	lwz	r10,excf+EX_CR(r13);	/* load orig CR back from PACA	*/  \
    391	lbz	r11,PACAIRQSOFTMASK(r13); /* get current IRQ softe */	    \
    392	ld	r12,exception_marker@toc(r2);				    \
    393	li	r0,0;							    \
    394	std	r3,GPR10(r1);		/* save r10 to stackframe */	    \
    395	std	r4,GPR11(r1);		/* save r11 to stackframe */	    \
    396	std	r5,GPR13(r1);		/* save it to stackframe */	    \
    397	std	r6,_LINK(r1);						    \
    398	std	r7,_CTR(r1);						    \
    399	std	r8,_XER(r1);						    \
    400	li	r3,(n);			/* regs.trap vector */		    \
    401	std	r9,0(r1);		/* store stack frame back link */   \
    402	std	r10,_CCR(r1);		/* store orig CR in stackframe */   \
    403	std	r9,GPR1(r1);		/* store stack frame back link */   \
    404	std	r11,SOFTE(r1);		/* and save it to stackframe */     \
    405	std	r12,STACK_FRAME_OVERHEAD-16(r1); /* mark the frame */	    \
    406	std	r3,_TRAP(r1);		/* set trap number		*/  \
    407	std	r0,RESULT(r1);		/* clear regs->result */	    \
    408	SAVE_NVGPRS(r1);
    409
    410#define EXCEPTION_COMMON(n) \
    411	EXCEPTION_COMMON_LVL(n, SPRN_SPRG_GEN_SCRATCH, PACA_EXGEN)
    412#define EXCEPTION_COMMON_CRIT(n) \
    413	EXCEPTION_COMMON_LVL(n, SPRN_SPRG_CRIT_SCRATCH, PACA_EXCRIT)
    414#define EXCEPTION_COMMON_MC(n) \
    415	EXCEPTION_COMMON_LVL(n, SPRN_SPRG_MC_SCRATCH, PACA_EXMC)
    416#define EXCEPTION_COMMON_DBG(n) \
    417	EXCEPTION_COMMON_LVL(n, SPRN_SPRG_DBG_SCRATCH, PACA_EXDBG)
    418
    419/* XXX FIXME: Restore r14/r15 when necessary */
    420#define BAD_STACK_TRAMPOLINE(n)						    \
    421exc_##n##_bad_stack:							    \
    422	li	r1,(n);			/* get exception number */	    \
    423	sth	r1,PACA_TRAP_SAVE(r13);	/* store trap */		    \
    424	b	bad_stack_book3e;	/* bad stack error */
    425
    426/* WARNING: If you change the layout of this stub, make sure you check
    427	*   the debug exception handler which handles single stepping
    428	*   into exceptions from userspace, and the MM code in
    429	*   arch/powerpc/mm/tlb_nohash.c which patches the branch here
    430	*   and would need to be updated if that branch is moved
    431	*/
    432#define	EXCEPTION_STUB(loc, label)					\
    433	. = interrupt_base_book3e + loc;				\
    434	nop;	/* To make debug interrupts happy */			\
    435	b	exc_##label##_book3e;
    436
    437#define ACK_NONE(r)
    438#define ACK_DEC(r)							\
    439	lis	r,TSR_DIS@h;						\
    440	mtspr	SPRN_TSR,r
    441#define ACK_FIT(r)							\
    442	lis	r,TSR_FIS@h;						\
    443	mtspr	SPRN_TSR,r
    444
    445/* Used by asynchronous interrupt that may happen in the idle loop.
    446 *
    447 * This check if the thread was in the idle loop, and if yes, returns
    448 * to the caller rather than the PC. This is to avoid a race if
    449 * interrupts happen before the wait instruction.
    450 */
    451#define CHECK_NAPPING()							\
    452	ld	r11, PACA_THREAD_INFO(r13);				\
    453	ld	r10,TI_LOCAL_FLAGS(r11);				\
    454	andi.	r9,r10,_TLF_NAPPING;					\
    455	beq+	1f;							\
    456	ld	r8,_LINK(r1);						\
    457	rlwinm	r7,r10,0,~_TLF_NAPPING;					\
    458	std	r8,_NIP(r1);						\
    459	std	r7,TI_LOCAL_FLAGS(r11);					\
    4601:
    461
    462
    463#define MASKABLE_EXCEPTION(trapnum, intnum, label, hdlr, ack)		\
    464	START_EXCEPTION(label);						\
    465	NORMAL_EXCEPTION_PROLOG(trapnum, intnum, PROLOG_ADDITION_MASKABLE)\
    466	EXCEPTION_COMMON(trapnum)					\
    467	ack(r8);							\
    468	CHECK_NAPPING();						\
    469	addi	r3,r1,STACK_FRAME_OVERHEAD;				\
    470	bl	hdlr;							\
    471	b	interrupt_return
    472
    473/* This value is used to mark exception frames on the stack. */
    474	.section	".toc","aw"
    475exception_marker:
    476	.tc	ID_EXC_MARKER[TC],STACK_FRAME_REGS_MARKER
    477
    478
    479/*
    480 * And here we have the exception vectors !
    481 */
    482
    483	.text
    484	.balign	0x1000
    485	.globl interrupt_base_book3e
    486interrupt_base_book3e:					/* fake trap */
    487	EXCEPTION_STUB(0x000, machine_check)
    488	EXCEPTION_STUB(0x020, critical_input)		/* 0x0100 */
    489	EXCEPTION_STUB(0x040, debug_crit)		/* 0x0d00 */
    490	EXCEPTION_STUB(0x060, data_storage)		/* 0x0300 */
    491	EXCEPTION_STUB(0x080, instruction_storage)	/* 0x0400 */
    492	EXCEPTION_STUB(0x0a0, external_input)		/* 0x0500 */
    493	EXCEPTION_STUB(0x0c0, alignment)		/* 0x0600 */
    494	EXCEPTION_STUB(0x0e0, program)			/* 0x0700 */
    495	EXCEPTION_STUB(0x100, fp_unavailable)		/* 0x0800 */
    496	EXCEPTION_STUB(0x120, system_call)		/* 0x0c00 */
    497	EXCEPTION_STUB(0x140, ap_unavailable)		/* 0x0f20 */
    498	EXCEPTION_STUB(0x160, decrementer)		/* 0x0900 */
    499	EXCEPTION_STUB(0x180, fixed_interval)		/* 0x0980 */
    500	EXCEPTION_STUB(0x1a0, watchdog)			/* 0x09f0 */
    501	EXCEPTION_STUB(0x1c0, data_tlb_miss)
    502	EXCEPTION_STUB(0x1e0, instruction_tlb_miss)
    503	EXCEPTION_STUB(0x200, altivec_unavailable)
    504	EXCEPTION_STUB(0x220, altivec_assist)
    505	EXCEPTION_STUB(0x260, perfmon)
    506	EXCEPTION_STUB(0x280, doorbell)
    507	EXCEPTION_STUB(0x2a0, doorbell_crit)
    508	EXCEPTION_STUB(0x2c0, guest_doorbell)
    509	EXCEPTION_STUB(0x2e0, guest_doorbell_crit)
    510	EXCEPTION_STUB(0x300, hypercall)
    511	EXCEPTION_STUB(0x320, ehpriv)
    512	EXCEPTION_STUB(0x340, lrat_error)
    513
    514	.globl __end_interrupts
    515__end_interrupts:
    516
    517/* Critical Input Interrupt */
    518	START_EXCEPTION(critical_input);
    519	CRIT_EXCEPTION_PROLOG(0x100, BOOKE_INTERRUPT_CRITICAL,
    520			      PROLOG_ADDITION_NONE)
    521	EXCEPTION_COMMON_CRIT(0x100)
    522	bl	special_reg_save
    523	CHECK_NAPPING();
    524	addi	r3,r1,STACK_FRAME_OVERHEAD
    525	bl	unknown_nmi_exception
    526	b	ret_from_crit_except
    527
    528/* Machine Check Interrupt */
    529	START_EXCEPTION(machine_check);
    530	MC_EXCEPTION_PROLOG(0x000, BOOKE_INTERRUPT_MACHINE_CHECK,
    531			    PROLOG_ADDITION_NONE)
    532	EXCEPTION_COMMON_MC(0x000)
    533	bl	special_reg_save
    534	CHECK_NAPPING();
    535	addi	r3,r1,STACK_FRAME_OVERHEAD
    536	bl	machine_check_exception
    537	b	ret_from_mc_except
    538
    539/* Data Storage Interrupt */
    540	START_EXCEPTION(data_storage)
    541	NORMAL_EXCEPTION_PROLOG(0x300, BOOKE_INTERRUPT_DATA_STORAGE,
    542				PROLOG_ADDITION_2REGS)
    543	mfspr	r14,SPRN_DEAR
    544	mfspr	r15,SPRN_ESR
    545	std	r14,_DEAR(r1)
    546	std	r15,_ESR(r1)
    547	ld	r14,PACA_EXGEN+EX_R14(r13)
    548	ld	r15,PACA_EXGEN+EX_R15(r13)
    549	EXCEPTION_COMMON(0x300)
    550	b	storage_fault_common
    551
    552/* Instruction Storage Interrupt */
    553	START_EXCEPTION(instruction_storage);
    554	NORMAL_EXCEPTION_PROLOG(0x400, BOOKE_INTERRUPT_INST_STORAGE,
    555				PROLOG_ADDITION_2REGS)
    556	li	r15,0
    557	mr	r14,r10
    558	std	r14,_DEAR(r1)
    559	std	r15,_ESR(r1)
    560	ld	r14,PACA_EXGEN+EX_R14(r13)
    561	ld	r15,PACA_EXGEN+EX_R15(r13)
    562	EXCEPTION_COMMON(0x400)
    563	b	storage_fault_common
    564
    565/* External Input Interrupt */
    566	MASKABLE_EXCEPTION(0x500, BOOKE_INTERRUPT_EXTERNAL,
    567			   external_input, do_IRQ, ACK_NONE)
    568
    569/* Alignment */
    570	START_EXCEPTION(alignment);
    571	NORMAL_EXCEPTION_PROLOG(0x600, BOOKE_INTERRUPT_ALIGNMENT,
    572				PROLOG_ADDITION_2REGS)
    573	mfspr	r14,SPRN_DEAR
    574	mfspr	r15,SPRN_ESR
    575	std	r14,_DEAR(r1)
    576	std	r15,_ESR(r1)
    577	ld	r14,PACA_EXGEN+EX_R14(r13)
    578	ld	r15,PACA_EXGEN+EX_R15(r13)
    579	EXCEPTION_COMMON(0x600)
    580	b	alignment_more	/* no room, go out of line */
    581
    582/* Program Interrupt */
    583	START_EXCEPTION(program);
    584	NORMAL_EXCEPTION_PROLOG(0x700, BOOKE_INTERRUPT_PROGRAM,
    585				PROLOG_ADDITION_1REG)
    586	mfspr	r14,SPRN_ESR
    587	std	r14,_ESR(r1)
    588	ld	r14,PACA_EXGEN+EX_R14(r13)
    589	EXCEPTION_COMMON(0x700)
    590	addi	r3,r1,STACK_FRAME_OVERHEAD
    591	bl	program_check_exception
    592	REST_NVGPRS(r1)
    593	b	interrupt_return
    594
    595/* Floating Point Unavailable Interrupt */
    596	START_EXCEPTION(fp_unavailable);
    597	NORMAL_EXCEPTION_PROLOG(0x800, BOOKE_INTERRUPT_FP_UNAVAIL,
    598				PROLOG_ADDITION_NONE)
    599	/* we can probably do a shorter exception entry for that one... */
    600	EXCEPTION_COMMON(0x800)
    601	ld	r12,_MSR(r1)
    602	andi.	r0,r12,MSR_PR;
    603	beq-	1f
    604	bl	load_up_fpu
    605	b	fast_interrupt_return
    6061:	addi	r3,r1,STACK_FRAME_OVERHEAD
    607	bl	kernel_fp_unavailable_exception
    608	b	interrupt_return
    609
    610/* Altivec Unavailable Interrupt */
    611	START_EXCEPTION(altivec_unavailable);
    612	NORMAL_EXCEPTION_PROLOG(0x200, BOOKE_INTERRUPT_ALTIVEC_UNAVAIL,
    613				PROLOG_ADDITION_NONE)
    614	/* we can probably do a shorter exception entry for that one... */
    615	EXCEPTION_COMMON(0x200)
    616#ifdef CONFIG_ALTIVEC
    617BEGIN_FTR_SECTION
    618	ld	r12,_MSR(r1)
    619	andi.	r0,r12,MSR_PR;
    620	beq-	1f
    621	bl	load_up_altivec
    622	b	fast_interrupt_return
    6231:
    624END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
    625#endif
    626	addi	r3,r1,STACK_FRAME_OVERHEAD
    627	bl	altivec_unavailable_exception
    628	b	interrupt_return
    629
    630/* AltiVec Assist */
    631	START_EXCEPTION(altivec_assist);
    632	NORMAL_EXCEPTION_PROLOG(0x220,
    633				BOOKE_INTERRUPT_ALTIVEC_ASSIST,
    634				PROLOG_ADDITION_NONE)
    635	EXCEPTION_COMMON(0x220)
    636	addi	r3,r1,STACK_FRAME_OVERHEAD
    637#ifdef CONFIG_ALTIVEC
    638BEGIN_FTR_SECTION
    639	bl	altivec_assist_exception
    640END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
    641	REST_NVGPRS(r1)
    642#else
    643	bl	unknown_exception
    644#endif
    645	b	interrupt_return
    646
    647
    648/* Decrementer Interrupt */
    649	MASKABLE_EXCEPTION(0x900, BOOKE_INTERRUPT_DECREMENTER,
    650			   decrementer, timer_interrupt, ACK_DEC)
    651
    652/* Fixed Interval Timer Interrupt */
    653	MASKABLE_EXCEPTION(0x980, BOOKE_INTERRUPT_FIT,
    654			   fixed_interval, unknown_exception, ACK_FIT)
    655
    656/* Watchdog Timer Interrupt */
    657	START_EXCEPTION(watchdog);
    658	CRIT_EXCEPTION_PROLOG(0x9f0, BOOKE_INTERRUPT_WATCHDOG,
    659			      PROLOG_ADDITION_NONE)
    660	EXCEPTION_COMMON_CRIT(0x9f0)
    661	bl	special_reg_save
    662	CHECK_NAPPING();
    663	addi	r3,r1,STACK_FRAME_OVERHEAD
    664#ifdef CONFIG_BOOKE_WDT
    665	bl	WatchdogException
    666#else
    667	bl	unknown_nmi_exception
    668#endif
    669	b	ret_from_crit_except
    670
    671/* System Call Interrupt */
    672	START_EXCEPTION(system_call)
    673	mr	r9,r13			/* keep a copy of userland r13 */
    674	mfspr	r11,SPRN_SRR0		/* get return address */
    675	mfspr	r12,SPRN_SRR1		/* get previous MSR */
    676	mfspr	r13,SPRN_SPRG_PACA	/* get our PACA */
    677	b	system_call_common
    678
    679/* Auxiliary Processor Unavailable Interrupt */
    680	START_EXCEPTION(ap_unavailable);
    681	NORMAL_EXCEPTION_PROLOG(0xf20, BOOKE_INTERRUPT_AP_UNAVAIL,
    682				PROLOG_ADDITION_NONE)
    683	EXCEPTION_COMMON(0xf20)
    684	addi	r3,r1,STACK_FRAME_OVERHEAD
    685	bl	unknown_exception
    686	b	interrupt_return
    687
    688/* Debug exception as a critical interrupt*/
    689	START_EXCEPTION(debug_crit);
    690	CRIT_EXCEPTION_PROLOG(0xd00, BOOKE_INTERRUPT_DEBUG,
    691			      PROLOG_ADDITION_2REGS)
    692
    693	/*
    694	 * If there is a single step or branch-taken exception in an
    695	 * exception entry sequence, it was probably meant to apply to
    696	 * the code where the exception occurred (since exception entry
    697	 * doesn't turn off DE automatically).  We simulate the effect
    698	 * of turning off DE on entry to an exception handler by turning
    699	 * off DE in the CSRR1 value and clearing the debug status.
    700	 */
    701
    702	mfspr	r14,SPRN_DBSR		/* check single-step/branch taken */
    703	andis.	r15,r14,(DBSR_IC|DBSR_BT)@h
    704	beq+	1f
    705
    706#ifdef CONFIG_RELOCATABLE
    707	ld	r15,PACATOC(r13)
    708	ld	r14,interrupt_base_book3e@got(r15)
    709	ld	r15,__end_interrupts@got(r15)
    710	cmpld	cr0,r10,r14
    711	cmpld	cr1,r10,r15
    712#else
    713	LOAD_REG_IMMEDIATE_SYM(r14, r15, interrupt_base_book3e)
    714	cmpld	cr0, r10, r14
    715	LOAD_REG_IMMEDIATE_SYM(r14, r15, __end_interrupts)
    716	cmpld	cr1, r10, r14
    717#endif
    718	blt+	cr0,1f
    719	bge+	cr1,1f
    720
    721	/* here it looks like we got an inappropriate debug exception. */
    722	lis	r14,(DBSR_IC|DBSR_BT)@h		/* clear the event */
    723	rlwinm	r11,r11,0,~MSR_DE	/* clear DE in the CSRR1 value */
    724	mtspr	SPRN_DBSR,r14
    725	mtspr	SPRN_CSRR1,r11
    726	lwz	r10,PACA_EXCRIT+EX_CR(r13)	/* restore registers */
    727	ld	r1,PACA_EXCRIT+EX_R1(r13)
    728	ld	r14,PACA_EXCRIT+EX_R14(r13)
    729	ld	r15,PACA_EXCRIT+EX_R15(r13)
    730	mtcr	r10
    731	ld	r10,PACA_EXCRIT+EX_R10(r13)	/* restore registers */
    732	ld	r11,PACA_EXCRIT+EX_R11(r13)
    733	mfspr	r13,SPRN_SPRG_CRIT_SCRATCH
    734	rfci
    735
    736	/* Normal debug exception */
    737	/* XXX We only handle coming from userspace for now since we can't
    738	 *     quite save properly an interrupted kernel state yet
    739	 */
    7401:	andi.	r14,r11,MSR_PR;		/* check for userspace again */
    741	beq	kernel_dbg_exc;		/* if from kernel mode */
    742
    743	/* Now we mash up things to make it look like we are coming on a
    744	 * normal exception
    745	 */
    746	mfspr	r14,SPRN_DBSR
    747	std	r14,_DSISR(r1)
    748	ld	r14,PACA_EXCRIT+EX_R14(r13)
    749	ld	r15,PACA_EXCRIT+EX_R15(r13)
    750	EXCEPTION_COMMON_CRIT(0xd00)
    751	addi	r3,r1,STACK_FRAME_OVERHEAD
    752	bl	DebugException
    753	REST_NVGPRS(r1)
    754	b	interrupt_return
    755
    756kernel_dbg_exc:
    757	b	.	/* NYI */
    758
    759/* Debug exception as a debug interrupt*/
    760	START_EXCEPTION(debug_debug);
    761	DBG_EXCEPTION_PROLOG(0xd00, BOOKE_INTERRUPT_DEBUG,
    762						 PROLOG_ADDITION_2REGS)
    763
    764	/*
    765	 * If there is a single step or branch-taken exception in an
    766	 * exception entry sequence, it was probably meant to apply to
    767	 * the code where the exception occurred (since exception entry
    768	 * doesn't turn off DE automatically).  We simulate the effect
    769	 * of turning off DE on entry to an exception handler by turning
    770	 * off DE in the DSRR1 value and clearing the debug status.
    771	 */
    772
    773	mfspr	r14,SPRN_DBSR		/* check single-step/branch taken */
    774	andis.	r15,r14,(DBSR_IC|DBSR_BT)@h
    775	beq+	1f
    776
    777#ifdef CONFIG_RELOCATABLE
    778	ld	r15,PACATOC(r13)
    779	ld	r14,interrupt_base_book3e@got(r15)
    780	ld	r15,__end_interrupts@got(r15)
    781	cmpld	cr0,r10,r14
    782	cmpld	cr1,r10,r15
    783#else
    784	LOAD_REG_IMMEDIATE_SYM(r14, r15, interrupt_base_book3e)
    785	cmpld	cr0, r10, r14
    786	LOAD_REG_IMMEDIATE_SYM(r14, r15,__end_interrupts)
    787	cmpld	cr1, r10, r14
    788#endif
    789	blt+	cr0,1f
    790	bge+	cr1,1f
    791
    792	/* here it looks like we got an inappropriate debug exception. */
    793	lis	r14,(DBSR_IC|DBSR_BT)@h		/* clear the event */
    794	rlwinm	r11,r11,0,~MSR_DE	/* clear DE in the DSRR1 value */
    795	mtspr	SPRN_DBSR,r14
    796	mtspr	SPRN_DSRR1,r11
    797	lwz	r10,PACA_EXDBG+EX_CR(r13)	/* restore registers */
    798	ld	r1,PACA_EXDBG+EX_R1(r13)
    799	ld	r14,PACA_EXDBG+EX_R14(r13)
    800	ld	r15,PACA_EXDBG+EX_R15(r13)
    801	mtcr	r10
    802	ld	r10,PACA_EXDBG+EX_R10(r13)	/* restore registers */
    803	ld	r11,PACA_EXDBG+EX_R11(r13)
    804	mfspr	r13,SPRN_SPRG_DBG_SCRATCH
    805	rfdi
    806
    807	/* Normal debug exception */
    808	/* XXX We only handle coming from userspace for now since we can't
    809	 *     quite save properly an interrupted kernel state yet
    810	 */
    8111:	andi.	r14,r11,MSR_PR;		/* check for userspace again */
    812	beq	kernel_dbg_exc;		/* if from kernel mode */
    813
    814	/* Now we mash up things to make it look like we are coming on a
    815	 * normal exception
    816	 */
    817	mfspr	r14,SPRN_DBSR
    818	std	r14,_DSISR(r1)
    819	ld	r14,PACA_EXDBG+EX_R14(r13)
    820	ld	r15,PACA_EXDBG+EX_R15(r13)
    821	EXCEPTION_COMMON_DBG(0xd08)
    822	addi	r3,r1,STACK_FRAME_OVERHEAD
    823	bl	DebugException
    824	REST_NVGPRS(r1)
    825	b	interrupt_return
    826
    827	START_EXCEPTION(perfmon);
    828	NORMAL_EXCEPTION_PROLOG(0x260, BOOKE_INTERRUPT_PERFORMANCE_MONITOR,
    829				PROLOG_ADDITION_NONE)
    830	EXCEPTION_COMMON(0x260)
    831	CHECK_NAPPING()
    832	addi	r3,r1,STACK_FRAME_OVERHEAD
    833	bl	performance_monitor_exception
    834	b	interrupt_return
    835
    836/* Doorbell interrupt */
    837	MASKABLE_EXCEPTION(0x280, BOOKE_INTERRUPT_DOORBELL,
    838			   doorbell, doorbell_exception, ACK_NONE)
    839
    840/* Doorbell critical Interrupt */
    841	START_EXCEPTION(doorbell_crit);
    842	CRIT_EXCEPTION_PROLOG(0x2a0, BOOKE_INTERRUPT_DOORBELL_CRITICAL,
    843			      PROLOG_ADDITION_NONE)
    844	EXCEPTION_COMMON_CRIT(0x2a0)
    845	bl	special_reg_save
    846	CHECK_NAPPING();
    847	addi	r3,r1,STACK_FRAME_OVERHEAD
    848	bl	unknown_nmi_exception
    849	b	ret_from_crit_except
    850
    851/*
    852 *	Guest doorbell interrupt
    853 *	This general exception use GSRRx save/restore registers
    854 */
    855	START_EXCEPTION(guest_doorbell);
    856	GDBELL_EXCEPTION_PROLOG(0x2c0, BOOKE_INTERRUPT_GUEST_DBELL,
    857			        PROLOG_ADDITION_NONE)
    858	EXCEPTION_COMMON(0x2c0)
    859	addi	r3,r1,STACK_FRAME_OVERHEAD
    860	bl	unknown_exception
    861	b	interrupt_return
    862
    863/* Guest Doorbell critical Interrupt */
    864	START_EXCEPTION(guest_doorbell_crit);
    865	CRIT_EXCEPTION_PROLOG(0x2e0, BOOKE_INTERRUPT_GUEST_DBELL_CRIT,
    866			      PROLOG_ADDITION_NONE)
    867	EXCEPTION_COMMON_CRIT(0x2e0)
    868	bl	special_reg_save
    869	CHECK_NAPPING();
    870	addi	r3,r1,STACK_FRAME_OVERHEAD
    871	bl	unknown_nmi_exception
    872	b	ret_from_crit_except
    873
    874/* Hypervisor call */
    875	START_EXCEPTION(hypercall);
    876	NORMAL_EXCEPTION_PROLOG(0x310, BOOKE_INTERRUPT_HV_SYSCALL,
    877			        PROLOG_ADDITION_NONE)
    878	EXCEPTION_COMMON(0x310)
    879	addi	r3,r1,STACK_FRAME_OVERHEAD
    880	bl	unknown_exception
    881	b	interrupt_return
    882
    883/* Embedded Hypervisor priviledged  */
    884	START_EXCEPTION(ehpriv);
    885	NORMAL_EXCEPTION_PROLOG(0x320, BOOKE_INTERRUPT_HV_PRIV,
    886			        PROLOG_ADDITION_NONE)
    887	EXCEPTION_COMMON(0x320)
    888	addi	r3,r1,STACK_FRAME_OVERHEAD
    889	bl	unknown_exception
    890	b	interrupt_return
    891
    892/* LRAT Error interrupt */
    893	START_EXCEPTION(lrat_error);
    894	NORMAL_EXCEPTION_PROLOG(0x340, BOOKE_INTERRUPT_LRAT_ERROR,
    895			        PROLOG_ADDITION_NONE)
    896	EXCEPTION_COMMON(0x340)
    897	addi	r3,r1,STACK_FRAME_OVERHEAD
    898	bl	unknown_exception
    899	b	interrupt_return
    900
    901.macro SEARCH_RESTART_TABLE
    902#ifdef CONFIG_RELOCATABLE
    903	ld	r11,PACATOC(r13)
    904	ld	r14,__start___restart_table@got(r11)
    905	ld	r15,__stop___restart_table@got(r11)
    906#else
    907	LOAD_REG_IMMEDIATE_SYM(r14, r11, __start___restart_table)
    908	LOAD_REG_IMMEDIATE_SYM(r15, r11, __stop___restart_table)
    909#endif
    910300:
    911	cmpd	r14,r15
    912	beq	302f
    913	ld	r11,0(r14)
    914	cmpld	r10,r11
    915	blt	301f
    916	ld	r11,8(r14)
    917	cmpld	r10,r11
    918	bge	301f
    919	ld	r11,16(r14)
    920	b	303f
    921301:
    922	addi	r14,r14,24
    923	b	300b
    924302:
    925	li	r11,0
    926303:
    927.endm
    928
    929/*
    930 * An interrupt came in while soft-disabled; We mark paca->irq_happened
    931 * accordingly and if the interrupt is level sensitive, we hard disable
    932 * hard disable (full_mask) corresponds to PACA_IRQ_MUST_HARD_MASK, so
    933 * keep these in synch.
    934 */
    935
    936.macro masked_interrupt_book3e paca_irq full_mask
    937	std	r14,PACA_EXGEN+EX_R14(r13)
    938	std	r15,PACA_EXGEN+EX_R15(r13)
    939
    940	lbz	r10,PACAIRQHAPPENED(r13)
    941	.if \full_mask == 1
    942	ori	r10,r10,\paca_irq | PACA_IRQ_HARD_DIS
    943	.else
    944	ori	r10,r10,\paca_irq
    945	.endif
    946	stb	r10,PACAIRQHAPPENED(r13)
    947
    948	.if \full_mask == 1
    949	xori	r11,r11,MSR_EE		/* clear MSR_EE */
    950	mtspr	SPRN_SRR1,r11
    951	.endif
    952
    953	mfspr	r10,SPRN_SRR0
    954	SEARCH_RESTART_TABLE
    955	cmpdi	r11,0
    956	beq	1f
    957	mtspr	SPRN_SRR0,r11		/* return to restart address */
    9581:
    959
    960	lwz	r11,PACA_EXGEN+EX_CR(r13)
    961	mtcr	r11
    962	ld	r10,PACA_EXGEN+EX_R10(r13)
    963	ld	r11,PACA_EXGEN+EX_R11(r13)
    964	ld	r14,PACA_EXGEN+EX_R14(r13)
    965	ld	r15,PACA_EXGEN+EX_R15(r13)
    966	mfspr	r13,SPRN_SPRG_GEN_SCRATCH
    967	rfi
    968	b	.
    969.endm
    970
    971masked_interrupt_book3e_0x500:
    972	masked_interrupt_book3e PACA_IRQ_EE 1
    973
    974masked_interrupt_book3e_0x900:
    975	ACK_DEC(r10);
    976	masked_interrupt_book3e PACA_IRQ_DEC 0
    977
    978masked_interrupt_book3e_0x980:
    979	ACK_FIT(r10);
    980	masked_interrupt_book3e PACA_IRQ_DEC 0
    981
    982masked_interrupt_book3e_0x280:
    983masked_interrupt_book3e_0x2c0:
    984	masked_interrupt_book3e PACA_IRQ_DBELL 0
    985
    986/*
    987 * This is called from 0x300 and 0x400 handlers after the prologs with
    988 * r14 and r15 containing the fault address and error code, with the
    989 * original values stashed away in the PACA
    990 */
    991storage_fault_common:
    992	addi	r3,r1,STACK_FRAME_OVERHEAD
    993	bl	do_page_fault
    994	b	interrupt_return
    995
    996/*
    997 * Alignment exception doesn't fit entirely in the 0x100 bytes so it
    998 * continues here.
    999 */
   1000alignment_more:
   1001	addi	r3,r1,STACK_FRAME_OVERHEAD
   1002	bl	alignment_exception
   1003	REST_NVGPRS(r1)
   1004	b	interrupt_return
   1005
   1006/*
   1007 * Trampolines used when spotting a bad kernel stack pointer in
   1008 * the exception entry code.
   1009 *
   1010 * TODO: move some bits like SRR0 read to trampoline, pass PACA
   1011 * index around, etc... to handle crit & mcheck
   1012 */
   1013BAD_STACK_TRAMPOLINE(0x000)
   1014BAD_STACK_TRAMPOLINE(0x100)
   1015BAD_STACK_TRAMPOLINE(0x200)
   1016BAD_STACK_TRAMPOLINE(0x220)
   1017BAD_STACK_TRAMPOLINE(0x260)
   1018BAD_STACK_TRAMPOLINE(0x280)
   1019BAD_STACK_TRAMPOLINE(0x2a0)
   1020BAD_STACK_TRAMPOLINE(0x2c0)
   1021BAD_STACK_TRAMPOLINE(0x2e0)
   1022BAD_STACK_TRAMPOLINE(0x300)
   1023BAD_STACK_TRAMPOLINE(0x310)
   1024BAD_STACK_TRAMPOLINE(0x320)
   1025BAD_STACK_TRAMPOLINE(0x340)
   1026BAD_STACK_TRAMPOLINE(0x400)
   1027BAD_STACK_TRAMPOLINE(0x500)
   1028BAD_STACK_TRAMPOLINE(0x600)
   1029BAD_STACK_TRAMPOLINE(0x700)
   1030BAD_STACK_TRAMPOLINE(0x800)
   1031BAD_STACK_TRAMPOLINE(0x900)
   1032BAD_STACK_TRAMPOLINE(0x980)
   1033BAD_STACK_TRAMPOLINE(0x9f0)
   1034BAD_STACK_TRAMPOLINE(0xa00)
   1035BAD_STACK_TRAMPOLINE(0xb00)
   1036BAD_STACK_TRAMPOLINE(0xc00)
   1037BAD_STACK_TRAMPOLINE(0xd00)
   1038BAD_STACK_TRAMPOLINE(0xd08)
   1039BAD_STACK_TRAMPOLINE(0xe00)
   1040BAD_STACK_TRAMPOLINE(0xf00)
   1041BAD_STACK_TRAMPOLINE(0xf20)
   1042
   1043	.globl	bad_stack_book3e
   1044bad_stack_book3e:
   1045	/* XXX: Needs to make SPRN_SPRG_GEN depend on exception type */
   1046	mfspr	r10,SPRN_SRR0;		  /* read SRR0 before touching stack */
   1047	ld	r1,PACAEMERGSP(r13)
   1048	subi	r1,r1,64+INT_FRAME_SIZE
   1049	std	r10,_NIP(r1)
   1050	std	r11,_MSR(r1)
   1051	ld	r10,PACA_EXGEN+EX_R1(r13) /* FIXME for crit & mcheck */
   1052	lwz	r11,PACA_EXGEN+EX_CR(r13) /* FIXME for crit & mcheck */
   1053	std	r10,GPR1(r1)
   1054	std	r11,_CCR(r1)
   1055	mfspr	r10,SPRN_DEAR
   1056	mfspr	r11,SPRN_ESR
   1057	std	r10,_DEAR(r1)
   1058	std	r11,_ESR(r1)
   1059	std	r0,GPR0(r1);		/* save r0 in stackframe */	    \
   1060	std	r2,GPR2(r1);		/* save r2 in stackframe */	    \
   1061	SAVE_GPRS(3, 9, r1);		/* save r3 - r9 in stackframe */    \
   1062	ld	r3,PACA_EXGEN+EX_R10(r13);/* get back r10 */		    \
   1063	ld	r4,PACA_EXGEN+EX_R11(r13);/* get back r11 */		    \
   1064	mfspr	r5,SPRN_SPRG_GEN_SCRATCH;/* get back r13 XXX can be wrong */ \
   1065	std	r3,GPR10(r1);		/* save r10 to stackframe */	    \
   1066	std	r4,GPR11(r1);		/* save r11 to stackframe */	    \
   1067	std	r12,GPR12(r1);		/* save r12 in stackframe */	    \
   1068	std	r5,GPR13(r1);		/* save it to stackframe */	    \
   1069	mflr	r10
   1070	mfctr	r11
   1071	mfxer	r12
   1072	std	r10,_LINK(r1)
   1073	std	r11,_CTR(r1)
   1074	std	r12,_XER(r1)
   1075	SAVE_GPRS(14, 31, r1)
   1076	lhz	r12,PACA_TRAP_SAVE(r13)
   1077	std	r12,_TRAP(r1)
   1078	addi	r11,r1,INT_FRAME_SIZE
   1079	std	r11,0(r1)
   1080	li	r12,0
   1081	std	r12,0(r11)
   1082	ld	r2,PACATOC(r13)
   10831:	addi	r3,r1,STACK_FRAME_OVERHEAD
   1084	bl	kernel_bad_stack
   1085	b	1b
   1086
   1087/*
   1088 * Setup the initial TLB for a core. This current implementation
   1089 * assume that whatever we are running off will not conflict with
   1090 * the new mapping at PAGE_OFFSET.
   1091 */
   1092_GLOBAL(initial_tlb_book3e)
   1093
   1094	/* Look for the first TLB with IPROT set */
   1095	mfspr	r4,SPRN_TLB0CFG
   1096	andi.	r3,r4,TLBnCFG_IPROT
   1097	lis	r3,MAS0_TLBSEL(0)@h
   1098	bne	found_iprot
   1099
   1100	mfspr	r4,SPRN_TLB1CFG
   1101	andi.	r3,r4,TLBnCFG_IPROT
   1102	lis	r3,MAS0_TLBSEL(1)@h
   1103	bne	found_iprot
   1104
   1105	mfspr	r4,SPRN_TLB2CFG
   1106	andi.	r3,r4,TLBnCFG_IPROT
   1107	lis	r3,MAS0_TLBSEL(2)@h
   1108	bne	found_iprot
   1109
   1110	lis	r3,MAS0_TLBSEL(3)@h
   1111	mfspr	r4,SPRN_TLB3CFG
   1112	/* fall through */
   1113
   1114found_iprot:
   1115	andi.	r5,r4,TLBnCFG_HES
   1116	bne	have_hes
   1117
   1118	mflr	r8				/* save LR */
   1119/* 1. Find the index of the entry we're executing in
   1120 *
   1121 * r3 = MAS0_TLBSEL (for the iprot array)
   1122 * r4 = SPRN_TLBnCFG
   1123 */
   1124	bcl	20,31,$+4			/* Find our address */
   1125invstr:	mflr	r6				/* Make it accessible */
   1126	mfmsr	r7
   1127	rlwinm	r5,r7,27,31,31			/* extract MSR[IS] */
   1128	mfspr	r7,SPRN_PID
   1129	slwi	r7,r7,16
   1130	or	r7,r7,r5
   1131	mtspr	SPRN_MAS6,r7
   1132	tlbsx	0,r6				/* search MSR[IS], SPID=PID */
   1133
   1134	mfspr	r3,SPRN_MAS0
   1135	rlwinm	r5,r3,16,20,31			/* Extract MAS0(Entry) */
   1136
   1137	mfspr	r7,SPRN_MAS1			/* Insure IPROT set */
   1138	oris	r7,r7,MAS1_IPROT@h
   1139	mtspr	SPRN_MAS1,r7
   1140	tlbwe
   1141
   1142/* 2. Invalidate all entries except the entry we're executing in
   1143 *
   1144 * r3 = MAS0 w/TLBSEL & ESEL for the entry we are running in
   1145 * r4 = SPRN_TLBnCFG
   1146 * r5 = ESEL of entry we are running in
   1147 */
   1148	andi.	r4,r4,TLBnCFG_N_ENTRY		/* Extract # entries */
   1149	li	r6,0				/* Set Entry counter to 0 */
   11501:	mr	r7,r3				/* Set MAS0(TLBSEL) */
   1151	rlwimi	r7,r6,16,4,15			/* Setup MAS0 = TLBSEL | ESEL(r6) */
   1152	mtspr	SPRN_MAS0,r7
   1153	tlbre
   1154	mfspr	r7,SPRN_MAS1
   1155	rlwinm	r7,r7,0,2,31			/* Clear MAS1 Valid and IPROT */
   1156	cmpw	r5,r6
   1157	beq	skpinv				/* Dont update the current execution TLB */
   1158	mtspr	SPRN_MAS1,r7
   1159	tlbwe
   1160	isync
   1161skpinv:	addi	r6,r6,1				/* Increment */
   1162	cmpw	r6,r4				/* Are we done? */
   1163	bne	1b				/* If not, repeat */
   1164
   1165	/* Invalidate all TLBs */
   1166	PPC_TLBILX_ALL(0,R0)
   1167	sync
   1168	isync
   1169
   1170/* 3. Setup a temp mapping and jump to it
   1171 *
   1172 * r3 = MAS0 w/TLBSEL & ESEL for the entry we are running in
   1173 * r5 = ESEL of entry we are running in
   1174 */
   1175	andi.	r7,r5,0x1	/* Find an entry not used and is non-zero */
   1176	addi	r7,r7,0x1
   1177	mr	r4,r3		/* Set MAS0(TLBSEL) = 1 */
   1178	mtspr	SPRN_MAS0,r4
   1179	tlbre
   1180
   1181	rlwimi	r4,r7,16,4,15	/* Setup MAS0 = TLBSEL | ESEL(r7) */
   1182	mtspr	SPRN_MAS0,r4
   1183
   1184	mfspr	r7,SPRN_MAS1
   1185	xori	r6,r7,MAS1_TS		/* Setup TMP mapping in the other Address space */
   1186	mtspr	SPRN_MAS1,r6
   1187
   1188	tlbwe
   1189
   1190	mfmsr	r6
   1191	xori	r6,r6,MSR_IS
   1192	mtspr	SPRN_SRR1,r6
   1193	bcl	20,31,$+4	/* Find our address */
   11941:	mflr	r6
   1195	addi	r6,r6,(2f - 1b)
   1196	mtspr	SPRN_SRR0,r6
   1197	rfi
   11982:
   1199
   1200/* 4. Clear out PIDs & Search info
   1201 *
   1202 * r3 = MAS0 w/TLBSEL & ESEL for the entry we started in
   1203 * r4 = MAS0 w/TLBSEL & ESEL for the temp mapping
   1204 * r5 = MAS3
   1205 */
   1206	li	r6,0
   1207	mtspr   SPRN_MAS6,r6
   1208	mtspr	SPRN_PID,r6
   1209
   1210/* 5. Invalidate mapping we started in
   1211 *
   1212 * r3 = MAS0 w/TLBSEL & ESEL for the entry we started in
   1213 * r4 = MAS0 w/TLBSEL & ESEL for the temp mapping
   1214 * r5 = MAS3
   1215 */
   1216	mtspr	SPRN_MAS0,r3
   1217	tlbre
   1218	mfspr	r6,SPRN_MAS1
   1219	rlwinm	r6,r6,0,2,31	/* clear IPROT and VALID */
   1220	mtspr	SPRN_MAS1,r6
   1221	tlbwe
   1222	sync
   1223	isync
   1224
   1225/* 6. Setup KERNELBASE mapping in TLB[0]
   1226 *
   1227 * r3 = MAS0 w/TLBSEL & ESEL for the entry we started in
   1228 * r4 = MAS0 w/TLBSEL & ESEL for the temp mapping
   1229 * r5 = MAS3
   1230 */
   1231	rlwinm	r3,r3,0,16,3	/* clear ESEL */
   1232	mtspr	SPRN_MAS0,r3
   1233	lis	r6,(MAS1_VALID|MAS1_IPROT)@h
   1234	ori	r6,r6,(MAS1_TSIZE(BOOK3E_PAGESZ_1GB))@l
   1235	mtspr	SPRN_MAS1,r6
   1236
   1237	LOAD_REG_IMMEDIATE(r6, PAGE_OFFSET | MAS2_M_IF_NEEDED)
   1238	mtspr	SPRN_MAS2,r6
   1239
   1240	rlwinm	r5,r5,0,0,25
   1241	ori	r5,r5,MAS3_SR | MAS3_SW | MAS3_SX
   1242	mtspr	SPRN_MAS3,r5
   1243	li	r5,-1
   1244	rlwinm	r5,r5,0,0,25
   1245
   1246	tlbwe
   1247
   1248/* 7. Jump to KERNELBASE mapping
   1249 *
   1250 * r4 = MAS0 w/TLBSEL & ESEL for the temp mapping
   1251 */
   1252	/* Now we branch the new virtual address mapped by this entry */
   1253	bcl	20,31,$+4	/* Find our address */
   12541:	mflr	r6
   1255	addi	r6,r6,(2f - 1b)
   1256	tovirt(r6,r6)
   1257	lis	r7,MSR_KERNEL@h
   1258	ori	r7,r7,MSR_KERNEL@l
   1259	mtspr	SPRN_SRR0,r6
   1260	mtspr	SPRN_SRR1,r7
   1261	rfi				/* start execution out of TLB1[0] entry */
   12622:
   1263
   1264/* 8. Clear out the temp mapping
   1265 *
   1266 * r4 = MAS0 w/TLBSEL & ESEL for the entry we are running in
   1267 */
   1268	mtspr	SPRN_MAS0,r4
   1269	tlbre
   1270	mfspr	r5,SPRN_MAS1
   1271	rlwinm	r5,r5,0,2,31	/* clear IPROT and VALID */
   1272	mtspr	SPRN_MAS1,r5
   1273	tlbwe
   1274	sync
   1275	isync
   1276
   1277	/* We translate LR and return */
   1278	tovirt(r8,r8)
   1279	mtlr	r8
   1280	blr
   1281
   1282have_hes:
   1283	/* Setup MAS 0,1,2,3 and 7 for tlbwe of a 1G entry that maps the
   1284	 * kernel linear mapping. We also set MAS8 once for all here though
   1285	 * that will have to be made dependent on whether we are running under
   1286	 * a hypervisor I suppose.
   1287	 */
   1288
   1289	/* BEWARE, MAGIC
   1290	 * This code is called as an ordinary function on the boot CPU. But to
   1291	 * avoid duplication, this code is also used in SCOM bringup of
   1292	 * secondary CPUs. We read the code between the initial_tlb_code_start
   1293	 * and initial_tlb_code_end labels one instruction at a time and RAM it
   1294	 * into the new core via SCOM. That doesn't process branches, so there
   1295	 * must be none between those two labels. It also means if this code
   1296	 * ever takes any parameters, the SCOM code must also be updated to
   1297	 * provide them.
   1298	 */
   1299	.globl a2_tlbinit_code_start
   1300a2_tlbinit_code_start:
   1301
   1302	ori	r11,r3,MAS0_WQ_ALLWAYS
   1303	oris	r11,r11,MAS0_ESEL(3)@h /* Use way 3: workaround A2 erratum 376 */
   1304	mtspr	SPRN_MAS0,r11
   1305	lis	r3,(MAS1_VALID | MAS1_IPROT)@h
   1306	ori	r3,r3,BOOK3E_PAGESZ_1GB << MAS1_TSIZE_SHIFT
   1307	mtspr	SPRN_MAS1,r3
   1308	LOAD_REG_IMMEDIATE(r3, PAGE_OFFSET | MAS2_M)
   1309	mtspr	SPRN_MAS2,r3
   1310	li	r3,MAS3_SR | MAS3_SW | MAS3_SX
   1311	mtspr	SPRN_MAS7_MAS3,r3
   1312	li	r3,0
   1313	mtspr	SPRN_MAS8,r3
   1314
   1315	/* Write the TLB entry */
   1316	tlbwe
   1317
   1318	.globl a2_tlbinit_after_linear_map
   1319a2_tlbinit_after_linear_map:
   1320
   1321	/* Now we branch the new virtual address mapped by this entry */
   1322#ifdef CONFIG_RELOCATABLE
   1323	ld	r5,PACATOC(r13)
   1324	ld	r3,1f@got(r5)
   1325#else
   1326	LOAD_REG_IMMEDIATE_SYM(r3, r5, 1f)
   1327#endif
   1328	mtctr	r3
   1329	bctr
   1330
   13311:	/* We are now running at PAGE_OFFSET, clean the TLB of everything
   1332	 * else (including IPROTed things left by firmware)
   1333	 * r4 = TLBnCFG
   1334	 * r3 = current address (more or less)
   1335	 */
   1336
   1337	li	r5,0
   1338	mtspr	SPRN_MAS6,r5
   1339	tlbsx	0,r3
   1340
   1341	rlwinm	r9,r4,0,TLBnCFG_N_ENTRY
   1342	rlwinm	r10,r4,8,0xff
   1343	addi	r10,r10,-1	/* Get inner loop mask */
   1344
   1345	li	r3,1
   1346
   1347	mfspr	r5,SPRN_MAS1
   1348	rlwinm	r5,r5,0,(~(MAS1_VALID|MAS1_IPROT))
   1349
   1350	mfspr	r6,SPRN_MAS2
   1351	rldicr	r6,r6,0,51		/* Extract EPN */
   1352
   1353	mfspr	r7,SPRN_MAS0
   1354	rlwinm	r7,r7,0,0xffff0fff	/* Clear HES and WQ */
   1355
   1356	rlwinm	r8,r7,16,0xfff		/* Extract ESEL */
   1357
   13582:	add	r4,r3,r8
   1359	and	r4,r4,r10
   1360
   1361	rlwimi	r7,r4,16,MAS0_ESEL_MASK
   1362
   1363	mtspr	SPRN_MAS0,r7
   1364	mtspr	SPRN_MAS1,r5
   1365	mtspr	SPRN_MAS2,r6
   1366	tlbwe
   1367
   1368	addi	r3,r3,1
   1369	and.	r4,r3,r10
   1370
   1371	bne	3f
   1372	addis	r6,r6,(1<<30)@h
   13733:
   1374	cmpw	r3,r9
   1375	blt	2b
   1376
   1377	.globl  a2_tlbinit_after_iprot_flush
   1378a2_tlbinit_after_iprot_flush:
   1379
   1380	PPC_TLBILX(0,0,R0)
   1381	sync
   1382	isync
   1383
   1384	.globl a2_tlbinit_code_end
   1385a2_tlbinit_code_end:
   1386
   1387	/* We translate LR and return */
   1388	mflr	r3
   1389	tovirt(r3,r3)
   1390	mtlr	r3
   1391	blr
   1392
   1393/*
   1394 * Main entry (boot CPU, thread 0)
   1395 *
   1396 * We enter here from head_64.S, possibly after the prom_init trampoline
   1397 * with r3 and r4 already saved to r31 and 30 respectively and in 64 bits
   1398 * mode. Anything else is as it was left by the bootloader
   1399 *
   1400 * Initial requirements of this port:
   1401 *
   1402 * - Kernel loaded at 0 physical
   1403 * - A good lump of memory mapped 0:0 by UTLB entry 0
   1404 * - MSR:IS & MSR:DS set to 0
   1405 *
   1406 * Note that some of the above requirements will be relaxed in the future
   1407 * as the kernel becomes smarter at dealing with different initial conditions
   1408 * but for now you have to be careful
   1409 */
   1410_GLOBAL(start_initialization_book3e)
   1411	mflr	r28
   1412
   1413	/* First, we need to setup some initial TLBs to map the kernel
   1414	 * text, data and bss at PAGE_OFFSET. We don't have a real mode
   1415	 * and always use AS 0, so we just set it up to match our link
   1416	 * address and never use 0 based addresses.
   1417	 */
   1418	bl	initial_tlb_book3e
   1419
   1420	/* Init global core bits */
   1421	bl	init_core_book3e
   1422
   1423	/* Init per-thread bits */
   1424	bl	init_thread_book3e
   1425
   1426	/* Return to common init code */
   1427	tovirt(r28,r28)
   1428	mtlr	r28
   1429	blr
   1430
   1431
   1432/*
   1433 * Secondary core/processor entry
   1434 *
   1435 * This is entered for thread 0 of a secondary core, all other threads
   1436 * are expected to be stopped. It's similar to start_initialization_book3e
   1437 * except that it's generally entered from the holding loop in head_64.S
   1438 * after CPUs have been gathered by Open Firmware.
   1439 *
   1440 * We assume we are in 32 bits mode running with whatever TLB entry was
   1441 * set for us by the firmware or POR engine.
   1442 */
   1443_GLOBAL(book3e_secondary_core_init_tlb_set)
   1444	li	r4,1
   1445	b	generic_secondary_smp_init
   1446
   1447_GLOBAL(book3e_secondary_core_init)
   1448	mflr	r28
   1449
   1450	/* Do we need to setup initial TLB entry ? */
   1451	cmplwi	r4,0
   1452	bne	2f
   1453
   1454	/* Setup TLB for this core */
   1455	bl	initial_tlb_book3e
   1456
   1457	/* We can return from the above running at a different
   1458	 * address, so recalculate r2 (TOC)
   1459	 */
   1460	bl	relative_toc
   1461
   1462	/* Init global core bits */
   14632:	bl	init_core_book3e
   1464
   1465	/* Init per-thread bits */
   14663:	bl	init_thread_book3e
   1467
   1468	/* Return to common init code at proper virtual address.
   1469	 *
   1470	 * Due to various previous assumptions, we know we entered this
   1471	 * function at either the final PAGE_OFFSET mapping or using a
   1472	 * 1:1 mapping at 0, so we don't bother doing a complicated check
   1473	 * here, we just ensure the return address has the right top bits.
   1474	 *
   1475	 * Note that if we ever want to be smarter about where we can be
   1476	 * started from, we have to be careful that by the time we reach
   1477	 * the code below we may already be running at a different location
   1478	 * than the one we were called from since initial_tlb_book3e can
   1479	 * have moved us already.
   1480	 */
   1481	cmpdi	cr0,r28,0
   1482	blt	1f
   1483	lis	r3,PAGE_OFFSET@highest
   1484	sldi	r3,r3,32
   1485	or	r28,r28,r3
   14861:	mtlr	r28
   1487	blr
   1488
   1489_GLOBAL(book3e_secondary_thread_init)
   1490	mflr	r28
   1491	b	3b
   1492
   1493	.globl init_core_book3e
   1494init_core_book3e:
   1495	/* Establish the interrupt vector base */
   1496	tovirt(r2,r2)
   1497	LOAD_REG_ADDR(r3, interrupt_base_book3e)
   1498	mtspr	SPRN_IVPR,r3
   1499	sync
   1500	blr
   1501
   1502init_thread_book3e:
   1503	lis	r3,(SPRN_EPCR_ICM | SPRN_EPCR_GICM)@h
   1504	mtspr	SPRN_EPCR,r3
   1505
   1506	/* Make sure interrupts are off */
   1507	wrteei	0
   1508
   1509	/* disable all timers and clear out status */
   1510	li	r3,0
   1511	mtspr	SPRN_TCR,r3
   1512	mfspr	r3,SPRN_TSR
   1513	mtspr	SPRN_TSR,r3
   1514
   1515	blr
   1516
   1517_GLOBAL(__setup_base_ivors)
   1518	SET_IVOR(0, 0x020) /* Critical Input */
   1519	SET_IVOR(1, 0x000) /* Machine Check */
   1520	SET_IVOR(2, 0x060) /* Data Storage */ 
   1521	SET_IVOR(3, 0x080) /* Instruction Storage */
   1522	SET_IVOR(4, 0x0a0) /* External Input */ 
   1523	SET_IVOR(5, 0x0c0) /* Alignment */ 
   1524	SET_IVOR(6, 0x0e0) /* Program */ 
   1525	SET_IVOR(7, 0x100) /* FP Unavailable */ 
   1526	SET_IVOR(8, 0x120) /* System Call */ 
   1527	SET_IVOR(9, 0x140) /* Auxiliary Processor Unavailable */ 
   1528	SET_IVOR(10, 0x160) /* Decrementer */ 
   1529	SET_IVOR(11, 0x180) /* Fixed Interval Timer */ 
   1530	SET_IVOR(12, 0x1a0) /* Watchdog Timer */ 
   1531	SET_IVOR(13, 0x1c0) /* Data TLB Error */ 
   1532	SET_IVOR(14, 0x1e0) /* Instruction TLB Error */
   1533	SET_IVOR(15, 0x040) /* Debug */
   1534
   1535	sync
   1536
   1537	blr
   1538
   1539_GLOBAL(setup_altivec_ivors)
   1540	SET_IVOR(32, 0x200) /* AltiVec Unavailable */
   1541	SET_IVOR(33, 0x220) /* AltiVec Assist */
   1542	blr
   1543
   1544_GLOBAL(setup_perfmon_ivor)
   1545	SET_IVOR(35, 0x260) /* Performance Monitor */
   1546	blr
   1547
   1548_GLOBAL(setup_doorbell_ivors)
   1549	SET_IVOR(36, 0x280) /* Processor Doorbell */
   1550	SET_IVOR(37, 0x2a0) /* Processor Doorbell Crit */
   1551	blr
   1552
   1553_GLOBAL(setup_ehv_ivors)
   1554	SET_IVOR(40, 0x300) /* Embedded Hypervisor System Call */
   1555	SET_IVOR(41, 0x320) /* Embedded Hypervisor Privilege */
   1556	SET_IVOR(38, 0x2c0) /* Guest Processor Doorbell */
   1557	SET_IVOR(39, 0x2e0) /* Guest Processor Doorbell Crit/MC */
   1558	blr
   1559
   1560_GLOBAL(setup_lrat_ivor)
   1561	SET_IVOR(42, 0x340) /* LRAT Error */
   1562	blr