fwcall.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. /**
  2. * (C) Copyright 2014, Cavium Inc.
  3. *
  4. * SPDX-License-Identifier: GPL-2.0+
  5. **/
  6. #include <asm-offsets.h>
  7. #include <config.h>
  8. #include <version.h>
  9. #include <asm/macro.h>
  10. #include <asm/psci.h>
  11. #include <asm/system.h>
  12. /*
  13. * Issue the hypervisor call
  14. *
  15. * x0~x7: input arguments
  16. * x0~x3: output arguments
  17. */
  18. static void hvc_call(struct pt_regs *args)
  19. {
  20. asm volatile(
  21. "ldr x0, %0\n"
  22. "ldr x1, %1\n"
  23. "ldr x2, %2\n"
  24. "ldr x3, %3\n"
  25. "ldr x4, %4\n"
  26. "ldr x5, %5\n"
  27. "ldr x6, %6\n"
  28. "ldr x7, %7\n"
  29. "hvc #0\n"
  30. "str x0, %0\n"
  31. "str x1, %1\n"
  32. "str x2, %2\n"
  33. "str x3, %3\n"
  34. : "+m" (args->regs[0]), "+m" (args->regs[1]),
  35. "+m" (args->regs[2]), "+m" (args->regs[3])
  36. : "m" (args->regs[4]), "m" (args->regs[5]),
  37. "m" (args->regs[6]), "m" (args->regs[7])
  38. : "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",
  39. "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15",
  40. "x16", "x17");
  41. }
  42. /*
  43. * void smc_call(arg0, arg1...arg7)
  44. *
  45. * issue the secure monitor call
  46. *
  47. * x0~x7: input arguments
  48. * x0~x3: output arguments
  49. */
  50. void smc_call(struct pt_regs *args)
  51. {
  52. asm volatile(
  53. "ldr x0, %0\n"
  54. "ldr x1, %1\n"
  55. "ldr x2, %2\n"
  56. "ldr x3, %3\n"
  57. "ldr x4, %4\n"
  58. "ldr x5, %5\n"
  59. "ldr x6, %6\n"
  60. "smc #0\n"
  61. "str x0, %0\n"
  62. "str x1, %1\n"
  63. "str x2, %2\n"
  64. "str x3, %3\n"
  65. : "+m" (args->regs[0]), "+m" (args->regs[1]),
  66. "+m" (args->regs[2]), "+m" (args->regs[3])
  67. : "m" (args->regs[4]), "m" (args->regs[5]),
  68. "m" (args->regs[6])
  69. : "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",
  70. "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15",
  71. "x16", "x17");
  72. }
  73. /*
  74. * For now, all systems we support run at least in EL2 and thus
  75. * trigger PSCI calls to EL3 using SMC. If anyone ever wants to
  76. * use PSCI on U-Boot running below a hypervisor, please detect
  77. * this and set the flag accordingly.
  78. */
  79. static const bool use_smc_for_psci = true;
  80. void __noreturn psci_system_reset(void)
  81. {
  82. struct pt_regs regs;
  83. regs.regs[0] = ARM_PSCI_0_2_FN_SYSTEM_RESET;
  84. if (use_smc_for_psci)
  85. smc_call(&regs);
  86. else
  87. hvc_call(&regs);
  88. while (1)
  89. ;
  90. }
  91. void __noreturn psci_system_off(void)
  92. {
  93. struct pt_regs regs;
  94. regs.regs[0] = ARM_PSCI_0_2_FN_SYSTEM_OFF;
  95. if (use_smc_for_psci)
  96. smc_call(&regs);
  97. else
  98. hvc_call(&regs);
  99. while (1)
  100. ;
  101. }