opal-wrappers.S 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. /* SPDX-License-Identifier: GPL-2.0-or-later */
  2. /*
  3. * PowerNV OPAL API wrappers
  4. *
  5. * Copyright 2011 IBM Corp.
  6. */
  7. #include <linux/jump_label.h>
  8. #include <asm/ppc_asm.h>
  9. #include <asm/hvcall.h>
  10. #include <asm/asm-offsets.h>
  11. #include <asm/opal.h>
  12. #include <asm/asm-compat.h>
  13. #include <asm/feature-fixups.h>
  14. .section ".text"
  15. /*
  16. * r3-r10 - OPAL call arguments
  17. * STK_PARAM(R11) - OPAL opcode
  18. * STK_PARAM(R12) - MSR to restore
  19. */
  20. _GLOBAL_TOC(__opal_call)
  21. mflr r0
  22. std r0,PPC_LR_STKOFF(r1)
  23. ld r12,STK_PARAM(R12)(r1)
  24. li r0,MSR_IR|MSR_DR|MSR_LE
  25. andc r12,r12,r0
  26. LOAD_REG_ADDR(r11, opal_return)
  27. mtlr r11
  28. LOAD_REG_ADDR(r11, opal)
  29. ld r2,0(r11)
  30. ld r11,8(r11)
  31. mtspr SPRN_HSRR0,r11
  32. mtspr SPRN_HSRR1,r12
  33. /* set token to r0 */
  34. ld r0,STK_PARAM(R11)(r1)
  35. hrfid
  36. opal_return:
  37. /*
  38. * Restore MSR on OPAL return. The MSR is set to big-endian.
  39. */
  40. #ifdef __BIG_ENDIAN__
  41. ld r11,STK_PARAM(R12)(r1)
  42. mtmsrd r11
  43. #else
  44. /* Endian can only be switched with rfi, must byte reverse MSR load */
  45. .short 0x4039 /* li r10,STK_PARAM(R12) */
  46. .byte (STK_PARAM(R12) >> 8) & 0xff
  47. .byte STK_PARAM(R12) & 0xff
  48. .long 0x280c6a7d /* ldbrx r11,r10,r1 */
  49. .long 0x05009f42 /* bcl 20,31,$+4 */
  50. .long 0xa602487d /* mflr r10 */
  51. .long 0x14004a39 /* addi r10,r10,20 */
  52. .long 0xa64b5a7d /* mthsrr0 r10 */
  53. .long 0xa64b7b7d /* mthsrr1 r11 */
  54. .long 0x2402004c /* hrfid */
  55. #endif
  56. LOAD_PACA_TOC()
  57. ld r0,PPC_LR_STKOFF(r1)
  58. mtlr r0
  59. blr