Linux Audio

Check our new training course

Loading...
v6.8
  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/asm-extable.h>
 10#include <asm/errno.h>
 11#include <asm/sigp.h>
 12
 13	.section .amode31.text,"ax"
 14/*
 15 * Simplified version of expoline thunk. The normal thunks can not be used here,
 16 * because they might be more than 2 GB away, and not reachable by the relative
 17 * branch. No comdat, exrl, etc. optimizations used here, because it only
 18 * affects a few functions that are not performance-relevant.
 19 */
 20	.macro BR_EX_AMODE31_r14
 21	larl	%r1,0f
 22	ex	0,0(%r1)
 23	j	.
 240:	br	%r14
 25	.endm
 26
 27/*
 28 * int _diag14_amode31(unsigned long rx, unsigned long ry1, unsigned long subcode)
 29 */
 30SYM_FUNC_START(_diag14_amode31)
 31	lgr	%r1,%r2
 32	lgr	%r2,%r3
 33	lgr	%r3,%r4
 34	lhi	%r5,-EIO
 35	sam31
 36	diag	%r1,%r2,0x14
 37.Ldiag14_ex:
 38	ipm	%r5
 39	srl	%r5,28
 40.Ldiag14_fault:
 41	sam64
 42	lgfr	%r2,%r5
 43	BR_EX_AMODE31_r14
 44	EX_TABLE_AMODE31(.Ldiag14_ex, .Ldiag14_fault)
 45SYM_FUNC_END(_diag14_amode31)
 46
 47/*
 48 * int _diag210_amode31(struct diag210 *addr)
 49 */
 50SYM_FUNC_START(_diag210_amode31)
 51	lgr	%r1,%r2
 52	lhi	%r2,-1
 53	sam31
 54	diag	%r1,%r0,0x210
 55.Ldiag210_ex:
 56	ipm	%r2
 57	srl	%r2,28
 58.Ldiag210_fault:
 59	sam64
 60	lgfr	%r2,%r2
 61	BR_EX_AMODE31_r14
 62	EX_TABLE_AMODE31(.Ldiag210_ex, .Ldiag210_fault)
 63SYM_FUNC_END(_diag210_amode31)
 64
 65/*
 66 * int diag8c(struct diag8c *addr, struct ccw_dev_id *devno, size_t len)
 67*/
 68SYM_FUNC_START(_diag8c_amode31)
 69	llgf	%r3,0(%r3)
 70	sam31
 71	diag	%r2,%r4,0x8c
 72.Ldiag8c_ex:
 73	sam64
 74	lgfr	%r2,%r3
 75	BR_EX_AMODE31_r14
 76	EX_TABLE_AMODE31(.Ldiag8c_ex, .Ldiag8c_ex)
 77SYM_FUNC_END(_diag8c_amode31)
 78/*
 79 * int _diag26c_amode31(void *req, void *resp, enum diag26c_sc subcode)
 80 */
 81SYM_FUNC_START(_diag26c_amode31)
 82	lghi	%r5,-EOPNOTSUPP
 83	sam31
 84	diag	%r2,%r4,0x26c
 85.Ldiag26c_ex:
 86	sam64
 87	lgfr	%r2,%r5
 88	BR_EX_AMODE31_r14
 89	EX_TABLE_AMODE31(.Ldiag26c_ex, .Ldiag26c_ex)
 90SYM_FUNC_END(_diag26c_amode31)
 91
 92/*
 93 * void _diag0c_amode31(struct hypfs_diag0c_entry *entry)
 94 */
 95SYM_FUNC_START(_diag0c_amode31)
 96	sam31
 97	diag	%r2,%r2,0x0c
 98	sam64
 99	BR_EX_AMODE31_r14
