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 _swsusp_reset_dma(void) 101 */ 102ENTRY(_swsusp_reset_dma) 103 larl %r1,restart_entry 104 larl %r2,.Lrestart_diag308_psw 105 og %r1,0(%r2) 106 stg %r1,0(%r0) 107 lghi %r0,0 108 diag %r0,%r0,0x308 109restart_entry: 110 lhi %r1,1 111 sigp %r1,%r0,SIGP_SET_ARCHITECTURE 112 sam64 113 BR_EX_DMA_r14 114ENDPROC(_swsusp_reset_dma) 115 116/* 117 * void _diag308_reset_dma(void) 118 * 119 * Calls diag 308 subcode 1 and continues execution 120 */ 121ENTRY(_diag308_reset_dma) 122 larl %r4,.Lctlregs # Save control registers 123 stctg %c0,%c15,0(%r4) 124 lg %r2,0(%r4) # Disable lowcore protection 125 nilh %r2,0xefff 126 larl %r4,.Lctlreg0 127 stg %r2,0(%r4) 128 lctlg %c0,%c0,0(%r4) 129 larl %r4,.Lfpctl # Floating point control register 130 stfpc 0(%r4) 131 larl %r4,.Lprefix # Save prefix register 132 stpx 0(%r4) 133 larl %r4,.Lprefix_zero # Set prefix register to 0 134 spx 0(%r4) 135 larl %r4,.Lcontinue_psw # Save PSW flags 136 epsw %r2,%r3 137 stm %r2,%r3,0(%r4) 138 larl %r4,restart_part2 # Setup restart PSW at absolute 0 139 larl %r3,.Lrestart_diag308_psw 140 og %r4,0(%r3) # Save PSW 141 lghi %r3,0 142 sturg %r4,%r3 # Use sturg, because of large pages 143 lghi %r1,1 144 lghi %r0,0 145 diag %r0,%r1,0x308 146restart_part2: 147 lhi %r0,0 # Load r0 with zero 148 lhi %r1,2 # Use mode 2 = ESAME (dump) 149 sigp %r1,%r0,SIGP_SET_ARCHITECTURE # Switch to ESAME mode 150 sam64 # Switch to 64 bit addressing mode 151 larl %r4,.Lctlregs # Restore control registers 152 lctlg %c0,%c15,0(%r4) 153 larl %r4,.Lfpctl # Restore floating point ctl register 154 lfpc 0(%r4) 155 larl %r4,.Lprefix # Restore prefix register 156 spx 0(%r4) 157 larl %r4,.Lcontinue_psw # Restore PSW flags 158 lpswe 0(%r4) 159.Lcontinue: 160 BR_EX_DMA_r14 161ENDPROC(_diag308_reset_dma) 162 163 .section .dma.data,"aw",@progbits 164.align 8 165.Lrestart_diag308_psw: 166 .long 0x00080000,0x80000000 167 168.align 8 169.Lcontinue_psw: 170 .quad 0,.Lcontinue 171 172.align 8 173.Lctlreg0: 174 .quad 0 175.Lctlregs: 176 .rept 16 177 .quad 0 178 .endr 179.Lfpctl: 180 .long 0 181.Lprefix: 182 .long 0 183.Lprefix_zero: 184 .long 0 185