WIP FPC-III support
[linux/fpc-iii.git] / arch / s390 / boot / text_dma.S
blobf7c77cd518f2ba5fa2f9d21fac2d8a655988735b
1 /* SPDX-License-Identifier: GPL-2.0 */
2 /*
3  * Code that needs to run below 2 GB.
4  *
5  * Copyright IBM Corp. 2019
6  */
8 #include <linux/linkage.h>
9 #include <asm/errno.h>
10 #include <asm/sigp.h>
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
22         .section .dma.text,"ax"
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
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)
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)
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)
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)
100  * void _diag308_reset_dma(void)
102  * Calls diag 308 subcode 1 and continues execution
103  */
104 ENTRY(_diag308_reset_dma)
105         larl    %r4,.Lctlregs           # Save control registers
106         stctg   %c0,%c15,0(%r4)
107         lg      %r2,0(%r4)              # Disable lowcore protection
108         nilh    %r2,0xefff
109         larl    %r4,.Lctlreg0
110         stg     %r2,0(%r4)
111         lctlg   %c0,%c0,0(%r4)
112         larl    %r4,.Lfpctl             # Floating point control register
113         stfpc   0(%r4)
114         larl    %r4,.Lprefix            # Save prefix register
115         stpx    0(%r4)
116         larl    %r4,.Lprefix_zero       # Set prefix register to 0
117         spx     0(%r4)
118         larl    %r4,.Lcontinue_psw      # Save PSW flags
119         epsw    %r2,%r3
120         stm     %r2,%r3,0(%r4)
121         larl    %r4,restart_part2       # Setup restart PSW at absolute 0
122         larl    %r3,.Lrestart_diag308_psw
123         og      %r4,0(%r3)              # Save PSW
124         lghi    %r3,0
125         sturg   %r4,%r3                 # Use sturg, because of large pages
126         lghi    %r1,1
127         lghi    %r0,0
128         diag    %r0,%r1,0x308
129 restart_part2:
130         lhi     %r0,0                   # Load r0 with zero
131         lhi     %r1,2                   # Use mode 2 = ESAME (dump)
132         sigp    %r1,%r0,SIGP_SET_ARCHITECTURE   # Switch to ESAME mode
133         sam64                           # Switch to 64 bit addressing mode
134         larl    %r4,.Lctlregs           # Restore control registers
135         lctlg   %c0,%c15,0(%r4)
136         larl    %r4,.Lfpctl             # Restore floating point ctl register
137         lfpc    0(%r4)
138         larl    %r4,.Lprefix            # Restore prefix register
139         spx     0(%r4)
140         larl    %r4,.Lcontinue_psw      # Restore PSW flags
141         lpswe   0(%r4)
142 .Lcontinue:
143         BR_EX_DMA_r14
144 ENDPROC(_diag308_reset_dma)
146         .section .dma.data,"aw",@progbits
147 .align  8
148 .Lrestart_diag308_psw:
149         .long   0x00080000,0x80000000
151 .align 8
152 .Lcontinue_psw:
153         .quad   0,.Lcontinue
155 .align 8
156 .Lctlreg0:
157         .quad   0
158 .Lctlregs:
159         .rept   16
160         .quad   0
161         .endr
162 .Lfpctl:
163         .long   0
164 .Lprefix:
165         .long   0
166 .Lprefix_zero:
167         .long   0