100SYM_FUNC_END(_diag0c_amode31)
101
102/*
103 * void _diag308_reset_amode31(void)
104 *
105 * Calls diag 308 subcode 1 and continues execution
106 */
107SYM_FUNC_START(_diag308_reset_amode31)
108	larl	%r4,ctlregs		# Save control registers
109	stctg	%c0,%c15,0(%r4)
110	lg	%r2,0(%r4)		# Disable lowcore protection
111	nilh	%r2,0xefff
112	larl	%r4,ctlreg0
113	stg	%r2,0(%r4)
114	lctlg	%c0,%c0,0(%r4)
115	larl	%r4,fpctl		# Floating point control register
116	stfpc	0(%r4)
117	larl	%r4,prefix		# Save prefix register
118	stpx	0(%r4)
119	larl	%r4,prefix_zero	# Set prefix register to 0
120	spx	0(%r4)
121	larl	%r4,continue_psw	# Save PSW flags
122	epsw	%r2,%r3
123	stm	%r2,%r3,0(%r4)
124	larl	%r4,.Lrestart_part2	# Setup restart PSW at absolute 0
125	larl	%r3,restart_diag308_psw
126	og	%r4,0(%r3)		# Save PSW
127	lghi	%r3,0
128	sturg	%r4,%r3			# Use sturg, because of large pages
129	lghi	%r1,1
130	lghi	%r0,0
131	diag	%r0,%r1,0x308
132.Lrestart_part2:
133	lhi	%r0,0			# Load r0 with zero
134	lhi	%r1,2			# Use mode 2 = ESAME (dump)
135	sigp	%r1,%r0,SIGP_SET_ARCHITECTURE	# Switch to ESAME mode
136	sam64				# Switch to 64 bit addressing mode
137	larl	%r4,ctlregs		# Restore control registers
138	lctlg	%c0,%c15,0(%r4)
139	larl	%r4,fpctl		# Restore floating point ctl register
140	lfpc	0(%r4)
141	larl	%r4,prefix		# Restore prefix register
142	spx	0(%r4)
143	larl	%r4,continue_psw	# Restore PSW flags
144	larl	%r2,.Lcontinue
145	stg	%r2,8(%r4)
146	lpswe	0(%r4)
147.Lcontinue:
148	BR_EX_AMODE31_r14
149SYM_FUNC_END(_diag308_reset_amode31)
150
151	.section .amode31.data,"aw",@progbits
152	.balign	8
153SYM_DATA_LOCAL(restart_diag308_psw,	.long 0x00080000,0x80000000)
154SYM_DATA_LOCAL(continue_psw,		.quad 0,0)
155SYM_DATA_LOCAL(ctlreg0,			.quad 0)
156SYM_DATA_LOCAL(ctlregs,			.fill 16,8,0)
157SYM_DATA_LOCAL(fpctl,			.long 0)
158SYM_DATA_LOCAL(prefix,			.long 0)
159SYM_DATA_LOCAL(prefix_zero,		.long 0)
v6.13.7
  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/asm-extable.h>
 10#include <asm/errno.h>
 11#include <asm/sigp.h>
 12
 13	.section .amode31.text,"ax"
 14/*
 15 * Simplified version of expoline thunk. The normal thunks can not be used here,
 16 * because they might be more than 2 GB away, and not reachable by the relative
 17 * branch. No comdat, exrl, etc. optimizations used here, because it only
 18 * affects a few functions that are not performance-relevant.
 19 */
 20	.macro BR_EX_AMODE31_r14
 21	larl	%r1,0f
 22	ex	0,0(%r1)
 23	j	.
 240:	br	%r14
 25	.endm
 26
 27/*
 28 * int _diag14_amode31(unsigned long rx, unsigned long ry1, unsigned long subcode)
 29 */
 30SYM_FUNC_START(_diag14_amode31)
 31	lgr	%r1,%r2
 32	lgr	%r2,%r3
 33	lgr	%r3,%r4
 34	lhi	%r5,-EIO
 35	sam31
 36	diag	%r1,%r2,0x14
 37.Ldiag14_ex:
 38	ipm	%r5
 39	srl	%r5,28
 40.Ldiag14_fault:
 41	sam64
 42	lgfr	%r2,%r5
 43	BR_EX_AMODE31_r14
 44	EX_TABLE_AMODE31(.Ldiag14_ex, .Ldiag14_fault)
 45SYM_FUNC_END(_diag14_amode31)
 46
 47/*
 48 * int _diag210_amode31(struct diag210 *addr)
 49 */
 50SYM_FUNC_START(_diag210_amode31)
 51	lgr	%r1,%r2
 52	lhi	%r2,-1
 53	sam31
 54	diag	%r1,%r0,0x210
 55.Ldiag210_ex:
 56	ipm	%r2
 57	srl	%r2,28
 58.Ldiag210_fault:
 59	sam64
 60	lgfr	%r2,%r2
 61	BR_EX_AMODE31_r14
 62	EX_TABLE_AMODE31(.Ldiag210_ex, .Ldiag210_fault)
 63SYM_FUNC_END(_diag210_amode31)
 64
 65/*
 66 * int diag8c(struct diag8c *addr, struct ccw_dev_id *devno, size_t len)
 67*/
 68SYM_FUNC_START(_diag8c_amode31)
 69	llgf	%r3,0(%r3)
 70	sam31
 71	diag	%r2,%r4,0x8c
 72.Ldiag8c_ex:
 73	sam64
 74	lgfr	%r2,%r3
 75	BR_EX_AMODE31_r14
 76	EX_TABLE_AMODE31(.Ldiag8c_ex, .Ldiag8c_ex)
 77SYM_FUNC_END(_diag8c_amode31)
 78/*
 79 * int _diag26c_amode31(void *req, void *resp, enum diag26c_sc subcode)
 80 */
 81SYM_FUNC_START(_diag26c_amode31)
 82	lghi	%r5,-EOPNOTSUPP
 83	sam31
 84	diag	%r2,%r4,0x26c
 85.Ldiag26c_ex:
 86	sam64
 87	lgfr	%r2,%r5
 88	BR_EX_AMODE31_r14
 89	EX_TABLE_AMODE31(.Ldiag26c_ex, .Ldiag26c_ex)
 90SYM_FUNC_END(_diag26c_amode31)
 91
 92/*
 93 * void _diag0c_amode31(unsigned long rx)
 94 */
 95SYM_FUNC_START(_diag0c_amode31)
 96	sam31
 97	diag	%r2,%r2,0x0c
 98	sam64
 99	BR_EX_AMODE31_r14
