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