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