plat_sip_calls.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. /*
  2. * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. */
  6. #include <arch.h>
  7. #include <arch_helpers.h>
  8. #include <assert.h>
  9. #include <common/bl_common.h>
  10. #include <lib/el3_runtime/context_mgmt.h>
  11. #include <common/debug.h>
  12. #include <errno.h>
  13. #include <mce.h>
  14. #include <mce_private.h>
  15. #include <memctrl.h>
  16. #include <common/runtime_svc.h>
  17. #include <tegra_private.h>
  18. #include <tegra_platform.h>
  19. #include <smmu.h>
  20. #include <stdbool.h>
  21. /*******************************************************************************
  22. * Tegra194 SiP SMCs
  23. ******************************************************************************/
  24. #define TEGRA_SIP_GET_SMMU_PER 0xC200FF00U
  25. #define TEGRA_SIP_CLEAR_RAS_CORRECTED_ERRORS 0xC200FF01U
  26. /*******************************************************************************
  27. * This function is responsible for handling all T194 SiP calls
  28. ******************************************************************************/
  29. int32_t plat_sip_handler(uint32_t smc_fid,
  30. uint64_t x1,
  31. uint64_t x2,
  32. uint64_t x3,
  33. uint64_t x4,
  34. const void *cookie,
  35. void *handle,
  36. uint64_t flags)
  37. {
  38. int32_t ret = 0;
  39. uint32_t i, smmu_per[6] = {0};
  40. uint32_t num_smmu_devices = plat_get_num_smmu_devices();
  41. uint64_t per[3] = {0ULL};
  42. (void)x1;
  43. (void)x4;
  44. (void)cookie;
  45. (void)flags;
  46. switch (smc_fid) {
  47. case TEGRA_SIP_GET_SMMU_PER:
  48. /* make sure we dont go past the array length */
  49. assert(num_smmu_devices <= ARRAY_SIZE(smmu_per));
  50. /* read all supported SMMU_PER records */
  51. for (i = 0U; i < num_smmu_devices; i++) {
  52. smmu_per[i] = tegra_smmu_read_32(i, SMMU_GSR0_PER);
  53. }
  54. /* pack results into 3 64bit variables. */
  55. per[0] = smmu_per[0] | ((uint64_t)smmu_per[1] << 32U);
  56. per[1] = smmu_per[2] | ((uint64_t)smmu_per[3] << 32U);
  57. per[2] = smmu_per[4] | ((uint64_t)smmu_per[5] << 32U);
  58. /* provide the results via X1-X3 CPU registers */
  59. write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X1, per[0]);
  60. write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X2, per[1]);
  61. write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X3, per[2]);
  62. break;
  63. #if ENABLE_FEAT_RAS
  64. case TEGRA_SIP_CLEAR_RAS_CORRECTED_ERRORS:
  65. {
  66. /*
  67. * clear all RAS error records for corrected errors at first.
  68. * x1 shall be 0 for first SMC call after FHI is asserted.
  69. * */
  70. uint64_t local_x1 = x1;
  71. tegra194_ras_corrected_err_clear(&local_x1);
  72. if (local_x1 == 0ULL) {
  73. /* clear HSM corrected error status after all corrected
  74. * RAS errors are cleared.
  75. */
  76. mce_clear_hsm_corr_status();
  77. }
  78. write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X1, local_x1);
  79. break;
  80. }
  81. #endif
  82. default:
  83. ret = -ENOTSUP;
  84. break;
  85. }
  86. return ret;
  87. }