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