Linux-libre 5.3.12-gnu
[librecmc/linux-libre.git] / arch / s390 / boot / text_dma.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/errno.h>
10 #include <asm/sigp.h>
11
12 #ifdef CC_USING_EXPOLINE
13         .pushsection .dma.text.__s390_indirect_jump_r14,"axG"
14 __dma__s390_indirect_jump_r14:
15         larl    %r1,0f
16         ex      0,0(%r1)
17         j       .
18 0:      br      %r14
19         .popsection
20 #endif
21
22         .section .dma.text,"ax"
23 /*
24  * Simplified version of expoline thunk. The normal thunks can not be used here,
25  * because they might be more than 2 GB away, and not reachable by the relative
26  * branch. No comdat, exrl, etc. optimizations used here, because it only
27  * affects a few functions that are not performance-relevant.
28  */
29         .macro BR_EX_DMA_r14
30 #ifdef CC_USING_EXPOLINE
31         jg      __dma__s390_indirect_jump_r14
32 #else
33         br      %r14
34 #endif
35         .endm
36
37 /*
38  * int _diag14_dma(unsigned long rx, unsigned long ry1, unsigned long subcode)
39  */
40 ENTRY(_diag14_dma)
41         lgr     %r1,%r2
42         lgr     %r2,%r3
43         lgr     %r3,%r4
44         lhi     %r5,-EIO
45         sam31
46         diag    %r1,%r2,0x14
47 .Ldiag14_ex:
48         ipm     %r5
49         srl     %r5,28
50 .Ldiag14_fault:
51         sam64
52         lgfr    %r2,%r5
53         BR_EX_DMA_r14
54         EX_TABLE_DMA(.Ldiag14_ex, .Ldiag14_fault)
55 ENDPROC(_diag14_dma)
56
57 /*
58  * int _diag210_dma(struct diag210 *addr)
59  */
60 ENTRY(_diag210_dma)
61         lgr     %r1,%r2
62         lhi     %r2,-1
63         sam31
64         diag    %r1,%r0,0x210
65 .Ldiag210_ex:
66         ipm     %r2
67         srl     %r2,28
68 .Ldiag210_fault:
69         sam64
70         lgfr    %r2,%r2
71         BR_EX_DMA_r14
72         EX_TABLE_DMA(.Ldiag210_ex, .Ldiag210_fault)
73 ENDPROC(_diag210_dma)
74
75 /*
76  * int _diag26c_dma(void *req, void *resp, enum diag26c_sc subcode)
77  */
78 ENTRY(_diag26c_dma)
79         lghi    %r5,-EOPNOTSUPP
80         sam31
81         diag    %r2,%r4,0x26c
82 .Ldiag26c_ex:
83         sam64
84         lgfr    %r2,%r5
85         BR_EX_DMA_r14
86         EX_TABLE_DMA(.Ldiag26c_ex, .Ldiag26c_ex)
87 ENDPROC(_diag26c_dma)
88
89 /*
90  * void _diag0c_dma(struct hypfs_diag0c_entry *entry)
91  */
92 ENTRY(_diag0c_dma)
93         sam31
94         diag    %r2,%r2,0x0c
95         sam64
96         BR_EX_DMA_r14
97 ENDPROC(_diag0c_dma)
98
99 /*
100  * void _swsusp_reset_dma(void)
101  */
102 ENTRY(_swsusp_reset_dma)
103         larl    %r1,restart_entry
104         larl    %r2,.Lrestart_diag308_psw
105         og      %r1,0(%r2)
106         stg     %r1,0(%r0)
107         lghi    %r0,0
108         diag    %r0,%r0,0x308
109 restart_entry:
110         lhi     %r1,1
111         sigp    %r1,%r0,SIGP_SET_ARCHITECTURE
112         sam64
113         BR_EX_DMA_r14
114 ENDPROC(_swsusp_reset_dma)
115
116 /*
117  * void _diag308_reset_dma(void)
118  *
119  * Calls diag 308 subcode 1 and continues execution
120  */
121 ENTRY(_diag308_reset_dma)
122         larl    %r4,.Lctlregs           # Save control registers
123         stctg   %c0,%c15,0(%r4)
124         lg      %r2,0(%r4)              # Disable lowcore protection
125         nilh    %r2,0xefff
126         larl    %r4,.Lctlreg0
127         stg     %r2,0(%r4)
128         lctlg   %c0,%c0,0(%r4)
129         larl    %r4,.Lfpctl             # Floating point control register
130         stfpc   0(%r4)
131         larl    %r4,.Lprefix            # Save prefix register
132         stpx    0(%r4)
133         larl    %r4,.Lprefix_zero       # Set prefix register to 0
134         spx     0(%r4)
135         larl    %r4,.Lcontinue_psw      # Save PSW flags
136         epsw    %r2,%r3
137         stm     %r2,%r3,0(%r4)
138         larl    %r4,restart_part2       # Setup restart PSW at absolute 0
139         larl    %r3,.Lrestart_diag308_psw
140         og      %r4,0(%r3)              # Save PSW
141         lghi    %r3,0
142         sturg   %r4,%r3                 # Use sturg, because of large pages
143         lghi    %r1,1
144         lghi    %r0,0
145         diag    %r0,%r1,0x308
146 restart_part2:
147         lhi     %r0,0                   # Load r0 with zero
148         lhi     %r1,2                   # Use mode 2 = ESAME (dump)
149         sigp    %r1,%r0,SIGP_SET_ARCHITECTURE   # Switch to ESAME mode
150         sam64                           # Switch to 64 bit addressing mode
151         larl    %r4,.Lctlregs           # Restore control registers
152         lctlg   %c0,%c15,0(%r4)
153         larl    %r4,.Lfpctl             # Restore floating point ctl register
154         lfpc    0(%r4)
155         larl    %r4,.Lprefix            # Restore prefix register
156         spx     0(%r4)
157         larl    %r4,.Lcontinue_psw      # Restore PSW flags
158         lpswe   0(%r4)
159 .Lcontinue:
160         BR_EX_DMA_r14
161 ENDPROC(_diag308_reset_dma)
162
163         .section .dma.data,"aw",@progbits
164 .align  8
165 .Lrestart_diag308_psw:
166         .long   0x00080000,0x80000000
167
168 .align 8
169 .Lcontinue_psw:
170         .quad   0,.Lcontinue
171
172 .align 8
173 .Lctlreg0:
174         .quad   0
175 .Lctlregs:
176         .rept   16
177         .quad   0
178         .endr
179 .Lfpctl:
180         .long   0
181 .Lprefix:
182         .long   0
183 .Lprefix_zero:
184         .long   0