1 /* 2 * Copyright (c) 2015-2016, ARM Limited and Contributors. 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 <bl_common.h> 11 #include <context.h> 12 #include <context_mgmt.h> 13 #include <debug.h> 14 #include <denver.h> 15 #include <mce.h> 16 #include <mce_private.h> 17 #include <mmio.h> 18 #include <string.h> 19 #include <sys/errno.h> 20 #include <t18x_ari.h> 21 #include <tegra_def.h> 22 #include <tegra_platform.h> 23 24 /* NVG functions handlers */ 25 static arch_mce_ops_t nvg_mce_ops = { 26 .enter_cstate = nvg_enter_cstate, 27 .update_cstate_info = nvg_update_cstate_info, 28 .update_crossover_time = nvg_update_crossover_time, 29 .read_cstate_stats = nvg_read_cstate_stats, 30 .write_cstate_stats = nvg_write_cstate_stats, 31 .call_enum_misc = ari_enumeration_misc, 32 .is_ccx_allowed = nvg_is_ccx_allowed, 33 .is_sc7_allowed = nvg_is_sc7_allowed, 34 .online_core = nvg_online_core, 35 .cc3_ctrl = nvg_cc3_ctrl, 36 .update_reset_vector = ari_reset_vector_update, 37 .roc_flush_cache = ari_roc_flush_cache, 38 .roc_flush_cache_trbits = ari_roc_flush_cache_trbits, 39 .roc_clean_cache = ari_roc_clean_cache, 40 .read_write_mca = ari_read_write_mca, 41 .update_ccplex_gsc = ari_update_ccplex_gsc, 42 .enter_ccplex_state = ari_enter_ccplex_state, 43 .read_write_uncore_perfmon = ari_read_write_uncore_perfmon, 44 .misc_ccplex = ari_misc_ccplex 45 }; 46 47 /* ARI functions handlers */ 48 static arch_mce_ops_t ari_mce_ops = { 49 .enter_cstate = ari_enter_cstate, 50 .update_cstate_info = ari_update_cstate_info, 51 .update_crossover_time = ari_update_crossover_time, 52 .read_cstate_stats = ari_read_cstate_stats, 53 .write_cstate_stats = ari_write_cstate_stats, 54 .call_enum_misc = ari_enumeration_misc, 55 .is_ccx_allowed = ari_is_ccx_allowed, 56 .is_sc7_allowed = ari_is_sc7_allowed, 57 .online_core = ari_online_core, 58 .cc3_ctrl = ari_cc3_ctrl, 59 .update_reset_vector = ari_reset_vector_update, 60 .roc_flush_cache = ari_roc_flush_cache, 61 .roc_flush_cache_trbits = ari_roc_flush_cache_trbits, 62 .roc_clean_cache = ari_roc_clean_cache, 63 .read_write_mca = ari_read_write_mca, 64 .update_ccplex_gsc = ari_update_ccplex_gsc, 65 .enter_ccplex_state = ari_enter_ccplex_state, 66 .read_write_uncore_perfmon = ari_read_write_uncore_perfmon, 67 .misc_ccplex = ari_misc_ccplex 68 }; 69 70 typedef struct mce_config { 71 uint32_t ari_base; 72 arch_mce_ops_t *ops; 73 } mce_config_t; 74 75 /* Table to hold the per-CPU ARI base address and function handlers */ 76 static mce_config_t mce_cfg_table[MCE_ARI_APERTURES_MAX] = { 77 { 78 /* A57 Core 0 */ 79 .ari_base = TEGRA_MMCRAB_BASE + MCE_ARI_APERTURE_0_OFFSET, 80 .ops = &ari_mce_ops, 81 }, 82 { 83 /* A57 Core 1 */ 84 .ari_base = TEGRA_MMCRAB_BASE + MCE_ARI_APERTURE_1_OFFSET, 85 .ops = &ari_mce_ops, 86 }, 87 { 88 /* A57 Core 2 */ 89 .ari_base = TEGRA_MMCRAB_BASE + MCE_ARI_APERTURE_2_OFFSET, 90 .ops = &ari_mce_ops, 91 }, 92 { 93 /* A57 Core 3 */ 94 .ari_base = TEGRA_MMCRAB_BASE + MCE_ARI_APERTURE_3_OFFSET, 95 .ops = &ari_mce_ops, 96 }, 97 { 98 /* D15 Core 0 */ 99 .ari_base = TEGRA_MMCRAB_BASE + MCE_ARI_APERTURE_4_OFFSET, 100 .ops = &nvg_mce_ops, 101 }, 102 { 103 /* D15 Core 1 */ 104 .ari_base = TEGRA_MMCRAB_BASE + MCE_ARI_APERTURE_5_OFFSET, 105 .ops = &nvg_mce_ops, 106 } 107 }; 108 109 static uint32_t mce_get_curr_cpu_ari_base(void) 110 { 111 uint32_t mpidr = read_mpidr(); 112 int cpuid = mpidr & MPIDR_CPU_MASK; 113 int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK; 114 115 /* 116 * T186 has 2 CPU clusters, one with Denver CPUs and the other with 117 * ARM CortexA-57 CPUs. Each cluster consists of 4 CPUs and the CPU 118 * numbers start from 0. In order to get the proper arch_mce_ops_t 119 * struct, we have to convert the Denver CPU ids to the corresponding 120 * indices in the mce_ops_table array. 121 */ 122 if (impl == DENVER_IMPL) 123 cpuid |= 0x4; 124 125 return mce_cfg_table[cpuid].ari_base; 126 } 127 128 static arch_mce_ops_t *mce_get_curr_cpu_ops(void) 129 { 130 uint32_t mpidr = read_mpidr(); 131 int cpuid = mpidr & MPIDR_CPU_MASK; 132 int impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK; 133 134 /* 135 * T186 has 2 CPU clusters, one with Denver CPUs and the other with 136 * ARM CortexA-57 CPUs. Each cluster consists of 4 CPUs and the CPU 137 * numbers start from 0. In order to get the proper arch_mce_ops_t 138 * struct, we have to convert the Denver CPU ids to the corresponding 139 * indices in the mce_ops_table array. 140 */ 141 if (impl == DENVER_IMPL) 142 cpuid |= 0x4; 143 144 return mce_cfg_table[cpuid].ops; 145 } 146 147 /******************************************************************************* 148 * Common handler for all MCE commands 149 ******************************************************************************/ 150 int mce_command_handler(mce_cmd_t cmd, uint64_t arg0, uint64_t arg1, 151 uint64_t arg2) 152 { 153 arch_mce_ops_t *ops; 154 uint32_t cpu_ari_base; 155 uint64_t ret64 = 0, arg3, arg4, arg5; 156 int ret = 0; 157 mca_cmd_t mca_cmd; 158 uncore_perfmon_req_t req; 159 cpu_context_t *ctx = cm_get_context(NON_SECURE); 160 gp_regs_t *gp_regs = get_gpregs_ctx(ctx); 161 162 assert(ctx); 163 assert(gp_regs); 164 165 /* get a pointer to the CPU's arch_mce_ops_t struct */ 166 ops = mce_get_curr_cpu_ops(); 167 168 /* get the CPU's ARI base address */ 169 cpu_ari_base = mce_get_curr_cpu_ari_base(); 170 171 switch (cmd) { 172 case MCE_CMD_ENTER_CSTATE: 173 ret = ops->enter_cstate(cpu_ari_base, arg0, arg1); 174 if (ret < 0) 175 ERROR("%s: enter_cstate failed(%d)\n", __func__, ret); 176 177 break; 178 179 case MCE_CMD_UPDATE_CSTATE_INFO: 180 /* 181 * get the parameters required for the update cstate info 182 * command 183 */ 184 arg3 = read_ctx_reg(gp_regs, CTX_GPREG_X4); 185 arg4 = read_ctx_reg(gp_regs, CTX_GPREG_X5); 186 arg5 = read_ctx_reg(gp_regs, CTX_GPREG_X6); 187 188 ret = ops->update_cstate_info(cpu_ari_base, (uint32_t)arg0, 189 (uint32_t)arg1, (uint32_t)arg2, (uint8_t)arg3, 190 (uint32_t)arg4, (uint8_t)arg5); 191 if (ret < 0) 192 ERROR("%s: update_cstate_info failed(%d)\n", 193 __func__, ret); 194 195 write_ctx_reg(gp_regs, CTX_GPREG_X4, 0); 196 write_ctx_reg(gp_regs, CTX_GPREG_X5, 0); 197 write_ctx_reg(gp_regs, CTX_GPREG_X6, 0); 198 199 break; 200 201 case MCE_CMD_UPDATE_CROSSOVER_TIME: 202 ret = ops->update_crossover_time(cpu_ari_base, arg0, arg1); 203 if (ret < 0) 204 ERROR("%s: update_crossover_time failed(%d)\n", 205 __func__, ret); 206 207 break; 208 209 case MCE_CMD_READ_CSTATE_STATS: 210 ret64 = ops->read_cstate_stats(cpu_ari_base, arg0); 211 212 /* update context to return cstate stats value */ 213 write_ctx_reg(gp_regs, CTX_GPREG_X1, ret64); 214 write_ctx_reg(gp_regs, CTX_GPREG_X2, ret64); 215 216 break; 217 218 case MCE_CMD_WRITE_CSTATE_STATS: 219 ret = ops->write_cstate_stats(cpu_ari_base, arg0, arg1); 220 if (ret < 0) 221 ERROR("%s: write_cstate_stats failed(%d)\n", 222 __func__, ret); 223 224 break; 225 226 case MCE_CMD_IS_CCX_ALLOWED: 227 ret = ops->is_ccx_allowed(cpu_ari_base, arg0, arg1); 228 if (ret < 0) { 229 ERROR("%s: is_ccx_allowed failed(%d)\n", __func__, ret); 230 break; 231 } 232 233 /* update context to return CCx status value */ 234 write_ctx_reg(gp_regs, CTX_GPREG_X1, ret); 235 236 break; 237 238 case MCE_CMD_IS_SC7_ALLOWED: 239 ret = ops->is_sc7_allowed(cpu_ari_base, arg0, arg1); 240 if (ret < 0) { 241 ERROR("%s: is_sc7_allowed failed(%d)\n", __func__, ret); 242 break; 243 } 244 245 /* update context to return SC7 status value */ 246 write_ctx_reg(gp_regs, CTX_GPREG_X1, ret); 247 write_ctx_reg(gp_regs, CTX_GPREG_X3, ret); 248 249 break; 250 251 case MCE_CMD_ONLINE_CORE: 252 ret = ops->online_core(cpu_ari_base, arg0); 253 if (ret < 0) 254 ERROR("%s: online_core failed(%d)\n", __func__, ret); 255 256 break; 257 258 case MCE_CMD_CC3_CTRL: 259 ret = ops->cc3_ctrl(cpu_ari_base, arg0, arg1, arg2); 260 if (ret < 0) 261 ERROR("%s: cc3_ctrl failed(%d)\n", __func__, ret); 262 263 break; 264 265 case MCE_CMD_ECHO_DATA: 266 ret64 = ops->call_enum_misc(cpu_ari_base, TEGRA_ARI_MISC_ECHO, 267 arg0); 268 269 /* update context to return if echo'd data matched source */ 270 write_ctx_reg(gp_regs, CTX_GPREG_X1, ret64 == arg0); 271 write_ctx_reg(gp_regs, CTX_GPREG_X2, ret64 == arg0); 272 273 break; 274 275 case MCE_CMD_READ_VERSIONS: 276 ret64 = ops->call_enum_misc(cpu_ari_base, TEGRA_ARI_MISC_VERSION, 277 arg0); 278 279 /* 280 * version = minor(63:32) | major(31:0). Update context 281 * to return major and minor version number. 282 */ 283 write_ctx_reg(gp_regs, CTX_GPREG_X1, (uint32_t)ret64); 284 write_ctx_reg(gp_regs, CTX_GPREG_X2, (uint32_t)(ret64 >> 32)); 285 286 break; 287 288 case MCE_CMD_ENUM_FEATURES: 289 ret64 = ops->call_enum_misc(cpu_ari_base, 290 TEGRA_ARI_MISC_FEATURE_LEAF_0, arg0); 291 292 /* update context to return features value */ 293 write_ctx_reg(gp_regs, CTX_GPREG_X1, ret64); 294 295 break; 296 297 case MCE_CMD_ROC_FLUSH_CACHE_TRBITS: 298 ret = ops->roc_flush_cache_trbits(cpu_ari_base); 299 if (ret < 0) 300 ERROR("%s: flush cache_trbits failed(%d)\n", __func__, 301 ret); 302 303 break; 304 305 case MCE_CMD_ROC_FLUSH_CACHE: 306 ret = ops->roc_flush_cache(cpu_ari_base); 307 if (ret < 0) 308 ERROR("%s: flush cache failed(%d)\n", __func__, ret); 309 310 break; 311 312 case MCE_CMD_ROC_CLEAN_CACHE: 313 ret = ops->roc_clean_cache(cpu_ari_base); 314 if (ret < 0) 315 ERROR("%s: clean cache failed(%d)\n", __func__, ret); 316 317 break; 318 319 case MCE_CMD_ENUM_READ_MCA: 320 memcpy(&mca_cmd, &arg0, sizeof(arg0)); 321 ret64 = ops->read_write_mca(cpu_ari_base, mca_cmd, &arg1); 322 323 /* update context to return MCA data/error */ 324 write_ctx_reg(gp_regs, CTX_GPREG_X1, ret64); 325 write_ctx_reg(gp_regs, CTX_GPREG_X2, arg1); 326 write_ctx_reg(gp_regs, CTX_GPREG_X3, ret64); 327 328 break; 329 330 case MCE_CMD_ENUM_WRITE_MCA: 331 memcpy(&mca_cmd, &arg0, sizeof(arg0)); 332 ret64 = ops->read_write_mca(cpu_ari_base, mca_cmd, &arg1); 333 334 /* update context to return MCA error */ 335 write_ctx_reg(gp_regs, CTX_GPREG_X1, ret64); 336 write_ctx_reg(gp_regs, CTX_GPREG_X3, ret64); 337 338 break; 339 340 #if ENABLE_CHIP_VERIFICATION_HARNESS 341 case MCE_CMD_ENABLE_LATIC: 342 /* 343 * This call is not for production use. The constant value, 344 * 0xFFFF0000, is specific to allowing for enabling LATIC on 345 * pre-production parts for the chip verification harness. 346 * 347 * Enabling LATIC allows S/W to read the MINI ISPs in the 348 * CCPLEX. The ISMs are used for various measurements relevant 349 * to particular locations in the Silicon. They are small 350 * counters which can be polled to determine how fast a 351 * particular location in the Silicon is. 352 */ 353 ops->enter_ccplex_state(mce_get_curr_cpu_ari_base(), 354 0xFFFF0000); 355 356 break; 357 #endif 358 359 case MCE_CMD_UNCORE_PERFMON_REQ: 360 memcpy(&req, &arg0, sizeof(arg0)); 361 ret = ops->read_write_uncore_perfmon(cpu_ari_base, req, &arg1); 362 363 /* update context to return data */ 364 write_ctx_reg(gp_regs, CTX_GPREG_X1, arg1); 365 break; 366 367 case MCE_CMD_MISC_CCPLEX: 368 ops->misc_ccplex(cpu_ari_base, arg0, arg1); 369 370 break; 371 372 default: 373 ERROR("unknown MCE command (%d)\n", cmd); 374 return EINVAL; 375 } 376 377 return ret; 378 } 379 380 /******************************************************************************* 381 * Handler to update the reset vector for CPUs 382 ******************************************************************************/ 383 int mce_update_reset_vector(void) 384 { 385 arch_mce_ops_t *ops = mce_get_curr_cpu_ops(); 386 387 ops->update_reset_vector(mce_get_curr_cpu_ari_base()); 388 389 return 0; 390 } 391 392 static int mce_update_ccplex_gsc(tegra_ari_gsc_index_t gsc_idx) 393 { 394 arch_mce_ops_t *ops = mce_get_curr_cpu_ops(); 395 396 ops->update_ccplex_gsc(mce_get_curr_cpu_ari_base(), gsc_idx); 397 398 return 0; 399 } 400 401 /******************************************************************************* 402 * Handler to update carveout values for Video Memory Carveout region 403 ******************************************************************************/ 404 int mce_update_gsc_videomem(void) 405 { 406 return mce_update_ccplex_gsc(TEGRA_ARI_GSC_VPR_IDX); 407 } 408 409 /******************************************************************************* 410 * Handler to update carveout values for TZDRAM aperture 411 ******************************************************************************/ 412 int mce_update_gsc_tzdram(void) 413 { 414 return mce_update_ccplex_gsc(TEGRA_ARI_GSC_TZ_DRAM_IDX); 415 } 416 417 /******************************************************************************* 418 * Handler to update carveout values for TZ SysRAM aperture 419 ******************************************************************************/ 420 int mce_update_gsc_tzram(void) 421 { 422 return mce_update_ccplex_gsc(TEGRA_ARI_GSC_TZRAM); 423 } 424 425 /******************************************************************************* 426 * Handler to shutdown/reset the entire system 427 ******************************************************************************/ 428 __dead2 void mce_enter_ccplex_state(uint32_t state_idx) 429 { 430 arch_mce_ops_t *ops = mce_get_curr_cpu_ops(); 431 432 /* sanity check state value */ 433 if (state_idx != TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_POWER_OFF && 434 state_idx != TEGRA_ARI_MISC_CCPLEX_SHUTDOWN_REBOOT) 435 panic(); 436 437 ops->enter_ccplex_state(mce_get_curr_cpu_ari_base(), state_idx); 438 439 /* wait till the CCPLEX powers down */ 440 for (;;) 441 ; 442 443 panic(); 444 } 445 446 /******************************************************************************* 447 * Handler to issue the UPDATE_CSTATE_INFO request 448 ******************************************************************************/ 449 void mce_update_cstate_info(mce_cstate_info_t *cstate) 450 { 451 arch_mce_ops_t *ops = mce_get_curr_cpu_ops(); 452 453 /* issue the UPDATE_CSTATE_INFO request */ 454 ops->update_cstate_info(mce_get_curr_cpu_ari_base(), cstate->cluster, 455 cstate->ccplex, cstate->system, cstate->system_state_force, 456 cstate->wake_mask, cstate->update_wake_mask); 457 } 458 459 /******************************************************************************* 460 * Handler to read the MCE firmware version and check if it is compatible 461 * with interface header the BL3-1 was compiled against 462 ******************************************************************************/ 463 void mce_verify_firmware_version(void) 464 { 465 arch_mce_ops_t *ops; 466 uint32_t cpu_ari_base; 467 uint64_t version; 468 uint32_t major, minor; 469 470 /* 471 * MCE firmware is not supported on simulation platforms. 472 */ 473 if (tegra_platform_is_emulation()) 474 return; 475 476 /* get a pointer to the CPU's arch_mce_ops_t struct */ 477 ops = mce_get_curr_cpu_ops(); 478 479 /* get the CPU's ARI base address */ 480 cpu_ari_base = mce_get_curr_cpu_ari_base(); 481 482 /* 483 * Read the MCE firmware version and extract the major and minor 484 * version fields 485 */ 486 version = ops->call_enum_misc(cpu_ari_base, TEGRA_ARI_MISC_VERSION, 0); 487 major = (uint32_t)version; 488 minor = (uint32_t)(version >> 32); 489 490 INFO("MCE Version - HW=%d:%d, SW=%d:%d\n", major, minor, 491 TEGRA_ARI_VERSION_MAJOR, TEGRA_ARI_VERSION_MINOR); 492 493 /* 494 * Verify that the MCE firmware version and the interface header 495 * match 496 */ 497 if (major != TEGRA_ARI_VERSION_MAJOR) { 498 ERROR("ARI major version mismatch\n"); 499 panic(); 500 } 501 502 if (minor < TEGRA_ARI_VERSION_MINOR) { 503 ERROR("ARI minor version mismatch\n"); 504 panic(); 505 } 506 } 507