• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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	.
230:	br	%r14
24	.endm
25
26/*
27 * int _diag14_dma(unsigned long rx, unsigned long ry1, unsigned long subcode)
28 */
29ENTRY(_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)
44ENDPROC(_diag14_dma)
45
46/*
47 * int _diag210_dma(struct diag210 *addr)
48 */
49ENTRY(_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)
62ENDPROC(_diag210_dma)
63
64/*
65 * int _diag26c_dma(void *req, void *resp, enum diag26c_sc subcode)
66 */
67ENTRY(_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)
76ENDPROC(_diag26c_dma)
77
78/*
79 * void _diag0c_dma(struct hypfs_diag0c_entry *entry)
80 */
81ENTRY(_diag0c_dma)
82	sam31
83	diag	%r2,%r2,0x0c
84	sam64
85	BR_EX_DMA_r14
86ENDPROC(_diag0c_dma)
87
88/*
89 * void _swsusp_reset_dma(void)
90 */
91ENTRY(_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
98restart_entry:
99	lhi	%r1,1
100	sigp	%r1,%r0,SIGP_SET_ARCHITECTURE
101	sam64
102	BR_EX_DMA_r14
103ENDPROC(_swsusp_reset_dma)
104
105/*
106 * void _diag308_reset_dma(void)
107 *
108 * Calls diag 308 subcode 1 and continues execution
109 */
110ENTRY(_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
135restart_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
150ENDPROC(_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
174