1 /* 2 * Copyright (c) 2019, 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 <mmio.h> 18 #include <platform_def.h> 19 #include <stdbool.h> 20 #include <string.h> 21 #include <errno.h> 22 #include <t194_nvg.h> 23 #include <tegra_def.h> 24 #include <tegra_platform.h> 25 26 /* Handler to check if MCE firmware is supported */ 27 static bool mce_firmware_not_supported(void) 28 { 29 bool status; 30 31 /* these platforms do not load MCE firmware */ 32 status = tegra_platform_is_linsim() || tegra_platform_is_qt() || 33 tegra_platform_is_virt_dev_kit(); 34 35 return status; 36 } 37 38 /******************************************************************************* 39 * Common handler for all MCE commands 40 ******************************************************************************/ 41 int32_t mce_command_handler(uint64_t cmd, uint64_t arg0, uint64_t arg1, 42 uint64_t arg2) 43 { 44 uint64_t ret64 = 0, arg3, arg4, arg5; 45 int32_t ret = 0; 46 cpu_context_t *ctx = cm_get_context(NON_SECURE); 47 gp_regs_t *gp_regs = get_gpregs_ctx(ctx); 48 49 assert(ctx); 50 assert(gp_regs); 51 52 switch (cmd) { 53 case MCE_CMD_ENTER_CSTATE: 54 ret = nvg_enter_cstate((uint32_t)arg0, (uint32_t)arg1); 55 if (ret < 0) { 56 ERROR("%s: enter_cstate failed(%d)\n", __func__, ret); 57 } 58 59 break; 60 61 case MCE_CMD_UPDATE_CSTATE_INFO: 62 /* 63 * get the parameters required for the update cstate info 64 * command 65 */ 66 arg3 = read_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X4)); 67 arg4 = read_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X5)); 68 arg5 = read_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X6)); 69 70 /* arg0 cluster 71 * arg1 ccplex 72 * arg2 system 73 * arg3 sys_state_force => T19x not support 74 * arg4 wake_mask 75 * arg5 update_wake_mask 76 */ 77 nvg_update_cstate_info((uint32_t)arg0, (uint32_t)arg1, 78 (uint32_t)arg2, (uint32_t)arg4, (uint8_t)arg5); 79 80 write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X4), (arg3)); 81 write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X5), (arg4)); 82 write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X6), (arg5)); 83 84 break; 85 86 case MCE_CMD_UPDATE_CROSSOVER_TIME: 87 ret = nvg_update_crossover_time((uint32_t)arg0, (uint32_t)arg1); 88 if (ret < 0) { 89 ERROR("%s: update_crossover_time failed(%d)\n", 90 __func__, ret); 91 } 92 93 break; 94 95 case MCE_CMD_READ_CSTATE_STATS: 96 ret64 = nvg_get_cstate_stat_query_value(); 97 98 /* update context to return cstate stats value */ 99 write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X1), (ret64)); 100 write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X2), (ret64)); 101 102 break; 103 104 case MCE_CMD_WRITE_CSTATE_STATS: 105 ret = nvg_set_cstate_stat_query_value(arg0); 106 107 break; 108 109 case MCE_CMD_IS_SC7_ALLOWED: 110 ret = nvg_is_sc7_allowed(); 111 if (ret < 0) { 112 ERROR("%s: is_sc7_allowed failed(%d)\n", __func__, ret); 113 break; 114 } 115 116 /* update context to return SC7 status value */ 117 write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X1), ((uint64_t)ret)); 118 write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X3), ((uint64_t)ret)); 119 120 break; 121 122 case MCE_CMD_ONLINE_CORE: 123 ret = nvg_online_core((uint32_t)arg0); 124 if (ret < 0) { 125 ERROR("%s: online_core failed(%d)\n", __func__, ret); 126 } 127 128 break; 129 130 case MCE_CMD_CC3_CTRL: 131 ret = nvg_cc3_ctrl((uint32_t)arg0, (uint8_t)arg2); 132 if (ret < 0) { 133 ERROR("%s: cc3_ctrl failed(%d)\n", __func__, ret); 134 } 135 136 break; 137 138 case MCE_CMD_READ_VERSIONS: 139 /* get the MCE firmware version */ 140 ret64 = nvg_get_version(); 141 142 /* 143 * version = minor(63:32) | major(31:0). Update context 144 * to return major and minor version number. 145 */ 146 write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X1), (ret64 & (uint64_t)0xFFFF)); 147 write_ctx_reg(gp_regs, ((uint64_t)CTX_GPREG_X2), (ret64 >> 32)); 148 149 break; 150 151 case MCE_CMD_ROC_FLUSH_CACHE_TRBITS: 152 ret = nvg_roc_clean_cache_trbits(); 153 if (ret < 0) { 154 ERROR("%s: flush cache_trbits failed(%d)\n", __func__, 155 ret); 156 } 157 158 break; 159 160 case MCE_CMD_ROC_FLUSH_CACHE: 161 ret = nvg_roc_flush_cache(); 162 if (ret < 0) { 163 ERROR("%s: flush cache failed(%d)\n", __func__, ret); 164 } 165 166 break; 167 168 case MCE_CMD_ROC_CLEAN_CACHE: 169 ret = nvg_roc_clean_cache(); 170 if (ret < 0) { 171 ERROR("%s: clean cache failed(%d)\n", __func__, ret); 172 } 173 174 break; 175 176 default: 177 ERROR("unknown MCE command (%llu)\n", cmd); 178 ret = EINVAL; 179 break; 180 } 181 182 return ret; 183 } 184 185 /******************************************************************************* 186 * Handler to update carveout values for Video Memory Carveout region 187 ******************************************************************************/ 188 int32_t mce_update_gsc_videomem(void) 189 { 190 int32_t ret; 191 192 /* 193 * MCE firmware is not running on simulation platforms. 194 */ 195 if (mce_firmware_not_supported()) { 196 ret = -EINVAL; 197 } else { 198 ret = nvg_update_ccplex_gsc((uint32_t)TEGRA_NVG_CHANNEL_UPDATE_GSC_VPR); 199 } 200 201 return ret; 202 } 203 204 /******************************************************************************* 205 * Handler to update carveout values for TZDRAM aperture 206 ******************************************************************************/ 207 int32_t mce_update_gsc_tzdram(void) 208 { 209 int32_t ret; 210 211 /* 212 * MCE firmware is not running on simulation platforms. 213 */ 214 if (mce_firmware_not_supported()) { 215 ret = -EINVAL; 216 } else { 217 ret = nvg_update_ccplex_gsc((uint32_t)TEGRA_NVG_CHANNEL_UPDATE_GSC_TZ_DRAM); 218 } 219 220 return ret; 221 } 222 223 /******************************************************************************* 224 * Handler to update carveout values for TZ SysRAM aperture 225 ******************************************************************************/ 226 int32_t mce_update_gsc_tzram(void) 227 { 228 int32_t ret; 229 230 /* 231 * MCE firmware is not running on simulation platforms. 232 */ 233 if (mce_firmware_not_supported()) { 234 ret = -EINVAL; 235 } else { 236 ret = nvg_update_ccplex_gsc((uint32_t)TEGRA_NVG_CHANNEL_UPDATE_GSC_TZRAM); 237 } 238 239 return ret; 240 } 241 242 /******************************************************************************* 243 * Handler to issue the UPDATE_CSTATE_INFO request 244 ******************************************************************************/ 245 void mce_update_cstate_info(const mce_cstate_info_t *cstate) 246 { 247 /* issue the UPDATE_CSTATE_INFO request */ 248 nvg_update_cstate_info(cstate->cluster, cstate->ccplex, cstate->system, 249 cstate->wake_mask, cstate->update_wake_mask); 250 } 251 252 /******************************************************************************* 253 * Handler to read the MCE firmware version and check if it is compatible 254 * with interface header the BL3-1 was compiled against 255 ******************************************************************************/ 256 void mce_verify_firmware_version(void) 257 { 258 uint64_t version; 259 uint32_t major, minor; 260 261 /* 262 * MCE firmware is not running on simulation platforms. 263 */ 264 if (mce_firmware_not_supported()) { 265 return; 266 } 267 268 /* 269 * Read the MCE firmware version and extract the major and minor 270 * version fields 271 */ 272 version = nvg_get_version(); 273 minor = (uint32_t)version; 274 major = (uint32_t)(version >> 32); 275 276 INFO("MCE Version - HW=%d:%d, SW=%d:%d\n", major, minor, 277 0, 0); 278 279 /* 280 * Verify that the MCE firmware version and the interface header 281 * match 282 */ 283 if (major != (uint32_t)TEGRA_NVG_VERSION_MAJOR) { 284 ERROR("MCE major version mismatch\n"); 285 panic(); 286 } 287 288 if (minor < (uint32_t)TEGRA_NVG_VERSION_MINOR) { 289 ERROR("MCE minor version mismatch\n"); 290 panic(); 291 } 292 } 293