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