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