xref: /linux/arch/s390/kernel/text_amode31.S (revision 12d5fc96ebbb3b948861805b32a4c3a96105ccd9)
1/* SPDX-License-Identifier: GPL-2.0 */
2/*
3 * Code that needs to run below 2 GB.
4 *
5 * Copyright IBM Corp. 2019
6 */
7
8#include <linux/cfi_types.h>
9#include <linux/linkage.h>
10#include <asm/asm-extable.h>
11#include <asm/errno.h>
12#include <asm/sigp.h>
13
14	.section .amode31.text,"ax"
15/*
16 * Simplified version of expoline thunk. The normal thunks can not be used here,
17 * because they might be more than 2 GB away, and not reachable by the relative
18 * branch. No comdat, exrl, etc. optimizations used here, because it only
19 * affects a few functions that are not performance-relevant.
20 */
21	.macro BR_EX_AMODE31_r14
22	exrl	0,555f
23	j	.
24555:	br	%r14
25	.endm
26
27/*
28 * int _diag14_amode31(unsigned long rx, unsigned long ry1, unsigned long subcode)
29 */
30SYM_TYPED_FUNC_START(_diag14_amode31)
31	lgr	%r1,%r2
32	lgr	%r2,%r3
33	lgr	%r3,%r4
34	lhi	%r5,-EIO
35	sam31
360:	diag	%r1,%r2,0x14
37	ipm	%r5
38	srl	%r5,28
391:	sam64
40	lgfr	%r2,%r5
41	BR_EX_AMODE31_r14
42	EX_TABLE_INSN_AMODE31(0b, 1b)
43SYM_FUNC_END(_diag14_amode31)
44
45/*
46 * int _diag210_amode31(struct diag210 *addr)
47 */
48SYM_TYPED_FUNC_START(_diag210_amode31)
49	lgr	%r1,%r2
50	lhi	%r2,-1
51	sam31
520:	diag	%r1,%r0,0x210
53	ipm	%r2
54	srl	%r2,28
551:	sam64
56	lgfr	%r2,%r2
57	BR_EX_AMODE31_r14
58	EX_TABLE_INSN_AMODE31(0b, 1b)
59SYM_FUNC_END(_diag210_amode31)
60
61/*
62 * int diag8c(struct diag8c *addr, struct ccw_dev_id *devno, size_t len)
63*/
64SYM_TYPED_FUNC_START(_diag8c_amode31)
65	llgf	%r3,0(%r3)
66	sam31
670:	diag	%r2,%r4,0x8c
681:	sam64
69	lgfr	%r2,%r3
70	BR_EX_AMODE31_r14
71	EX_TABLE_INSN_AMODE31(0b, 1b)
72SYM_FUNC_END(_diag8c_amode31)
73/*
74 * int _diag26c_amode31(void *req, void *resp, enum diag26c_sc subcode)
75 */
76SYM_TYPED_FUNC_START(_diag26c_amode31)
77	lghi	%r5,-EOPNOTSUPP
78	sam31
790:	diag	%r2,%r4,0x26c
801:	sam64
81	lgfr	%r2,%r5
82	BR_EX_AMODE31_r14
83	EX_TABLE_INSN_AMODE31(0b, 1b)
84SYM_FUNC_END(_diag26c_amode31)
85
86/*
87 * void _diag0c_amode31(unsigned long rx)
88 */
89SYM_TYPED_FUNC_START(_diag0c_amode31)
90	sam31
91	diag	%r2,%r2,0x0c
92	sam64
93	BR_EX_AMODE31_r14
94SYM_FUNC_END(_diag0c_amode31)
95
96/*
97 * void _diag308_reset_amode31(void)
98 *
99 * Calls diag 308 subcode 1 and continues execution
100 */
101SYM_TYPED_FUNC_START(_diag308_reset_amode31)
102	larl	%r4,ctlregs		# Save control registers
103	stctg	%c0,%c15,0(%r4)
104	lg	%r2,0(%r4)		# Disable lowcore protection
105	nilh	%r2,0xefff
106	larl	%r4,ctlreg0
107	stg	%r2,0(%r4)
108	lctlg	%c0,%c0,0(%r4)
109	larl	%r4,fpctl		# Floating point control register
110	stfpc	0(%r4)
111	larl	%r4,prefix		# Save prefix register
112	stpx	0(%r4)
113	larl	%r4,prefix_zero	# Set prefix register to 0
114	spx	0(%r4)
115	larl	%r4,continue_psw	# Save PSW flags
116	epsw	%r2,%r3
117	stm	%r2,%r3,0(%r4)
118	larl	%r4,.Lrestart_part2	# Setup restart PSW at absolute 0
119	larl	%r3,restart_diag308_psw
120	og	%r4,0(%r3)		# Save PSW
121	lghi	%r3,0
122	sturg	%r4,%r3			# Use sturg, because of large pages
123	lghi	%r1,1
124	lghi	%r0,0
125	diag	%r0,%r1,0x308
126.Lrestart_part2:
127	lhi	%r0,0			# Load r0 with zero
128	lhi	%r1,2			# Use mode 2 = ESAME (dump)
129	sigp	%r1,%r0,SIGP_SET_ARCHITECTURE	# Switch to ESAME mode
130	sam64				# Switch to 64 bit addressing mode
131	larl	%r4,ctlregs		# Restore control registers
132	lctlg	%c0,%c15,0(%r4)
133	larl	%r4,fpctl		# Restore floating point ctl register
134	lfpc	0(%r4)
135	larl	%r4,prefix		# Restore prefix register
136	spx	0(%r4)
137	larl	%r4,continue_psw	# Restore PSW flags
138	larl	%r2,.Lcontinue
139	stg	%r2,8(%r4)
140	lpswe	0(%r4)
141.Lcontinue:
142	BR_EX_AMODE31_r14
143SYM_FUNC_END(_diag308_reset_amode31)
144
145	.section .amode31.data,"aw",@progbits
146	.balign	8
147SYM_DATA_LOCAL(restart_diag308_psw,	.long 0x00080000,0x80000000)
148SYM_DATA_LOCAL(continue_psw,		.quad 0,0)
149SYM_DATA_LOCAL(ctlreg0,			.quad 0)
150SYM_DATA_LOCAL(ctlregs,			.fill 16,8,0)
151SYM_DATA_LOCAL(fpctl,			.long 0)
152SYM_DATA_LOCAL(prefix,			.long 0)
153SYM_DATA_LOCAL(prefix_zero,		.long 0)
154