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 <string.h> 19 #include <errno.h> 20 #include <tegra_def.h> 21 #include <tegra_platform.h> 22 23 /******************************************************************************* 24 * Common handler for all MCE commands 25 ******************************************************************************/ 26 int mce_command_handler(mce_cmd_t cmd, uint64_t arg0, uint64_t arg1, 27 uint64_t arg2) 28 { 29 uint64_t ret64 = 0, arg3, arg4, arg5; 30 int ret = 0; 31 mca_cmd_t mca_cmd; 32 uncore_perfmon_req_t req; 33 cpu_context_t *ctx = cm_get_context(NON_SECURE); 34 gp_regs_t *gp_regs = get_gpregs_ctx(ctx); 35 36 assert(ctx); 37 assert(gp_regs); 38 39 switch (cmd) { 40 case MCE_CMD_ENTER_CSTATE: 41 /* NVG */ 42 break; 43 44 case MCE_CMD_UPDATE_CSTATE_INFO: 45 /* 46 * get the parameters required for the update cstate info 47 * command 48 */ 49 arg3 = read_ctx_reg(gp_regs, CTX_GPREG_X4); 50 arg4 = read_ctx_reg(gp_regs, CTX_GPREG_X5); 51 arg5 = read_ctx_reg(gp_regs, CTX_GPREG_X6); 52 53 /* NVG */ 54 55 write_ctx_reg(gp_regs, CTX_GPREG_X4, arg3); 56 write_ctx_reg(gp_regs, CTX_GPREG_X5, arg4); 57 write_ctx_reg(gp_regs, CTX_GPREG_X6, arg5); 58 59 break; 60 61 case MCE_CMD_UPDATE_CROSSOVER_TIME: 62 /* NVG */ 63 64 break; 65 66 case MCE_CMD_READ_CSTATE_STATS: 67 /* NVG */ 68 69 /* update context to return cstate stats value */ 70 write_ctx_reg(gp_regs, CTX_GPREG_X1, ret64); 71 write_ctx_reg(gp_regs, CTX_GPREG_X2, ret64); 72 73 break; 74 75 case MCE_CMD_WRITE_CSTATE_STATS: 76 /* NVG */ 77 78 break; 79 80 case MCE_CMD_IS_CCX_ALLOWED: 81 /* NVG */ 82 83 /* update context to return CCx status value */ 84 write_ctx_reg(gp_regs, CTX_GPREG_X1, ret); 85 86 break; 87 88 case MCE_CMD_IS_SC7_ALLOWED: 89 /* NVG */ 90 91 /* update context to return SC7 status value */ 92 write_ctx_reg(gp_regs, CTX_GPREG_X1, ret); 93 write_ctx_reg(gp_regs, CTX_GPREG_X3, ret); 94 95 break; 96 97 case MCE_CMD_ONLINE_CORE: 98 /* NVG */ 99 100 break; 101 102 case MCE_CMD_CC3_CTRL: 103 /* NVG */ 104 105 break; 106 107 case MCE_CMD_ECHO_DATA: 108 /* issue NVG to echo data */ 109 110 /* update context to return if echo'd data matched source */ 111 write_ctx_reg(gp_regs, CTX_GPREG_X1, ret64 == arg0); 112 write_ctx_reg(gp_regs, CTX_GPREG_X2, ret64 == arg0); 113 114 break; 115 116 case MCE_CMD_READ_VERSIONS: 117 /* get the MCE firmware version */ 118 119 /* 120 * version = minor(63:32) | major(31:0). Update context 121 * to return major and minor version number. 122 */ 123 write_ctx_reg(gp_regs, CTX_GPREG_X1, (uint32_t)ret64); 124 write_ctx_reg(gp_regs, CTX_GPREG_X2, (uint32_t)(ret64 >> 32)); 125 126 break; 127 128 case MCE_CMD_ENUM_FEATURES: 129 break; 130 131 case MCE_CMD_ROC_FLUSH_CACHE_TRBITS: 132 /* NVG */ 133 134 break; 135 136 case MCE_CMD_ROC_FLUSH_CACHE: 137 /* NVG */ 138 139 break; 140 141 case MCE_CMD_ROC_CLEAN_CACHE: 142 /* NVG */ 143 144 break; 145 146 case MCE_CMD_ENUM_READ_MCA: 147 memcpy(&mca_cmd, &arg0, sizeof(arg0)); 148 149 /* NVG */ 150 151 /* update context to return MCA data/error */ 152 write_ctx_reg(gp_regs, CTX_GPREG_X1, ret64); 153 write_ctx_reg(gp_regs, CTX_GPREG_X2, arg1); 154 write_ctx_reg(gp_regs, CTX_GPREG_X3, ret64); 155 156 break; 157 158 case MCE_CMD_ENUM_WRITE_MCA: 159 memcpy(&mca_cmd, &arg0, sizeof(arg0)); 160 161 /* NVG */ 162 163 /* update context to return MCA error */ 164 write_ctx_reg(gp_regs, CTX_GPREG_X1, ret64); 165 write_ctx_reg(gp_regs, CTX_GPREG_X3, ret64); 166 167 break; 168 169 case MCE_CMD_ENABLE_LATIC: 170 /* 171 * This call is not for production use. The constant value, 172 * 0xFFFF0000, is specific to allowing for enabling LATIC on 173 * pre-production parts for the chip verification harness. 174 * 175 * Enabling LATIC allows S/W to read the MINI ISPs in the 176 * CCPLEX. The ISMs are used for various measurements relevant 177 * to particular locations in the Silicon. They are small 178 * counters which can be polled to determine how fast a 179 * particular location in the Silicon is. 180 */ 181 /* NVG */ 182 183 break; 184 185 case MCE_CMD_UNCORE_PERFMON_REQ: 186 memcpy(&req, &arg0, sizeof(arg0)); 187 /* NVG */ 188 189 /* update context to return data */ 190 write_ctx_reg(gp_regs, CTX_GPREG_X1, arg1); 191 break; 192 193 case MCE_CMD_MISC_CCPLEX: 194 /* NVG */ 195 196 break; 197 198 default: 199 ERROR("unknown MCE command (%lld)\n", cmd); 200 return EINVAL; 201 } 202 203 return ret; 204 } 205 206 /******************************************************************************* 207 * Handler to update the reset vector for CPUs 208 ******************************************************************************/ 209 int mce_update_reset_vector(void) 210 { 211 return 0; 212 } 213 214 static int mce_update_ccplex_gsc(/* GSC ID */) 215 { 216 return 0; 217 } 218 219 /******************************************************************************* 220 * Handler to update carveout values for Video Memory Carveout region 221 ******************************************************************************/ 222 int mce_update_gsc_videomem(void) 223 { 224 return mce_update_ccplex_gsc(); 225 } 226 227 /******************************************************************************* 228 * Handler to update carveout values for TZDRAM aperture 229 ******************************************************************************/ 230 int mce_update_gsc_tzdram(void) 231 { 232 return mce_update_ccplex_gsc(); 233 } 234 235 /******************************************************************************* 236 * Handler to update carveout values for TZ SysRAM aperture 237 ******************************************************************************/ 238 int mce_update_gsc_tzram(void) 239 { 240 return mce_update_ccplex_gsc(); 241 } 242 243 /******************************************************************************* 244 * Handler to shutdown/reset the entire system 245 ******************************************************************************/ 246 __dead2 void mce_enter_ccplex_state(uint32_t state_idx) 247 { 248 /* sanity check state value */ 249 250 /* enter ccplex power state */ 251 252 /* wait till the CCPLEX powers down */ 253 for (;;) 254 ; 255 256 panic(); 257 } 258 259 /******************************************************************************* 260 * Handler to issue the UPDATE_CSTATE_INFO request 261 ******************************************************************************/ 262 void mce_update_cstate_info(mce_cstate_info_t *cstate) 263 { 264 /* issue the UPDATE_CSTATE_INFO request */ 265 /* NVG */ 266 } 267 268 /******************************************************************************* 269 * Handler to read the MCE firmware version and check if it is compatible 270 * with interface header the BL3-1 was compiled against 271 ******************************************************************************/ 272 void mce_verify_firmware_version(void) 273 { 274 uint64_t version; 275 uint32_t major, minor; 276 277 /* 278 * MCE firmware is not running on simulation platforms. 279 */ 280 if (tegra_platform_is_linsim() || tegra_platform_is_virt_dev_kit()) 281 return; 282 283 /* get a pointer to the CPU's arch_mce_ops_t struct */ 284 285 /* 286 * Read the MCE firmware version and extract the major and minor 287 * version fields 288 */ 289 version = 0; 290 major = (uint32_t)version; 291 minor = (uint32_t)(version >> 32); 292 293 INFO("MCE Version - HW=%d:%d, SW=%d:%d\n", major, minor, 294 0, 0); 295 296 /* 297 * Verify that the MCE firmware version and the interface header 298 * match 299 */ 300 if (major != 0) { 301 ERROR("MCE major version mismatch\n"); 302 panic(); 303 } 304 305 if (minor < 0) { 306 ERROR("MCE minor version mismatch\n"); 307 panic(); 308 } 309 } 310