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