cmd_cpu.c revision 4759:3a228be89946
1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21/* 22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26#pragma ident "%Z%%M% %I% %E% SMI" 27 28/* 29 * Support routines for managing per-CPU state. 30 */ 31 32#include <cmd_cpu.h> 33 34#ifdef sun4u 35#include <cmd_ecache.h> 36#endif /* sun4u */ 37 38#include <cmd_mem.h> 39#include <cmd.h> 40 41#include <stdio.h> 42#include <string.h> 43#include <strings.h> 44#include <errno.h> 45#include <kstat.h> 46#include <fm/fmd_api.h> 47#include <sys/async.h> 48#include <sys/fm/protocol.h> 49 50#ifdef sun4u 51#include <sys/cheetahregs.h> 52#include <sys/fm/cpu/UltraSPARC-III.h> 53#include <cmd_opl.h> 54#else /* sun4u */ 55#include <sys/niagararegs.h> 56#include <sys/fm/cpu/UltraSPARC-T1.h> 57#include <cmd_hc_sun4v.h> 58#endif /* sun4u */ 59 60#define CMD_CPU_UEC_INCR 10 61 62/* Must be in sync with cmd_cpu_type_t */ 63static const char *const cpu_names[] = { 64 NULL, 65 "ultraSPARC-III", 66 "ultraSPARC-IIIplus", 67 "ultraSPARC-IIIi", 68 "ultraSPARC-IV", 69 "ultraSPARC-IVplus", 70 "ultraSPARC-IIIiplus", 71 "ultraSPARC-T1", 72 "SPARC64-VI", 73 "ultraSPARC-T2", 74 "ultraSPARC-T2plus" 75}; 76 77/* 78 * This needs to be in sync with cpu_family_t. 79 */ 80static const faminfo_t fam_info_tbl[] = { 81 { CMD_CPU_FAM_UNSUPPORTED, B_FALSE }, 82 { CMD_CPU_FAM_CHEETAH, B_TRUE }, 83 { CMD_CPU_FAM_NIAGARA, B_FALSE }, 84 { CMD_CPU_FAM_SPARC64, B_FALSE } 85}; 86 87static cmd_cpu_t *cpu_lookup_by_cpuid(uint32_t, uint8_t); 88static cmd_cpu_t *cpu_create(fmd_hdl_t *, nvlist_t *, uint32_t, 89 uint8_t, cmd_cpu_type_t); 90static void cpu_buf_write(fmd_hdl_t *, cmd_cpu_t *); 91 92static const char * 93cpu_type2name(fmd_hdl_t *hdl, cmd_cpu_type_t type) 94{ 95 if (type < 1 || type > sizeof (cpu_names) / sizeof (char *)) 96 fmd_hdl_abort(hdl, "illegal CPU type %d\n", type); 97 98 return (cpu_names[type]); 99} 100 101static cmd_cpu_type_t 102cpu_nname2type(fmd_hdl_t *hdl, const char *name, size_t n) 103{ 104 int i; 105 106 for (i = 1; i < sizeof (cpu_names) / sizeof (char *); i++) { 107 if (strlen(cpu_names[i]) == n && 108 strncmp(cpu_names[i], name, n) == 0) 109 return (i); 110 } 111 112 fmd_hdl_abort(hdl, "illegal CPU name %*.*s\n", n, n, name); 113 /*NOTREACHED*/ 114 return (0); 115} 116 117const char *fmd_fmri_get_platform(); 118#define is_starcat (strcmp(fmd_fmri_get_platform(), \ 119"SUNW,Sun-Fire-15000") == 0) 120#define is_serengeti (strcmp(fmd_fmri_get_platform(), \ 121"SUNW,Sun-Fire") == 0) 122 123static void 124core2cpus(uint32_t core, cmd_cpu_type_t type, uint8_t level, 125 uint32_t *cpuinit, uint32_t *cpufinal, uint32_t *cpustep) 126{ 127 switch (type) { 128#ifdef sun4u 129 130#define US4P_SCAT_CPUS_PER_CORE 2 131#define US4P_SCAT_CPU_CORE_STEP 4 132#define US4P_SGTI_CPUS_PER_CORE 2 133#define US4P_SGTI_CPU_CORE_STEP 512 134#define US4P_DAKC_CPUS_PER_CORE 2 135#define US4P_DAKC_CPU_CORE_STEP 16 136 137 case CPU_ULTRASPARC_IVplus: 138 switch (level) { 139 case CMD_CPU_LEVEL_CORE: 140 if (is_starcat) 141 *cpustep = US4P_SCAT_CPU_CORE_STEP; 142 else if (is_serengeti) 143 *cpustep = US4P_SGTI_CPU_CORE_STEP; 144 else 145 *cpustep = US4P_DAKC_CPU_CORE_STEP; 146 *cpuinit = core; 147 *cpufinal = *cpuinit + *cpustep; 148 return; 149 default: 150 *cpuinit = *cpufinal = core; 151 *cpustep = 1; 152 return; 153 } 154#else /* i.e. sun4v */ 155 156#define UST1_CPUS_PER_CORE 4 157#define UST1_CPU_CORE_STEP 1 158#define UST1_CPUS_PER_CHIP 32 159#define UST1_CPU_CHIP_STEP 1 160#define UST2_CPUS_PER_CORE 8 161#define UST2_CPU_CORE_STEP 1 162#define UST2_CPUS_PER_CHIP 64 163#define UST2_CPU_CHIP_STEP 1 164 165 case CPU_ULTRASPARC_T1: 166 switch (level) { 167 case CMD_CPU_LEVEL_CORE: 168 *cpuinit = core * UST1_CPUS_PER_CORE; 169 *cpufinal = *cpuinit + UST1_CPUS_PER_CORE - 1; 170 *cpustep = UST1_CPU_CORE_STEP; 171 return; 172 case CMD_CPU_LEVEL_CHIP: 173 *cpuinit = core * UST1_CPUS_PER_CHIP; 174 *cpufinal = *cpuinit + UST1_CPUS_PER_CHIP - 1; 175 *cpustep = UST1_CPU_CHIP_STEP; 176 return; 177 default: 178 *cpuinit = *cpufinal = core; 179 *cpustep = 1; 180 return; 181 } 182 case CPU_ULTRASPARC_T2: 183 case CPU_ULTRASPARC_T2plus: 184 switch (level) { 185 case CMD_CPU_LEVEL_CORE: 186 *cpuinit = core * UST2_CPUS_PER_CORE; 187 *cpufinal = *cpuinit + UST2_CPUS_PER_CORE - 1; 188 *cpustep = UST2_CPU_CORE_STEP; 189 return; 190 case CMD_CPU_LEVEL_CHIP: 191 *cpuinit = core * UST2_CPUS_PER_CHIP; 192 *cpufinal = *cpuinit + UST2_CPUS_PER_CHIP - 1; 193 *cpustep = UST2_CPU_CHIP_STEP; 194 return; 195 default: 196 *cpuinit = *cpufinal = core; 197 *cpustep = 1; 198 return; 199 } 200 201#endif /* sun4u */ 202 default: 203 *cpuinit = *cpufinal = core; 204 *cpustep = 1; 205 return; 206 } 207} 208 209uint32_t 210cmd_cpu2core(uint32_t cpuid, cmd_cpu_type_t type, uint8_t level) { 211 212 switch (type) { 213#ifdef sun4u 214 215#define US4P_SCAT_CORE_SYSBD_STEP 32 216 217 case CPU_ULTRASPARC_IVplus: 218 switch (level) { 219 case CMD_CPU_LEVEL_CORE: 220 if (is_starcat) 221 return ((cpuid / 222 US4P_SCAT_CORE_SYSBD_STEP) * 223 US4P_SCAT_CORE_SYSBD_STEP + 224 (cpuid % US4P_SCAT_CPU_CORE_STEP)); 225 else if (is_serengeti) 226 return (cpuid % US4P_SGTI_CPU_CORE_STEP); 227 else 228 return (cpuid % US4P_DAKC_CPU_CORE_STEP); 229 default: 230 return (cpuid); 231 } 232#else /* i.e. sun4v */ 233 case CPU_ULTRASPARC_T1: 234 switch (level) { 235 case CMD_CPU_LEVEL_CORE: 236 return (cpuid/UST1_CPUS_PER_CORE); 237 case CMD_CPU_LEVEL_CHIP: 238 return (cpuid/UST1_CPUS_PER_CHIP); 239 default: 240 return (cpuid); 241 } 242 case CPU_ULTRASPARC_T2: 243 case CPU_ULTRASPARC_T2plus: 244 switch (level) { 245 case CMD_CPU_LEVEL_CORE: 246 return (cpuid/UST2_CPUS_PER_CORE); 247 case CMD_CPU_LEVEL_CHIP: 248 return (cpuid/UST2_CPUS_PER_CHIP); 249 default: 250 return (cpuid); 251 } 252 253#endif /* sun4u */ 254 default: 255 return (cpuid); 256 } 257} 258 259#ifdef sun4u 260static void 261cpu_uec_write(fmd_hdl_t *hdl, cmd_cpu_t *cpu, cmd_cpu_uec_t *uec) 262{ 263 /* 264 * The UE cache may change size. fmd expects statically-sized buffers, 265 * so we must delete and re-create it if the size has changed from the 266 * last time it was written. 267 */ 268 if (fmd_buf_size(hdl, NULL, uec->uec_bufname) != sizeof (uint64_t) * 269 uec->uec_nent) 270 fmd_buf_destroy(hdl, NULL, uec->uec_bufname); 271 272 if (uec->uec_cache != NULL) { 273 fmd_buf_write(hdl, NULL, uec->uec_bufname, uec->uec_cache, 274 sizeof (uint64_t) * uec->uec_nent); 275 } 276 277 cpu_buf_write(hdl, cpu); 278} 279 280static void 281cpu_uec_create(fmd_hdl_t *hdl, cmd_cpu_t *cpu, cmd_cpu_uec_t *uec, 282 const char *fmt, ...) 283{ 284 va_list ap; 285 286 va_start(ap, fmt); 287 cmd_vbufname(uec->uec_bufname, sizeof (uec->uec_bufname), fmt, ap); 288 va_end(ap); 289 290 cpu_uec_write(hdl, cpu, uec); 291} 292 293static void 294cpu_uec_restore(fmd_hdl_t *hdl, cmd_cpu_uec_t *uec) 295{ 296 if (uec->uec_cache != NULL) { 297 uec->uec_cache = cmd_buf_read(hdl, NULL, uec->uec_bufname, 298 sizeof (uint64_t) * uec->uec_nent); 299 } 300} 301 302static void 303cpu_uec_free(fmd_hdl_t *hdl, cmd_cpu_uec_t *uec, int destroy) 304{ 305 if (uec->uec_cache == NULL) 306 return; 307 308 if (destroy) 309 fmd_buf_destroy(hdl, NULL, uec->uec_bufname); 310 311 fmd_hdl_free(hdl, uec->uec_cache, sizeof (uint64_t) * uec->uec_nent); 312} 313 314static void 315cpu_uec_flush_finish(fmd_hdl_t *hdl, cmd_cpu_t *cpu) 316{ 317 fmd_hdl_debug(hdl, "completing UE cache flush\n"); 318 if (cpu->cpu_olduec.uec_cache != NULL) { 319 fmd_hdl_free(hdl, cpu->cpu_olduec.uec_cache, sizeof (uint64_t) * 320 cpu->cpu_olduec.uec_nent); 321 322 cpu->cpu_olduec.uec_cache = NULL; 323 cpu->cpu_olduec.uec_nent = 0; 324 cpu->cpu_olduec.uec_flags = 0; 325 cpu_uec_write(hdl, cpu, &cpu->cpu_olduec); 326 } 327 328 cpu->cpu_uec_flush = 0; 329 cpu_buf_write(hdl, cpu); 330} 331 332static void 333cpu_uec_flush(fmd_hdl_t *hdl, cmd_cpu_t *cpu) 334{ 335 if (cpu->cpu_uec.uec_cache == NULL && !cpu->cpu_uec.uec_flags) 336 return; /* nothing to flush */ 337 338 fmd_hdl_debug(hdl, "flushing UE cache for CPU %d\n", cpu->cpu_cpuid); 339 340 if (cmd_ecache_flush(cpu->cpu_cpuid) < 0) { 341 fmd_hdl_debug(hdl, "failed to flush E$ for CPU %d\n", 342 cpu->cpu_cpuid); 343 return; /* don't flush the UE cache unless we can flush E$ */ 344 } 345 346 if (cpu->cpu_olduec.uec_cache != NULL) { 347 /* 348 * If there's already an old UE cache, we're racing with another 349 * flush. For safety, we'll add the current contents of the 350 * cache to the existing old cache. 351 */ 352 size_t nent = cpu->cpu_olduec.uec_nent + cpu->cpu_uec.uec_nent; 353 uint64_t *new = fmd_hdl_alloc(hdl, sizeof (uint64_t) * nent, 354 FMD_SLEEP); 355 356 bcopy(cpu->cpu_olduec.uec_cache, new, sizeof (uint64_t) * 357 cpu->cpu_olduec.uec_nent); 358 bcopy(cpu->cpu_uec.uec_cache, new + cpu->cpu_olduec.uec_nent, 359 sizeof (uint64_t) * cpu->cpu_uec.uec_nent); 360 361 fmd_hdl_free(hdl, cpu->cpu_olduec.uec_cache, 362 sizeof (uint64_t) * cpu->cpu_olduec.uec_nent); 363 fmd_hdl_free(hdl, cpu->cpu_uec.uec_cache, 364 sizeof (uint64_t) * cpu->cpu_uec.uec_nent); 365 366 cpu->cpu_olduec.uec_cache = new; 367 cpu->cpu_olduec.uec_nent = nent; 368 cpu->cpu_olduec.uec_flags |= cpu->cpu_uec.uec_flags; 369 } else { 370 cpu->cpu_olduec.uec_cache = cpu->cpu_uec.uec_cache; 371 cpu->cpu_olduec.uec_nent = cpu->cpu_uec.uec_nent; 372 cpu->cpu_olduec.uec_flags = cpu->cpu_uec.uec_flags; 373 } 374 cpu_uec_write(hdl, cpu, &cpu->cpu_olduec); 375 376 cpu->cpu_uec.uec_cache = NULL; 377 cpu->cpu_uec.uec_nent = 0; 378 cpu->cpu_uec.uec_flags = 0; 379 cpu_uec_write(hdl, cpu, &cpu->cpu_uec); 380 381 if (cpu->cpu_uec_flush != 0) 382 fmd_timer_remove(hdl, cpu->cpu_uec_flush); 383 384 cpu->cpu_uec_flush = fmd_timer_install(hdl, 385 (void *)CMD_TIMERTYPE_CPU_UEC_FLUSH, NULL, NANOSEC); 386 cpu_buf_write(hdl, cpu); 387} 388 389void 390cmd_cpu_uec_add(fmd_hdl_t *hdl, cmd_cpu_t *cpu, uint64_t pa) 391{ 392 cmd_cpu_uec_t *uec = &cpu->cpu_uec; 393 uint64_t *new, *tgt = NULL; 394 int i; 395 396 pa = pa & cmd.cmd_pagemask; 397 398 fmd_hdl_debug(hdl, "adding 0x%llx to CPU %d's UE cache\n", 399 (u_longlong_t)pa, cpu->cpu_cpuid); 400 401 if (uec->uec_cache != NULL) { 402 for (tgt = NULL, i = 0; i < uec->uec_nent; i++) { 403 if (tgt == NULL && uec->uec_cache[i] == 0) 404 tgt = &uec->uec_cache[i]; 405 406 if (uec->uec_cache[i] == pa) 407 return; /* already there */ 408 } 409 } 410 411 if (tgt == NULL) { 412 /* no space - resize the cache */ 413 new = fmd_hdl_zalloc(hdl, sizeof (uint64_t) * 414 (uec->uec_nent + CMD_CPU_UEC_INCR), FMD_SLEEP); 415 416 if (uec->uec_cache != NULL) { 417 bcopy(uec->uec_cache, new, sizeof (uint64_t) * 418 uec->uec_nent); 419 fmd_hdl_free(hdl, uec->uec_cache, sizeof (uint64_t) * 420 uec->uec_nent); 421 } 422 423 uec->uec_cache = new; 424 tgt = &uec->uec_cache[uec->uec_nent]; 425 uec->uec_nent += CMD_CPU_UEC_INCR; 426 } 427 428 *tgt = pa; 429 cpu_uec_write(hdl, cpu, uec); 430} 431 432void 433cmd_cpu_uec_set_allmatch(fmd_hdl_t *hdl, cmd_cpu_t *cpu) 434{ 435 fmd_hdl_debug(hdl, "setting cpu %d's uec to allmatch\n", 436 cpu->cpu_cpuid); 437 438 cpu->cpu_uec.uec_flags |= CPU_UEC_F_ALLMATCH; 439 cpu_uec_write(hdl, cpu, &cpu->cpu_uec); 440 441 if (++cpu->cpu_uec_nflushes <= CPU_UEC_FLUSH_MAX) 442 cpu_uec_flush(hdl, cpu); 443} 444 445int 446cmd_cpu_uec_match(cmd_cpu_t *cpu, uint64_t pa) 447{ 448 int i; 449 450 /* 451 * The UE cache works as long as we are able to add an entry for every 452 * UE seen by a given CPU. If we see a UE with a non-valid AFAR, we 453 * can't guarantee our ability to filter a corresponding xxU, and must, 454 * for safety, assume that every subsequent xxU (until the E$ and UE 455 * cache are flushed) has a matching UE. 456 */ 457 if ((cpu->cpu_uec.uec_flags & CPU_UEC_F_ALLMATCH) || 458 (cpu->cpu_olduec.uec_flags & CPU_UEC_F_ALLMATCH)) 459 return (1); 460 461 pa = pa & cmd.cmd_pagemask; 462 463 for (i = 0; i < cpu->cpu_uec.uec_nent; i++) { 464 if (cpu->cpu_uec.uec_cache[i] == pa) 465 return (1); 466 } 467 468 for (i = 0; i < cpu->cpu_olduec.uec_nent; i++) { 469 if (cpu->cpu_olduec.uec_cache[i] == pa) 470 return (1); 471 } 472 473 return (0); 474} 475#endif /* sun4u */ 476 477void 478cmd_xr_write(fmd_hdl_t *hdl, cmd_xr_t *xr) 479{ 480 fmd_hdl_debug(hdl, "writing redelivery clcode %llx for case %s\n", 481 xr->xr_clcode, fmd_case_uuid(hdl, xr->xr_case)); 482 483 fmd_buf_write(hdl, xr->xr_case, "redelivery", xr, 484 sizeof (cmd_xr_t)); 485} 486 487static cmd_xr_hdlr_f * 488cmd_xr_id2hdlr(fmd_hdl_t *hdl, uint_t id) 489{ 490 switch (id) { 491 case CMD_XR_HDLR_XXC: 492 return (cmd_xxc_resolve); 493 case CMD_XR_HDLR_XXU: 494 return (cmd_xxu_resolve); 495 default: 496 fmd_hdl_abort(hdl, "cmd_xr_id2hdlr called with bad hdlrid %x\n", 497 id); 498 } 499 500 return (NULL); 501} 502 503cmd_xr_t * 504cmd_xr_create(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, 505 cmd_cpu_t *cpu, cmd_errcl_t clcode) 506{ 507 cmd_xr_t *xr = fmd_hdl_zalloc(hdl, sizeof (cmd_xr_t), 508 FMD_SLEEP); 509 nvlist_t *rsrc = NULL; 510 const char *uuid; 511 int err = 0; 512 513 err |= nvlist_lookup_uint64(nvl, FM_EREPORT_ENA, &xr->xr_ena); 514 515 /* 516 * Skip the cmd_xr_fill() for misc reg errors because 517 * these data are not in the misc reg ereport 518 */ 519 if (!CMD_ERRCL_ISMISCREGS(clcode)) 520 err |= cmd_xr_fill(hdl, nvl, xr, clcode); 521 522 (void) nvlist_lookup_nvlist(nvl, FM_EREPORT_PAYLOAD_NAME_RESOURCE, 523 &rsrc); 524 525 if (err != 0) { 526 fmd_hdl_free(hdl, xr, sizeof (cmd_xr_t)); 527 return (NULL); 528 } 529 530 xr->xr_cpu = cpu; 531 xr->xr_cpuid = cpu->cpu_cpuid; 532 xr->xr_clcode = clcode; 533 xr->xr_case = cmd_case_create(hdl, &cpu->cpu_header, 534 CMD_PTR_CPU_XR_RETRY, &uuid); 535 fmd_case_setprincipal(hdl, xr->xr_case, ep); 536 537 if (rsrc != NULL) { 538 cmd_fmri_init(hdl, &xr->xr_rsrc, rsrc, "%s_rsrc", 539 fmd_case_uuid(hdl, xr->xr_case)); 540 } 541 542 cmd_xr_write(hdl, xr); 543 return (xr); 544} 545 546cmd_evdisp_t 547cmd_xr_reschedule(fmd_hdl_t *hdl, cmd_xr_t *xr, uint_t hdlrid) 548{ 549 fmd_hdl_debug(hdl, "scheduling redelivery of %llx with xr %p\n", 550 xr->xr_clcode, xr); 551 552 xr->xr_hdlrid = hdlrid; 553 xr->xr_hdlr = cmd_xr_id2hdlr(hdl, hdlrid); 554 555 if (CMD_ERRCL_ISMISCREGS(xr->xr_clcode)) 556 xr->xr_id = fmd_timer_install(hdl, 557 (void *)CMD_TIMERTYPE_CPU_XR_WAITER, NULL, 558 cmd.cmd_miscregs_trdelay); 559 else 560 xr->xr_id = fmd_timer_install(hdl, 561 (void *)CMD_TIMERTYPE_CPU_XR_WAITER, 562 NULL, cmd.cmd_xxcu_trdelay); 563 564 if (xr->xr_ref++ == 0) 565 cmd_list_append(&cmd.cmd_xxcu_redelivs, xr); 566 567 cmd_xr_write(hdl, xr); 568 return (CMD_EVD_OK); 569} 570 571static void 572cmd_xr_destroy(fmd_hdl_t *hdl, cmd_xr_t *xr) 573{ 574 fmd_hdl_debug(hdl, "destroying xr (clcode %llx) at %p\n", 575 xr->xr_clcode, xr); 576 577 fmd_case_reset(hdl, xr->xr_case); 578 cmd_case_fini(hdl, xr->xr_case, FMD_B_TRUE); 579 580 if (xr->xr_rsrc_nvl != NULL) 581 cmd_fmri_fini(hdl, &xr->xr_rsrc, FMD_B_TRUE); 582 583 fmd_buf_destroy(hdl, xr->xr_case, "redelivery"); 584 fmd_hdl_free(hdl, xr, sizeof (cmd_xr_t)); 585} 586 587void 588cmd_xr_deref(fmd_hdl_t *hdl, cmd_xr_t *xr) 589{ 590 if (xr->xr_ref == 0) 591 fmd_hdl_abort(hdl, "attempt to deref xr with zero ref\n"); 592 593 fmd_hdl_debug(hdl, "deref xr %p [%d]\n", xr, xr->xr_ref); 594 595 if (--xr->xr_ref == 0) { 596 cmd_list_delete(&cmd.cmd_xxcu_redelivs, xr); 597 cmd_xr_destroy(hdl, xr); 598 } 599} 600 601static void 602cmd_xr_restore(fmd_hdl_t *hdl, cmd_cpu_t *cpu, fmd_case_t *cp) 603{ 604 cmd_xr_t *xr; 605 606 if ((xr = cmd_buf_read(hdl, cp, "redelivery", sizeof (cmd_xr_t))) == 607 NULL) { 608 fmd_hdl_abort(hdl, "failed to find redelivery for case %s\n", 609 fmd_case_uuid(hdl, cp)); 610 } 611 612 xr->xr_case = cp; 613 xr->xr_hdlr = cmd_xr_id2hdlr(hdl, xr->xr_hdlrid); 614 if (xr->xr_rsrc_nvl != NULL) 615 cmd_fmri_restore(hdl, &xr->xr_rsrc); 616 xr->xr_cpu = cpu; 617 618 /* 619 * fmd is still in the process of starting up. If we reschedule this 620 * event with the normal redelivery timeout, it'll get redelivered 621 * before initialization has completed, we'll potentially fail to 622 * match the train, deref() the waiter (causing any subsequent side- 623 * effects to miss the waiter), and use this ereport to blame the CPU. 624 * The other side-effects will blame the CPU too, since we'll have 625 * deref()'d the waiter out of existence. We can get up to three 626 * additions to the SERD engine this way, which is bad. To keep that 627 * from happening, we're going to schedule an arbitrarily long timeout, 628 * which *should* be long enough. It's pretty bad, but there's no 629 * real way to keep the other side-effects from taking out the CPU. 630 */ 631 xr->xr_id = fmd_timer_install(hdl, (void *)CMD_TIMERTYPE_CPU_XR_WAITER, 632 NULL, fmd_prop_get_int64(hdl, "xxcu_restart_delay")); 633 634 cmd_list_append(&cmd.cmd_xxcu_redelivs, xr); 635 636 fmd_hdl_debug(hdl, "revived xr for class %llx\n", xr->xr_clcode); 637} 638 639typedef struct cmd_xxcu_train { 640 cmd_errcl_t tr_mask; /* errors we must see to match this train */ 641 cmd_errcl_t tr_cause; /* the error at the root of this train */ 642} cmd_xxcu_train_t; 643 644#define CMD_TRAIN(cause, side_effects) { (cause) | (side_effects), (cause) } 645 646static const cmd_xxcu_train_t cmd_xxcu_trains[] = { 647#ifdef sun4u 648 /* UCC: WDC */ 649 CMD_TRAIN(CMD_ERRCL_UCC, CMD_ERRCL_WDC), 650 651 /* UCU: WDU, WDU+L3_WDU */ 652 CMD_TRAIN(CMD_ERRCL_UCU, CMD_ERRCL_WDU), 653 CMD_TRAIN(CMD_ERRCL_UCU, CMD_ERRCL_L3_WDU | CMD_ERRCL_WDU), 654 655 /* EDC: WDC */ 656 CMD_TRAIN(CMD_ERRCL_EDC, CMD_ERRCL_WDC), 657 658 /* EDU: WDU, WDU+L3_WDU */ 659 CMD_TRAIN(CMD_ERRCL_EDU_ST, CMD_ERRCL_WDU), 660 CMD_TRAIN(CMD_ERRCL_EDU_BL, CMD_ERRCL_WDU), 661 CMD_TRAIN(CMD_ERRCL_EDU_ST, CMD_ERRCL_L3_WDU | CMD_ERRCL_WDU), 662 CMD_TRAIN(CMD_ERRCL_EDU_BL, CMD_ERRCL_L3_WDU | CMD_ERRCL_WDU), 663 664 /* CPC: WDC, EDC+WDC, UCC+WDC, EDC+UCC+WDC */ 665 CMD_TRAIN(CMD_ERRCL_CPC, CMD_ERRCL_WDC), 666 CMD_TRAIN(CMD_ERRCL_CPC, CMD_ERRCL_EDC | CMD_ERRCL_WDC), 667 CMD_TRAIN(CMD_ERRCL_CPC, CMD_ERRCL_UCC | CMD_ERRCL_WDC), 668 CMD_TRAIN(CMD_ERRCL_CPC, CMD_ERRCL_EDC | CMD_ERRCL_UCC | 669 CMD_ERRCL_WDC), 670 671 /* CPU: WDU, WDU+L3_WDU, UCU+WDU, UCU+WDU+L3_WDU */ 672 CMD_TRAIN(CMD_ERRCL_CPU, CMD_ERRCL_WDU), 673 CMD_TRAIN(CMD_ERRCL_CPU, CMD_ERRCL_L3_WDU | CMD_ERRCL_WDU), 674 CMD_TRAIN(CMD_ERRCL_CPU, CMD_ERRCL_UCU | CMD_ERRCL_WDU), 675 CMD_TRAIN(CMD_ERRCL_CPU, CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU | 676 CMD_ERRCL_WDU), 677 678 /* CPU: EDU+WDU, EDU+WDU+L3_WDU, EDU+UCU+WDU, EDU+UCU+WDU+L3_WDU */ 679 CMD_TRAIN(CMD_ERRCL_CPU, CMD_ERRCL_EDU_ST | CMD_ERRCL_WDU), 680 CMD_TRAIN(CMD_ERRCL_CPU, CMD_ERRCL_EDU_BL | CMD_ERRCL_WDU), 681 CMD_TRAIN(CMD_ERRCL_CPU, CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL | 682 CMD_ERRCL_WDU), 683 CMD_TRAIN(CMD_ERRCL_CPU, CMD_ERRCL_EDU_ST | CMD_ERRCL_WDU | 684 CMD_ERRCL_L3_WDU), 685 CMD_TRAIN(CMD_ERRCL_CPU, CMD_ERRCL_EDU_BL | CMD_ERRCL_WDU | 686 CMD_ERRCL_L3_WDU), 687 CMD_TRAIN(CMD_ERRCL_CPU, CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL | 688 CMD_ERRCL_WDU | CMD_ERRCL_L3_WDU), 689 CMD_TRAIN(CMD_ERRCL_CPU, CMD_ERRCL_EDU_ST | CMD_ERRCL_UCU | 690 CMD_ERRCL_WDU), 691 CMD_TRAIN(CMD_ERRCL_CPU, CMD_ERRCL_EDU_BL | CMD_ERRCL_UCU | 692 CMD_ERRCL_WDU), 693 CMD_TRAIN(CMD_ERRCL_CPU, CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL | 694 CMD_ERRCL_UCU | CMD_ERRCL_WDU), 695 CMD_TRAIN(CMD_ERRCL_CPU, CMD_ERRCL_EDU_ST | CMD_ERRCL_UCU | 696 CMD_ERRCL_WDU | CMD_ERRCL_L3_WDU), 697 CMD_TRAIN(CMD_ERRCL_CPU, CMD_ERRCL_EDU_BL | CMD_ERRCL_UCU | 698 CMD_ERRCL_WDU | CMD_ERRCL_L3_WDU), 699 CMD_TRAIN(CMD_ERRCL_CPU, CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL | 700 CMD_ERRCL_UCU | CMD_ERRCL_WDU | CMD_ERRCL_L3_WDU), 701 702 /* WDU: L3_WDU */ 703 CMD_TRAIN(CMD_ERRCL_WDU, CMD_ERRCL_L3_WDU), 704 705 /* L3_UCC: WDC+(zero or more of EDC, CPC, UCC) */ 706 CMD_TRAIN(CMD_ERRCL_L3_UCC, CMD_ERRCL_WDC), 707 CMD_TRAIN(CMD_ERRCL_L3_UCC, CMD_ERRCL_WDC | CMD_ERRCL_EDC), 708 CMD_TRAIN(CMD_ERRCL_L3_UCC, CMD_ERRCL_WDC | CMD_ERRCL_CPC), 709 CMD_TRAIN(CMD_ERRCL_L3_UCC, CMD_ERRCL_WDC | CMD_ERRCL_UCC), 710 CMD_TRAIN(CMD_ERRCL_L3_UCC, CMD_ERRCL_WDC | CMD_ERRCL_EDC | 711 CMD_ERRCL_CPC), 712 CMD_TRAIN(CMD_ERRCL_L3_UCC, CMD_ERRCL_WDC | CMD_ERRCL_EDC | 713 CMD_ERRCL_UCC), 714 CMD_TRAIN(CMD_ERRCL_L3_UCC, CMD_ERRCL_WDC | CMD_ERRCL_CPC | 715 CMD_ERRCL_UCC), 716 CMD_TRAIN(CMD_ERRCL_L3_UCC, CMD_ERRCL_WDC | CMD_ERRCL_EDC | 717 CMD_ERRCL_CPC | CMD_ERRCL_UCC), 718 719 /* L3_UCU: WDU+(zero or more of EDU, CPU, UCU) */ 720 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU), 721 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST), 722 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL), 723 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 724 CMD_ERRCL_EDU_BL), 725 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_CPU), 726 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_UCU), 727 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 728 CMD_ERRCL_CPU), 729 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL | 730 CMD_ERRCL_CPU), 731 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 732 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU), 733 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 734 CMD_ERRCL_UCU), 735 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL | 736 CMD_ERRCL_UCU), 737 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 738 CMD_ERRCL_EDU_BL | CMD_ERRCL_UCU), 739 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_CPU | 740 CMD_ERRCL_UCU), 741 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 742 CMD_ERRCL_CPU | CMD_ERRCL_UCU), 743 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL | 744 CMD_ERRCL_CPU | CMD_ERRCL_UCU), 745 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 746 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | CMD_ERRCL_UCU), 747 748 /* L3_UCU: WDU+(zero or more of EDU, CPU, UCU)+L3_WDU */ 749 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_L3_WDU), 750 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 751 CMD_ERRCL_L3_WDU), 752 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL | 753 CMD_ERRCL_L3_WDU), 754 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 755 CMD_ERRCL_EDU_BL | CMD_ERRCL_L3_WDU), 756 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_CPU | 757 CMD_ERRCL_L3_WDU), 758 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_UCU | 759 CMD_ERRCL_L3_WDU), 760 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 761 CMD_ERRCL_CPU | CMD_ERRCL_L3_WDU), 762 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL | 763 CMD_ERRCL_CPU | CMD_ERRCL_L3_WDU), 764 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 765 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | CMD_ERRCL_L3_WDU), 766 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 767 CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU), 768 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL | 769 CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU), 770 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 771 CMD_ERRCL_EDU_BL | CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU), 772 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_CPU | 773 CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU), 774 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 775 CMD_ERRCL_CPU | CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU), 776 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL | 777 CMD_ERRCL_CPU | CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU), 778 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 779 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | CMD_ERRCL_UCU | 780 CMD_ERRCL_L3_WDU), 781 782 /* L3_EDC: WDC+(zero or more of EDC, CPC, UCC) */ 783 CMD_TRAIN(CMD_ERRCL_L3_EDC, CMD_ERRCL_WDC), 784 CMD_TRAIN(CMD_ERRCL_L3_EDC, CMD_ERRCL_WDC | CMD_ERRCL_EDC), 785 CMD_TRAIN(CMD_ERRCL_L3_EDC, CMD_ERRCL_WDC | CMD_ERRCL_CPC), 786 CMD_TRAIN(CMD_ERRCL_L3_EDC, CMD_ERRCL_WDC | CMD_ERRCL_UCC), 787 CMD_TRAIN(CMD_ERRCL_L3_EDC, CMD_ERRCL_WDC | CMD_ERRCL_EDC | 788 CMD_ERRCL_CPC), 789 CMD_TRAIN(CMD_ERRCL_L3_EDC, CMD_ERRCL_WDC | CMD_ERRCL_EDC | 790 CMD_ERRCL_UCC), 791 CMD_TRAIN(CMD_ERRCL_L3_EDC, CMD_ERRCL_WDC | CMD_ERRCL_CPC | 792 CMD_ERRCL_UCC), 793 CMD_TRAIN(CMD_ERRCL_L3_EDC, CMD_ERRCL_WDC | CMD_ERRCL_EDC | 794 CMD_ERRCL_CPC | CMD_ERRCL_UCC), 795 796 /* L3_EDU: WDU+(zero or more of EDU, CPU, UCU) */ 797 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU), 798 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST), 799 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL), 800 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 801 CMD_ERRCL_EDU_BL), 802 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_CPU), 803 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_UCU), 804 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 805 CMD_ERRCL_CPU), 806 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL | 807 CMD_ERRCL_CPU), 808 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 809 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU), 810 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 811 CMD_ERRCL_UCU), 812 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL | 813 CMD_ERRCL_UCU), 814 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 815 CMD_ERRCL_EDU_BL | CMD_ERRCL_UCU), 816 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_CPU | 817 CMD_ERRCL_UCU), 818 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 819 CMD_ERRCL_CPU | CMD_ERRCL_UCU), 820 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL | 821 CMD_ERRCL_CPU | CMD_ERRCL_UCU), 822 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 823 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | CMD_ERRCL_UCU), 824 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU), 825 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST), 826 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL), 827 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 828 CMD_ERRCL_EDU_BL), 829 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_CPU), 830 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_UCU), 831 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 832 CMD_ERRCL_CPU), 833 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL | 834 CMD_ERRCL_CPU), 835 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 836 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU), 837 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 838 CMD_ERRCL_UCU), 839 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL | 840 CMD_ERRCL_UCU), 841 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 842 CMD_ERRCL_EDU_BL | CMD_ERRCL_UCU), 843 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_CPU | 844 CMD_ERRCL_UCU), 845 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 846 CMD_ERRCL_CPU | CMD_ERRCL_UCU), 847 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL | 848 CMD_ERRCL_CPU | CMD_ERRCL_UCU), 849 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 850 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | CMD_ERRCL_UCU), 851 852 /* L3_EDU: WDU+(zero or more of EDU, CPU, UCU)+L3_WDU */ 853 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_L3_WDU), 854 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 855 CMD_ERRCL_L3_WDU), 856 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL | 857 CMD_ERRCL_L3_WDU), 858 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 859 CMD_ERRCL_EDU_BL | CMD_ERRCL_L3_WDU), 860 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_CPU | 861 CMD_ERRCL_L3_WDU), 862 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_UCU | 863 CMD_ERRCL_L3_WDU), 864 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 865 CMD_ERRCL_CPU | CMD_ERRCL_L3_WDU), 866 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL | 867 CMD_ERRCL_CPU | CMD_ERRCL_L3_WDU), 868 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 869 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | CMD_ERRCL_L3_WDU), 870 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 871 CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU), 872 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL | 873 CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU), 874 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 875 CMD_ERRCL_EDU_BL | CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU), 876 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_CPU | 877 CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU), 878 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 879 CMD_ERRCL_CPU | CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU), 880 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL | 881 CMD_ERRCL_CPU | CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU), 882 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 883 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | CMD_ERRCL_UCU | 884 CMD_ERRCL_L3_WDU), 885 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_L3_WDU), 886 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 887 CMD_ERRCL_L3_WDU), 888 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL | 889 CMD_ERRCL_L3_WDU), 890 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 891 CMD_ERRCL_EDU_BL | CMD_ERRCL_L3_WDU), 892 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_CPU | 893 CMD_ERRCL_L3_WDU), 894 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_UCU | 895 CMD_ERRCL_L3_WDU), 896 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 897 CMD_ERRCL_CPU | CMD_ERRCL_L3_WDU), 898 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL | 899 CMD_ERRCL_CPU | CMD_ERRCL_L3_WDU), 900 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 901 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | CMD_ERRCL_L3_WDU), 902 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 903 CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU), 904 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL | 905 CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU), 906 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 907 CMD_ERRCL_EDU_BL | CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU), 908 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_CPU | 909 CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU), 910 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 911 CMD_ERRCL_CPU | CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU), 912 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL | 913 CMD_ERRCL_CPU | CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU), 914 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 915 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | CMD_ERRCL_UCU | 916 CMD_ERRCL_L3_WDU), 917 918 /* L3_CPC: L3_WDC */ 919 CMD_TRAIN(CMD_ERRCL_L3_CPC, CMD_ERRCL_L3_WDC), 920 921 /* L3_CPC: L3_EDC+ WDC+(zero or more of EDC, CPC, UCC) */ 922 CMD_TRAIN(CMD_ERRCL_L3_CPC, CMD_ERRCL_L3_EDC | CMD_ERRCL_WDC), 923 CMD_TRAIN(CMD_ERRCL_L3_CPC, CMD_ERRCL_L3_EDC | CMD_ERRCL_WDC | 924 CMD_ERRCL_EDC), 925 CMD_TRAIN(CMD_ERRCL_L3_CPC, CMD_ERRCL_L3_EDC | CMD_ERRCL_WDC | 926 CMD_ERRCL_CPC), 927 CMD_TRAIN(CMD_ERRCL_L3_CPC, CMD_ERRCL_L3_EDC | CMD_ERRCL_WDC | 928 CMD_ERRCL_UCC), 929 CMD_TRAIN(CMD_ERRCL_L3_CPC, CMD_ERRCL_L3_EDC | CMD_ERRCL_WDC | 930 CMD_ERRCL_EDC | CMD_ERRCL_CPC), 931 CMD_TRAIN(CMD_ERRCL_L3_CPC, CMD_ERRCL_L3_EDC | CMD_ERRCL_WDC | 932 CMD_ERRCL_EDC | CMD_ERRCL_UCC), 933 CMD_TRAIN(CMD_ERRCL_L3_CPC, CMD_ERRCL_L3_EDC | CMD_ERRCL_WDC | 934 CMD_ERRCL_CPC | CMD_ERRCL_UCC), 935 CMD_TRAIN(CMD_ERRCL_L3_CPC, CMD_ERRCL_L3_EDC | CMD_ERRCL_WDC | 936 CMD_ERRCL_EDC | CMD_ERRCL_CPC | CMD_ERRCL_UCC), 937 938 /* L3_CPC: L3_UCC+WDC+(zero or more of EDC, CPC, UCC) */ 939 CMD_TRAIN(CMD_ERRCL_L3_CPC, CMD_ERRCL_L3_UCC | CMD_ERRCL_WDC), 940 CMD_TRAIN(CMD_ERRCL_L3_CPC, CMD_ERRCL_L3_UCC | CMD_ERRCL_WDC | 941 CMD_ERRCL_EDC), 942 CMD_TRAIN(CMD_ERRCL_L3_CPC, CMD_ERRCL_L3_UCC | CMD_ERRCL_WDC | 943 CMD_ERRCL_CPC), 944 CMD_TRAIN(CMD_ERRCL_L3_CPC, CMD_ERRCL_L3_UCC | CMD_ERRCL_WDC | 945 CMD_ERRCL_UCC), 946 CMD_TRAIN(CMD_ERRCL_L3_CPC, CMD_ERRCL_L3_UCC | CMD_ERRCL_WDC | 947 CMD_ERRCL_EDC | CMD_ERRCL_CPC), 948 CMD_TRAIN(CMD_ERRCL_L3_CPC, CMD_ERRCL_L3_UCC | CMD_ERRCL_WDC | 949 CMD_ERRCL_EDC | CMD_ERRCL_UCC), 950 CMD_TRAIN(CMD_ERRCL_L3_CPC, CMD_ERRCL_L3_UCC | CMD_ERRCL_WDC | 951 CMD_ERRCL_CPC | CMD_ERRCL_UCC), 952 CMD_TRAIN(CMD_ERRCL_L3_CPC, CMD_ERRCL_L3_UCC | CMD_ERRCL_WDC | 953 CMD_ERRCL_EDC | CMD_ERRCL_CPC | CMD_ERRCL_UCC), 954 955 /* L3_CPU: L3_WDU */ 956 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_WDU), 957 958 /* L3_CPU: L3_EDU+WDU+(zero or more of EDU, CPU, UCU) */ 959 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU), 960 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU), 961 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | 962 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU), 963 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU | 964 CMD_ERRCL_EDU_ST), 965 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | 966 CMD_ERRCL_EDU_ST), 967 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | 968 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST), 969 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU | 970 CMD_ERRCL_EDU_BL), 971 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | 972 CMD_ERRCL_EDU_BL), 973 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | 974 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL), 975 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU | 976 CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL), 977 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | 978 CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL), 979 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | 980 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 981 CMD_ERRCL_EDU_BL), 982 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU | 983 CMD_ERRCL_CPU), 984 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | 985 CMD_ERRCL_CPU), 986 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | 987 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_CPU), 988 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU | 989 CMD_ERRCL_UCU), 990 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | 991 CMD_ERRCL_UCU), 992 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | 993 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_UCU), 994 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU | 995 CMD_ERRCL_EDU_ST | CMD_ERRCL_CPU), 996 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | 997 CMD_ERRCL_EDU_ST | CMD_ERRCL_CPU), 998 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | 999 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 1000 CMD_ERRCL_CPU), 1001 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU | 1002 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU), 1003 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | 1004 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU), 1005 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | 1006 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL | 1007 CMD_ERRCL_CPU), 1008 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU | 1009 CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU), 1010 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | 1011 CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU), 1012 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | 1013 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 1014 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU), 1015 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU | 1016 CMD_ERRCL_EDU_ST | CMD_ERRCL_UCU), 1017 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | 1018 CMD_ERRCL_EDU_ST | CMD_ERRCL_UCU), 1019 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | 1020 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 1021 CMD_ERRCL_UCU), 1022 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU | 1023 CMD_ERRCL_EDU_BL | CMD_ERRCL_UCU), 1024 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | 1025 CMD_ERRCL_EDU_BL | CMD_ERRCL_UCU), 1026 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | 1027 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL | 1028 CMD_ERRCL_UCU), 1029 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU | 1030 CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL | CMD_ERRCL_UCU), 1031 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | 1032 CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL | CMD_ERRCL_UCU), 1033 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | 1034 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 1035 CMD_ERRCL_EDU_BL | CMD_ERRCL_UCU), 1036 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU | 1037 CMD_ERRCL_CPU | CMD_ERRCL_UCU), 1038 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | 1039 CMD_ERRCL_CPU | CMD_ERRCL_UCU), 1040 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | 1041 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_CPU | 1042 CMD_ERRCL_UCU), 1043 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU | 1044 CMD_ERRCL_EDU_ST | CMD_ERRCL_CPU | CMD_ERRCL_UCU), 1045 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | 1046 CMD_ERRCL_EDU_ST | CMD_ERRCL_CPU | CMD_ERRCL_UCU), 1047 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | 1048 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 1049 CMD_ERRCL_CPU | CMD_ERRCL_UCU), 1050 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU | 1051 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | CMD_ERRCL_UCU), 1052 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | 1053 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | CMD_ERRCL_UCU), 1054 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | 1055 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL | 1056 CMD_ERRCL_CPU | CMD_ERRCL_UCU), 1057 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU | 1058 CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | 1059 CMD_ERRCL_UCU), 1060 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | 1061 CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | 1062 CMD_ERRCL_UCU), 1063 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | 1064 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 1065 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | CMD_ERRCL_UCU), 1066 1067 /* L3_CPU: L3_UCU+WDU+(zero or more of EDU, CPU, UCU) */ 1068 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU), 1069 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU | 1070 CMD_ERRCL_EDU_ST), 1071 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU | 1072 CMD_ERRCL_EDU_BL), 1073 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU | 1074 CMD_ERRCL_EDU_ST |CMD_ERRCL_EDU_BL), 1075 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU | 1076 CMD_ERRCL_CPU), 1077 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU | 1078 CMD_ERRCL_UCU), 1079 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU | 1080 CMD_ERRCL_EDU_ST | CMD_ERRCL_CPU), 1081 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU | 1082 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU), 1083 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU | 1084 CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU), 1085 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU | 1086 CMD_ERRCL_EDU_ST | CMD_ERRCL_UCU), 1087 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU | 1088 CMD_ERRCL_EDU_BL | CMD_ERRCL_UCU), 1089 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU | 1090 CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL | CMD_ERRCL_UCU), 1091 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU | 1092 CMD_ERRCL_CPU | CMD_ERRCL_UCU), 1093 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU | 1094 CMD_ERRCL_EDU_ST | CMD_ERRCL_CPU | CMD_ERRCL_UCU), 1095 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU | 1096 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | CMD_ERRCL_UCU), 1097 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU | 1098 CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | 1099 CMD_ERRCL_UCU), 1100 1101 /* L3_CPU: L3_EDU+WDU+(zero or more of EDU, CPU, UCU)+L3_WDU */ 1102 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU | 1103 CMD_ERRCL_L3_WDU), 1104 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | 1105 CMD_ERRCL_L3_WDU), 1106 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | 1107 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_L3_WDU), 1108 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU | 1109 CMD_ERRCL_EDU_ST | CMD_ERRCL_L3_WDU), 1110 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | 1111 CMD_ERRCL_EDU_ST | CMD_ERRCL_L3_WDU), 1112 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | 1113 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 1114 CMD_ERRCL_L3_WDU), 1115 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU | 1116 CMD_ERRCL_EDU_BL | CMD_ERRCL_L3_WDU), 1117 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | 1118 CMD_ERRCL_EDU_BL | CMD_ERRCL_L3_WDU), 1119 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | 1120 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL | 1121 CMD_ERRCL_L3_WDU), 1122 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU | 1123 CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL | CMD_ERRCL_L3_WDU), 1124 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | 1125 CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL | CMD_ERRCL_L3_WDU), 1126 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | 1127 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 1128 CMD_ERRCL_EDU_BL | CMD_ERRCL_L3_WDU), 1129 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU | 1130 CMD_ERRCL_CPU | CMD_ERRCL_L3_WDU), 1131 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | 1132 CMD_ERRCL_CPU | CMD_ERRCL_L3_WDU), 1133 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | 1134 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_CPU | 1135 CMD_ERRCL_L3_WDU), 1136 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU | 1137 CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU), 1138 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | 1139 CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU), 1140 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | 1141 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_UCU | 1142 CMD_ERRCL_L3_WDU), 1143 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU | 1144 CMD_ERRCL_EDU_ST | CMD_ERRCL_CPU | CMD_ERRCL_L3_WDU), 1145 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | 1146 CMD_ERRCL_EDU_ST | CMD_ERRCL_CPU | CMD_ERRCL_L3_WDU), 1147 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | 1148 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 1149 CMD_ERRCL_CPU | CMD_ERRCL_L3_WDU), 1150 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU | 1151 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | CMD_ERRCL_L3_WDU), 1152 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | 1153 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | CMD_ERRCL_L3_WDU), 1154 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | 1155 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL | 1156 CMD_ERRCL_CPU | CMD_ERRCL_L3_WDU), 1157 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU | 1158 CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | 1159 CMD_ERRCL_L3_WDU), 1160 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | 1161 CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | 1162 CMD_ERRCL_L3_WDU), 1163 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | 1164 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 1165 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | CMD_ERRCL_L3_WDU), 1166 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU | 1167 CMD_ERRCL_EDU_ST | CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU), 1168 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | 1169 CMD_ERRCL_EDU_ST | CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU), 1170 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | 1171 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 1172 CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU), 1173 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU | 1174 CMD_ERRCL_EDU_BL | CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU), 1175 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | 1176 CMD_ERRCL_EDU_BL | CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU), 1177 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | 1178 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL | 1179 CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU), 1180 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU | 1181 CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL | CMD_ERRCL_UCU | 1182 CMD_ERRCL_L3_WDU), 1183 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | 1184 CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL | CMD_ERRCL_UCU | 1185 CMD_ERRCL_L3_WDU), 1186 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | 1187 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 1188 CMD_ERRCL_EDU_BL | CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU), 1189 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU | 1190 CMD_ERRCL_CPU | CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU), 1191 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | 1192 CMD_ERRCL_CPU | CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU), 1193 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | 1194 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_CPU | 1195 CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU), 1196 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU | 1197 CMD_ERRCL_EDU_ST | CMD_ERRCL_CPU | CMD_ERRCL_UCU | 1198 CMD_ERRCL_L3_WDU), 1199 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | 1200 CMD_ERRCL_EDU_ST | CMD_ERRCL_CPU | CMD_ERRCL_UCU | 1201 CMD_ERRCL_L3_WDU), 1202 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | 1203 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 1204 CMD_ERRCL_CPU | CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU), 1205 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU | 1206 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | CMD_ERRCL_UCU | 1207 CMD_ERRCL_L3_WDU), 1208 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | 1209 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | CMD_ERRCL_UCU | 1210 CMD_ERRCL_L3_WDU), 1211 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | 1212 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL | 1213 CMD_ERRCL_CPU | CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU), 1214 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU | 1215 CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | 1216 CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU), 1217 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | 1218 CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | 1219 CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU), 1220 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | 1221 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST | 1222 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | CMD_ERRCL_UCU | 1223 CMD_ERRCL_L3_WDU), 1224 1225 /* L3_CPU: L3_UCU+WDU+(zero or more of EDU, CPU, UCU)+L3_WDU */ 1226 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU 1227 | CMD_ERRCL_L3_WDU), 1228 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU | 1229 CMD_ERRCL_EDU_ST | CMD_ERRCL_L3_WDU), 1230 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU | 1231 CMD_ERRCL_EDU_BL | CMD_ERRCL_L3_WDU), 1232 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU | 1233 CMD_ERRCL_EDU_ST |CMD_ERRCL_EDU_BL | CMD_ERRCL_L3_WDU), 1234 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU | 1235 CMD_ERRCL_CPU | CMD_ERRCL_L3_WDU), 1236 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU | 1237 CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU), 1238 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU | 1239 CMD_ERRCL_EDU_ST | CMD_ERRCL_CPU | CMD_ERRCL_L3_WDU), 1240 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU | 1241 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | CMD_ERRCL_L3_WDU), 1242 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU | 1243 CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | 1244 CMD_ERRCL_L3_WDU), 1245 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU | 1246 CMD_ERRCL_EDU_ST | CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU), 1247 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU | 1248 CMD_ERRCL_EDU_BL | CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU), 1249 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU | 1250 CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL | CMD_ERRCL_UCU | 1251 CMD_ERRCL_L3_WDU), 1252 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU | 1253 CMD_ERRCL_CPU | CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU), 1254 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU | 1255 CMD_ERRCL_EDU_ST | CMD_ERRCL_CPU | CMD_ERRCL_UCU | 1256 CMD_ERRCL_L3_WDU), 1257 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU | 1258 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | CMD_ERRCL_UCU | 1259 CMD_ERRCL_L3_WDU), 1260 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU | 1261 CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | 1262 CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU), 1263#else /* sun4u */ 1264 CMD_TRAIN(CMD_ERRCL_LDAC, CMD_ERRCL_LDWC), 1265 CMD_TRAIN(CMD_ERRCL_LDRC, CMD_ERRCL_LDWC), 1266 CMD_TRAIN(CMD_ERRCL_LDSC, CMD_ERRCL_LDWC), 1267 CMD_TRAIN(CMD_ERRCL_LDAU, CMD_ERRCL_LDWU), 1268 CMD_TRAIN(CMD_ERRCL_LDRU, CMD_ERRCL_LDWU), 1269 CMD_TRAIN(CMD_ERRCL_LDSU, CMD_ERRCL_LDWU), 1270 /* SBDLC: SBDPC */ 1271 CMD_TRAIN(CMD_ERRCL_SBDLC, CMD_ERRCL_SBDPC), 1272 /* TCCP: TCCD */ 1273 CMD_TRAIN(CMD_ERRCL_TCCP, CMD_ERRCL_TCCD), 1274 /* TCCD: TCCD */ 1275 CMD_TRAIN(CMD_ERRCL_TCCD, CMD_ERRCL_TCCD), 1276#endif /* sun4u */ 1277 CMD_TRAIN(0, 0) 1278}; 1279 1280cmd_errcl_t 1281cmd_xxcu_train_match(cmd_errcl_t mask) 1282{ 1283 int i; 1284 1285 for (i = 0; cmd_xxcu_trains[i].tr_mask != 0; i++) { 1286 if (cmd_xxcu_trains[i].tr_mask == mask) 1287 return (cmd_xxcu_trains[i].tr_cause); 1288 } 1289 1290 return (0); 1291} 1292/* 1293 * Search for the entry that matches the ena and the AFAR 1294 * if we have a valid AFAR, otherwise just match the ENA 1295 */ 1296cmd_xxcu_trw_t * 1297cmd_trw_lookup(uint64_t ena, uint8_t afar_status, uint64_t afar) 1298{ 1299 int i; 1300 1301 if (afar_status == AFLT_STAT_VALID) { 1302 for (i = 0; i < cmd.cmd_xxcu_ntrw; i++) { 1303 if (cmd.cmd_xxcu_trw[i].trw_ena == ena && 1304 cmd.cmd_xxcu_trw[i].trw_afar == afar) 1305 return (&cmd.cmd_xxcu_trw[i]); 1306 } 1307 } else { 1308 for (i = 0; i < cmd.cmd_xxcu_ntrw; i++) { 1309 if (cmd.cmd_xxcu_trw[i].trw_ena == ena) 1310 return (&cmd.cmd_xxcu_trw[i]); 1311 } 1312 } 1313 return (NULL); 1314} 1315 1316cmd_xxcu_trw_t * 1317cmd_trw_alloc(uint64_t ena, uint64_t afar) 1318{ 1319 int i; 1320 1321 for (i = 0; i < cmd.cmd_xxcu_ntrw; i++) { 1322 cmd_xxcu_trw_t *trw = &cmd.cmd_xxcu_trw[i]; 1323 if (trw->trw_ena == NULL) { 1324 trw->trw_ena = ena; 1325 trw->trw_afar = afar; 1326 return (trw); 1327 } 1328 } 1329 1330 return (NULL); 1331} 1332 1333void 1334cmd_trw_write(fmd_hdl_t *hdl) 1335{ 1336 fmd_buf_write(hdl, NULL, "waiters", cmd.cmd_xxcu_trw, 1337 cmd.cmd_xxcu_ntrw * sizeof (cmd_xxcu_trw_t)); 1338} 1339 1340/*ARGSUSED*/ 1341void 1342cmd_trw_ref(fmd_hdl_t *hdl, cmd_xxcu_trw_t *trw, cmd_errcl_t clcode) 1343{ 1344 trw->trw_ref++; 1345 trw->trw_mask |= clcode; 1346 cmd_trw_write(hdl); 1347} 1348 1349void 1350cmd_trw_deref(fmd_hdl_t *hdl, cmd_xxcu_trw_t *trw) 1351{ 1352 if (trw->trw_ref == 0) 1353 fmd_hdl_abort(hdl, "attempt to deref trw with zero ref\n"); 1354 1355 if (--trw->trw_ref == 0) 1356 bzero(trw, sizeof (cmd_xxcu_trw_t)); 1357 1358 cmd_trw_write(hdl); 1359} 1360 1361void 1362cmd_trw_restore(fmd_hdl_t *hdl) 1363{ 1364 size_t sz; 1365 1366 if ((sz = fmd_buf_size(hdl, NULL, "waiters")) != 0) { 1367 uint_t ntrw = sz / sizeof (cmd_xxcu_trw_t); 1368 1369 if (sz % sizeof (cmd_xxcu_trw_t) != 0) { 1370 fmd_hdl_abort(hdl, "waiters array isn't of " 1371 "correct size\n"); 1372 } 1373 1374 /* 1375 * If the existing buffer is larger than our tuned size, 1376 * we'll only read as many as will fit. 1377 */ 1378 if (ntrw > cmd.cmd_xxcu_ntrw) 1379 ntrw = cmd.cmd_xxcu_ntrw; 1380 1381 fmd_buf_read(hdl, NULL, "waiters", cmd.cmd_xxcu_trw, 1382 ntrw * sizeof (cmd_xxcu_trw_t)); 1383 1384 if (ntrw * sizeof (cmd_xxcu_trw_t) != sz) { 1385 fmd_buf_destroy(hdl, NULL, "waiters"); 1386 fmd_buf_write(hdl, NULL, "waiters", cmd.cmd_xxcu_trw, 1387 ntrw * sizeof (cmd_xxcu_trw_t)); 1388 } 1389 } 1390} 1391 1392char * 1393cmd_cpu_serdnm_create(fmd_hdl_t *hdl, cmd_cpu_t *cpu, const char *serdbase) 1394{ 1395 char *nm; 1396 const char *fmt; 1397 size_t sz; 1398 if (cpu->cpu_level == CMD_CPU_LEVEL_THREAD) { 1399 fmt = "cpu_%d_%s_serd"; 1400 sz = snprintf(NULL, 0, fmt, cpu->cpu_cpuid, serdbase) + 1; 1401 nm = fmd_hdl_alloc(hdl, sz, FMD_SLEEP); 1402 (void) snprintf(nm, sz, fmt, cpu->cpu_cpuid, serdbase); 1403 } else { 1404 fmt = "cpu_%d_%d_%s_serd"; 1405 sz = snprintf(NULL, 0, fmt, cpu->cpu_cpuid, cpu->cpu_level, 1406 serdbase) + 1; 1407 nm = fmd_hdl_alloc(hdl, sz, FMD_SLEEP); 1408 (void) snprintf(nm, sz, fmt, cpu->cpu_cpuid, cpu->cpu_level, 1409 serdbase); 1410 } 1411 1412 return (nm); 1413} 1414 1415/* 1416 * cmd_cpu_create_faultlist is a combination of the former cmd_cpu_create_fault 1417 * and fmd_case_add_suspect. If a 'cpu' structure represents a set of threads 1418 * (level > CMD_CPU_LEVEL_THREAD), then we must add multiple faults to 1419 * this case, under loop control. Use call to cmd_cpu_create_faultlist to 1420 * replace the sequence 1421 * 1422 * flt = cmd_cpu_create_fault(...); 1423 * fmd_case_add_suspect(hdl, cc->cp, flt); 1424 */ 1425 1426void 1427cmd_cpu_create_faultlist(fmd_hdl_t *hdl, fmd_case_t *casep, cmd_cpu_t *cpu, 1428 const char *type, nvlist_t *rsrc, uint_t cert) 1429{ 1430 char fltnm[64]; 1431 uint32_t cpuinit, cpufinal, cpustep, i; 1432 nvlist_t *flt; 1433 1434 (void) snprintf(fltnm, sizeof (fltnm), "fault.cpu.%s.%s", 1435 cpu_type2name(hdl, cpu->cpu_type), type); 1436 1437 cpu->cpu_faulting = FMD_B_TRUE; 1438 cpu_buf_write(hdl, cpu); 1439 1440 if (cpu->cpu_level > CMD_CPU_LEVEL_THREAD) { 1441 core2cpus(cpu->cpu_cpuid, cpu->cpu_type, cpu->cpu_level, 1442 &cpuinit, &cpufinal, &cpustep); 1443 for (i = cpuinit; i <= cpufinal; i += cpustep) { 1444 cmd_cpu_t *cpui = cpu_lookup_by_cpuid(i, 1445 CMD_CPU_LEVEL_THREAD); 1446 if (cpui == NULL) { 1447 nvlist_t *asru; 1448 if (nvlist_dup(cpu->cpu_asru_nvl, 1449 &asru, 0) != 0) { 1450 fmd_hdl_abort(hdl, "unable to alloc" 1451 "ASRU for thread in core\n"); 1452 } 1453 (void) nvlist_remove_all(asru, 1454 FM_FMRI_CPU_ID); 1455 if (nvlist_add_uint32(asru, 1456 FM_FMRI_CPU_ID, i) != 0) { 1457 fmd_hdl_abort(hdl, 1458 "unable to create thread struct\n"); 1459 } 1460 cpui = cpu_create(hdl, asru, i, 1461 CMD_CPU_LEVEL_THREAD, cpu->cpu_type); 1462 nvlist_free(asru); 1463 } 1464 cpui->cpu_faulting = FMD_B_TRUE; 1465 cpu_buf_write(hdl, cpui); 1466 flt = fmd_nvl_create_fault(hdl, fltnm, cert, 1467 cpui->cpu_asru_nvl, cpu->cpu_fru_nvl, rsrc); 1468#ifdef sun4v 1469 flt = cmd_fault_add_location(hdl, flt, "MB"); 1470#endif /* sun4v */ 1471 fmd_case_add_suspect(hdl, casep, flt); 1472 } 1473 } else { 1474 flt = fmd_nvl_create_fault(hdl, fltnm, cert, 1475 cpu->cpu_asru_nvl, cpu->cpu_fru_nvl, rsrc); 1476#ifdef sun4v 1477 flt = cmd_fault_add_location(hdl, flt, "MB"); 1478#endif /* sun4v */ 1479 fmd_case_add_suspect(hdl, casep, flt); 1480 } 1481} 1482 1483static void 1484cmd_cpu_free(fmd_hdl_t *hdl, cmd_cpu_t *cpu, int destroy) 1485{ 1486 int i; 1487 1488 for (i = 0; i < sizeof (cmd_cpu_cases_t) / sizeof (cmd_case_t); i++) { 1489 cmd_case_t *cc = &(((cmd_case_t *)&cpu->cpu_cases)[i]); 1490 1491 if (cc->cc_cp != NULL) { 1492 cmd_case_fini(hdl, cc->cc_cp, destroy); 1493 if (cc->cc_serdnm != NULL) { 1494 if (fmd_serd_exists(hdl, cc->cc_serdnm) && 1495 destroy) 1496 fmd_serd_destroy(hdl, cc->cc_serdnm); 1497 fmd_hdl_strfree(hdl, cc->cc_serdnm); 1498 } 1499 } 1500 } 1501 1502#ifdef sun4u 1503 cpu_uec_free(hdl, &cpu->cpu_uec, destroy); 1504 cpu_uec_free(hdl, &cpu->cpu_olduec, destroy); 1505#endif /* sun4u */ 1506 1507 cmd_fmri_fini(hdl, &cpu->cpu_asru, destroy); 1508 cmd_fmri_fini(hdl, &cpu->cpu_fru, destroy); 1509 1510 cmd_list_delete(&cmd.cmd_cpus, cpu); 1511 1512 if (destroy) 1513 fmd_buf_destroy(hdl, NULL, cpu->cpu_bufname); 1514 fmd_hdl_free(hdl, cpu, sizeof (cmd_cpu_t)); 1515} 1516 1517void 1518cmd_cpu_destroy(fmd_hdl_t *hdl, cmd_cpu_t *cpu) 1519{ 1520 cmd_cpu_free(hdl, cpu, FMD_B_TRUE); 1521} 1522 1523static cmd_cpu_t * 1524cpu_lookup_by_cpuid(uint32_t cpuid, uint8_t level) 1525{ 1526 cmd_cpu_t *cpu; 1527 1528 for (cpu = cmd_list_next(&cmd.cmd_cpus); cpu != NULL; 1529 cpu = cmd_list_next(cpu)) { 1530 if ((cpu->cpu_cpuid == cpuid) && 1531 (cpu->cpu_level == level)) 1532 return (cpu); 1533 } 1534 1535 return (NULL); 1536} 1537 1538static nvlist_t * 1539cpu_getfru(fmd_hdl_t *hdl, cmd_cpu_t *cp) 1540{ 1541 char *frustr, *partstr, *serialstr; 1542 nvlist_t *nvlp; 1543 1544 if ((frustr = cmd_cpu_getfrustr(hdl, cp)) == NULL) { 1545 return (NULL); 1546 } 1547 partstr = cmd_cpu_getpartstr(hdl, cp); 1548 serialstr = cmd_cpu_getserialstr(hdl, cp); 1549 nvlp = cmd_cpu_mkfru(frustr, serialstr, partstr); 1550 fmd_hdl_strfree(hdl, frustr); 1551 fmd_hdl_strfree(hdl, partstr); 1552 fmd_hdl_strfree(hdl, serialstr); 1553 1554 return (nvlp); 1555} 1556 1557static void 1558cpu_buf_write(fmd_hdl_t *hdl, cmd_cpu_t *cpu) 1559{ 1560 if (fmd_buf_size(hdl, NULL, cpu->cpu_bufname) != 1561 sizeof (cmd_cpu_pers_t)) 1562 fmd_buf_destroy(hdl, NULL, cpu->cpu_bufname); 1563 1564 fmd_buf_write(hdl, NULL, cpu->cpu_bufname, &cpu->cpu_pers, 1565 sizeof (cmd_cpu_pers_t)); 1566} 1567 1568static void 1569cpu_buf_create(fmd_hdl_t *hdl, cmd_cpu_t *cpu) 1570{ 1571 size_t sz; 1572 1573 /* 1574 * We need to be tolerant of leaked CPU buffers, as their effects can 1575 * be severe. Consider the following scenario: we create a version 0 1576 * cmd_cpu_t in response to some error, commit it to a persistent 1577 * buffer, and then leak it. We then upgrade, and restart the DE using 1578 * version 1 cmd_cpu_t's. Another error comes along, for the same CPU 1579 * whose struct was leaked. Not knowing about the leaked buffer, we 1580 * create a new cmd_cpu_t for that CPU, and create a buffer for it. As 1581 * the v1 cmd_cpu_t is smaller than the v0 cmd_cpu_t, fmd will use the 1582 * pre-existing (leaked) buffer. We'll therefore have an x-byte, v1 1583 * cmd_cpu_t in a y-byte buffer, where y > x. Upon the next DE restart, 1584 * we'll attempt to restore the cmd_cpu_t, but will do version 1585 * validation using the size of the buffer (y). This won't match what 1586 * we're expecting (x), and the DE will abort. 1587 * 1588 * To protect against such a scenario, we're going to check for and 1589 * remove the pre-existing cmd_cpu_t for this CPU, if one exists. While 1590 * this won't fix the leak, it'll allow us to continue functioning 1591 * properly in spite of it. 1592 */ 1593 if ((sz = fmd_buf_size(hdl, NULL, cpu->cpu_bufname)) != 0 && 1594 sz != sizeof (cmd_cpu_pers_t)) { 1595 fmd_hdl_debug(hdl, "removing unexpected pre-existing cpu " 1596 "buffer %s (size %u bytes)\n", cpu->cpu_bufname, sz); 1597 fmd_buf_destroy(hdl, NULL, cpu->cpu_bufname); 1598 } 1599 1600 cpu_buf_write(hdl, cpu); 1601} 1602 1603static cmd_cpu_t * 1604cpu_create(fmd_hdl_t *hdl, nvlist_t *asru, uint32_t cpuid, uint8_t level, 1605 cmd_cpu_type_t type) 1606{ 1607 cmd_cpu_t *cpu; 1608 nvlist_t *fru; 1609 1610 /* 1611 * No CPU state matches the CPU described in the ereport. Create a new 1612 * one, add it to the list, and pass it back. 1613 */ 1614 fmd_hdl_debug(hdl, "cpu_lookup: creating new cpuid %u\n", cpuid); 1615 CMD_STAT_BUMP(cpu_creat); 1616 1617 cpu = fmd_hdl_zalloc(hdl, sizeof (cmd_cpu_t), FMD_SLEEP); 1618 cpu->cpu_nodetype = CMD_NT_CPU; 1619 cpu->cpu_cpuid = cpuid; 1620 cpu->cpu_level = level; 1621 cpu->cpu_type = type; 1622 cpu->cpu_version = CMD_CPU_VERSION; 1623 1624 if (cpu->cpu_level > CMD_CPU_LEVEL_THREAD) { 1625 cmd_bufname(cpu->cpu_bufname, sizeof (cpu->cpu_bufname), 1626 "cpu_%d", cpu->cpu_cpuid); 1627 } else { 1628 cmd_bufname(cpu->cpu_bufname, sizeof (cpu->cpu_bufname), 1629 "cpu_%d_%d", cpu->cpu_cpuid, cpu->cpu_level); 1630 } 1631 1632#ifdef sun4u 1633 cpu_uec_create(hdl, cpu, &cpu->cpu_uec, "cpu_uec_%d", cpu->cpu_cpuid); 1634 cpu_uec_create(hdl, cpu, &cpu->cpu_olduec, "cpu_olduec_%d", 1635 cpu->cpu_cpuid); 1636#endif /* sun4u */ 1637 1638 cmd_fmri_init(hdl, &cpu->cpu_asru, asru, "cpu_asru_%d", cpu->cpu_cpuid); 1639 1640 if ((fru = cpu_getfru(hdl, cpu)) != NULL) { 1641 cmd_fmri_init(hdl, &cpu->cpu_fru, fru, "cpu_fru_%d", 1642 cpu->cpu_cpuid); 1643 nvlist_free(fru); 1644 } else { 1645 cmd_fmri_init(hdl, &cpu->cpu_fru, asru, "cpu_fru_%d", 1646 cpu->cpu_cpuid); 1647 } 1648 1649 cpu_buf_create(hdl, cpu); 1650 1651 cmd_list_append(&cmd.cmd_cpus, cpu); 1652 1653 return (cpu); 1654} 1655 1656/* 1657 * As its name implies, 'cpu_all_threads_invalid' determines if all cpu 1658 * threads (level 0) contained within the cpu structure are invalid. 1659 * This is done by checking all the (level 0) threads which may be 1660 * contained within this chip, core, or thread; if all are invalid, return 1661 * FMD_B_TRUE; if any are valid, return FMD_B_FALSE. 1662 */ 1663 1664int 1665cpu_all_threads_invalid(fmd_hdl_t *hdl, cmd_cpu_t *cpu) 1666{ 1667 nvlist_t *asru; 1668 uint32_t cpuinit, cpufinal, cpustep, i; 1669 1670 core2cpus(cpu->cpu_cpuid, cpu->cpu_type, cpu->cpu_level, 1671 &cpuinit, &cpufinal, &cpustep); 1672 1673 if (cpuinit == cpufinal) { 1674 if (fmd_nvl_fmri_present(hdl, cpu->cpu_asru_nvl) && 1675 !fmd_nvl_fmri_unusable(hdl, cpu->cpu_asru_nvl)) 1676 return (FMD_B_FALSE); 1677 else return (FMD_B_TRUE); 1678 } else { 1679 1680 if (nvlist_dup(cpu->cpu_asru_nvl, &asru, 0) != 0) 1681 fmd_hdl_abort(hdl, "cannot copy asru\n"); 1682 for (i = cpuinit; i <= cpufinal; i += cpustep) { 1683 (void) nvlist_remove_all(asru, FM_FMRI_CPU_ID); 1684 if (nvlist_add_uint32(asru, FM_FMRI_CPU_ID, i) != 0) { 1685 fmd_hdl_abort(hdl, "cpu_all_threads_invalid: ", 1686 "cannot add thread %d to asru\n", i); 1687 } 1688 if (fmd_nvl_fmri_present(hdl, asru) && 1689 !fmd_nvl_fmri_unusable(hdl, asru)) { 1690 nvlist_free(asru); 1691 return (FMD_B_FALSE); 1692 } 1693 } 1694 } 1695 nvlist_free(asru); 1696 return (FMD_B_TRUE); 1697} 1698 1699/* 1700 * Locate the state structure for this CPU, creating a new one if one doesn't 1701 * already exist. Before passing it back, we also need to validate it against 1702 * the current state of the world, checking to ensure that the CPU described by 1703 * the ereport, the CPU indicated in the cmd_cpu_t, and the CPU currently 1704 * residing at the indicated cpuid are the same. We do this by comparing the 1705 * serial IDs from the three entities. 1706 */ 1707cmd_cpu_t * 1708cmd_cpu_lookup(fmd_hdl_t *hdl, nvlist_t *asru, const char *class, 1709 uint8_t level) 1710{ 1711 cmd_cpu_t *cpu; 1712 uint8_t vers; 1713 const char *scheme, *cpuname; 1714 uint32_t cpuid; 1715 cmd_cpu_type_t ct; 1716 1717 if (fmd_nvl_fmri_expand(hdl, asru) < 0) { 1718 CMD_STAT_BUMP(bad_cpu_asru); 1719 return (NULL); 1720 } 1721 1722 if (nvlist_lookup_pairs(asru, 0, 1723 FM_VERSION, DATA_TYPE_UINT8, &vers, 1724 FM_FMRI_SCHEME, DATA_TYPE_STRING, &scheme, 1725 FM_FMRI_CPU_ID, DATA_TYPE_UINT32, &cpuid, 1726 NULL) != 0 || (vers != CPU_SCHEME_VERSION0 && 1727 vers != CPU_SCHEME_VERSION1) || 1728 strcmp(scheme, FM_FMRI_SCHEME_CPU) != 0) { 1729 CMD_STAT_BUMP(bad_cpu_asru); 1730 return (NULL); 1731 } 1732 1733 /* 1734 * 'cpuid' at this point refers to a thread, because it 1735 * was extracted from a detector FMRI 1736 */ 1737 1738 cpuname = class + sizeof ("ereport.cpu"); 1739 ct = cpu_nname2type(hdl, cpuname, 1740 (size_t)(strchr(cpuname, '.') - cpuname)); 1741 1742 cpu = cpu_lookup_by_cpuid(cmd_cpu2core(cpuid, ct, level), level); 1743 1744 if (cpu != NULL && 1745 cpu_all_threads_invalid(hdl, cpu) == FMD_B_TRUE) { 1746 fmd_hdl_debug(hdl, "cpu_lookup: discarding old state\n"); 1747 cmd_cpu_destroy(hdl, cpu); 1748 cpu = NULL; 1749 } 1750 1751 /* 1752 * Check to see if the CPU described by the ereport has been removed 1753 * from the system. If it has, return to the caller without a CPU. 1754 */ 1755 if (!fmd_nvl_fmri_present(hdl, asru) || 1756 fmd_nvl_fmri_unusable(hdl, asru)) { 1757 fmd_hdl_debug(hdl, "cpu_lookup: discarding old ereport\n"); 1758 return (NULL); 1759 } 1760 1761 if (cpu == NULL) { 1762 cpu = cpu_create(hdl, asru, 1763 cmd_cpu2core(cpuid, ct, level), level, ct); 1764 } 1765 1766 return (cpu); 1767} 1768 1769cmd_cpu_t * 1770cmd_cpu_lookup_from_detector(fmd_hdl_t *hdl, nvlist_t *nvl, const char *class, 1771 uint8_t level) 1772{ 1773 nvlist_t *det; 1774 1775 (void) nvlist_lookup_nvlist(nvl, FM_EREPORT_DETECTOR, &det); 1776 1777 return (cmd_cpu_lookup(hdl, det, class, level)); 1778} 1779 1780static cmd_cpu_t * 1781cpu_v0tov3(fmd_hdl_t *hdl, cmd_cpu_0_t *old, size_t oldsz) 1782{ 1783 cmd_cpu_t *new; 1784 1785 if (oldsz != sizeof (cmd_cpu_0_t)) { 1786 fmd_hdl_abort(hdl, "size of state doesn't match size of " 1787 "version 0 state (%u bytes).\n", sizeof (cmd_cpu_0_t)); 1788 } 1789 1790 new = fmd_hdl_zalloc(hdl, sizeof (cmd_cpu_t), FMD_SLEEP); 1791 new->cpu_header = old->cpu0_header; 1792 new->cpu_version = CMD_CPU_VERSION; 1793 new->cpu_cpuid = old->cpu0_cpuid; 1794 new->cpu_type = old->cpu0_type; 1795 new->cpu_faulting = old->cpu0_faulting; 1796 new->cpu_level = CMD_CPU_LEVEL_THREAD; 1797 new->cpu_asru = old->cpu0_asru; 1798 new->cpu_fru = old->cpu0_fru; 1799 new->cpu_uec = old->cpu0_uec; 1800 new->cpu_olduec = old->cpu0_olduec; 1801 1802 fmd_hdl_free(hdl, old, oldsz); 1803 return (new); 1804} 1805 1806static cmd_cpu_t * 1807cpu_v1tov3(fmd_hdl_t *hdl, cmd_cpu_1_t *old, size_t oldsz) 1808{ 1809 cmd_cpu_t *new; 1810 1811 if (oldsz != sizeof (cmd_cpu_1_t)) { 1812 fmd_hdl_abort(hdl, "size of state doesn't match size of " 1813 "version 1 state (%u bytes).\n", sizeof (cmd_cpu_1_t)); 1814 } 1815 1816 new = fmd_hdl_zalloc(hdl, sizeof (cmd_cpu_t), FMD_SLEEP); 1817 new->cpu_header = old->cpu1_header; 1818 new->cpu_version = CMD_CPU_VERSION; 1819 new->cpu_cpuid = old->cpu1_cpuid; 1820 new->cpu_type = old->cpu1_type; 1821 new->cpu_faulting = old->cpu1_faulting; 1822 new->cpu_level = CMD_CPU_LEVEL_THREAD; 1823 new->cpu_asru = old->cpu1_asru; 1824 new->cpu_fru = old->cpu1_fru; 1825 new->cpu_uec = old->cpu1_uec; 1826 new->cpu_olduec = old->cpu1_olduec; 1827 1828 fmd_hdl_free(hdl, old, oldsz); 1829 return (new); 1830} 1831 1832static cmd_cpu_t * 1833cpu_v2tov3(fmd_hdl_t *hdl, cmd_cpu_2_t *old, size_t oldsz) 1834{ 1835 cmd_cpu_t *new; 1836 1837 if (oldsz != sizeof (cmd_cpu_2_t)) { 1838 fmd_hdl_abort(hdl, "size of state doesn't match size of " 1839 "version 2 state (%u bytes).\n", sizeof (cmd_cpu_2_t)); 1840 } 1841 1842 new = fmd_hdl_zalloc(hdl, sizeof (cmd_cpu_t), FMD_SLEEP); 1843 1844 new->cpu_header = old->cpu2_header; 1845 new->cpu_cpuid = old->cpu2_cpuid; 1846 new->cpu_type = old->cpu2_type; 1847 new->cpu_faulting = old->cpu2_faulting; 1848 new->cpu_asru = old->cpu2_asru; 1849 new->cpu_fru = old->cpu2_fru; 1850 new->cpu_uec = old->cpu2_uec; 1851 new->cpu_olduec = old->cpu2_olduec; 1852 new->cpu_version = CMD_CPU_VERSION; 1853 new->cpu_level = CMD_CPU_LEVEL_THREAD; 1854 fmd_hdl_free(hdl, old, oldsz); 1855 return (new); 1856} 1857 1858static cmd_cpu_t * 1859cpu_wrapv3(fmd_hdl_t *hdl, cmd_cpu_pers_t *pers, size_t psz) 1860{ 1861 cmd_cpu_t *cpu; 1862 1863 if (psz != sizeof (cmd_cpu_pers_t)) { 1864 fmd_hdl_abort(hdl, "size of state doesn't match size of " 1865 "version 3 state (%u bytes).\n", sizeof (cmd_cpu_pers_t)); 1866 } 1867 1868 cpu = fmd_hdl_zalloc(hdl, sizeof (cmd_cpu_t), FMD_SLEEP); 1869 bcopy(pers, cpu, sizeof (cmd_cpu_pers_t)); 1870 fmd_hdl_free(hdl, pers, psz); 1871 return (cpu); 1872} 1873 1874static void 1875cpu_case_restore(fmd_hdl_t *hdl, cmd_cpu_t *cpu, cmd_case_t *cc, fmd_case_t *cp, 1876 const char *serdbase) 1877{ 1878 cmd_case_restore(hdl, cc, cp, cmd_cpu_serdnm_create(hdl, cpu, 1879 serdbase)); 1880} 1881 1882void * 1883cmd_cpu_restore(fmd_hdl_t *hdl, fmd_case_t *cp, cmd_case_ptr_t *ptr) 1884{ 1885 cmd_cpu_t *cpu; 1886 1887 for (cpu = cmd_list_next(&cmd.cmd_cpus); cpu != NULL; 1888 cpu = cmd_list_next(cpu)) { 1889 if (strcmp(cpu->cpu_bufname, ptr->ptr_name) == 0) 1890 break; 1891 } 1892 1893 if (cpu == NULL) { 1894 int migrated = 0; 1895 size_t cpusz; 1896 1897 fmd_hdl_debug(hdl, "restoring cpu from %s\n", ptr->ptr_name); 1898 1899 if ((cpusz = fmd_buf_size(hdl, NULL, ptr->ptr_name)) == 0) { 1900 fmd_hdl_abort(hdl, "cpu referenced by case %s does " 1901 "not exist in saved state\n", 1902 fmd_case_uuid(hdl, cp)); 1903 } else if (cpusz > CMD_CPU_MAXSIZE || cpusz < CMD_CPU_MINSIZE) { 1904 fmd_hdl_abort(hdl, "cpu buffer referenced by case %s " 1905 "is out of bounds (is %u bytes)\n", 1906 fmd_case_uuid(hdl, cp), cpusz); 1907 } 1908 1909 if ((cpu = cmd_buf_read(hdl, NULL, ptr->ptr_name, 1910 cpusz)) == NULL) { 1911 fmd_hdl_abort(hdl, "failed to read buf %s", 1912 ptr->ptr_name); 1913 } 1914 1915 fmd_hdl_debug(hdl, "found %d in version field\n", 1916 cpu->cpu_version); 1917 1918 if (CMD_CPU_VERSIONED(cpu)) { 1919 switch (cpu->cpu_version) { 1920 case CMD_CPU_VERSION_1: 1921 cpu = cpu_v1tov3(hdl, (cmd_cpu_1_t *)cpu, 1922 cpusz); 1923 migrated = 1; 1924 break; 1925 case CMD_CPU_VERSION_2: 1926 cpu = cpu_v2tov3(hdl, (cmd_cpu_2_t *)cpu, 1927 cpusz); 1928 migrated = 1; 1929 break; 1930 case CMD_CPU_VERSION_3: 1931 cpu = cpu_wrapv3(hdl, (cmd_cpu_pers_t *)cpu, 1932 cpusz); 1933 break; 1934 default: 1935 fmd_hdl_abort(hdl, "unknown version (found %d) " 1936 "for cpu state referenced by case %s.\n", 1937 cpu->cpu_version, fmd_case_uuid(hdl, cp)); 1938 break; 1939 } 1940 } else { 1941 cpu = cpu_v0tov3(hdl, (cmd_cpu_0_t *)cpu, cpusz); 1942 migrated = 1; 1943 } 1944 1945 if (migrated) { 1946 CMD_STAT_BUMP(cpu_migrat); 1947 cpu_buf_write(hdl, cpu); 1948 } 1949 1950 cmd_fmri_restore(hdl, &cpu->cpu_asru); 1951 cmd_fmri_restore(hdl, &cpu->cpu_fru); 1952#ifdef sun4u 1953 cpu_uec_restore(hdl, &cpu->cpu_uec); 1954 cpu_uec_restore(hdl, &cpu->cpu_olduec); 1955 1956 if (cpu->cpu_uec.uec_cache != NULL) 1957 cpu_uec_flush(hdl, cpu); 1958#endif /* sun4u */ 1959 bzero(&cpu->cpu_xxu_retries, sizeof (cmd_list_t)); 1960 1961 cmd_list_append(&cmd.cmd_cpus, cpu); 1962 } 1963 1964 switch (ptr->ptr_subtype) { 1965 case CMD_PTR_CPU_ICACHE: 1966 cpu_case_restore(hdl, cpu, &cpu->cpu_icache, cp, "icache"); 1967 break; 1968 case CMD_PTR_CPU_DCACHE: 1969 cpu_case_restore(hdl, cpu, &cpu->cpu_dcache, cp, "dcache"); 1970 break; 1971 case CMD_PTR_CPU_PCACHE: 1972 cpu_case_restore(hdl, cpu, &cpu->cpu_pcache, cp, "pcache"); 1973 break; 1974 case CMD_PTR_CPU_ITLB: 1975 cpu_case_restore(hdl, cpu, &cpu->cpu_itlb, cp, "itlb"); 1976 break; 1977 case CMD_PTR_CPU_DTLB: 1978 cpu_case_restore(hdl, cpu, &cpu->cpu_dtlb, cp, "dtlb"); 1979 break; 1980 case CMD_PTR_CPU_L2DATA: 1981 cpu_case_restore(hdl, cpu, &cpu->cpu_l2data, cp, 1982 cmd.cmd_l2data_serd.cs_name); 1983 break; 1984 case CMD_PTR_CPU_L2DATA_UERETRY: 1985 /* No longer used -- discard */ 1986 break; 1987 case CMD_PTR_CPU_L2TAG: 1988 cpu_case_restore(hdl, cpu, &cpu->cpu_l2tag, cp, "l2tag"); 1989 break; 1990 case CMD_PTR_CPU_L3DATA: 1991 cpu_case_restore(hdl, cpu, &cpu->cpu_l3data, cp, 1992 cmd.cmd_l3data_serd.cs_name); 1993 break; 1994 case CMD_PTR_CPU_L3DATA_UERETRY: 1995 /* No longer used -- discard */ 1996 break; 1997 case CMD_PTR_CPU_L3TAG: 1998 cpu_case_restore(hdl, cpu, &cpu->cpu_l3tag, cp, "l3tag"); 1999 break; 2000 case CMD_PTR_CPU_FPU: 2001 cpu_case_restore(hdl, cpu, &cpu->cpu_fpu, cp, "fpu"); 2002 break; 2003 case CMD_PTR_CPU_XR_RETRY: 2004 cmd_xr_restore(hdl, cpu, cp); 2005 break; 2006 case CMD_PTR_CPU_IREG: 2007 cpu_case_restore(hdl, cpu, &cpu->cpu_ireg, cp, "ireg"); 2008 break; 2009 case CMD_PTR_CPU_FREG: 2010 cpu_case_restore(hdl, cpu, &cpu->cpu_freg, cp, "freg"); 2011 break; 2012 case CMD_PTR_CPU_MAU: 2013 cpu_case_restore(hdl, cpu, &cpu->cpu_mau, cp, "mau"); 2014 break; 2015 case CMD_PTR_CPU_L2CTL: 2016 cpu_case_restore(hdl, cpu, &cpu->cpu_l2ctl, cp, "l2ctl"); 2017 break; 2018 case CMD_PTR_CPU_MISC_REGS: 2019 cpu_case_restore(hdl, cpu, &cpu->cpu_misc_regs, cp, 2020 "misc_regs"); 2021 break; 2022 case CMD_PTR_CPU_LFU: 2023 cpu_case_restore(hdl, cpu, &cpu->cpu_lfu, cp, "lfu"); 2024 break; 2025#ifdef sun4u 2026 case CMD_PTR_CPU_INV_SFSR: 2027 cpu_case_restore(hdl, cpu, &cpu->cpu_opl_invsfsr, cp, 2028 "opl_invsfsr"); 2029 break; 2030 case CMD_PTR_CPU_UE_DET_CPU: 2031 cpu_case_restore(hdl, cpu, &cpu->cpu_oplue_detcpu, cp, 2032 "oplue_detcpu"); 2033 break; 2034 case CMD_PTR_CPU_UE_DET_IO: 2035 cpu_case_restore(hdl, cpu, &cpu->cpu_oplue_detio, cp, 2036 "oplue_detio"); 2037 break; 2038 case CMD_PTR_CPU_MTLB: 2039 cpu_case_restore(hdl, cpu, &cpu->cpu_opl_mtlb, cp, 2040 "opl_mtlb"); 2041 break; 2042 case CMD_PTR_CPU_TLBP: 2043 cpu_case_restore(hdl, cpu, &cpu->cpu_opl_tlbp, cp, 2044 "opl_tlbp"); 2045 break; 2046 case CMD_PTR_CPU_UGESR_INV_URG: 2047 cpu_case_restore(hdl, cpu, &cpu->cpu_opl_inv_urg, cp, 2048 "opl_inv_urg"); 2049 break; 2050 case CMD_PTR_CPU_UGESR_CRE: 2051 cpu_case_restore(hdl, cpu, &cpu->cpu_opl_cre, cp, 2052 "opl_cre"); 2053 break; 2054 case CMD_PTR_CPU_UGESR_TSB_CTX: 2055 cpu_case_restore(hdl, cpu, &cpu->cpu_opl_tsb_ctx, cp, 2056 "opl_tsb_ctx"); 2057 break; 2058 case CMD_PTR_CPU_UGESR_TSBP: 2059 cpu_case_restore(hdl, cpu, &cpu->cpu_opl_tsbp, cp, 2060 "opl_tsbp"); 2061 break; 2062 case CMD_PTR_CPU_UGESR_PSTATE: 2063 cpu_case_restore(hdl, cpu, &cpu->cpu_opl_pstate, cp, 2064 "opl_pstate"); 2065 break; 2066 case CMD_PTR_CPU_UGESR_TSTATE: 2067 cpu_case_restore(hdl, cpu, &cpu->cpu_opl_tstate, cp, 2068 "opl_tstate"); 2069 break; 2070 case CMD_PTR_CPU_UGESR_IUG_F: 2071 cpu_case_restore(hdl, cpu, &cpu->cpu_opl_iug_f, cp, 2072 "opl_iug_f"); 2073 break; 2074 case CMD_PTR_CPU_UGESR_IUG_R: 2075 cpu_case_restore(hdl, cpu, &cpu->cpu_opl_iug_r, cp, 2076 "opl_iug_r"); 2077 break; 2078 case CMD_PTR_CPU_UGESR_SDC: 2079 cpu_case_restore(hdl, cpu, &cpu->cpu_opl_sdc, cp, 2080 "opl_sdc"); 2081 break; 2082 case CMD_PTR_CPU_UGESR_WDT: 2083 cpu_case_restore(hdl, cpu, &cpu->cpu_opl_wdt, cp, 2084 "opl_wdt"); 2085 break; 2086 case CMD_PTR_CPU_UGESR_DTLB: 2087 cpu_case_restore(hdl, cpu, &cpu->cpu_opl_dtlb, cp, 2088 "opl_dtlb"); 2089 break; 2090 case CMD_PTR_CPU_UGESR_ITLB: 2091 cpu_case_restore(hdl, cpu, &cpu->cpu_opl_itlb, cp, 2092 "opl_itlb"); 2093 break; 2094 case CMD_PTR_CPU_UGESR_CORE_ERR: 2095 cpu_case_restore(hdl, cpu, &cpu->cpu_opl_core_err, cp, 2096 "opl_core_err"); 2097 break; 2098 case CMD_PTR_CPU_UGESR_DAE: 2099 cpu_case_restore(hdl, cpu, &cpu->cpu_opl_dae, cp, 2100 "opl_dae"); 2101 break; 2102 case CMD_PTR_CPU_UGESR_IAE: 2103 cpu_case_restore(hdl, cpu, &cpu->cpu_opl_iae, cp, 2104 "opl_iae"); 2105 break; 2106 case CMD_PTR_CPU_UGESR_UGE: 2107 cpu_case_restore(hdl, cpu, &cpu->cpu_opl_uge, cp, 2108 "opl_uge"); 2109 break; 2110#endif /* sun4u */ 2111 default: 2112 fmd_hdl_abort(hdl, "invalid %s subtype %d\n", 2113 ptr->ptr_name, ptr->ptr_subtype); 2114 } 2115 2116 return (cpu); 2117} 2118 2119void 2120cmd_cpu_validate(fmd_hdl_t *hdl) 2121{ 2122 cmd_xr_t *xr, *xrn; 2123 cmd_cpu_t *cpu, *cpun; 2124 2125 for (cpu = cmd_list_next(&cmd.cmd_cpus); cpu != NULL; 2126 cpu = cmd_list_next(cpu)) { 2127 if (cpu_all_threads_invalid(hdl, cpu) == FMD_B_TRUE) 2128 cpu->cpu_flags |= CMD_CPU_F_DELETING; 2129 } 2130 2131 for (xr = cmd_list_next(&cmd.cmd_xxcu_redelivs); xr != NULL; xr = xrn) { 2132 xrn = cmd_list_next(xr); 2133 2134 if (xr->xr_cpu->cpu_flags & CMD_CPU_F_DELETING) 2135 cmd_xr_destroy(hdl, xr); 2136 } 2137 2138 for (cpu = cmd_list_next(&cmd.cmd_cpus); cpu != NULL; cpu = cpun) { 2139 cpun = cmd_list_next(cpu); 2140 2141 if (cpu->cpu_flags & CMD_CPU_F_DELETING) 2142 cmd_cpu_destroy(hdl, cpu); 2143 } 2144} 2145 2146static void 2147cmd_xxcu_timeout(fmd_hdl_t *hdl, id_t id) 2148{ 2149 cmd_xr_t *xr; 2150 2151 for (xr = cmd_list_next(&cmd.cmd_xxcu_redelivs); xr != NULL; 2152 xr = cmd_list_next(xr)) { 2153 if (xr->xr_id == id) { 2154 fmd_event_t *ep = fmd_case_getprincipal(hdl, 2155 xr->xr_case); 2156 xr->xr_hdlr(hdl, xr, ep); 2157 cmd_xr_deref(hdl, xr); 2158 return; 2159 } 2160 } 2161} 2162 2163/*ARGSUSED*/ 2164static void 2165cmd_xxu_flush_timeout(fmd_hdl_t *hdl, id_t id) 2166{ 2167#ifdef sun4u 2168 cmd_cpu_t *cpu; 2169 2170 for (cpu = cmd_list_next(&cmd.cmd_cpus); cpu != NULL; 2171 cpu = cmd_list_next(cpu)) { 2172 if (cpu->cpu_uec_flush == id) { 2173 cpu_uec_flush_finish(hdl, cpu); 2174 return; 2175 } 2176 } 2177#else /* sun4u */ 2178 return; 2179#endif /* sun4u */ 2180} 2181 2182void 2183cmd_cpu_timeout(fmd_hdl_t *hdl, id_t id, void *type) 2184{ 2185 switch ((uintptr_t)type) { 2186 case (uintptr_t)CMD_TIMERTYPE_CPU_UEC_FLUSH: 2187 cmd_xxu_flush_timeout(hdl, id); 2188 break; 2189 case (uintptr_t)CMD_TIMERTYPE_CPU_XR_WAITER: 2190 cmd_xxcu_timeout(hdl, id); 2191 break; 2192 } 2193} 2194 2195static int 2196cpu_gc_keep_one(fmd_hdl_t *hdl, cmd_cpu_t *cpu) 2197{ 2198 int i; 2199 2200 if (cpu_all_threads_invalid(hdl, cpu) == FMD_B_TRUE) { 2201 fmd_hdl_debug(hdl, "GC of CPU %d: no longer working\n", 2202 cpu->cpu_cpuid); 2203 return (0); 2204 } 2205 2206 for (i = 0; i < sizeof (cmd_cpu_cases_t) / sizeof (cmd_case_t); i++) { 2207 cmd_case_t *cp = &((cmd_case_t *)&cpu->cpu_cases)[i]; 2208 2209 if (cp->cc_cp == NULL || cp->cc_serdnm == NULL) 2210 continue; 2211 2212 if (fmd_serd_exists(hdl, cp->cc_serdnm) && 2213 !fmd_serd_empty(hdl, cp->cc_serdnm)) 2214 return (1); 2215 } 2216 2217 if (cmd_list_next(&cpu->cpu_xxu_retries) != NULL) 2218 return (1); 2219 2220 if (cpu->cpu_uec.uec_cache != NULL || 2221 cpu->cpu_olduec.uec_cache != NULL) 2222 return (1); 2223 2224 return (0); 2225} 2226 2227/*ARGSUSED*/ 2228void 2229cmd_cpu_gc(fmd_hdl_t *hdl) 2230{ 2231 cmd_cpu_t *cpu, *next; 2232 2233 fmd_hdl_debug(hdl, "GC of CPUs\n"); 2234 2235 for (cpu = cmd_list_next(&cmd.cmd_cpus); cpu != NULL; cpu = next) { 2236 next = cmd_list_next(cpu); 2237 2238 if (!cpu_gc_keep_one(hdl, cpu)) { 2239 fmd_hdl_debug(hdl, "GC of CPU %d: destroying\n", 2240 cpu->cpu_cpuid); 2241 continue; 2242 } 2243#ifdef sun4u 2244 if (cpu->cpu_uec.uec_cache != NULL) 2245 cpu_uec_flush(hdl, cpu); 2246#endif /* sun4u */ 2247 cpu->cpu_uec_nflushes = 0; 2248 } 2249} 2250 2251void 2252cmd_cpu_fini(fmd_hdl_t *hdl) 2253{ 2254 cmd_cpu_t *cpu; 2255 2256 while ((cpu = cmd_list_next(&cmd.cmd_cpus)) != NULL) 2257 cmd_cpu_free(hdl, cpu, FMD_B_FALSE); 2258} 2259 2260typedef struct { 2261 const char *fam_name; 2262 cpu_family_t fam_value; 2263} famdata_t; 2264 2265static famdata_t famdata_tbl[] = { 2266 {"UltraSPARC-III", CMD_CPU_FAM_CHEETAH}, 2267 {"UltraSPARC-IV", CMD_CPU_FAM_CHEETAH}, 2268 {"UltraSPARC-T", CMD_CPU_FAM_NIAGARA}, 2269 {"SPARC64-VI", CMD_CPU_FAM_SPARC64} 2270}; 2271 2272cpu_family_t 2273cpu_family(char *knsp) 2274{ 2275 int j; 2276 2277 for (j = 0; j < sizeof (famdata_tbl)/sizeof (famdata_t); j++) { 2278 if (strncmp(knsp, famdata_tbl[j].fam_name, 2279 strlen(famdata_tbl[j].fam_name)) == 0) { 2280 return (famdata_tbl[j].fam_value); 2281 } 2282 } 2283 return (CMD_CPU_FAM_UNSUPPORTED); 2284} 2285 2286/* 2287 * Determine which CPU family this diagnosis is being run on. 2288 * This assumes that ereports are being generated by this system. 2289 */ 2290 2291cpu_family_t 2292cmd_cpu_check_support(void) 2293{ 2294 kstat_named_t *kn; 2295 kstat_ctl_t *kc; 2296 kstat_t *ksp; 2297 int i; 2298 2299 if ((kc = kstat_open()) == NULL) 2300 return (CMD_CPU_FAM_UNSUPPORTED); 2301 2302 for (ksp = kc->kc_chain; ksp != NULL; ksp = ksp->ks_next) { 2303 if (strcmp(ksp->ks_module, "cpu_info") != 0) 2304 continue; 2305 2306 if (kstat_read(kc, ksp, NULL) == -1) { 2307 (void) kstat_close(kc); 2308 return (CMD_CPU_FAM_UNSUPPORTED); 2309 } 2310 2311 for (kn = ksp->ks_data, i = 0; i < ksp->ks_ndata; i++, kn++) { 2312 cpu_family_t family; 2313 if (strcmp(kn->name, "implementation") != 0) 2314 continue; 2315 family = cpu_family(KSTAT_NAMED_STR_PTR(kn)); 2316 (void) kstat_close(kc); 2317 return (family); 2318 } 2319 } 2320 (void) kstat_close(kc); 2321 return (CMD_CPU_FAM_UNSUPPORTED); 2322} 2323 2324boolean_t 2325cmd_cpu_ecache_support(void) 2326{ 2327 cpu_family_t value; 2328 2329 value = cmd_cpu_check_support(); 2330 return (fam_info_tbl[value].ecache_flush_needed); 2331} 2332 2333/* 2334 * This function builds the fmri of the 2335 * given cpuid based on the cpu scheme. 2336 */ 2337nvlist_t * 2338cmd_cpu_fmri_create(uint32_t cpuid, uint8_t cpumask) 2339{ 2340 nvlist_t *fmri; 2341 2342 if ((errno = nvlist_alloc(&fmri, NV_UNIQUE_NAME, 0)) != 0) 2343 return (NULL); 2344 2345 if (nvlist_add_uint8(fmri, FM_VERSION, 2346 FM_CPU_SCHEME_VERSION) != 0 || nvlist_add_string(fmri, 2347 FM_FMRI_SCHEME, FM_FMRI_SCHEME_CPU) != 0 || 2348 nvlist_add_uint32(fmri, FM_FMRI_CPU_ID, cpuid) != 0 || 2349 nvlist_add_uint8(fmri, FM_FMRI_CPU_MASK, cpumask) != 0) { 2350 nvlist_free(fmri); 2351 return (NULL); 2352 } 2353 2354 return (fmri); 2355} 2356