sbsa_sip_svc.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /*
  2. * Copyright (c) 2023, Linaro Limited and Contributors. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <assert.h>
  7. #include <common/runtime_svc.h>
  8. #include <smccc_helpers.h>
  9. #include <sbsa_platform.h>
  10. #define SMC_FASTCALL 0x80000000
  11. #define SMC64_FUNCTION (SMC_FASTCALL | 0x40000000)
  12. #define SIP_FUNCTION (SMC64_FUNCTION | 0x02000000)
  13. #define SIP_FUNCTION_ID(n) (SIP_FUNCTION | (n))
  14. /*
  15. * We do not use SMCCC_ARCH_SOC_ID here because qemu_sbsa is virtual platform
  16. * which uses SoC present in QEMU. And they can change on their own while we
  17. * need version of whole 'virtual hardware platform'.
  18. */
  19. #define SIP_SVC_VERSION SIP_FUNCTION_ID(1)
  20. #define SIP_SVC_GET_GIC SIP_FUNCTION_ID(100)
  21. #define SIP_SVC_GET_GIC_ITS SIP_FUNCTION_ID(101)
  22. #define SIP_SVC_GET_CPU_COUNT SIP_FUNCTION_ID(200)
  23. #define SIP_SVC_GET_CPU_NODE SIP_FUNCTION_ID(201)
  24. #define SIP_SVC_GET_CPU_TOPOLOGY SIP_FUNCTION_ID(202)
  25. #define SIP_SVC_GET_MEMORY_NODE_COUNT SIP_FUNCTION_ID(300)
  26. #define SIP_SVC_GET_MEMORY_NODE SIP_FUNCTION_ID(301)
  27. uintptr_t sbsa_get_gicd(void);
  28. uintptr_t sbsa_get_gicr(void);
  29. /*
  30. * This function is responsible for handling all SiP calls from the NS world
  31. */
  32. uintptr_t sbsa_sip_smc_handler(uint32_t smc_fid,
  33. u_register_t x1,
  34. u_register_t x2,
  35. u_register_t x3,
  36. u_register_t x4,
  37. void *cookie,
  38. void *handle,
  39. u_register_t flags)
  40. {
  41. uint32_t ns;
  42. uint64_t index;
  43. /* Determine which security state this SMC originated from */
  44. ns = is_caller_non_secure(flags);
  45. if (!ns) {
  46. ERROR("%s: wrong world SMC (0x%x)\n", __func__, smc_fid);
  47. SMC_RET1(handle, SMC_UNK);
  48. }
  49. switch (smc_fid) {
  50. case SIP_SVC_VERSION:
  51. INFO("Platform version requested\n");
  52. SMC_RET3(handle, NULL, sbsa_platform_version_major(),
  53. sbsa_platform_version_minor());
  54. case SIP_SVC_GET_GIC:
  55. SMC_RET3(handle, NULL, sbsa_get_gicd(), sbsa_get_gicr());
  56. case SIP_SVC_GET_GIC_ITS:
  57. SMC_RET2(handle, NULL, sbsa_platform_gic_its_addr());
  58. case SIP_SVC_GET_CPU_COUNT:
  59. SMC_RET2(handle, NULL, sbsa_platform_num_cpus());
  60. case SIP_SVC_GET_CPU_NODE:
  61. index = x1;
  62. if (index < PLATFORM_CORE_COUNT) {
  63. struct platform_cpu_data data;
  64. data = sbsa_platform_cpu_node(index);
  65. SMC_RET3(handle, NULL, data.nodeid, data.mpidr);
  66. } else {
  67. SMC_RET1(handle, SMC_ARCH_CALL_INVAL_PARAM);
  68. }
  69. case SIP_SVC_GET_CPU_TOPOLOGY:
  70. struct platform_cpu_topology topology;
  71. topology = sbsa_platform_cpu_topology();
  72. if (topology.cores > 0) {
  73. SMC_RET5(handle, NULL, topology.sockets,
  74. topology.clusters, topology.cores,
  75. topology.threads);
  76. } else {
  77. /* we do not know topology so we report SMC as unknown */
  78. SMC_RET1(handle, SMC_UNK);
  79. }
  80. case SIP_SVC_GET_MEMORY_NODE_COUNT:
  81. SMC_RET2(handle, NULL, sbsa_platform_num_memnodes());
  82. case SIP_SVC_GET_MEMORY_NODE:
  83. index = x1;
  84. if (index < PLAT_MAX_MEM_NODES) {
  85. struct platform_memory_data data;
  86. data = sbsa_platform_memory_node(index);
  87. SMC_RET4(handle, NULL, data.nodeid,
  88. data.addr_base, data.addr_size);
  89. } else {
  90. SMC_RET1(handle, SMC_ARCH_CALL_INVAL_PARAM);
  91. }
  92. default:
  93. ERROR("%s: unhandled SMC (0x%x) (function id: %d)\n", __func__, smc_fid,
  94. smc_fid - SIP_FUNCTION);
  95. SMC_RET1(handle, SMC_UNK);
  96. }
  97. }
  98. int sbsa_sip_smc_setup(void)
  99. {
  100. return 0;
  101. }
  102. /* Define a runtime service descriptor for fast SMC calls */
  103. DECLARE_RT_SVC(
  104. sbsa_sip_svc,
  105. OEN_SIP_START,
  106. OEN_SIP_END,
  107. SMC_TYPE_FAST,
  108. sbsa_sip_smc_setup,
  109. sbsa_sip_smc_handler
  110. );