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