rtas_entry.S 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /* SPDX-License-Identifier: GPL-2.0-or-later */
  2. #include <asm/asm-offsets.h>
  3. #include <asm/bug.h>
  4. #include <asm/page.h>
  5. #include <asm/ppc_asm.h>
  6. /*
  7. * RTAS is called with MSR IR, DR, EE disabled, and LR in the return address.
  8. *
  9. * Note: r3 is an input parameter to rtas, so don't trash it...
  10. */
  11. #ifdef CONFIG_PPC32
  12. _GLOBAL(enter_rtas)
  13. stwu r1,-INT_FRAME_SIZE(r1)
  14. mflr r0
  15. stw r0,INT_FRAME_SIZE+4(r1)
  16. LOAD_REG_ADDR(r4, rtas)
  17. lis r6,1f@ha /* physical return address for rtas */
  18. addi r6,r6,1f@l
  19. tophys(r6,r6)
  20. lwz r8,RTASENTRY(r4)
  21. lwz r4,RTASBASE(r4)
  22. mfmsr r9
  23. stw r9,8(r1)
  24. li r9,MSR_KERNEL & ~(MSR_IR|MSR_DR)
  25. mtlr r6
  26. stw r1, THREAD + RTAS_SP(r2)
  27. mtspr SPRN_SRR0,r8
  28. mtspr SPRN_SRR1,r9
  29. rfi
  30. 1:
  31. lis r8, 1f@h
  32. ori r8, r8, 1f@l
  33. LOAD_REG_IMMEDIATE(r9,MSR_KERNEL)
  34. mtspr SPRN_SRR0,r8
  35. mtspr SPRN_SRR1,r9
  36. rfi /* Reactivate MMU translation */
  37. 1:
  38. lwz r8,INT_FRAME_SIZE+4(r1) /* get return address */
  39. lwz r9,8(r1) /* original msr value */
  40. addi r1,r1,INT_FRAME_SIZE
  41. li r0,0
  42. stw r0, THREAD + RTAS_SP(r2)
  43. mtlr r8
  44. mtmsr r9
  45. blr /* return to caller */
  46. _ASM_NOKPROBE_SYMBOL(enter_rtas)
  47. #else /* CONFIG_PPC32 */
  48. #include <asm/exception-64s.h>
  49. /*
  50. * 32-bit rtas on 64-bit machines has the additional problem that RTAS may
  51. * not preserve the upper parts of registers it uses.
  52. */
  53. _GLOBAL(enter_rtas)
  54. mflr r0
  55. std r0,16(r1)
  56. stdu r1,-SWITCH_FRAME_SIZE(r1) /* Save SP and create stack space. */
  57. /* Because RTAS is running in 32b mode, it clobbers the high order half
  58. * of all registers that it saves. We therefore save those registers
  59. * RTAS might touch to the stack. (r0, r3-r12 are caller saved)
  60. */
  61. SAVE_GPR(2, r1) /* Save the TOC */
  62. SAVE_NVGPRS(r1) /* Save the non-volatiles */
  63. mfcr r4
  64. std r4,_CCR(r1)
  65. mfctr r5
  66. std r5,_CTR(r1)
  67. mfspr r6,SPRN_XER
  68. std r6,_XER(r1)
  69. mfdar r7
  70. std r7,_DAR(r1)
  71. mfdsisr r8
  72. std r8,_DSISR(r1)
  73. /* Temporary workaround to clear CR until RTAS can be modified to
  74. * ignore all bits.
  75. */
  76. li r0,0
  77. mtcr r0
  78. mfmsr r6
  79. /* Unfortunately, the stack pointer and the MSR are also clobbered,
  80. * so they are saved in the PACA which allows us to restore
  81. * our original state after RTAS returns.
  82. */
  83. std r1,PACAR1(r13)
  84. std r6,PACASAVEDMSR(r13)
  85. /* Setup our real return addr */
  86. LOAD_REG_ADDR(r4,rtas_return_loc)
  87. clrldi r4,r4,2 /* convert to realmode address */
  88. mtlr r4
  89. __enter_rtas:
  90. LOAD_REG_ADDR(r4, rtas)
  91. ld r5,RTASENTRY(r4) /* get the rtas->entry value */
  92. ld r4,RTASBASE(r4) /* get the rtas->base value */
  93. /*
  94. * RTAS runs in 32-bit big endian real mode, but leave MSR[RI] on as we
  95. * may hit NMI (SRESET or MCE) while in RTAS. RTAS should disable RI in
  96. * its critical regions (as specified in PAPR+ section 7.2.1). MSR[S]
  97. * is not impacted by RFI_TO_KERNEL (only urfid can unset it). So if
  98. * MSR[S] is set, it will remain when entering RTAS.
  99. * If we're in HV mode, RTAS must also run in HV mode, so extract MSR_HV
  100. * from the saved MSR value and insert into the value RTAS will use.
  101. */
  102. extrdi r0, r6, 1, 63 - MSR_HV_LG
  103. LOAD_REG_IMMEDIATE(r6, MSR_ME | MSR_RI)
  104. insrdi r6, r0, 1, 63 - MSR_HV_LG
  105. li r0,0
  106. mtmsrd r0,1 /* disable RI before using SRR0/1 */
  107. mtspr SPRN_SRR0,r5
  108. mtspr SPRN_SRR1,r6
  109. RFI_TO_KERNEL
  110. b . /* prevent speculative execution */
  111. rtas_return_loc:
  112. FIXUP_ENDIAN
  113. /* Set SF before anything. */
  114. LOAD_REG_IMMEDIATE(r6, MSR_KERNEL & ~(MSR_IR|MSR_DR))
  115. mtmsrd r6
  116. /* relocation is off at this point */
  117. GET_PACA(r13)
  118. bcl 20,31,$+4
  119. 0: mflr r3
  120. ld r3,(1f-0b)(r3) /* get &rtas_restore_regs */
  121. ld r1,PACAR1(r13) /* Restore our SP */
  122. ld r4,PACASAVEDMSR(r13) /* Restore our MSR */
  123. mtspr SPRN_SRR0,r3
  124. mtspr SPRN_SRR1,r4
  125. RFI_TO_KERNEL
  126. b . /* prevent speculative execution */
  127. _ASM_NOKPROBE_SYMBOL(enter_rtas)
  128. _ASM_NOKPROBE_SYMBOL(__enter_rtas)
  129. _ASM_NOKPROBE_SYMBOL(rtas_return_loc)
  130. .align 3
  131. 1: .8byte rtas_restore_regs
  132. rtas_restore_regs:
  133. /* relocation is on at this point */
  134. REST_GPR(2, r1) /* Restore the TOC */
  135. REST_NVGPRS(r1) /* Restore the non-volatiles */
  136. ld r4,_CCR(r1)
  137. mtcr r4
  138. ld r5,_CTR(r1)
  139. mtctr r5
  140. ld r6,_XER(r1)
  141. mtspr SPRN_XER,r6
  142. ld r7,_DAR(r1)
  143. mtdar r7
  144. ld r8,_DSISR(r1)
  145. mtdsisr r8
  146. addi r1,r1,SWITCH_FRAME_SIZE /* Unstack our frame */
  147. ld r0,16(r1) /* get return address */
  148. mtlr r0
  149. blr /* return to caller */
  150. #endif /* CONFIG_PPC32 */