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#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 . 180: br %r14 19 .popsection 20#endif 21 22 .section .dma.text,"ax" 23/* 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 36 37/* 38 * int _diag14_dma(unsigned long rx, unsigned long ry1, unsigned long subcode) 39 */ 40ENTRY(_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) 55ENDPROC(_diag14_dma) 56 57/* 58 * int _diag210_dma(struct diag210 *addr) 59 */ 60ENTRY(_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) 73ENDPROC(_diag210_dma) 74 75/* 76 * int _diag26c_dma(void *req, void *resp, enum diag26c_sc subcode) 77 */ 78ENTRY(_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) 87ENDPROC(_diag26c_dma) 88 89/* 90 * void _diag0c_dma(struct hypfs_diag0c_entry *entry) 91 */ 92ENTRY(_diag0c_dma) 93 sam31 94 diag %r2,%r2,0x0c 95 sam64 96 BR_EX_DMA_r14 97ENDPROC(_diag0c_dma) 98 99/* 100 * void _diag308_reset_dma(void) 101 * 102 * Calls diag 308 subcode 1 and continues execution 103 */ 104ENTRY(_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 129restart_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 144ENDPROC(_diag308_reset_dma) 145 146 .section .dma.data,"aw",@progbits 147.align 8 148.Lrestart_diag308_psw: 149 .long 0x00080000,0x80000000 150 151.align 8 152.Lcontinue_psw: 153 .quad 0,.Lcontinue 154 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 168