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 <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 /******************************************************************************* 23 * Tegra194 SiP SMCs 24 ******************************************************************************/ 25 #define TEGRA_SIP_GET_SMMU_PER 0xC200FF00U 26 27 /******************************************************************************* 28 * This function is responsible for handling all T194 SiP calls 29 ******************************************************************************/ 30 int32_t plat_sip_handler(uint32_t smc_fid, 31 uint64_t x1, 32 uint64_t x2, 33 uint64_t x3, 34 uint64_t x4, 35 const void *cookie, 36 void *handle, 37 uint64_t flags) 38 { 39 int32_t ret = 0; 40 uint32_t i, smmu_per[6] = {0}; 41 uint32_t num_smmu_devices = plat_get_num_smmu_devices(); 42 uint64_t per[3] = {0ULL}; 43 44 (void)x1; 45 (void)x4; 46 (void)cookie; 47 (void)flags; 48 49 switch (smc_fid) { 50 case TEGRA_SIP_GET_SMMU_PER: 51 52 /* make sure we dont go past the array length */ 53 assert(num_smmu_devices <= ARRAY_SIZE(smmu_per)); 54 55 /* read all supported SMMU_PER records */ 56 for (i = 0U; i < num_smmu_devices; i++) { 57 smmu_per[i] = tegra_smmu_read_32(i, SMMU_GSR0_PER); 58 } 59 60 /* pack results into 3 64bit variables. */ 61 per[0] = smmu_per[0] | ((uint64_t)smmu_per[1] << 32U); 62 per[1] = smmu_per[2] | ((uint64_t)smmu_per[3] << 32U); 63 per[2] = smmu_per[4] | ((uint64_t)smmu_per[5] << 32U); 64 65 /* provide the results via X1-X3 CPU registers */ 66 write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X1, per[0]); 67 write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X2, per[1]); 68 write_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X3, per[2]); 69 70 break; 71 72 default: 73 ret = -ENOTSUP; 74 break; 75 } 76 77 return ret; 78 } 79