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 <context.h>
12 #include <lib/el3_runtime/context_mgmt.h>
13 #include <common/debug.h>
14 #include <denver.h>
15 #include <mce.h>
16 #include <mce_private.h>
17 #include <platform_def.h>
18 #include <stdbool.h>
19 #include <string.h>
20 #include <errno.h>
21 #include <t194_nvg.h>
22 #include <tegra_def.h>
23 #include <tegra_platform.h>
24 #include <tegra_private.h>
25
26 /* Handler to check if MCE firmware is supported */
mce_firmware_not_supported(void)27 static bool mce_firmware_not_supported(void)
28 {
29 bool status;
30
31 /* these platforms do not load MCE firmware */
32 status = tegra_platform_is_linsim() || tegra_platform_is_qt() ||
33 tegra_platform_is_virt_dev_kit();
34
35 return status;
36 }
37
38 /*******************************************************************************
39 * Common handler for all MCE commands
40 ******************************************************************************/
mce_command_handler(uint64_t cmd,uint64_t arg0,uint64_t arg1,uint64_t arg2)41 int32_t mce_command_handler(uint64_t cmd, uint64_t arg0, uint64_t arg1,
42 uint64_t arg2)
43 {
44 int32_t ret = 0;
45
46 switch (cmd) {
47 case (uint64_t)MCE_CMD_ENTER_CSTATE:
48 ret = nvg_enter_cstate((uint32_t)arg0, (uint32_t)arg1);
49 if (ret < 0) {
50 ERROR("%s: enter_cstate failed(%d)\n", __func__, ret);
51 }
52
53 break;
54
55 case (uint64_t)MCE_CMD_IS_SC7_ALLOWED:
56 ret = nvg_is_sc7_allowed();
57 if (ret < 0) {
58 ERROR("%s: is_sc7_allowed failed(%d)\n", __func__, ret);
59 }
60
61 break;
62
63 case (uint64_t)MCE_CMD_ONLINE_CORE:
64 ret = nvg_online_core((uint32_t)arg0);
65 if (ret < 0) {
66 ERROR("%s: online_core failed(%d)\n", __func__, ret);
67 }
68
69 break;
70
71 default:
72 ERROR("unknown MCE command (%llu)\n", cmd);
73 ret = -EINVAL;
74 break;
75 }
76
77 return ret;
78 }
79
80 /*******************************************************************************
81 * Handler to update carveout values for Video Memory Carveout region
82 ******************************************************************************/
mce_update_gsc_videomem(void)83 int32_t mce_update_gsc_videomem(void)
84 {
85 int32_t ret;
86
87 /*
88 * MCE firmware is not running on simulation platforms.
89 */
90 if (mce_firmware_not_supported()) {
91 ret = -EINVAL;
92 } else {
93 ret = nvg_update_ccplex_gsc((uint32_t)TEGRA_NVG_CHANNEL_UPDATE_GSC_VPR);
94 }
95
96 return ret;
97 }
98
99 /*******************************************************************************
100 * Handler to update carveout values for TZDRAM aperture
101 ******************************************************************************/
mce_update_gsc_tzdram(void)102 int32_t mce_update_gsc_tzdram(void)
103 {
104 int32_t ret;
105
106 /*
107 * MCE firmware is not running on simulation platforms.
108 */
109 if (mce_firmware_not_supported()) {
110 ret = -EINVAL;
111 } else {
112 ret = nvg_update_ccplex_gsc((uint32_t)TEGRA_NVG_CHANNEL_UPDATE_GSC_TZ_DRAM);
113 }
114
115 return ret;
116 }
117
118 /*******************************************************************************
119 * Handler to issue the UPDATE_CSTATE_INFO request
120 ******************************************************************************/
mce_update_cstate_info(const mce_cstate_info_t * cstate)121 void mce_update_cstate_info(const mce_cstate_info_t *cstate)
122 {
123 /* issue the UPDATE_CSTATE_INFO request */
124 nvg_update_cstate_info(cstate->cluster, cstate->ccplex, cstate->system,
125 cstate->wake_mask, cstate->update_wake_mask);
126 }
127
128 /*******************************************************************************
129 * Handler to read the MCE firmware version and check if it is compatible
130 * with interface header the BL3-1 was compiled against
131 ******************************************************************************/
mce_verify_firmware_version(void)132 void mce_verify_firmware_version(void)
133 {
134 uint64_t version;
135 uint32_t major, minor;
136
137 /*
138 * MCE firmware is not running on simulation platforms.
139 */
140 if (mce_firmware_not_supported()) {
141 return;
142 }
143
144 /*
145 * Read the MCE firmware version and extract the major and minor
146 * version fields
147 */
148 version = nvg_get_version();
149 minor = (uint32_t)version;
150 major = (uint32_t)(version >> 32);
151
152 INFO("MCE Version - HW=%u:%u, SW=%u:%u\n", major, minor,
153 TEGRA_NVG_VERSION_MAJOR, TEGRA_NVG_VERSION_MINOR);
154
155 /*
156 * Verify that the MCE firmware version and the interface header
157 * match
158 */
159 if (major != (uint32_t)TEGRA_NVG_VERSION_MAJOR) {
160 ERROR("MCE major version mismatch\n");
161 panic();
162 }
163
164 if (minor < (uint32_t)TEGRA_NVG_VERSION_MINOR) {
165 ERROR("MCE minor version mismatch\n");
166 panic();
167 }
168 }
169
170 #if ENABLE_STRICT_CHECKING_MODE
171 /*******************************************************************************
172 * Handler to enable the strict checking mode
173 ******************************************************************************/
mce_enable_strict_checking(void)174 void mce_enable_strict_checking(void)
175 {
176 uint64_t sctlr = read_sctlr_el3();
177 int32_t ret = 0;
178
179 if (tegra_platform_is_silicon() || tegra_platform_is_fpga()) {
180 /*
181 * Step1: TZ-DRAM and TZRAM should be setup before the MMU is
182 * enabled.
183 *
184 * The common code makes sure that TZDRAM/TZRAM are already
185 * enabled before calling into this handler. If this is not the
186 * case, the following sequence must be executed before moving
187 * on to step 2.
188 *
189 * tlbialle1is();
190 * tlbialle3is();
191 * dsbsy();
192 * isb();
193 *
194 */
195 if ((sctlr & (uint64_t)SCTLR_M_BIT) == (uint64_t)SCTLR_M_BIT) {
196 tlbialle1is();
197 tlbialle3is();
198 dsbsy();
199 isb();
200 }
201
202 /*
203 * Step2: SCF flush - Clean and invalidate caches and clear the
204 * TR-bits
205 */
206 ret = nvg_roc_clean_cache_trbits();
207 if (ret < 0) {
208 ERROR("%s: flush cache_trbits failed(%d)\n", __func__,
209 ret);
210 return;
211 }
212
213 /*
214 * Step3: Issue the SECURITY_CONFIG request to MCE to enable
215 * strict checking mode.
216 */
217 nvg_enable_strict_checking_mode();
218 }
219 }
mce_verify_strict_checking(void)220 void mce_verify_strict_checking(void)
221 {
222 bool is_silicon = tegra_platform_is_silicon();
223 bool is_fpga = tegra_platform_is_fpga();
224
225 if (is_silicon || is_fpga) {
226 nvg_verify_strict_checking_mode();
227 }
228 }
229 #endif
230
231 /*******************************************************************************
232 * Handler to power down the entire system
233 ******************************************************************************/
mce_system_shutdown(void)234 void mce_system_shutdown(void)
235 {
236 nvg_system_shutdown();
237 }
238
239 /*******************************************************************************
240 * Handler to reboot the entire system
241 ******************************************************************************/
mce_system_reboot(void)242 void mce_system_reboot(void)
243 {
244 nvg_system_reboot();
245 }
246
247 /*******************************************************************************
248 * Handler to clear CCPLEX->HSM correctable RAS error signal.
249 ******************************************************************************/
mce_clear_hsm_corr_status(void)250 void mce_clear_hsm_corr_status(void)
251 {
252 nvg_clear_hsm_corr_status();
253 }
254