zonefs: convert zonefs to use the new mount api
[sfrench/cifs-2.6.git] / arch / s390 / kernel / text_amode31.S
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>
9 #include <asm/asm-extable.h>
10 #include <asm/errno.h>
11 #include <asm/sigp.h>
12
13         .section .amode31.text,"ax"
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  */
20         .macro BR_EX_AMODE31_r14
21         larl    %r1,0f
22         ex      0,0(%r1)
23         j       .
24 0:      br      %r14
25         .endm
26
27 /*
28  * int _diag14_amode31(unsigned long rx, unsigned long ry1, unsigned long subcode)
29  */
30 SYM_FUNC_START(_diag14_amode31)
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
43         BR_EX_AMODE31_r14
44         EX_TABLE_AMODE31(.Ldiag14_ex, .Ldiag14_fault)
45 SYM_FUNC_END(_diag14_amode31)
46
47 /*
48  * int _diag210_amode31(struct diag210 *addr)
49  */
50 SYM_FUNC_START(_diag210_amode31)
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
61         BR_EX_AMODE31_r14
62         EX_TABLE_AMODE31(.Ldiag210_ex, .Ldiag210_fault)
63 SYM_FUNC_END(_diag210_amode31)
64
65 /*
66  * int diag8c(struct diag8c *addr, struct ccw_dev_id *devno, size_t len)
67 */
68 SYM_FUNC_START(_diag8c_amode31)
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)
77 SYM_FUNC_END(_diag8c_amode31)
78 /*
79  * int _diag26c_amode31(void *req, void *resp, enum diag26c_sc subcode)
80  */
81 SYM_FUNC_START(_diag26c_amode31)
82         lghi    %r5,-EOPNOTSUPP
83         sam31
84         diag    %r2,%r4,0x26c
85 .Ldiag26c_ex:
86         sam64
87         lgfr    %r2,%r5
88         BR_EX_AMODE31_r14
89         EX_TABLE_AMODE31(.Ldiag26c_ex, .Ldiag26c_ex)
90 SYM_FUNC_END(_diag26c_amode31)
91
92 /*
93  * void _diag0c_amode31(struct hypfs_diag0c_entry *entry)
94  */
95 SYM_FUNC_START(_diag0c_amode31)
96         sam31
97         diag    %r2,%r2,0x0c
98         sam64
99         BR_EX_AMODE31_r14
100 SYM_FUNC_END(_diag0c_amode31)
101
102 /*
103  * void _diag308_reset_amode31(void)
104  *
105  * Calls diag 308 subcode 1 and continues execution
106  */
107 SYM_FUNC_START(_diag308_reset_amode31)
108         larl    %r4,ctlregs             # Save control registers
109         stctg   %c0,%c15,0(%r4)
110         lg      %r2,0(%r4)              # Disable lowcore protection
111         nilh    %r2,0xefff
112         larl    %r4,ctlreg0
113         stg     %r2,0(%r4)
114         lctlg   %c0,%c0,0(%r4)
115         larl    %r4,fpctl               # Floating point control register
116         stfpc   0(%r4)
117         larl    %r4,prefix              # Save prefix register
118         stpx    0(%r4)
119         larl    %r4,prefix_zero # Set prefix register to 0
120         spx     0(%r4)
121         larl    %r4,continue_psw        # Save PSW flags
122         epsw    %r2,%r3
123         stm     %r2,%r3,0(%r4)
124         larl    %r4,.Lrestart_part2     # Setup restart PSW at absolute 0
125         larl    %r3,restart_diag308_psw
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
132 .Lrestart_part2:
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
137         larl    %r4,ctlregs             # Restore control registers
138         lctlg   %c0,%c15,0(%r4)
139         larl    %r4,fpctl               # Restore floating point ctl register
140         lfpc    0(%r4)
141         larl    %r4,prefix              # Restore prefix register
142         spx     0(%r4)
143         larl    %r4,continue_psw        # Restore PSW flags
144         larl    %r2,.Lcontinue
145         stg     %r2,8(%r4)
146         lpswe   0(%r4)
147 .Lcontinue:
148         BR_EX_AMODE31_r14
149 SYM_FUNC_END(_diag308_reset_amode31)
150
151         .section .amode31.data,"aw",@progbits
152         .balign 8
153 SYM_DATA_LOCAL(restart_diag308_psw,     .long 0x00080000,0x80000000)
154 SYM_DATA_LOCAL(continue_psw,            .quad 0,0)
155 SYM_DATA_LOCAL(ctlreg0,                 .quad 0)
156 SYM_DATA_LOCAL(ctlregs,                 .fill 16,8,0)
157 SYM_DATA_LOCAL(fpctl,                   .long 0)
158 SYM_DATA_LOCAL(prefix,                  .long 0)
159 SYM_DATA_LOCAL(prefix_zero,             .long 0)