100SYM_FUNC_END(_diag0c_amode31)
101
102/*
103 * void _diag308_reset_amode31(void)
104 *
105 * Calls diag 308 subcode 1 and continues execution
106 */
107SYM_FUNC_START(_diag308_reset_amode31)
108	larl	%r4,ctlregs		# Save control registers
109	stctg	%c0,%c15,0(%r4)
110	lg	%r2,0(%r4)		# Disable lowcore protection
111	nilh	%r2,0xefff
112	larl	%r4,ctlreg0
113	stg	%r2,0(%r4)
114	lctlg	%c0,%c0,0(%r4)
115	larl	%r4,fpctl		# Floating point control register
116	stfpc	0(%r4)
117	larl	%r4,prefix		# Save prefix register
118	stpx	0(%r4)
119	larl	%r4,prefix_zero	# Set prefix register to 0
120	spx	0(%r4)
121	larl	%r4,continue_psw	# Save PSW flags
122	epsw	%r2,%r3
123	stm	%r2,%r3,0(%r4)
124	larl	%r4,.Lrestart_part2	# Setup restart PSW at absolute 0
125	larl	%r3,restart_diag308_psw
126	og	%r4,0(%r3)		# Save PSW
127	lghi	%r3,0
128	sturg	%r4,%r3			# Use sturg, because of large pages
129	lghi	%r1,1
130	lghi	%r0,0
131	diag	%r0,%r1,0x308
132.Lrestart_part2:
133	lhi	%r0,0			# Load r0 with zero
134	lhi	%r1,2			# Use mode 2 = ESAME (dump)
135	sigp	%r1,%r0,SIGP_SET_ARCHITECTURE	# Switch to ESAME mode
136	sam64				# Switch to 64 bit addressing mode
137	larl	%r4,ctlregs		# Restore control registers
138	lctlg	%c0,%c15,0(%r4)
139	larl	%r4,fpctl		# Restore floating point ctl register
140	lfpc	0(%r4)
141	larl	%r4,prefix		# Restore prefix register
142	spx	0(%r4)
143	larl	%r4,continue_psw	# Restore PSW flags
144	larl	%r2,.Lcontinue
145	stg	%r2,8(%r4)
146	lpswe	0(%r4)
147.Lcontinue:
148	BR_EX_AMODE31_r14
149SYM_FUNC_END(_diag308_reset_amode31)
150
151	.section .amode31.data,"aw",@progbits
152	.balign	8
153SYM_DATA_LOCAL(restart_diag308_psw,	.long 0x00080000,0x80000000)
154SYM_DATA_LOCAL(continue_psw,		.quad 0,0)
155SYM_DATA_LOCAL(ctlreg0,			.quad 0)
156SYM_DATA_LOCAL(ctlregs,			.fill 16,8,0)
157SYM_DATA_LOCAL(fpctl,			.long 0)
158SYM_DATA_LOCAL(prefix,			.long 0)
159SYM_DATA_LOCAL(prefix_zero,		.long 0)