opal-takeover.S 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. /*
  2. * PowerNV OPAL takeover assembly code, for use by prom_init.c
  3. *
  4. * Copyright 2011 IBM Corp.
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version
  9. * 2 of the License, or (at your option) any later version.
  10. */
  11. #include <asm/ppc_asm.h>
  12. #include <asm/hvcall.h>
  13. #include <asm/asm-offsets.h>
  14. #include <asm/opal.h>
  15. #define STK_PARAM(i) (48 + ((i)-3)*8)
  16. #define H_HAL_TAKEOVER 0x5124
  17. #define H_HAL_TAKEOVER_QUERY_MAGIC -1
  18. .text
  19. _GLOBAL(opal_query_takeover)
  20. mfcr r0
  21. stw r0,8(r1)
  22. std r3,STK_PARAM(r3)(r1)
  23. std r4,STK_PARAM(r4)(r1)
  24. li r3,H_HAL_TAKEOVER
  25. li r4,H_HAL_TAKEOVER_QUERY_MAGIC
  26. HVSC
  27. ld r10,STK_PARAM(r3)(r1)
  28. std r4,0(r10)
  29. ld r10,STK_PARAM(r4)(r1)
  30. std r5,0(r10)
  31. lwz r0,8(r1)
  32. mtcrf 0xff,r0
  33. blr
  34. _GLOBAL(opal_do_takeover)
  35. mfcr r0
  36. stw r0,8(r1)
  37. mflr r0
  38. std r0,16(r1)
  39. bl __opal_do_takeover
  40. ld r0,16(r1)
  41. mtlr r0
  42. lwz r0,8(r1)
  43. mtcrf 0xff,r0
  44. blr
  45. __opal_do_takeover:
  46. ld r4,0(r3)
  47. ld r5,0x8(r3)
  48. ld r6,0x10(r3)
  49. ld r7,0x18(r3)
  50. ld r8,0x20(r3)
  51. ld r9,0x28(r3)
  52. ld r10,0x30(r3)
  53. ld r11,0x38(r3)
  54. li r3,H_HAL_TAKEOVER
  55. HVSC
  56. blr
  57. .globl opal_secondary_entry
  58. opal_secondary_entry:
  59. mr r31,r3
  60. mfmsr r11
  61. li r12,(MSR_SF | MSR_ISF)@highest
  62. sldi r12,r12,48
  63. or r11,r11,r12
  64. mtmsrd r11
  65. isync
  66. mfspr r4,SPRN_PIR
  67. std r4,0(r3)
  68. 1: HMT_LOW
  69. ld r4,8(r3)
  70. cmpli cr0,r4,0
  71. beq 1b
  72. HMT_MEDIUM
  73. 1: addi r3,r31,16
  74. bl __opal_do_takeover
  75. b 1b
  76. _GLOBAL(opal_enter_rtas)
  77. mflr r0
  78. std r0,16(r1)
  79. stdu r1,-PROM_FRAME_SIZE(r1) /* Save SP and create stack space */
  80. /* Because PROM is running in 32b mode, it clobbers the high order half
  81. * of all registers that it saves. We therefore save those registers
  82. * PROM might touch to the stack. (r0, r3-r13 are caller saved)
  83. */
  84. SAVE_GPR(2, r1)
  85. SAVE_GPR(13, r1)
  86. SAVE_8GPRS(14, r1)
  87. SAVE_10GPRS(22, r1)
  88. mfcr r10
  89. mfmsr r11
  90. std r10,_CCR(r1)
  91. std r11,_MSR(r1)
  92. /* Get the PROM entrypoint */
  93. mtlr r5
  94. /* Switch MSR to 32 bits mode
  95. */
  96. li r12,1
  97. rldicr r12,r12,MSR_SF_LG,(63-MSR_SF_LG)
  98. andc r11,r11,r12
  99. li r12,1
  100. rldicr r12,r12,MSR_ISF_LG,(63-MSR_ISF_LG)
  101. andc r11,r11,r12
  102. mtmsrd r11
  103. isync
  104. /* Enter RTAS here... */
  105. blrl
  106. /* Just make sure that r1 top 32 bits didn't get
  107. * corrupt by OF
  108. */
  109. rldicl r1,r1,0,32
  110. /* Restore the MSR (back to 64 bits) */
  111. ld r0,_MSR(r1)
  112. MTMSRD(r0)
  113. isync
  114. /* Restore other registers */
  115. REST_GPR(2, r1)
  116. REST_GPR(13, r1)
  117. REST_8GPRS(14, r1)
  118. REST_10GPRS(22, r1)
  119. ld r4,_CCR(r1)
  120. mtcr r4
  121. addi r1,r1,PROM_FRAME_SIZE
  122. ld r0,16(r1)
  123. mtlr r0
  124. blr