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 */ 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 ******************************************************************************/ 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 ******************************************************************************/ 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 ******************************************************************************/ 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 ******************************************************************************/ 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 ******************************************************************************/ 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 ******************************************************************************/ 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 } 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 ******************************************************************************/ 236 void mce_system_shutdown(void) 237 { 238 nvg_system_shutdown(); 239 } 240 241 /******************************************************************************* 242 * Handler to reboot the entire system 243 ******************************************************************************/ 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 ******************************************************************************/ 252 void mce_clear_hsm_corr_status(void) 253 { 254 nvg_clear_hsm_corr_status(); 255 } 256