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