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