141612559SVarun Wadekar /*
2a3c2c0e9SSteven Kao * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved.
341612559SVarun Wadekar *
441612559SVarun Wadekar * SPDX-License-Identifier: BSD-3-Clause
541612559SVarun Wadekar */
641612559SVarun Wadekar
741612559SVarun Wadekar #include <arch.h>
841612559SVarun Wadekar #include <arch_helpers.h>
941612559SVarun Wadekar #include <assert.h>
1041612559SVarun Wadekar #include <common/bl_common.h>
1141612559SVarun Wadekar #include <context.h>
1241612559SVarun Wadekar #include <lib/el3_runtime/context_mgmt.h>
1341612559SVarun Wadekar #include <common/debug.h>
1441612559SVarun Wadekar #include <denver.h>
1541612559SVarun Wadekar #include <mce.h>
1641612559SVarun Wadekar #include <mce_private.h>
179808032cSSteven Kao #include <platform_def.h>
182bda9202SSteven Kao #include <stdbool.h>
19*4ce3e99aSScott Branden #include <stdint.h>
2041612559SVarun Wadekar #include <string.h>
2141612559SVarun Wadekar #include <errno.h>
22*4ce3e99aSScott Branden #include <inttypes.h>
239808032cSSteven Kao #include <t194_nvg.h>
2441612559SVarun Wadekar #include <tegra_def.h>
2541612559SVarun Wadekar #include <tegra_platform.h>
26ac252f95SDilan Lee #include <tegra_private.h>
2741612559SVarun Wadekar
282bda9202SSteven Kao /* Handler to check if MCE firmware is supported */
mce_firmware_not_supported(void)292bda9202SSteven Kao static bool mce_firmware_not_supported(void)
302bda9202SSteven Kao {
312bda9202SSteven Kao bool status;
322bda9202SSteven Kao
332bda9202SSteven Kao /* these platforms do not load MCE firmware */
342bda9202SSteven Kao status = tegra_platform_is_linsim() || tegra_platform_is_qt() ||
352bda9202SSteven Kao tegra_platform_is_virt_dev_kit();
362bda9202SSteven Kao
372bda9202SSteven Kao return status;
382bda9202SSteven Kao }
392bda9202SSteven Kao
4041612559SVarun Wadekar /*******************************************************************************
4141612559SVarun Wadekar * Common handler for all MCE commands
4241612559SVarun Wadekar ******************************************************************************/
mce_command_handler(uint64_t cmd,uint64_t arg0,uint64_t arg1,uint64_t arg2)4373dad7f9SAnthony Zhou int32_t mce_command_handler(uint64_t cmd, uint64_t arg0, uint64_t arg1,
4441612559SVarun Wadekar uint64_t arg2)
4541612559SVarun Wadekar {
469808032cSSteven Kao int32_t ret = 0;
4741612559SVarun Wadekar
4841612559SVarun Wadekar switch (cmd) {
496152de3bSAnthony Zhou case (uint64_t)MCE_CMD_ENTER_CSTATE:
509808032cSSteven Kao ret = nvg_enter_cstate((uint32_t)arg0, (uint32_t)arg1);
519808032cSSteven Kao if (ret < 0) {
529808032cSSteven Kao ERROR("%s: enter_cstate failed(%d)\n", __func__, ret);
539808032cSSteven Kao }
549808032cSSteven Kao
5541612559SVarun Wadekar break;
5641612559SVarun Wadekar
576152de3bSAnthony Zhou case (uint64_t)MCE_CMD_IS_SC7_ALLOWED:
589808032cSSteven Kao ret = nvg_is_sc7_allowed();
599808032cSSteven Kao if (ret < 0) {
609808032cSSteven Kao ERROR("%s: is_sc7_allowed failed(%d)\n", __func__, ret);
619808032cSSteven Kao }
6241612559SVarun Wadekar
6341612559SVarun Wadekar break;
6441612559SVarun Wadekar
656152de3bSAnthony Zhou case (uint64_t)MCE_CMD_ONLINE_CORE:
669808032cSSteven Kao ret = nvg_online_core((uint32_t)arg0);
679808032cSSteven Kao if (ret < 0) {
689808032cSSteven Kao ERROR("%s: online_core failed(%d)\n", __func__, ret);
699808032cSSteven Kao }
7041612559SVarun Wadekar
7141612559SVarun Wadekar break;
7241612559SVarun Wadekar
7341612559SVarun Wadekar default:
74*4ce3e99aSScott Branden ERROR("unknown MCE command (%" PRIu64 ")\n", cmd);
7508c085dcSVarun Wadekar ret = -EINVAL;
769808032cSSteven Kao break;
7741612559SVarun Wadekar }
7841612559SVarun Wadekar
7941612559SVarun Wadekar return ret;
8041612559SVarun Wadekar }
8141612559SVarun Wadekar
8241612559SVarun Wadekar /*******************************************************************************
8341612559SVarun Wadekar * Handler to update carveout values for Video Memory Carveout region
8441612559SVarun Wadekar ******************************************************************************/
mce_update_gsc_videomem(void)859808032cSSteven Kao int32_t mce_update_gsc_videomem(void)
8641612559SVarun Wadekar {
872bda9202SSteven Kao int32_t ret;
882bda9202SSteven Kao
892bda9202SSteven Kao /*
902bda9202SSteven Kao * MCE firmware is not running on simulation platforms.
912bda9202SSteven Kao */
922bda9202SSteven Kao if (mce_firmware_not_supported()) {
932bda9202SSteven Kao ret = -EINVAL;
942bda9202SSteven Kao } else {
952bda9202SSteven Kao ret = nvg_update_ccplex_gsc((uint32_t)TEGRA_NVG_CHANNEL_UPDATE_GSC_VPR);
962bda9202SSteven Kao }
972bda9202SSteven Kao
982bda9202SSteven Kao return ret;
9941612559SVarun Wadekar }
10041612559SVarun Wadekar
10141612559SVarun Wadekar /*******************************************************************************
10241612559SVarun Wadekar * Handler to update carveout values for TZDRAM aperture
10341612559SVarun Wadekar ******************************************************************************/
mce_update_gsc_tzdram(void)1049808032cSSteven Kao int32_t mce_update_gsc_tzdram(void)
10541612559SVarun Wadekar {
1062bda9202SSteven Kao int32_t ret;
1072bda9202SSteven Kao
1082bda9202SSteven Kao /*
1092bda9202SSteven Kao * MCE firmware is not running on simulation platforms.
1102bda9202SSteven Kao */
1112bda9202SSteven Kao if (mce_firmware_not_supported()) {
1122bda9202SSteven Kao ret = -EINVAL;
1132bda9202SSteven Kao } else {
1142bda9202SSteven Kao ret = nvg_update_ccplex_gsc((uint32_t)TEGRA_NVG_CHANNEL_UPDATE_GSC_TZ_DRAM);
1152bda9202SSteven Kao }
1162bda9202SSteven Kao
1172bda9202SSteven Kao return ret;
11841612559SVarun Wadekar }
11941612559SVarun Wadekar
12041612559SVarun Wadekar /*******************************************************************************
12141612559SVarun Wadekar * Handler to issue the UPDATE_CSTATE_INFO request
12241612559SVarun Wadekar ******************************************************************************/
mce_update_cstate_info(const mce_cstate_info_t * cstate)12373dad7f9SAnthony Zhou void mce_update_cstate_info(const mce_cstate_info_t *cstate)
12441612559SVarun Wadekar {
12541612559SVarun Wadekar /* issue the UPDATE_CSTATE_INFO request */
1269808032cSSteven Kao nvg_update_cstate_info(cstate->cluster, cstate->ccplex, cstate->system,
1279808032cSSteven Kao cstate->wake_mask, cstate->update_wake_mask);
12841612559SVarun Wadekar }
12941612559SVarun Wadekar
13041612559SVarun Wadekar /*******************************************************************************
13141612559SVarun Wadekar * Handler to read the MCE firmware version and check if it is compatible
13241612559SVarun Wadekar * with interface header the BL3-1 was compiled against
13341612559SVarun Wadekar ******************************************************************************/
mce_verify_firmware_version(void)13441612559SVarun Wadekar void mce_verify_firmware_version(void)
13541612559SVarun Wadekar {
13641612559SVarun Wadekar uint64_t version;
13741612559SVarun Wadekar uint32_t major, minor;
13841612559SVarun Wadekar
13941612559SVarun Wadekar /*
14041612559SVarun Wadekar * MCE firmware is not running on simulation platforms.
14141612559SVarun Wadekar */
1422bda9202SSteven Kao if (mce_firmware_not_supported()) {
14341612559SVarun Wadekar return;
1449808032cSSteven Kao }
14541612559SVarun Wadekar
14641612559SVarun Wadekar /*
14741612559SVarun Wadekar * Read the MCE firmware version and extract the major and minor
14841612559SVarun Wadekar * version fields
14941612559SVarun Wadekar */
1509808032cSSteven Kao version = nvg_get_version();
1519808032cSSteven Kao minor = (uint32_t)version;
1529808032cSSteven Kao major = (uint32_t)(version >> 32);
15341612559SVarun Wadekar
154ac2cc6b0SVarun Wadekar INFO("MCE Version - HW=%u:%u, SW=%u:%u\n", major, minor,
155ac2cc6b0SVarun Wadekar TEGRA_NVG_VERSION_MAJOR, TEGRA_NVG_VERSION_MINOR);
15641612559SVarun Wadekar
15741612559SVarun Wadekar /*
15841612559SVarun Wadekar * Verify that the MCE firmware version and the interface header
15941612559SVarun Wadekar * match
16041612559SVarun Wadekar */
1619808032cSSteven Kao if (major != (uint32_t)TEGRA_NVG_VERSION_MAJOR) {
16241612559SVarun Wadekar ERROR("MCE major version mismatch\n");
16341612559SVarun Wadekar panic();
16441612559SVarun Wadekar }
16541612559SVarun Wadekar
1669808032cSSteven Kao if (minor < (uint32_t)TEGRA_NVG_VERSION_MINOR) {
16741612559SVarun Wadekar ERROR("MCE minor version mismatch\n");
16841612559SVarun Wadekar panic();
16941612559SVarun Wadekar }
17041612559SVarun Wadekar }
171ac252f95SDilan Lee
172a3c2c0e9SSteven Kao #if ENABLE_STRICT_CHECKING_MODE
173ac252f95SDilan Lee /*******************************************************************************
174ac252f95SDilan Lee * Handler to enable the strict checking mode
175ac252f95SDilan Lee ******************************************************************************/
mce_enable_strict_checking(void)176ac252f95SDilan Lee void mce_enable_strict_checking(void)
177ac252f95SDilan Lee {
178ac252f95SDilan Lee uint64_t sctlr = read_sctlr_el3();
179ac252f95SDilan Lee int32_t ret = 0;
180ac252f95SDilan Lee
181ac252f95SDilan Lee if (tegra_platform_is_silicon() || tegra_platform_is_fpga()) {
182ac252f95SDilan Lee /*
183ac252f95SDilan Lee * Step1: TZ-DRAM and TZRAM should be setup before the MMU is
184ac252f95SDilan Lee * enabled.
185ac252f95SDilan Lee *
186ac252f95SDilan Lee * The common code makes sure that TZDRAM/TZRAM are already
187ac252f95SDilan Lee * enabled before calling into this handler. If this is not the
188ac252f95SDilan Lee * case, the following sequence must be executed before moving
189ac252f95SDilan Lee * on to step 2.
190ac252f95SDilan Lee *
191ac252f95SDilan Lee * tlbialle1is();
192ac252f95SDilan Lee * tlbialle3is();
193ac252f95SDilan Lee * dsbsy();
194ac252f95SDilan Lee * isb();
195ac252f95SDilan Lee *
196ac252f95SDilan Lee */
197ac252f95SDilan Lee if ((sctlr & (uint64_t)SCTLR_M_BIT) == (uint64_t)SCTLR_M_BIT) {
198ac252f95SDilan Lee tlbialle1is();
199ac252f95SDilan Lee tlbialle3is();
200ac252f95SDilan Lee dsbsy();
201ac252f95SDilan Lee isb();
202ac252f95SDilan Lee }
203ac252f95SDilan Lee
204ac252f95SDilan Lee /*
205ac252f95SDilan Lee * Step2: SCF flush - Clean and invalidate caches and clear the
206ac252f95SDilan Lee * TR-bits
207ac252f95SDilan Lee */
208ac252f95SDilan Lee ret = nvg_roc_clean_cache_trbits();
209ac252f95SDilan Lee if (ret < 0) {
210ac252f95SDilan Lee ERROR("%s: flush cache_trbits failed(%d)\n", __func__,
211ac252f95SDilan Lee ret);
212ac252f95SDilan Lee return;
213ac252f95SDilan Lee }
214ac252f95SDilan Lee
215ac252f95SDilan Lee /*
216ac252f95SDilan Lee * Step3: Issue the SECURITY_CONFIG request to MCE to enable
217ac252f95SDilan Lee * strict checking mode.
218ac252f95SDilan Lee */
219ac252f95SDilan Lee nvg_enable_strict_checking_mode();
220ac252f95SDilan Lee }
221ac252f95SDilan Lee }
mce_verify_strict_checking(void)2225ce05d6bSAnthony Zhou void mce_verify_strict_checking(void)
2235ce05d6bSAnthony Zhou {
2245ce05d6bSAnthony Zhou bool is_silicon = tegra_platform_is_silicon();
2255ce05d6bSAnthony Zhou bool is_fpga = tegra_platform_is_fpga();
2265ce05d6bSAnthony Zhou
2275ce05d6bSAnthony Zhou if (is_silicon || is_fpga) {
2285ce05d6bSAnthony Zhou nvg_verify_strict_checking_mode();
2295ce05d6bSAnthony Zhou }
2305ce05d6bSAnthony Zhou }
231a3c2c0e9SSteven Kao #endif
2320789758aSVignesh Radhakrishnan
2330789758aSVignesh Radhakrishnan /*******************************************************************************
2340789758aSVignesh Radhakrishnan * Handler to power down the entire system
2350789758aSVignesh Radhakrishnan ******************************************************************************/
mce_system_shutdown(void)2360789758aSVignesh Radhakrishnan void mce_system_shutdown(void)
2370789758aSVignesh Radhakrishnan {
2380789758aSVignesh Radhakrishnan nvg_system_shutdown();
2390789758aSVignesh Radhakrishnan }
2400789758aSVignesh Radhakrishnan
2410789758aSVignesh Radhakrishnan /*******************************************************************************
2420789758aSVignesh Radhakrishnan * Handler to reboot the entire system
2430789758aSVignesh Radhakrishnan ******************************************************************************/
mce_system_reboot(void)2440789758aSVignesh Radhakrishnan void mce_system_reboot(void)
2450789758aSVignesh Radhakrishnan {
2460789758aSVignesh Radhakrishnan nvg_system_reboot();
2470789758aSVignesh Radhakrishnan }
2480d851195SVarun Wadekar
2490d851195SVarun Wadekar /*******************************************************************************
2500d851195SVarun Wadekar * Handler to clear CCPLEX->HSM correctable RAS error signal.
2510d851195SVarun Wadekar ******************************************************************************/
mce_clear_hsm_corr_status(void)2520d851195SVarun Wadekar void mce_clear_hsm_corr_status(void)
2530d851195SVarun Wadekar {
2540d851195SVarun Wadekar nvg_clear_hsm_corr_status();
2550d851195SVarun Wadekar }
256