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