text_amode31.S 3.3 KB

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