root/arch/s390/boot/text_dma.S

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

/* [<][>][^][v][top][bottom][index][help] */