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

assembly.h (14241B)


      1/* SPDX-License-Identifier: GPL-2.0-or-later */
      2/*
      3 * Copyright (C) 1999 Hewlett-Packard (Frank Rowand)
      4 * Copyright (C) 1999 Philipp Rumpf <prumpf@tux.org>
      5 * Copyright (C) 1999 SuSE GmbH
      6 * Copyright (C) 2021 Helge Deller <deller@gmx.de>
      7 */
      8
      9#ifndef _PARISC_ASSEMBLY_H
     10#define _PARISC_ASSEMBLY_H
     11
     12#ifdef CONFIG_64BIT
     13#define RP_OFFSET	16
     14#define FRAME_SIZE	128
     15#define CALLEE_REG_FRAME_SIZE	144
     16#define REG_SZ		8
     17#define ASM_ULONG_INSN	.dword
     18#else	/* CONFIG_64BIT */
     19#define RP_OFFSET	20
     20#define FRAME_SIZE	64
     21#define CALLEE_REG_FRAME_SIZE	128
     22#define REG_SZ		4
     23#define ASM_ULONG_INSN	.word
     24#endif
     25
     26/* Frame alignment for 32- and 64-bit */
     27#define FRAME_ALIGN     64
     28
     29#define CALLEE_FLOAT_FRAME_SIZE	80
     30#define CALLEE_SAVE_FRAME_SIZE (CALLEE_REG_FRAME_SIZE + CALLEE_FLOAT_FRAME_SIZE)
     31
     32#ifdef CONFIG_PA20
     33#define LDCW		ldcw,co
     34#define BL		b,l
     35# ifdef CONFIG_64BIT
     36#  define PA_ASM_LEVEL	2.0w
     37# else
     38#  define PA_ASM_LEVEL	2.0
     39# endif
     40#else
     41#define LDCW		ldcw
     42#define BL		bl
     43#define PA_ASM_LEVEL	1.1
     44#endif
     45
     46/* Privilege level field in the rightmost two bits of the IA queues */
     47#define PRIV_USER	3
     48#define PRIV_KERNEL	0
     49
     50/* Space register used inside kernel */
     51#define SR_KERNEL	0
     52#define SR_TEMP1	1
     53#define SR_TEMP2	2
     54#define SR_USER		3
     55
     56#ifdef __ASSEMBLY__
     57
     58#ifdef CONFIG_64BIT
     59#define LDREG	ldd
     60#define STREG	std
     61#define LDREGX  ldd,s
     62#define LDREGM	ldd,mb
     63#define STREGM	std,ma
     64#define SHRREG	shrd
     65#define SHLREG	shld
     66#define ANDCM   andcm,*
     67#define	COND(x)	* ## x
     68#else	/* CONFIG_64BIT */
     69#define LDREG	ldw
     70#define STREG	stw
     71#define LDREGX  ldwx,s
     72#define LDREGM	ldwm
     73#define STREGM	stwm
     74#define SHRREG	shr
     75#define SHLREG	shlw
     76#define ANDCM   andcm
     77#define COND(x)	x
     78#endif
     79
     80#ifdef CONFIG_64BIT
     81/* the 64-bit pa gnu assembler unfortunately defaults to .level 1.1 or 2.0 so
     82 * work around that for now... */
     83	.level 2.0w
     84#endif
     85
     86#include <asm/asm-offsets.h>
     87#include <asm/page.h>
     88#include <asm/types.h>
     89
     90#include <asm/asmregs.h>
     91#include <asm/psw.h>
     92
     93	sp	=	30
     94	gp	=	27
     95	ipsw	=	22
     96
     97	/*
     98	 * We provide two versions of each macro to convert from physical
     99	 * to virtual and vice versa. The "_r1" versions take one argument
    100	 * register, but trashes r1 to do the conversion. The other
    101	 * version takes two arguments: a src and destination register.
    102	 * However, the source and destination registers can not be
    103	 * the same register.
    104	 */
    105
    106	.macro  tophys  grvirt, grphys
    107	ldil    L%(__PAGE_OFFSET), \grphys
    108	sub     \grvirt, \grphys, \grphys
    109	.endm
    110	
    111	.macro  tovirt  grphys, grvirt
    112	ldil    L%(__PAGE_OFFSET), \grvirt
    113	add     \grphys, \grvirt, \grvirt
    114	.endm
    115
    116	.macro  tophys_r1  gr
    117	ldil    L%(__PAGE_OFFSET), %r1
    118	sub     \gr, %r1, \gr
    119	.endm
    120	
    121	.macro  tovirt_r1  gr
    122	ldil    L%(__PAGE_OFFSET), %r1
    123	add     \gr, %r1, \gr
    124	.endm
    125
    126	.macro delay value
    127	ldil	L%\value, 1
    128	ldo	R%\value(1), 1
    129	addib,UV,n -1,1,.
    130	addib,NUV,n -1,1,.+8
    131	nop
    132	.endm
    133
    134	.macro	debug value
    135	.endm
    136
    137	.macro shlw r, sa, t
    138	zdep	\r, 31-(\sa), 32-(\sa), \t
    139	.endm
    140
    141	/* And the PA 2.0W shift left */
    142	.macro shld r, sa, t
    143	depd,z	\r, 63-(\sa), 64-(\sa), \t
    144	.endm
    145
    146	/* Shift Right for 32-bit. Clobbers upper 32-bit on PA2.0. */
    147	.macro shr r, sa, t
    148	extru \r, 31-(\sa), 32-(\sa), \t
    149	.endm
    150
    151	/* pa20w version of shift right */
    152	.macro shrd r, sa, t
    153	extrd,u \r, 63-(\sa), 64-(\sa), \t
    154	.endm
    155
    156	/* Extract unsigned for 32- and 64-bit
    157	 * The extru instruction leaves the most significant 32 bits of the
    158	 * target register in an undefined state on PA 2.0 systems. */
    159	.macro extru_safe r, p, len, t
    160#ifdef CONFIG_64BIT
    161	extrd,u	\r, 32+(\p), \len, \t
    162#else
    163	extru	\r, \p, \len, \t
    164#endif
    165	.endm
    166
    167	/* The depi instruction leaves the most significant 32 bits of the
    168	 * target register in an undefined state on PA 2.0 systems. */
    169	.macro depi_safe i, p, len, t
    170#ifdef CONFIG_64BIT
    171	depdi	\i, 32+(\p), \len, \t
    172#else
    173	depi	\i, \p, \len, \t
    174#endif
    175	.endm
    176
    177	/* The depw instruction leaves the most significant 32 bits of the
    178	 * target register in an undefined state on PA 2.0 systems. */
    179	.macro dep_safe i, p, len, t
    180#ifdef CONFIG_64BIT
    181	depd	\i, 32+(\p), \len, \t
    182#else
    183	depw	\i, \p, \len, \t
    184#endif
    185	.endm
    186
    187	/* load 32-bit 'value' into 'reg' compensating for the ldil
    188	 * sign-extension when running in wide mode.
    189	 * WARNING!! neither 'value' nor 'reg' can be expressions
    190	 * containing '.'!!!! */
    191	.macro	load32 value, reg
    192	ldil	L%\value, \reg
    193	ldo	R%\value(\reg), \reg
    194	.endm
    195
    196	.macro loadgp
    197#ifdef CONFIG_64BIT
    198	ldil		L%__gp, %r27
    199	ldo		R%__gp(%r27), %r27
    200#else
    201	ldil		L%$global$, %r27
    202	ldo		R%$global$(%r27), %r27
    203#endif
    204	.endm
    205
    206#define SAVE_SP(r, where) mfsp r, %r1 ! STREG %r1, where
    207#define REST_SP(r, where) LDREG where, %r1 ! mtsp %r1, r
    208#define SAVE_CR(r, where) mfctl r, %r1 ! STREG %r1, where
    209#define REST_CR(r, where) LDREG where, %r1 ! mtctl %r1, r
    210
    211	.macro	save_general	regs
    212	STREG %r1, PT_GR1 (\regs)
    213	STREG %r2, PT_GR2 (\regs)
    214	STREG %r3, PT_GR3 (\regs)
    215	STREG %r4, PT_GR4 (\regs)
    216	STREG %r5, PT_GR5 (\regs)
    217	STREG %r6, PT_GR6 (\regs)
    218	STREG %r7, PT_GR7 (\regs)
    219	STREG %r8, PT_GR8 (\regs)
    220	STREG %r9, PT_GR9 (\regs)
    221	STREG %r10, PT_GR10(\regs)
    222	STREG %r11, PT_GR11(\regs)
    223	STREG %r12, PT_GR12(\regs)
    224	STREG %r13, PT_GR13(\regs)
    225	STREG %r14, PT_GR14(\regs)
    226	STREG %r15, PT_GR15(\regs)
    227	STREG %r16, PT_GR16(\regs)
    228	STREG %r17, PT_GR17(\regs)
    229	STREG %r18, PT_GR18(\regs)
    230	STREG %r19, PT_GR19(\regs)
    231	STREG %r20, PT_GR20(\regs)
    232	STREG %r21, PT_GR21(\regs)
    233	STREG %r22, PT_GR22(\regs)
    234	STREG %r23, PT_GR23(\regs)
    235	STREG %r24, PT_GR24(\regs)
    236	STREG %r25, PT_GR25(\regs)
    237	/* r26 is saved in get_stack and used to preserve a value across virt_map */
    238	STREG %r27, PT_GR27(\regs)
    239	STREG %r28, PT_GR28(\regs)
    240	/* r29 is saved in get_stack and used to point to saved registers */
    241	/* r30 stack pointer saved in get_stack */
    242	STREG %r31, PT_GR31(\regs)
    243	.endm
    244
    245	.macro	rest_general	regs
    246	/* r1 used as a temp in rest_stack and is restored there */
    247	LDREG PT_GR2 (\regs), %r2
    248	LDREG PT_GR3 (\regs), %r3
    249	LDREG PT_GR4 (\regs), %r4
    250	LDREG PT_GR5 (\regs), %r5
    251	LDREG PT_GR6 (\regs), %r6
    252	LDREG PT_GR7 (\regs), %r7
    253	LDREG PT_GR8 (\regs), %r8
    254	LDREG PT_GR9 (\regs), %r9
    255	LDREG PT_GR10(\regs), %r10
    256	LDREG PT_GR11(\regs), %r11
    257	LDREG PT_GR12(\regs), %r12
    258	LDREG PT_GR13(\regs), %r13
    259	LDREG PT_GR14(\regs), %r14
    260	LDREG PT_GR15(\regs), %r15
    261	LDREG PT_GR16(\regs), %r16
    262	LDREG PT_GR17(\regs), %r17
    263	LDREG PT_GR18(\regs), %r18
    264	LDREG PT_GR19(\regs), %r19
    265	LDREG PT_GR20(\regs), %r20
    266	LDREG PT_GR21(\regs), %r21
    267	LDREG PT_GR22(\regs), %r22
    268	LDREG PT_GR23(\regs), %r23
    269	LDREG PT_GR24(\regs), %r24
    270	LDREG PT_GR25(\regs), %r25
    271	LDREG PT_GR26(\regs), %r26
    272	LDREG PT_GR27(\regs), %r27
    273	LDREG PT_GR28(\regs), %r28
    274	/* r29 points to register save area, and is restored in rest_stack */
    275	/* r30 stack pointer restored in rest_stack */
    276	LDREG PT_GR31(\regs), %r31
    277	.endm
    278
    279	.macro	save_fp 	regs
    280	fstd,ma  %fr0, 8(\regs)
    281	fstd,ma	 %fr1, 8(\regs)
    282	fstd,ma	 %fr2, 8(\regs)
    283	fstd,ma	 %fr3, 8(\regs)
    284	fstd,ma	 %fr4, 8(\regs)
    285	fstd,ma	 %fr5, 8(\regs)
    286	fstd,ma	 %fr6, 8(\regs)
    287	fstd,ma	 %fr7, 8(\regs)
    288	fstd,ma	 %fr8, 8(\regs)
    289	fstd,ma	 %fr9, 8(\regs)
    290	fstd,ma	%fr10, 8(\regs)
    291	fstd,ma	%fr11, 8(\regs)
    292	fstd,ma	%fr12, 8(\regs)
    293	fstd,ma	%fr13, 8(\regs)
    294	fstd,ma	%fr14, 8(\regs)
    295	fstd,ma	%fr15, 8(\regs)
    296	fstd,ma	%fr16, 8(\regs)
    297	fstd,ma	%fr17, 8(\regs)
    298	fstd,ma	%fr18, 8(\regs)
    299	fstd,ma	%fr19, 8(\regs)
    300	fstd,ma	%fr20, 8(\regs)
    301	fstd,ma	%fr21, 8(\regs)
    302	fstd,ma	%fr22, 8(\regs)
    303	fstd,ma	%fr23, 8(\regs)
    304	fstd,ma	%fr24, 8(\regs)
    305	fstd,ma	%fr25, 8(\regs)
    306	fstd,ma	%fr26, 8(\regs)
    307	fstd,ma	%fr27, 8(\regs)
    308	fstd,ma	%fr28, 8(\regs)
    309	fstd,ma	%fr29, 8(\regs)
    310	fstd,ma	%fr30, 8(\regs)
    311	fstd	%fr31, 0(\regs)
    312	.endm
    313
    314	.macro	rest_fp 	regs
    315	fldd	0(\regs),	 %fr31
    316	fldd,mb	-8(\regs),       %fr30
    317	fldd,mb	-8(\regs),       %fr29
    318	fldd,mb	-8(\regs),       %fr28
    319	fldd,mb	-8(\regs),       %fr27
    320	fldd,mb	-8(\regs),       %fr26
    321	fldd,mb	-8(\regs),       %fr25
    322	fldd,mb	-8(\regs),       %fr24
    323	fldd,mb	-8(\regs),       %fr23
    324	fldd,mb	-8(\regs),       %fr22
    325	fldd,mb	-8(\regs),       %fr21
    326	fldd,mb	-8(\regs),       %fr20
    327	fldd,mb	-8(\regs),       %fr19
    328	fldd,mb	-8(\regs),       %fr18
    329	fldd,mb	-8(\regs),       %fr17
    330	fldd,mb	-8(\regs),       %fr16
    331	fldd,mb	-8(\regs),       %fr15
    332	fldd,mb	-8(\regs),       %fr14
    333	fldd,mb	-8(\regs),       %fr13
    334	fldd,mb	-8(\regs),       %fr12
    335	fldd,mb	-8(\regs),       %fr11
    336	fldd,mb	-8(\regs),       %fr10
    337	fldd,mb	-8(\regs),       %fr9
    338	fldd,mb	-8(\regs),       %fr8
    339	fldd,mb	-8(\regs),       %fr7
    340	fldd,mb	-8(\regs),       %fr6
    341	fldd,mb	-8(\regs),       %fr5
    342	fldd,mb	-8(\regs),       %fr4
    343	fldd,mb	-8(\regs),       %fr3
    344	fldd,mb	-8(\regs),       %fr2
    345	fldd,mb	-8(\regs),       %fr1
    346	fldd,mb	-8(\regs),       %fr0
    347	.endm
    348
    349	.macro	callee_save_float
    350	fstd,ma	 %fr12,	8(%r30)
    351	fstd,ma	 %fr13,	8(%r30)
    352	fstd,ma	 %fr14,	8(%r30)
    353	fstd,ma	 %fr15,	8(%r30)
    354	fstd,ma	 %fr16,	8(%r30)
    355	fstd,ma	 %fr17,	8(%r30)
    356	fstd,ma	 %fr18,	8(%r30)
    357	fstd,ma	 %fr19,	8(%r30)
    358	fstd,ma	 %fr20,	8(%r30)
    359	fstd,ma	 %fr21,	8(%r30)
    360	.endm
    361
    362	.macro	callee_rest_float
    363	fldd,mb	-8(%r30),   %fr21
    364	fldd,mb	-8(%r30),   %fr20
    365	fldd,mb	-8(%r30),   %fr19
    366	fldd,mb	-8(%r30),   %fr18
    367	fldd,mb	-8(%r30),   %fr17
    368	fldd,mb	-8(%r30),   %fr16
    369	fldd,mb	-8(%r30),   %fr15
    370	fldd,mb	-8(%r30),   %fr14
    371	fldd,mb	-8(%r30),   %fr13
    372	fldd,mb	-8(%r30),   %fr12
    373	.endm
    374
    375#ifdef CONFIG_64BIT
    376	.macro	callee_save
    377	std,ma	  %r3,	 CALLEE_REG_FRAME_SIZE(%r30)
    378	mfctl	  %cr27, %r3
    379	std	  %r4,	-136(%r30)
    380	std	  %r5,	-128(%r30)
    381	std	  %r6,	-120(%r30)
    382	std	  %r7,	-112(%r30)
    383	std	  %r8,	-104(%r30)
    384	std	  %r9,	 -96(%r30)
    385	std	 %r10,	 -88(%r30)
    386	std	 %r11,	 -80(%r30)
    387	std	 %r12,	 -72(%r30)
    388	std	 %r13,	 -64(%r30)
    389	std	 %r14,	 -56(%r30)
    390	std	 %r15,	 -48(%r30)
    391	std	 %r16,	 -40(%r30)
    392	std	 %r17,	 -32(%r30)
    393	std	 %r18,	 -24(%r30)
    394	std	  %r3,	 -16(%r30)
    395	.endm
    396
    397	.macro	callee_rest
    398	ldd	 -16(%r30),    %r3
    399	ldd	 -24(%r30),   %r18
    400	ldd	 -32(%r30),   %r17
    401	ldd	 -40(%r30),   %r16
    402	ldd	 -48(%r30),   %r15
    403	ldd	 -56(%r30),   %r14
    404	ldd	 -64(%r30),   %r13
    405	ldd	 -72(%r30),   %r12
    406	ldd	 -80(%r30),   %r11
    407	ldd	 -88(%r30),   %r10
    408	ldd	 -96(%r30),    %r9
    409	ldd	-104(%r30),    %r8
    410	ldd	-112(%r30),    %r7
    411	ldd	-120(%r30),    %r6
    412	ldd	-128(%r30),    %r5
    413	ldd	-136(%r30),    %r4
    414	mtctl	%r3, %cr27
    415	ldd,mb	-CALLEE_REG_FRAME_SIZE(%r30),    %r3
    416	.endm
    417
    418#else /* ! CONFIG_64BIT */
    419
    420	.macro	callee_save
    421	stw,ma	 %r3,	CALLEE_REG_FRAME_SIZE(%r30)
    422	mfctl	 %cr27, %r3
    423	stw	 %r4,	-124(%r30)
    424	stw	 %r5,	-120(%r30)
    425	stw	 %r6,	-116(%r30)
    426	stw	 %r7,	-112(%r30)
    427	stw	 %r8,	-108(%r30)
    428	stw	 %r9,	-104(%r30)
    429	stw	 %r10,	-100(%r30)
    430	stw	 %r11,	 -96(%r30)
    431	stw	 %r12,	 -92(%r30)
    432	stw	 %r13,	 -88(%r30)
    433	stw	 %r14,	 -84(%r30)
    434	stw	 %r15,	 -80(%r30)
    435	stw	 %r16,	 -76(%r30)
    436	stw	 %r17,	 -72(%r30)
    437	stw	 %r18,	 -68(%r30)
    438	stw	  %r3,	 -64(%r30)
    439	.endm
    440
    441	.macro	callee_rest
    442	ldw	 -64(%r30),    %r3
    443	ldw	 -68(%r30),   %r18
    444	ldw	 -72(%r30),   %r17
    445	ldw	 -76(%r30),   %r16
    446	ldw	 -80(%r30),   %r15
    447	ldw	 -84(%r30),   %r14
    448	ldw	 -88(%r30),   %r13
    449	ldw	 -92(%r30),   %r12
    450	ldw	 -96(%r30),   %r11
    451	ldw	-100(%r30),   %r10
    452	ldw	-104(%r30),   %r9
    453	ldw	-108(%r30),   %r8
    454	ldw	-112(%r30),   %r7
    455	ldw	-116(%r30),   %r6
    456	ldw	-120(%r30),   %r5
    457	ldw	-124(%r30),   %r4
    458	mtctl	%r3, %cr27
    459	ldw,mb	-CALLEE_REG_FRAME_SIZE(%r30),   %r3
    460	.endm
    461#endif /* ! CONFIG_64BIT */
    462
    463	.macro	save_specials	regs
    464
    465	SAVE_SP  (%sr0, PT_SR0 (\regs))
    466	SAVE_SP  (%sr1, PT_SR1 (\regs))
    467	SAVE_SP  (%sr2, PT_SR2 (\regs))
    468	SAVE_SP  (%sr3, PT_SR3 (\regs))
    469	SAVE_SP  (%sr4, PT_SR4 (\regs))
    470	SAVE_SP  (%sr5, PT_SR5 (\regs))
    471	SAVE_SP  (%sr6, PT_SR6 (\regs))
    472
    473	SAVE_CR  (%cr17, PT_IASQ0(\regs))
    474	mtctl	 %r0,	%cr17
    475	SAVE_CR  (%cr17, PT_IASQ1(\regs))
    476
    477	SAVE_CR  (%cr18, PT_IAOQ0(\regs))
    478	mtctl	 %r0,	%cr18
    479	SAVE_CR  (%cr18, PT_IAOQ1(\regs))
    480
    481#ifdef CONFIG_64BIT
    482	/* cr11 (sar) is a funny one.  5 bits on PA1.1 and 6 bit on PA2.0
    483	 * For PA2.0 mtsar or mtctl always write 6 bits, but mfctl only
    484	 * reads 5 bits.  Use mfctl,w to read all six bits.  Otherwise
    485	 * we lose the 6th bit on a save/restore over interrupt.
    486	 */
    487	mfctl,w  %cr11, %r1
    488	STREG    %r1, PT_SAR (\regs)
    489#else
    490	SAVE_CR  (%cr11, PT_SAR  (\regs))
    491#endif
    492	SAVE_CR  (%cr19, PT_IIR  (\regs))
    493
    494	/*
    495	 * Code immediately following this macro (in intr_save) relies
    496	 * on r8 containing ipsw.
    497	 */
    498	mfctl    %cr22, %r8
    499	STREG    %r8,   PT_PSW(\regs)
    500	.endm
    501
    502	.macro	rest_specials	regs
    503
    504	REST_SP  (%sr0, PT_SR0 (\regs))
    505	REST_SP  (%sr1, PT_SR1 (\regs))
    506	REST_SP  (%sr2, PT_SR2 (\regs))
    507	REST_SP  (%sr3, PT_SR3 (\regs))
    508	REST_SP  (%sr4, PT_SR4 (\regs))
    509	REST_SP  (%sr5, PT_SR5 (\regs))
    510	REST_SP  (%sr6, PT_SR6 (\regs))
    511	REST_SP  (%sr7, PT_SR7 (\regs))
    512
    513	REST_CR	(%cr17, PT_IASQ0(\regs))
    514	REST_CR	(%cr17, PT_IASQ1(\regs))
    515
    516	REST_CR	(%cr18, PT_IAOQ0(\regs))
    517	REST_CR	(%cr18, PT_IAOQ1(\regs))
    518
    519	REST_CR (%cr11, PT_SAR	(\regs))
    520
    521	REST_CR	(%cr22, PT_PSW	(\regs))
    522	.endm
    523
    524
    525	/* First step to create a "relied upon translation"
    526	 * See PA 2.0 Arch. page F-4 and F-5.
    527	 *
    528	 * The ssm was originally necessary due to a "PCxT bug".
    529	 * But someone decided it needed to be added to the architecture
    530	 * and this "feature" went into rev3 of PA-RISC 1.1 Arch Manual.
    531	 * It's been carried forward into PA 2.0 Arch as well. :^(
    532	 *
    533	 * "ssm 0,%r0" is a NOP with side effects (prefetch barrier).
    534	 * rsm/ssm prevents the ifetch unit from speculatively fetching
    535	 * instructions past this line in the code stream.
    536	 * PA 2.0 processor will single step all insn in the same QUAD (4 insn).
    537	 */
    538	.macro	pcxt_ssm_bug
    539	rsm	PSW_SM_I,%r0
    540	nop	/* 1 */
    541	nop	/* 2 */
    542	nop	/* 3 */
    543	nop	/* 4 */
    544	nop	/* 5 */
    545	nop	/* 6 */
    546	nop	/* 7 */
    547	.endm
    548
    549	/* Switch to virtual mapping, trashing only %r1 */
    550	.macro  virt_map
    551	/* pcxt_ssm_bug */
    552	rsm	PSW_SM_I, %r0		/* barrier for "Relied upon Translation */
    553	mtsp	%r0, %sr4
    554	mtsp	%r0, %sr5
    555	mtsp	%r0, %sr6
    556	tovirt_r1 %r29
    557	load32	KERNEL_PSW, %r1
    558
    559	rsm     PSW_SM_QUIET,%r0	/* second "heavy weight" ctl op */
    560	mtctl	%r0, %cr17		/* Clear IIASQ tail */
    561	mtctl	%r0, %cr17		/* Clear IIASQ head */
    562	mtctl	%r1, %ipsw
    563	load32	4f, %r1
    564	mtctl	%r1, %cr18		/* Set IIAOQ tail */
    565	ldo	4(%r1), %r1
    566	mtctl	%r1, %cr18		/* Set IIAOQ head */
    567	rfir
    568	nop
    5694:
    570	.endm
    571
    572
    573	/*
    574	 * ASM_EXCEPTIONTABLE_ENTRY
    575	 *
    576	 * Creates an exception table entry.
    577	 * Do not convert to a assembler macro. This won't work.
    578	 */
    579#define ASM_EXCEPTIONTABLE_ENTRY(fault_addr, except_addr)	\
    580	.section __ex_table,"aw"			!	\
    581	.word (fault_addr - .), (except_addr - .)	!	\
    582	.previous
    583
    584
    585#endif /* __ASSEMBLY__ */
    586#endif