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 ******************************************************************************/
plat_sip_handler(uint32_t smc_fid,uint64_t x1,uint64_t x2,uint64_t x3,uint64_t x4,const void * cookie,void * handle,uint64_t flags)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 ENABLE_FEAT_RAS
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