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