generic-arm64-smcall.c 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /*
  2. * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <stdio.h>
  7. #include <common/debug.h>
  8. #include <common/runtime_svc.h>
  9. #include <platform_def.h>
  10. #include "generic-arm64-smcall.h"
  11. #ifndef PLAT_ARM_GICD_BASE
  12. #ifdef GICD_BASE
  13. #define PLAT_ARM_GICD_BASE GICD_BASE
  14. #define PLAT_ARM_GICC_BASE GICC_BASE
  15. #ifdef GICR_BASE
  16. #define PLAT_ARM_GICR_BASE GICR_BASE
  17. #endif
  18. #else
  19. #error PLAT_ARM_GICD_BASE or GICD_BASE must be defined
  20. #endif
  21. #endif
  22. #ifndef PLAT_ARM_GICR_BASE
  23. #define PLAT_ARM_GICR_BASE SMC_UNK
  24. #endif
  25. int trusty_disable_serial_debug;
  26. struct dputc_state {
  27. char linebuf[128];
  28. unsigned l;
  29. };
  30. static struct dputc_state dputc_state[2];
  31. static void trusty_dputc(char ch, int secure)
  32. {
  33. unsigned i;
  34. struct dputc_state *s = &dputc_state[!secure];
  35. if (trusty_disable_serial_debug)
  36. return;
  37. s->linebuf[s->l++] = ch;
  38. if (s->l == sizeof(s->linebuf) || ch == '\n') {
  39. if (secure)
  40. printf("secure os: ");
  41. else
  42. printf("non-secure os: ");
  43. for (i = 0; i < s->l; i++) {
  44. putchar(s->linebuf[i]);
  45. }
  46. if (ch != '\n') {
  47. printf(" <...>\n");
  48. }
  49. s->l = 0;
  50. }
  51. }
  52. static uint64_t trusty_get_reg_base(uint32_t reg)
  53. {
  54. switch (reg) {
  55. case SMC_GET_GIC_BASE_GICD:
  56. return PLAT_ARM_GICD_BASE;
  57. case SMC_GET_GIC_BASE_GICC:
  58. return PLAT_ARM_GICC_BASE;
  59. case SMC_GET_GIC_BASE_GICR:
  60. return PLAT_ARM_GICR_BASE;
  61. default:
  62. NOTICE("%s(0x%x) unknown reg\n", __func__, reg);
  63. return SMC_UNK;
  64. }
  65. }
  66. static uintptr_t trusty_generic_platform_smc(uint32_t smc_fid,
  67. u_register_t x1,
  68. u_register_t x2,
  69. u_register_t x3,
  70. u_register_t x4,
  71. void *cookie,
  72. void *handle,
  73. u_register_t flags)
  74. {
  75. switch (smc_fid) {
  76. case SMC_FC_DEBUG_PUTC:
  77. trusty_dputc(x1, is_caller_secure(flags));
  78. SMC_RET1(handle, 0);
  79. case SMC_FC_GET_REG_BASE:
  80. case SMC_FC64_GET_REG_BASE:
  81. SMC_RET1(handle, trusty_get_reg_base(x1));
  82. default:
  83. NOTICE("%s(0x%x, 0x%lx) unknown smc\n", __func__, smc_fid, x1);
  84. SMC_RET1(handle, SMC_UNK);
  85. }
  86. }
  87. /* Define a SPD runtime service descriptor for fast SMC calls */
  88. DECLARE_RT_SVC(
  89. trusty_fast,
  90. SMC_ENTITY_PLATFORM_MONITOR,
  91. SMC_ENTITY_PLATFORM_MONITOR,
  92. SMC_TYPE_FAST,
  93. NULL,
  94. trusty_generic_platform_smc
  95. );