^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Code that needs to run below 2 GB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright IBM Corp. 2019
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/linkage.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <asm/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <asm/sigp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) .section .dma.text,"ax"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * Simplified version of expoline thunk. The normal thunks can not be used here,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * because they might be more than 2 GB away, and not reachable by the relative
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * branch. No comdat, exrl, etc. optimizations used here, because it only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * affects a few functions that are not performance-relevant.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) .macro BR_EX_DMA_r14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) larl %r1,0f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) ex 0,0(%r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) j .
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) 0: br %r14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) .endm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * int _diag14_dma(unsigned long rx, unsigned long ry1, unsigned long subcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) ENTRY(_diag14_dma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) lgr %r1,%r2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) lgr %r2,%r3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) lgr %r3,%r4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) lhi %r5,-EIO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) sam31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) diag %r1,%r2,0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) .Ldiag14_ex:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) ipm %r5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) srl %r5,28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) .Ldiag14_fault:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) sam64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) lgfr %r2,%r5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) BR_EX_DMA_r14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) EX_TABLE_DMA(.Ldiag14_ex, .Ldiag14_fault)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) ENDPROC(_diag14_dma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * int _diag210_dma(struct diag210 *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) ENTRY(_diag210_dma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) lgr %r1,%r2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) lhi %r2,-1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) sam31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) diag %r1,%r0,0x210
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) .Ldiag210_ex:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) ipm %r2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) srl %r2,28
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) .Ldiag210_fault:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) sam64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) lgfr %r2,%r2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) BR_EX_DMA_r14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) EX_TABLE_DMA(.Ldiag210_ex, .Ldiag210_fault)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) ENDPROC(_diag210_dma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * int _diag26c_dma(void *req, void *resp, enum diag26c_sc subcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) ENTRY(_diag26c_dma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) lghi %r5,-EOPNOTSUPP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) sam31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) diag %r2,%r4,0x26c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) .Ldiag26c_ex:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) sam64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) lgfr %r2,%r5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) BR_EX_DMA_r14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) EX_TABLE_DMA(.Ldiag26c_ex, .Ldiag26c_ex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) ENDPROC(_diag26c_dma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * void _diag0c_dma(struct hypfs_diag0c_entry *entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) ENTRY(_diag0c_dma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) sam31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) diag %r2,%r2,0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) sam64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) BR_EX_DMA_r14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) ENDPROC(_diag0c_dma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * void _diag308_reset_dma(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * Calls diag 308 subcode 1 and continues execution
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) ENTRY(_diag308_reset_dma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) larl %r4,.Lctlregs # Save control registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) stctg %c0,%c15,0(%r4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) lg %r2,0(%r4) # Disable lowcore protection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) nilh %r2,0xefff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) larl %r4,.Lctlreg0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) stg %r2,0(%r4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) lctlg %c0,%c0,0(%r4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) larl %r4,.Lfpctl # Floating point control register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) stfpc 0(%r4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) larl %r4,.Lprefix # Save prefix register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) stpx 0(%r4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) larl %r4,.Lprefix_zero # Set prefix register to 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) spx 0(%r4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) larl %r4,.Lcontinue_psw # Save PSW flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) epsw %r2,%r3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) stm %r2,%r3,0(%r4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) larl %r4,restart_part2 # Setup restart PSW at absolute 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) larl %r3,.Lrestart_diag308_psw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) og %r4,0(%r3) # Save PSW
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) lghi %r3,0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) sturg %r4,%r3 # Use sturg, because of large pages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) lghi %r1,1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) lghi %r0,0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) diag %r0,%r1,0x308
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) restart_part2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) lhi %r0,0 # Load r0 with zero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) lhi %r1,2 # Use mode 2 = ESAME (dump)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) sigp %r1,%r0,SIGP_SET_ARCHITECTURE # Switch to ESAME mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) sam64 # Switch to 64 bit addressing mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) larl %r4,.Lctlregs # Restore control registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) lctlg %c0,%c15,0(%r4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) larl %r4,.Lfpctl # Restore floating point ctl register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) lfpc 0(%r4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) larl %r4,.Lprefix # Restore prefix register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) spx 0(%r4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) larl %r4,.Lcontinue_psw # Restore PSW flags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) lpswe 0(%r4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) .Lcontinue:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) BR_EX_DMA_r14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) ENDPROC(_diag308_reset_dma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) .section .dma.data,"aw",@progbits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) .align 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) .Lrestart_diag308_psw:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) .long 0x00080000,0x80000000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) .align 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) .Lcontinue_psw:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) .quad 0,.Lcontinue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) .align 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) .Lctlreg0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) .quad 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) .Lctlregs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) .rept 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) .quad 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) .endr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) .Lfpctl:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) .long 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) .Lprefix:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) .long 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) .Lprefix_zero:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) .long 0