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