18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Code that needs to run below 2 GB. 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright IBM Corp. 2019 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include <linux/linkage.h> 98c2ecf20Sopenharmony_ci#include <asm/errno.h> 108c2ecf20Sopenharmony_ci#include <asm/sigp.h> 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci .section .dma.text,"ax" 138c2ecf20Sopenharmony_ci/* 148c2ecf20Sopenharmony_ci * Simplified version of expoline thunk. The normal thunks can not be used here, 158c2ecf20Sopenharmony_ci * because they might be more than 2 GB away, and not reachable by the relative 168c2ecf20Sopenharmony_ci * branch. No comdat, exrl, etc. optimizations used here, because it only 178c2ecf20Sopenharmony_ci * affects a few functions that are not performance-relevant. 188c2ecf20Sopenharmony_ci */ 198c2ecf20Sopenharmony_ci .macro BR_EX_DMA_r14 208c2ecf20Sopenharmony_ci larl %r1,0f 218c2ecf20Sopenharmony_ci ex 0,0(%r1) 228c2ecf20Sopenharmony_ci j . 238c2ecf20Sopenharmony_ci0: br %r14 248c2ecf20Sopenharmony_ci .endm 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci/* 278c2ecf20Sopenharmony_ci * int _diag14_dma(unsigned long rx, unsigned long ry1, unsigned long subcode) 288c2ecf20Sopenharmony_ci */ 298c2ecf20Sopenharmony_ciENTRY(_diag14_dma) 308c2ecf20Sopenharmony_ci lgr %r1,%r2 318c2ecf20Sopenharmony_ci lgr %r2,%r3 328c2ecf20Sopenharmony_ci lgr %r3,%r4 338c2ecf20Sopenharmony_ci lhi %r5,-EIO 348c2ecf20Sopenharmony_ci sam31 358c2ecf20Sopenharmony_ci diag %r1,%r2,0x14 368c2ecf20Sopenharmony_ci.Ldiag14_ex: 378c2ecf20Sopenharmony_ci ipm %r5 388c2ecf20Sopenharmony_ci srl %r5,28 398c2ecf20Sopenharmony_ci.Ldiag14_fault: 408c2ecf20Sopenharmony_ci sam64 418c2ecf20Sopenharmony_ci lgfr %r2,%r5 428c2ecf20Sopenharmony_ci BR_EX_DMA_r14 438c2ecf20Sopenharmony_ci EX_TABLE_DMA(.Ldiag14_ex, .Ldiag14_fault) 448c2ecf20Sopenharmony_ciENDPROC(_diag14_dma) 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci/* 478c2ecf20Sopenharmony_ci * int _diag210_dma(struct diag210 *addr) 488c2ecf20Sopenharmony_ci */ 498c2ecf20Sopenharmony_ciENTRY(_diag210_dma) 508c2ecf20Sopenharmony_ci lgr %r1,%r2 518c2ecf20Sopenharmony_ci lhi %r2,-1 528c2ecf20Sopenharmony_ci sam31 538c2ecf20Sopenharmony_ci diag %r1,%r0,0x210 548c2ecf20Sopenharmony_ci.Ldiag210_ex: 558c2ecf20Sopenharmony_ci ipm %r2 568c2ecf20Sopenharmony_ci srl %r2,28 578c2ecf20Sopenharmony_ci.Ldiag210_fault: 588c2ecf20Sopenharmony_ci sam64 598c2ecf20Sopenharmony_ci lgfr %r2,%r2 608c2ecf20Sopenharmony_ci BR_EX_DMA_r14 618c2ecf20Sopenharmony_ci EX_TABLE_DMA(.Ldiag210_ex, .Ldiag210_fault) 628c2ecf20Sopenharmony_ciENDPROC(_diag210_dma) 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci/* 658c2ecf20Sopenharmony_ci * int _diag26c_dma(void *req, void *resp, enum diag26c_sc subcode) 668c2ecf20Sopenharmony_ci */ 678c2ecf20Sopenharmony_ciENTRY(_diag26c_dma) 688c2ecf20Sopenharmony_ci lghi %r5,-EOPNOTSUPP 698c2ecf20Sopenharmony_ci sam31 708c2ecf20Sopenharmony_ci diag %r2,%r4,0x26c 718c2ecf20Sopenharmony_ci.Ldiag26c_ex: 728c2ecf20Sopenharmony_ci sam64 738c2ecf20Sopenharmony_ci lgfr %r2,%r5 748c2ecf20Sopenharmony_ci BR_EX_DMA_r14 758c2ecf20Sopenharmony_ci EX_TABLE_DMA(.Ldiag26c_ex, .Ldiag26c_ex) 768c2ecf20Sopenharmony_ciENDPROC(_diag26c_dma) 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci/* 798c2ecf20Sopenharmony_ci * void _diag0c_dma(struct hypfs_diag0c_entry *entry) 808c2ecf20Sopenharmony_ci */ 818c2ecf20Sopenharmony_ciENTRY(_diag0c_dma) 828c2ecf20Sopenharmony_ci sam31 838c2ecf20Sopenharmony_ci diag %r2,%r2,0x0c 848c2ecf20Sopenharmony_ci sam64 858c2ecf20Sopenharmony_ci BR_EX_DMA_r14 868c2ecf20Sopenharmony_ciENDPROC(_diag0c_dma) 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci/* 898c2ecf20Sopenharmony_ci * void _diag308_reset_dma(void) 908c2ecf20Sopenharmony_ci * 918c2ecf20Sopenharmony_ci * Calls diag 308 subcode 1 and continues execution 928c2ecf20Sopenharmony_ci */ 938c2ecf20Sopenharmony_ciENTRY(_diag308_reset_dma) 948c2ecf20Sopenharmony_ci larl %r4,.Lctlregs # Save control registers 958c2ecf20Sopenharmony_ci stctg %c0,%c15,0(%r4) 968c2ecf20Sopenharmony_ci lg %r2,0(%r4) # Disable lowcore protection 978c2ecf20Sopenharmony_ci nilh %r2,0xefff 988c2ecf20Sopenharmony_ci larl %r4,.Lctlreg0 998c2ecf20Sopenharmony_ci stg %r2,0(%r4) 1008c2ecf20Sopenharmony_ci lctlg %c0,%c0,0(%r4) 1018c2ecf20Sopenharmony_ci larl %r4,.Lfpctl # Floating point control register 1028c2ecf20Sopenharmony_ci stfpc 0(%r4) 1038c2ecf20Sopenharmony_ci larl %r4,.Lprefix # Save prefix register 1048c2ecf20Sopenharmony_ci stpx 0(%r4) 1058c2ecf20Sopenharmony_ci larl %r4,.Lprefix_zero # Set prefix register to 0 1068c2ecf20Sopenharmony_ci spx 0(%r4) 1078c2ecf20Sopenharmony_ci larl %r4,.Lcontinue_psw # Save PSW flags 1088c2ecf20Sopenharmony_ci epsw %r2,%r3 1098c2ecf20Sopenharmony_ci stm %r2,%r3,0(%r4) 1108c2ecf20Sopenharmony_ci larl %r4,restart_part2 # Setup restart PSW at absolute 0 1118c2ecf20Sopenharmony_ci larl %r3,.Lrestart_diag308_psw 1128c2ecf20Sopenharmony_ci og %r4,0(%r3) # Save PSW 1138c2ecf20Sopenharmony_ci lghi %r3,0 1148c2ecf20Sopenharmony_ci sturg %r4,%r3 # Use sturg, because of large pages 1158c2ecf20Sopenharmony_ci lghi %r1,1 1168c2ecf20Sopenharmony_ci lghi %r0,0 1178c2ecf20Sopenharmony_ci diag %r0,%r1,0x308 1188c2ecf20Sopenharmony_cirestart_part2: 1198c2ecf20Sopenharmony_ci lhi %r0,0 # Load r0 with zero 1208c2ecf20Sopenharmony_ci lhi %r1,2 # Use mode 2 = ESAME (dump) 1218c2ecf20Sopenharmony_ci sigp %r1,%r0,SIGP_SET_ARCHITECTURE # Switch to ESAME mode 1228c2ecf20Sopenharmony_ci sam64 # Switch to 64 bit addressing mode 1238c2ecf20Sopenharmony_ci larl %r4,.Lctlregs # Restore control registers 1248c2ecf20Sopenharmony_ci lctlg %c0,%c15,0(%r4) 1258c2ecf20Sopenharmony_ci larl %r4,.Lfpctl # Restore floating point ctl register 1268c2ecf20Sopenharmony_ci lfpc 0(%r4) 1278c2ecf20Sopenharmony_ci larl %r4,.Lprefix # Restore prefix register 1288c2ecf20Sopenharmony_ci spx 0(%r4) 1298c2ecf20Sopenharmony_ci larl %r4,.Lcontinue_psw # Restore PSW flags 1308c2ecf20Sopenharmony_ci lpswe 0(%r4) 1318c2ecf20Sopenharmony_ci.Lcontinue: 1328c2ecf20Sopenharmony_ci BR_EX_DMA_r14 1338c2ecf20Sopenharmony_ciENDPROC(_diag308_reset_dma) 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ci .section .dma.data,"aw",@progbits 1368c2ecf20Sopenharmony_ci.align 8 1378c2ecf20Sopenharmony_ci.Lrestart_diag308_psw: 1388c2ecf20Sopenharmony_ci .long 0x00080000,0x80000000 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_ci.align 8 1418c2ecf20Sopenharmony_ci.Lcontinue_psw: 1428c2ecf20Sopenharmony_ci .quad 0,.Lcontinue 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ci.align 8 1458c2ecf20Sopenharmony_ci.Lctlreg0: 1468c2ecf20Sopenharmony_ci .quad 0 1478c2ecf20Sopenharmony_ci.Lctlregs: 1488c2ecf20Sopenharmony_ci .rept 16 1498c2ecf20Sopenharmony_ci .quad 0 1508c2ecf20Sopenharmony_ci .endr 1518c2ecf20Sopenharmony_ci.Lfpctl: 1528c2ecf20Sopenharmony_ci .long 0 1538c2ecf20Sopenharmony_ci.Lprefix: 1548c2ecf20Sopenharmony_ci .long 0 1558c2ecf20Sopenharmony_ci.Lprefix_zero: 1568c2ecf20Sopenharmony_ci .long 0 157