mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
167 lines
3.3 KiB
167 lines
3.3 KiB
/* SPDX-License-Identifier: GPL-2.0 */ |
|
/* |
|
* Code that needs to run below 2 GB. |
|
* |
|
* Copyright IBM Corp. 2019 |
|
*/ |
|
|
|
#include <linux/linkage.h> |
|
#include <asm/errno.h> |
|
#include <asm/sigp.h> |
|
|
|
#ifdef CC_USING_EXPOLINE |
|
.pushsection .dma.text.__s390_indirect_jump_r14,"axG" |
|
__dma__s390_indirect_jump_r14: |
|
larl %r1,0f |
|
ex 0,0(%r1) |
|
j . |
|
0: br %r14 |
|
.popsection |
|
#endif |
|
|
|
.section .dma.text,"ax" |
|
/* |
|
* Simplified version of expoline thunk. The normal thunks can not be used here, |
|
* because they might be more than 2 GB away, and not reachable by the relative |
|
* branch. No comdat, exrl, etc. optimizations used here, because it only |
|
* affects a few functions that are not performance-relevant. |
|
*/ |
|
.macro BR_EX_DMA_r14 |
|
#ifdef CC_USING_EXPOLINE |
|
jg __dma__s390_indirect_jump_r14 |
|
#else |
|
br %r14 |
|
#endif |
|
.endm |
|
|
|
/* |
|
* int _diag14_dma(unsigned long rx, unsigned long ry1, unsigned long subcode) |
|
*/ |
|
ENTRY(_diag14_dma) |
|
lgr %r1,%r2 |
|
lgr %r2,%r3 |
|
lgr %r3,%r4 |
|
lhi %r5,-EIO |
|
sam31 |
|
diag %r1,%r2,0x14 |
|
.Ldiag14_ex: |
|
ipm %r5 |
|
srl %r5,28 |
|
.Ldiag14_fault: |
|
sam64 |
|
lgfr %r2,%r5 |
|
BR_EX_DMA_r14 |
|
EX_TABLE_DMA(.Ldiag14_ex, .Ldiag14_fault) |
|
ENDPROC(_diag14_dma) |
|
|
|
/* |
|
* int _diag210_dma(struct diag210 *addr) |
|
*/ |
|
ENTRY(_diag210_dma) |
|
lgr %r1,%r2 |
|
lhi %r2,-1 |
|
sam31 |
|
diag %r1,%r0,0x210 |
|
.Ldiag210_ex: |
|
ipm %r2 |
|
srl %r2,28 |
|
.Ldiag210_fault: |
|
sam64 |
|
lgfr %r2,%r2 |
|
BR_EX_DMA_r14 |
|
EX_TABLE_DMA(.Ldiag210_ex, .Ldiag210_fault) |
|
ENDPROC(_diag210_dma) |
|
|
|
/* |
|
* int _diag26c_dma(void *req, void *resp, enum diag26c_sc subcode) |
|
*/ |
|
ENTRY(_diag26c_dma) |
|
lghi %r5,-EOPNOTSUPP |
|
sam31 |
|
diag %r2,%r4,0x26c |
|
.Ldiag26c_ex: |
|
sam64 |
|
lgfr %r2,%r5 |
|
BR_EX_DMA_r14 |
|
EX_TABLE_DMA(.Ldiag26c_ex, .Ldiag26c_ex) |
|
ENDPROC(_diag26c_dma) |
|
|
|
/* |
|
* void _diag0c_dma(struct hypfs_diag0c_entry *entry) |
|
*/ |
|
ENTRY(_diag0c_dma) |
|
sam31 |
|
diag %r2,%r2,0x0c |
|
sam64 |
|
BR_EX_DMA_r14 |
|
ENDPROC(_diag0c_dma) |
|
|
|
/* |
|
* void _diag308_reset_dma(void) |
|
* |
|
* Calls diag 308 subcode 1 and continues execution |
|
*/ |
|
ENTRY(_diag308_reset_dma) |
|
larl %r4,.Lctlregs # Save control registers |
|
stctg %c0,%c15,0(%r4) |
|
lg %r2,0(%r4) # Disable lowcore protection |
|
nilh %r2,0xefff |
|
larl %r4,.Lctlreg0 |
|
stg %r2,0(%r4) |
|
lctlg %c0,%c0,0(%r4) |
|
larl %r4,.Lfpctl # Floating point control register |
|
stfpc 0(%r4) |
|
larl %r4,.Lprefix # Save prefix register |
|
stpx 0(%r4) |
|
larl %r4,.Lprefix_zero # Set prefix register to 0 |
|
spx 0(%r4) |
|
larl %r4,.Lcontinue_psw # Save PSW flags |
|
epsw %r2,%r3 |
|
stm %r2,%r3,0(%r4) |
|
larl %r4,restart_part2 # Setup restart PSW at absolute 0 |
|
larl %r3,.Lrestart_diag308_psw |
|
og %r4,0(%r3) # Save PSW |
|
lghi %r3,0 |
|
sturg %r4,%r3 # Use sturg, because of large pages |
|
lghi %r1,1 |
|
lghi %r0,0 |
|
diag %r0,%r1,0x308 |
|
restart_part2: |
|
lhi %r0,0 # Load r0 with zero |
|
lhi %r1,2 # Use mode 2 = ESAME (dump) |
|
sigp %r1,%r0,SIGP_SET_ARCHITECTURE # Switch to ESAME mode |
|
sam64 # Switch to 64 bit addressing mode |
|
larl %r4,.Lctlregs # Restore control registers |
|
lctlg %c0,%c15,0(%r4) |
|
larl %r4,.Lfpctl # Restore floating point ctl register |
|
lfpc 0(%r4) |
|
larl %r4,.Lprefix # Restore prefix register |
|
spx 0(%r4) |
|
larl %r4,.Lcontinue_psw # Restore PSW flags |
|
lpswe 0(%r4) |
|
.Lcontinue: |
|
BR_EX_DMA_r14 |
|
ENDPROC(_diag308_reset_dma) |
|
|
|
.section .dma.data,"aw",@progbits |
|
.align 8 |
|
.Lrestart_diag308_psw: |
|
.long 0x00080000,0x80000000 |
|
|
|
.align 8 |
|
.Lcontinue_psw: |
|
.quad 0,.Lcontinue |
|
|
|
.align 8 |
|
.Lctlreg0: |
|
.quad 0 |
|
.Lctlregs: |
|
.rept 16 |
|
.quad 0 |
|
.endr |
|
.Lfpctl: |
|
.long 0 |
|
.Lprefix: |
|
.long 0 |
|
.Lprefix_zero: |
|
.long 0
|
|
|