dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / cmd / fm / modules / sun4 / cpumem-diagnosis / cmd_cpu.c
blobb06532a7f3f449de5e2281c00f305a458be450d1
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
27 * Support routines for managing per-CPU state.
30 #include <cmd_cpu.h>
32 #ifdef sun4u
33 #include <cmd_ecache.h>
34 #endif /* sun4u */
36 #include <cmd_mem.h>
37 #include <cmd.h>
39 #include <stdio.h>
40 #include <string.h>
41 #include <strings.h>
42 #include <errno.h>
43 #include <kstat.h>
44 #include <fm/fmd_api.h>
45 #include <sys/async.h>
46 #include <sys/fm/protocol.h>
48 #ifdef sun4u
49 #include <sys/cheetahregs.h>
50 #include <sys/fm/cpu/UltraSPARC-III.h>
51 #include <cmd_opl.h>
52 #include <cmd_Lxcache.h>
53 #else /* sun4u */
54 #include <sys/niagararegs.h>
55 #include <sys/fm/cpu/UltraSPARC-T1.h>
56 #include <cmd_hc_sun4v.h>
57 #endif /* sun4u */
59 #define CMD_CPU_UEC_INCR 10
61 /* Must be in sync with cmd_cpu_type_t */
62 static const char *const cpu_names[] = {
63 NULL,
64 "ultraSPARC-III",
65 "ultraSPARC-IIIplus",
66 "ultraSPARC-IIIi",
67 "ultraSPARC-IV",
68 "ultraSPARC-IVplus",
69 "ultraSPARC-IIIiplus",
70 "ultraSPARC-T1",
71 "SPARC64-VI",
72 "SPARC64-VII",
73 "ultraSPARC-T2",
74 "ultraSPARC-T2plus"
78 * This needs to be in sync with cpu_family_t.
80 static 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 }
87 static cmd_cpu_t *cpu_lookup_by_cpuid(uint32_t, uint8_t);
88 static cmd_cpu_t *cpu_create(fmd_hdl_t *, nvlist_t *, uint32_t,
89 uint8_t, cmd_cpu_type_t);
90 static void cpu_buf_write(fmd_hdl_t *, cmd_cpu_t *);
92 const char *
93 cmd_cpu_type2name(fmd_hdl_t *hdl, cmd_cpu_type_t type)
95 if (type < 1 || type > sizeof (cpu_names) / sizeof (char *))
96 fmd_hdl_abort(hdl, "illegal CPU type %d\n", type);
98 return (cpu_names[type]);
101 static cmd_cpu_type_t
102 cpu_nname2type(fmd_hdl_t *hdl, const char *name, size_t n)
104 int i;
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);
112 fmd_hdl_abort(hdl, "illegal CPU name %*.*s\n", n, n, name);
113 /*NOTREACHED*/
114 return (0);
117 const 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)
123 static void
124 core2cpus(uint32_t core, cmd_cpu_type_t type, uint8_t level,
125 uint32_t *cpuinit, uint32_t *cpufinal, uint32_t *cpustep)
127 switch (type) {
128 #ifdef sun4u
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
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;
154 #else /* i.e. sun4v */
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
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;
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;
201 #endif /* sun4u */
202 default:
203 *cpuinit = *cpufinal = core;
204 *cpustep = 1;
205 return;
209 uint32_t
210 cmd_cpu2core(uint32_t cpuid, cmd_cpu_type_t type, uint8_t level) {
212 switch (type) {
213 #ifdef sun4u
215 #define US4P_SCAT_CORE_SYSBD_STEP 32
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);
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);
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);
253 #endif /* sun4u */
254 default:
255 return (cpuid);
259 #ifdef sun4u
260 static void
261 cpu_uec_write(fmd_hdl_t *hdl, cmd_cpu_t *cpu, cmd_cpu_uec_t *uec)
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.
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);
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);
277 cpu_buf_write(hdl, cpu);
280 static void
281 cpu_uec_create(fmd_hdl_t *hdl, cmd_cpu_t *cpu, cmd_cpu_uec_t *uec,
282 const char *fmt, ...)
284 va_list ap;
286 va_start(ap, fmt);
287 cmd_vbufname(uec->uec_bufname, sizeof (uec->uec_bufname), fmt, ap);
288 va_end(ap);
290 cpu_uec_write(hdl, cpu, uec);
293 static void
294 cpu_uec_restore(fmd_hdl_t *hdl, cmd_cpu_uec_t *uec)
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);
302 static void
303 cpu_uec_free(fmd_hdl_t *hdl, cmd_cpu_uec_t *uec, int destroy)
305 if (uec->uec_cache == NULL)
306 return;
308 if (destroy)
309 fmd_buf_destroy(hdl, NULL, uec->uec_bufname);
311 fmd_hdl_free(hdl, uec->uec_cache, sizeof (uint64_t) * uec->uec_nent);
314 static void
315 cpu_uec_flush_finish(fmd_hdl_t *hdl, cmd_cpu_t *cpu)
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);
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);
328 cpu->cpu_uec_flush = 0;
329 cpu_buf_write(hdl, cpu);
332 static void
333 cpu_uec_flush(fmd_hdl_t *hdl, cmd_cpu_t *cpu)
335 if (cpu->cpu_uec.uec_cache == NULL && !cpu->cpu_uec.uec_flags)
336 return; /* nothing to flush */
338 fmd_hdl_debug(hdl, "flushing UE cache for CPU %d\n", cpu->cpu_cpuid);
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$ */
346 if (cpu->cpu_olduec.uec_cache != NULL) {
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.
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);
356 bcopy(cpu->cpu_olduec.uec_cache, new,
357 sizeof (uint64_t) * 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);
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);
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;
374 cpu_uec_write(hdl, cpu, &cpu->cpu_olduec);
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);
381 if (cpu->cpu_uec_flush != 0)
382 fmd_timer_remove(hdl, cpu->cpu_uec_flush);
384 cpu->cpu_uec_flush = fmd_timer_install(hdl,
385 (void *)CMD_TIMERTYPE_CPU_UEC_FLUSH, NULL, NANOSEC);
386 cpu_buf_write(hdl, cpu);
389 void
390 cmd_cpu_uec_add(fmd_hdl_t *hdl, cmd_cpu_t *cpu, uint64_t pa)
392 cmd_cpu_uec_t *uec = &cpu->cpu_uec;
393 uint64_t *new, *tgt = NULL;
394 int i;
396 pa = pa & cmd.cmd_pagemask;
398 fmd_hdl_debug(hdl, "adding 0x%llx to CPU %d's UE cache\n",
399 (u_longlong_t)pa, cpu->cpu_cpuid);
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];
406 if (uec->uec_cache[i] == pa)
407 return; /* already there */
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);
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);
423 uec->uec_cache = new;
424 tgt = &uec->uec_cache[uec->uec_nent];
425 uec->uec_nent += CMD_CPU_UEC_INCR;
428 *tgt = pa;
429 cpu_uec_write(hdl, cpu, uec);
432 void
433 cmd_cpu_uec_set_allmatch(fmd_hdl_t *hdl, cmd_cpu_t *cpu)
435 fmd_hdl_debug(hdl, "setting cpu %d's uec to allmatch\n",
436 cpu->cpu_cpuid);
438 cpu->cpu_uec.uec_flags |= CPU_UEC_F_ALLMATCH;
439 cpu_uec_write(hdl, cpu, &cpu->cpu_uec);
441 if (++cpu->cpu_uec_nflushes <= CPU_UEC_FLUSH_MAX)
442 cpu_uec_flush(hdl, cpu);
446 cmd_cpu_uec_match(cmd_cpu_t *cpu, uint64_t pa)
448 int i;
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.
457 if ((cpu->cpu_uec.uec_flags & CPU_UEC_F_ALLMATCH) ||
458 (cpu->cpu_olduec.uec_flags & CPU_UEC_F_ALLMATCH))
459 return (1);
461 pa = pa & cmd.cmd_pagemask;
463 for (i = 0; i < cpu->cpu_uec.uec_nent; i++) {
464 if (cpu->cpu_uec.uec_cache[i] == pa)
465 return (1);
468 for (i = 0; i < cpu->cpu_olduec.uec_nent; i++) {
469 if (cpu->cpu_olduec.uec_cache[i] == pa)
470 return (1);
473 return (0);
475 #endif /* sun4u */
477 void
478 cmd_xr_write(fmd_hdl_t *hdl, cmd_xr_t *xr)
480 fmd_hdl_debug(hdl, "writing redelivery clcode %llx for case %s\n",
481 xr->xr_clcode, fmd_case_uuid(hdl, xr->xr_case));
483 fmd_buf_write(hdl, xr->xr_case, "redelivery", xr,
484 sizeof (cmd_xr_t));
487 static cmd_xr_hdlr_f *
488 cmd_xr_id2hdlr(fmd_hdl_t *hdl, uint_t id)
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 case CMD_XR_HDLR_NOP:
496 return (cmd_nop_resolve);
497 default:
498 fmd_hdl_abort(hdl, "cmd_xr_id2hdlr called with bad hdlrid %x\n",
499 id);
502 return (NULL);
505 cmd_xr_t *
506 cmd_xr_create(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl,
507 cmd_cpu_t *cpu, cmd_errcl_t clcode)
509 cmd_xr_t *xr = fmd_hdl_zalloc(hdl, sizeof (cmd_xr_t),
510 FMD_SLEEP);
511 nvlist_t *rsrc = NULL;
512 const char *uuid;
513 int err = 0;
515 err |= nvlist_lookup_uint64(nvl, FM_EREPORT_ENA, &xr->xr_ena);
517 err |= cmd_xr_fill(hdl, nvl, xr, clcode);
518 #ifdef sun4u
519 err |= cmd_xr_pn_cache_fill(hdl, nvl, xr, cpu, clcode);
520 #endif
521 (void) nvlist_lookup_nvlist(nvl, FM_EREPORT_PAYLOAD_NAME_RESOURCE,
522 &rsrc);
524 if (err != 0) {
525 fmd_hdl_free(hdl, xr, sizeof (cmd_xr_t));
526 return (NULL);
529 xr->xr_cpu = cpu;
530 xr->xr_cpuid = cpu->cpu_cpuid;
531 xr->xr_clcode = clcode;
532 xr->xr_case = cmd_case_create(hdl, &cpu->cpu_header,
533 CMD_PTR_CPU_XR_RETRY, &uuid);
534 fmd_case_setprincipal(hdl, xr->xr_case, ep);
536 if (rsrc != NULL) {
537 cmd_fmri_init(hdl, &xr->xr_rsrc, rsrc, "%s_rsrc",
538 fmd_case_uuid(hdl, xr->xr_case));
541 cmd_xr_write(hdl, xr);
542 return (xr);
545 cmd_evdisp_t
546 cmd_xr_reschedule(fmd_hdl_t *hdl, cmd_xr_t *xr, uint_t hdlrid)
549 fmd_hdl_debug(hdl, "scheduling redelivery of %llx with xr %p\n",
550 xr->xr_clcode, xr);
552 xr->xr_hdlrid = hdlrid;
553 xr->xr_hdlr = cmd_xr_id2hdlr(hdl, hdlrid);
555 xr->xr_id = fmd_timer_install(hdl, (void *)CMD_TIMERTYPE_CPU_XR_WAITER,
556 NULL, cmd.cmd_xxcu_trdelay);
558 if (xr->xr_ref++ == 0)
559 cmd_list_append(&cmd.cmd_xxcu_redelivs, xr);
561 cmd_xr_write(hdl, xr);
562 return (CMD_EVD_OK);
565 static void
566 cmd_xr_destroy(fmd_hdl_t *hdl, cmd_xr_t *xr)
568 fmd_hdl_debug(hdl, "destroying xr (clcode %llx) at %p\n",
569 xr->xr_clcode, xr);
571 fmd_case_reset(hdl, xr->xr_case);
572 cmd_case_fini(hdl, xr->xr_case, FMD_B_TRUE);
574 if (xr->xr_rsrc_nvl != NULL)
575 cmd_fmri_fini(hdl, &xr->xr_rsrc, FMD_B_TRUE);
577 fmd_buf_destroy(hdl, xr->xr_case, "redelivery");
578 fmd_hdl_free(hdl, xr, sizeof (cmd_xr_t));
581 void
582 cmd_xr_deref(fmd_hdl_t *hdl, cmd_xr_t *xr)
584 if (xr->xr_ref == 0)
585 fmd_hdl_abort(hdl, "attempt to deref xr with zero ref\n");
587 fmd_hdl_debug(hdl, "deref xr %p [%d]\n", xr, xr->xr_ref);
589 if (--xr->xr_ref == 0) {
590 cmd_list_delete(&cmd.cmd_xxcu_redelivs, xr);
591 cmd_xr_destroy(hdl, xr);
595 static void
596 cmd_xr_restore(fmd_hdl_t *hdl, cmd_cpu_t *cpu, fmd_case_t *cp)
598 cmd_xr_t *xr;
600 if ((xr = cmd_buf_read(hdl, cp, "redelivery", sizeof (cmd_xr_t))) ==
601 NULL) {
602 fmd_hdl_abort(hdl, "failed to find redelivery for case %s\n",
603 fmd_case_uuid(hdl, cp));
606 xr->xr_case = cp;
607 xr->xr_hdlr = cmd_xr_id2hdlr(hdl, xr->xr_hdlrid);
608 if (xr->xr_rsrc_nvl != NULL)
609 cmd_fmri_restore(hdl, &xr->xr_rsrc);
610 xr->xr_cpu = cpu;
613 * fmd is still in the process of starting up. If we reschedule this
614 * event with the normal redelivery timeout, it'll get redelivered
615 * before initialization has completed, we'll potentially fail to
616 * match the train, deref() the waiter (causing any subsequent side-
617 * effects to miss the waiter), and use this ereport to blame the CPU.
618 * The other side-effects will blame the CPU too, since we'll have
619 * deref()'d the waiter out of existence. We can get up to three
620 * additions to the SERD engine this way, which is bad. To keep that
621 * from happening, we're going to schedule an arbitrarily long timeout,
622 * which *should* be long enough. It's pretty bad, but there's no
623 * real way to keep the other side-effects from taking out the CPU.
625 xr->xr_id = fmd_timer_install(hdl, (void *)CMD_TIMERTYPE_CPU_XR_WAITER,
626 NULL, fmd_prop_get_int64(hdl, "xxcu_restart_delay"));
628 cmd_list_append(&cmd.cmd_xxcu_redelivs, xr);
630 fmd_hdl_debug(hdl, "revived xr for class %llx\n", xr->xr_clcode);
633 typedef struct cmd_xxcu_train {
634 cmd_errcl_t tr_mask; /* errors we must see to match this train */
635 cmd_errcl_t tr_cause; /* the error at the root of this train */
636 } cmd_xxcu_train_t;
638 #define CMD_TRAIN(cause, side_effects) { (cause) | (side_effects), (cause) }
640 static const cmd_xxcu_train_t cmd_xxcu_trains[] = {
641 #ifdef sun4u
642 /* UCC: WDC */
643 CMD_TRAIN(CMD_ERRCL_UCC, CMD_ERRCL_WDC),
645 /* UCU: WDU, WDU+L3_WDU */
646 CMD_TRAIN(CMD_ERRCL_UCU, CMD_ERRCL_WDU),
647 CMD_TRAIN(CMD_ERRCL_UCU, CMD_ERRCL_L3_WDU | CMD_ERRCL_WDU),
649 /* EDC: WDC */
650 CMD_TRAIN(CMD_ERRCL_EDC, CMD_ERRCL_WDC),
652 /* EDU: WDU, WDU+L3_WDU */
653 CMD_TRAIN(CMD_ERRCL_EDU_ST, CMD_ERRCL_WDU),
654 CMD_TRAIN(CMD_ERRCL_EDU_BL, CMD_ERRCL_WDU),
655 CMD_TRAIN(CMD_ERRCL_EDU_ST, CMD_ERRCL_L3_WDU | CMD_ERRCL_WDU),
656 CMD_TRAIN(CMD_ERRCL_EDU_BL, CMD_ERRCL_L3_WDU | CMD_ERRCL_WDU),
658 /* CPC: WDC, EDC+WDC, UCC+WDC, EDC+UCC+WDC */
659 CMD_TRAIN(CMD_ERRCL_CPC, CMD_ERRCL_WDC),
660 CMD_TRAIN(CMD_ERRCL_CPC, CMD_ERRCL_EDC | CMD_ERRCL_WDC),
661 CMD_TRAIN(CMD_ERRCL_CPC, CMD_ERRCL_UCC | CMD_ERRCL_WDC),
662 CMD_TRAIN(CMD_ERRCL_CPC, CMD_ERRCL_EDC | CMD_ERRCL_UCC |
663 CMD_ERRCL_WDC),
665 /* CPU: WDU, WDU+L3_WDU, UCU+WDU, UCU+WDU+L3_WDU */
666 CMD_TRAIN(CMD_ERRCL_CPU, CMD_ERRCL_WDU),
667 CMD_TRAIN(CMD_ERRCL_CPU, CMD_ERRCL_L3_WDU | CMD_ERRCL_WDU),
668 CMD_TRAIN(CMD_ERRCL_CPU, CMD_ERRCL_UCU | CMD_ERRCL_WDU),
669 CMD_TRAIN(CMD_ERRCL_CPU, CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU |
670 CMD_ERRCL_WDU),
672 /* CPU: EDU+WDU, EDU+WDU+L3_WDU, EDU+UCU+WDU, EDU+UCU+WDU+L3_WDU */
673 CMD_TRAIN(CMD_ERRCL_CPU, CMD_ERRCL_EDU_ST | CMD_ERRCL_WDU),
674 CMD_TRAIN(CMD_ERRCL_CPU, CMD_ERRCL_EDU_BL | CMD_ERRCL_WDU),
675 CMD_TRAIN(CMD_ERRCL_CPU, CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL |
676 CMD_ERRCL_WDU),
677 CMD_TRAIN(CMD_ERRCL_CPU, CMD_ERRCL_EDU_ST | CMD_ERRCL_WDU |
678 CMD_ERRCL_L3_WDU),
679 CMD_TRAIN(CMD_ERRCL_CPU, CMD_ERRCL_EDU_BL | CMD_ERRCL_WDU |
680 CMD_ERRCL_L3_WDU),
681 CMD_TRAIN(CMD_ERRCL_CPU, CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL |
682 CMD_ERRCL_WDU | CMD_ERRCL_L3_WDU),
683 CMD_TRAIN(CMD_ERRCL_CPU, CMD_ERRCL_EDU_ST | CMD_ERRCL_UCU |
684 CMD_ERRCL_WDU),
685 CMD_TRAIN(CMD_ERRCL_CPU, CMD_ERRCL_EDU_BL | CMD_ERRCL_UCU |
686 CMD_ERRCL_WDU),
687 CMD_TRAIN(CMD_ERRCL_CPU, CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL |
688 CMD_ERRCL_UCU | CMD_ERRCL_WDU),
689 CMD_TRAIN(CMD_ERRCL_CPU, CMD_ERRCL_EDU_ST | CMD_ERRCL_UCU |
690 CMD_ERRCL_WDU | CMD_ERRCL_L3_WDU),
691 CMD_TRAIN(CMD_ERRCL_CPU, CMD_ERRCL_EDU_BL | CMD_ERRCL_UCU |
692 CMD_ERRCL_WDU | CMD_ERRCL_L3_WDU),
693 CMD_TRAIN(CMD_ERRCL_CPU, CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL |
694 CMD_ERRCL_UCU | CMD_ERRCL_WDU | CMD_ERRCL_L3_WDU),
696 /* WDU: L3_WDU */
697 CMD_TRAIN(CMD_ERRCL_WDU, CMD_ERRCL_L3_WDU),
699 /* L3_UCC: WDC+(zero or more of EDC, CPC, UCC) */
700 CMD_TRAIN(CMD_ERRCL_L3_UCC, CMD_ERRCL_WDC),
701 CMD_TRAIN(CMD_ERRCL_L3_UCC, CMD_ERRCL_WDC | CMD_ERRCL_EDC),
702 CMD_TRAIN(CMD_ERRCL_L3_UCC, CMD_ERRCL_WDC | CMD_ERRCL_CPC),
703 CMD_TRAIN(CMD_ERRCL_L3_UCC, CMD_ERRCL_WDC | CMD_ERRCL_UCC),
704 CMD_TRAIN(CMD_ERRCL_L3_UCC, CMD_ERRCL_WDC | CMD_ERRCL_EDC |
705 CMD_ERRCL_CPC),
706 CMD_TRAIN(CMD_ERRCL_L3_UCC, CMD_ERRCL_WDC | CMD_ERRCL_EDC |
707 CMD_ERRCL_UCC),
708 CMD_TRAIN(CMD_ERRCL_L3_UCC, CMD_ERRCL_WDC | CMD_ERRCL_CPC |
709 CMD_ERRCL_UCC),
710 CMD_TRAIN(CMD_ERRCL_L3_UCC, CMD_ERRCL_WDC | CMD_ERRCL_EDC |
711 CMD_ERRCL_CPC | CMD_ERRCL_UCC),
713 /* L3_UCU: WDU+(zero or more of EDU, CPU, UCU) */
714 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU),
715 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST),
716 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL),
717 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
718 CMD_ERRCL_EDU_BL),
719 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_CPU),
720 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_UCU),
721 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
722 CMD_ERRCL_CPU),
723 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL |
724 CMD_ERRCL_CPU),
725 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
726 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU),
727 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
728 CMD_ERRCL_UCU),
729 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL |
730 CMD_ERRCL_UCU),
731 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
732 CMD_ERRCL_EDU_BL | CMD_ERRCL_UCU),
733 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_CPU |
734 CMD_ERRCL_UCU),
735 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
736 CMD_ERRCL_CPU | CMD_ERRCL_UCU),
737 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL |
738 CMD_ERRCL_CPU | CMD_ERRCL_UCU),
739 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
740 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | CMD_ERRCL_UCU),
742 /* L3_UCU: WDU+(zero or more of EDU, CPU, UCU)+L3_WDU */
743 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_L3_WDU),
744 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
745 CMD_ERRCL_L3_WDU),
746 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL |
747 CMD_ERRCL_L3_WDU),
748 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
749 CMD_ERRCL_EDU_BL | CMD_ERRCL_L3_WDU),
750 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_CPU |
751 CMD_ERRCL_L3_WDU),
752 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_UCU |
753 CMD_ERRCL_L3_WDU),
754 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
755 CMD_ERRCL_CPU | CMD_ERRCL_L3_WDU),
756 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL |
757 CMD_ERRCL_CPU | CMD_ERRCL_L3_WDU),
758 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
759 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | CMD_ERRCL_L3_WDU),
760 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
761 CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU),
762 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL |
763 CMD_ERRCL_UCU | 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_UCU | CMD_ERRCL_L3_WDU),
766 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_CPU |
767 CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU),
768 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
769 CMD_ERRCL_CPU | CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU),
770 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL |
771 CMD_ERRCL_CPU | CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU),
772 CMD_TRAIN(CMD_ERRCL_L3_UCU, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
773 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | CMD_ERRCL_UCU |
774 CMD_ERRCL_L3_WDU),
776 /* L3_EDC: WDC+(zero or more of EDC, CPC, UCC) */
777 CMD_TRAIN(CMD_ERRCL_L3_EDC, CMD_ERRCL_WDC),
778 CMD_TRAIN(CMD_ERRCL_L3_EDC, CMD_ERRCL_WDC | CMD_ERRCL_EDC),
779 CMD_TRAIN(CMD_ERRCL_L3_EDC, CMD_ERRCL_WDC | CMD_ERRCL_CPC),
780 CMD_TRAIN(CMD_ERRCL_L3_EDC, CMD_ERRCL_WDC | CMD_ERRCL_UCC),
781 CMD_TRAIN(CMD_ERRCL_L3_EDC, CMD_ERRCL_WDC | CMD_ERRCL_EDC |
782 CMD_ERRCL_CPC),
783 CMD_TRAIN(CMD_ERRCL_L3_EDC, CMD_ERRCL_WDC | CMD_ERRCL_EDC |
784 CMD_ERRCL_UCC),
785 CMD_TRAIN(CMD_ERRCL_L3_EDC, CMD_ERRCL_WDC | CMD_ERRCL_CPC |
786 CMD_ERRCL_UCC),
787 CMD_TRAIN(CMD_ERRCL_L3_EDC, CMD_ERRCL_WDC | CMD_ERRCL_EDC |
788 CMD_ERRCL_CPC | CMD_ERRCL_UCC),
790 /* L3_EDU: WDU+(zero or more of EDU, CPU, UCU) */
791 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU),
792 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST),
793 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL),
794 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
795 CMD_ERRCL_EDU_BL),
796 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_CPU),
797 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_UCU),
798 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
799 CMD_ERRCL_CPU),
800 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL |
801 CMD_ERRCL_CPU),
802 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
803 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU),
804 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
805 CMD_ERRCL_UCU),
806 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL |
807 CMD_ERRCL_UCU),
808 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
809 CMD_ERRCL_EDU_BL | CMD_ERRCL_UCU),
810 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_CPU |
811 CMD_ERRCL_UCU),
812 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
813 CMD_ERRCL_CPU | CMD_ERRCL_UCU),
814 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL |
815 CMD_ERRCL_CPU | CMD_ERRCL_UCU),
816 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
817 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | CMD_ERRCL_UCU),
818 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU),
819 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST),
820 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL),
821 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
822 CMD_ERRCL_EDU_BL),
823 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_CPU),
824 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_UCU),
825 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
826 CMD_ERRCL_CPU),
827 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL |
828 CMD_ERRCL_CPU),
829 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
830 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU),
831 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
832 CMD_ERRCL_UCU),
833 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL |
834 CMD_ERRCL_UCU),
835 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
836 CMD_ERRCL_EDU_BL | CMD_ERRCL_UCU),
837 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_CPU |
838 CMD_ERRCL_UCU),
839 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
840 CMD_ERRCL_CPU | CMD_ERRCL_UCU),
841 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL |
842 CMD_ERRCL_CPU | CMD_ERRCL_UCU),
843 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
844 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | CMD_ERRCL_UCU),
846 /* L3_EDU: WDU+(zero or more of EDU, CPU, UCU)+L3_WDU */
847 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_L3_WDU),
848 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
849 CMD_ERRCL_L3_WDU),
850 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL |
851 CMD_ERRCL_L3_WDU),
852 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
853 CMD_ERRCL_EDU_BL | CMD_ERRCL_L3_WDU),
854 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_CPU |
855 CMD_ERRCL_L3_WDU),
856 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_UCU |
857 CMD_ERRCL_L3_WDU),
858 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
859 CMD_ERRCL_CPU | CMD_ERRCL_L3_WDU),
860 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL |
861 CMD_ERRCL_CPU | CMD_ERRCL_L3_WDU),
862 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
863 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | CMD_ERRCL_L3_WDU),
864 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
865 CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU),
866 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL |
867 CMD_ERRCL_UCU | 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_UCU | CMD_ERRCL_L3_WDU),
870 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_CPU |
871 CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU),
872 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
873 CMD_ERRCL_CPU | CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU),
874 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL |
875 CMD_ERRCL_CPU | CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU),
876 CMD_TRAIN(CMD_ERRCL_L3_EDU_ST, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
877 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | CMD_ERRCL_UCU |
878 CMD_ERRCL_L3_WDU),
879 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_L3_WDU),
880 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
881 CMD_ERRCL_L3_WDU),
882 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL |
883 CMD_ERRCL_L3_WDU),
884 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
885 CMD_ERRCL_EDU_BL | CMD_ERRCL_L3_WDU),
886 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_CPU |
887 CMD_ERRCL_L3_WDU),
888 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_UCU |
889 CMD_ERRCL_L3_WDU),
890 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
891 CMD_ERRCL_CPU | CMD_ERRCL_L3_WDU),
892 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL |
893 CMD_ERRCL_CPU | CMD_ERRCL_L3_WDU),
894 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
895 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | CMD_ERRCL_L3_WDU),
896 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
897 CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU),
898 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL |
899 CMD_ERRCL_UCU | 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_UCU | CMD_ERRCL_L3_WDU),
902 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_CPU |
903 CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU),
904 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
905 CMD_ERRCL_CPU | CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU),
906 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL |
907 CMD_ERRCL_CPU | CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU),
908 CMD_TRAIN(CMD_ERRCL_L3_EDU_BL, CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
909 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | CMD_ERRCL_UCU |
910 CMD_ERRCL_L3_WDU),
912 /* L3_CPC: L3_WDC */
913 CMD_TRAIN(CMD_ERRCL_L3_CPC, CMD_ERRCL_L3_WDC),
915 /* L3_CPC: L3_EDC+ WDC+(zero or more of EDC, CPC, UCC) */
916 CMD_TRAIN(CMD_ERRCL_L3_CPC, CMD_ERRCL_L3_EDC | CMD_ERRCL_WDC),
917 CMD_TRAIN(CMD_ERRCL_L3_CPC, CMD_ERRCL_L3_EDC | CMD_ERRCL_WDC |
918 CMD_ERRCL_EDC),
919 CMD_TRAIN(CMD_ERRCL_L3_CPC, CMD_ERRCL_L3_EDC | CMD_ERRCL_WDC |
920 CMD_ERRCL_CPC),
921 CMD_TRAIN(CMD_ERRCL_L3_CPC, CMD_ERRCL_L3_EDC | CMD_ERRCL_WDC |
922 CMD_ERRCL_UCC),
923 CMD_TRAIN(CMD_ERRCL_L3_CPC, CMD_ERRCL_L3_EDC | CMD_ERRCL_WDC |
924 CMD_ERRCL_EDC | CMD_ERRCL_CPC),
925 CMD_TRAIN(CMD_ERRCL_L3_CPC, CMD_ERRCL_L3_EDC | CMD_ERRCL_WDC |
926 CMD_ERRCL_EDC | CMD_ERRCL_UCC),
927 CMD_TRAIN(CMD_ERRCL_L3_CPC, CMD_ERRCL_L3_EDC | CMD_ERRCL_WDC |
928 CMD_ERRCL_CPC | CMD_ERRCL_UCC),
929 CMD_TRAIN(CMD_ERRCL_L3_CPC, CMD_ERRCL_L3_EDC | CMD_ERRCL_WDC |
930 CMD_ERRCL_EDC | CMD_ERRCL_CPC | CMD_ERRCL_UCC),
932 /* L3_CPC: L3_UCC+WDC+(zero or more of EDC, CPC, UCC) */
933 CMD_TRAIN(CMD_ERRCL_L3_CPC, CMD_ERRCL_L3_UCC | CMD_ERRCL_WDC),
934 CMD_TRAIN(CMD_ERRCL_L3_CPC, CMD_ERRCL_L3_UCC | CMD_ERRCL_WDC |
935 CMD_ERRCL_EDC),
936 CMD_TRAIN(CMD_ERRCL_L3_CPC, CMD_ERRCL_L3_UCC | CMD_ERRCL_WDC |
937 CMD_ERRCL_CPC),
938 CMD_TRAIN(CMD_ERRCL_L3_CPC, CMD_ERRCL_L3_UCC | CMD_ERRCL_WDC |
939 CMD_ERRCL_UCC),
940 CMD_TRAIN(CMD_ERRCL_L3_CPC, CMD_ERRCL_L3_UCC | CMD_ERRCL_WDC |
941 CMD_ERRCL_EDC | CMD_ERRCL_CPC),
942 CMD_TRAIN(CMD_ERRCL_L3_CPC, CMD_ERRCL_L3_UCC | CMD_ERRCL_WDC |
943 CMD_ERRCL_EDC | CMD_ERRCL_UCC),
944 CMD_TRAIN(CMD_ERRCL_L3_CPC, CMD_ERRCL_L3_UCC | CMD_ERRCL_WDC |
945 CMD_ERRCL_CPC | CMD_ERRCL_UCC),
946 CMD_TRAIN(CMD_ERRCL_L3_CPC, CMD_ERRCL_L3_UCC | CMD_ERRCL_WDC |
947 CMD_ERRCL_EDC | CMD_ERRCL_CPC | CMD_ERRCL_UCC),
949 /* L3_CPU: L3_WDU */
950 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_WDU),
952 /* L3_CPU: L3_EDU+WDU+(zero or more of EDU, CPU, UCU) */
953 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU),
954 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU),
955 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST |
956 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU),
957 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU |
958 CMD_ERRCL_EDU_ST),
959 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU |
960 CMD_ERRCL_EDU_ST),
961 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST |
962 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST),
963 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU |
964 CMD_ERRCL_EDU_BL),
965 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU |
966 CMD_ERRCL_EDU_BL),
967 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST |
968 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL),
969 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU |
970 CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL),
971 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU |
972 CMD_ERRCL_EDU_ST | 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_ST |
975 CMD_ERRCL_EDU_BL),
976 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU |
977 CMD_ERRCL_CPU),
978 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU |
979 CMD_ERRCL_CPU),
980 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST |
981 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_CPU),
982 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU |
983 CMD_ERRCL_UCU),
984 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU |
985 CMD_ERRCL_UCU),
986 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST |
987 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_UCU),
988 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU |
989 CMD_ERRCL_EDU_ST | CMD_ERRCL_CPU),
990 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU |
991 CMD_ERRCL_EDU_ST | CMD_ERRCL_CPU),
992 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST |
993 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
994 CMD_ERRCL_CPU),
995 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU |
996 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU),
997 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU |
998 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU),
999 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST |
1000 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL |
1001 CMD_ERRCL_CPU),
1002 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU |
1003 CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU),
1004 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU |
1005 CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU),
1006 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST |
1007 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
1008 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU),
1009 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU |
1010 CMD_ERRCL_EDU_ST | CMD_ERRCL_UCU),
1011 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU |
1012 CMD_ERRCL_EDU_ST | CMD_ERRCL_UCU),
1013 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST |
1014 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
1015 CMD_ERRCL_UCU),
1016 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU |
1017 CMD_ERRCL_EDU_BL | CMD_ERRCL_UCU),
1018 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU |
1019 CMD_ERRCL_EDU_BL | CMD_ERRCL_UCU),
1020 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST |
1021 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL |
1022 CMD_ERRCL_UCU),
1023 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU |
1024 CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL | CMD_ERRCL_UCU),
1025 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU |
1026 CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL | CMD_ERRCL_UCU),
1027 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST |
1028 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
1029 CMD_ERRCL_EDU_BL | CMD_ERRCL_UCU),
1030 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU |
1031 CMD_ERRCL_CPU | CMD_ERRCL_UCU),
1032 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU |
1033 CMD_ERRCL_CPU | CMD_ERRCL_UCU),
1034 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST |
1035 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_CPU |
1036 CMD_ERRCL_UCU),
1037 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU |
1038 CMD_ERRCL_EDU_ST | CMD_ERRCL_CPU | CMD_ERRCL_UCU),
1039 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU |
1040 CMD_ERRCL_EDU_ST | CMD_ERRCL_CPU | CMD_ERRCL_UCU),
1041 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST |
1042 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
1043 CMD_ERRCL_CPU | CMD_ERRCL_UCU),
1044 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU |
1045 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | CMD_ERRCL_UCU),
1046 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU |
1047 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | CMD_ERRCL_UCU),
1048 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST |
1049 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL |
1050 CMD_ERRCL_CPU | CMD_ERRCL_UCU),
1051 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU |
1052 CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU |
1053 CMD_ERRCL_UCU),
1054 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU |
1055 CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU |
1056 CMD_ERRCL_UCU),
1057 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST |
1058 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
1059 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | CMD_ERRCL_UCU),
1061 /* L3_CPU: L3_UCU+WDU+(zero or more of EDU, CPU, UCU) */
1062 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU),
1063 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU |
1064 CMD_ERRCL_EDU_ST),
1065 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU |
1066 CMD_ERRCL_EDU_BL),
1067 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU |
1068 CMD_ERRCL_EDU_ST |CMD_ERRCL_EDU_BL),
1069 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU |
1070 CMD_ERRCL_CPU),
1071 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU |
1072 CMD_ERRCL_UCU),
1073 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU |
1074 CMD_ERRCL_EDU_ST | CMD_ERRCL_CPU),
1075 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU |
1076 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU),
1077 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU |
1078 CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU),
1079 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU |
1080 CMD_ERRCL_EDU_ST | CMD_ERRCL_UCU),
1081 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU |
1082 CMD_ERRCL_EDU_BL | CMD_ERRCL_UCU),
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_UCU),
1085 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU |
1086 CMD_ERRCL_CPU | CMD_ERRCL_UCU),
1087 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU |
1088 CMD_ERRCL_EDU_ST | CMD_ERRCL_CPU | CMD_ERRCL_UCU),
1089 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU |
1090 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | CMD_ERRCL_UCU),
1091 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU |
1092 CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU |
1093 CMD_ERRCL_UCU),
1095 /* L3_CPU: L3_EDU+WDU+(zero or more of EDU, CPU, UCU)+L3_WDU */
1096 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU |
1097 CMD_ERRCL_L3_WDU),
1098 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU |
1099 CMD_ERRCL_L3_WDU),
1100 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST |
1101 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_L3_WDU),
1102 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU |
1103 CMD_ERRCL_EDU_ST | CMD_ERRCL_L3_WDU),
1104 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU |
1105 CMD_ERRCL_EDU_ST | 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_EDU_ST |
1108 CMD_ERRCL_L3_WDU),
1109 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU |
1110 CMD_ERRCL_EDU_BL | CMD_ERRCL_L3_WDU),
1111 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU |
1112 CMD_ERRCL_EDU_BL | CMD_ERRCL_L3_WDU),
1113 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST |
1114 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL |
1115 CMD_ERRCL_L3_WDU),
1116 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU |
1117 CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL | CMD_ERRCL_L3_WDU),
1118 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU |
1119 CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL | CMD_ERRCL_L3_WDU),
1120 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST |
1121 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
1122 CMD_ERRCL_EDU_BL | CMD_ERRCL_L3_WDU),
1123 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU |
1124 CMD_ERRCL_CPU | CMD_ERRCL_L3_WDU),
1125 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU |
1126 CMD_ERRCL_CPU | CMD_ERRCL_L3_WDU),
1127 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST |
1128 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_CPU |
1129 CMD_ERRCL_L3_WDU),
1130 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU |
1131 CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU),
1132 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU |
1133 CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU),
1134 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST |
1135 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_UCU |
1136 CMD_ERRCL_L3_WDU),
1137 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU |
1138 CMD_ERRCL_EDU_ST | CMD_ERRCL_CPU | CMD_ERRCL_L3_WDU),
1139 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU |
1140 CMD_ERRCL_EDU_ST | CMD_ERRCL_CPU | CMD_ERRCL_L3_WDU),
1141 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST |
1142 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
1143 CMD_ERRCL_CPU | CMD_ERRCL_L3_WDU),
1144 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU |
1145 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | CMD_ERRCL_L3_WDU),
1146 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU |
1147 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | CMD_ERRCL_L3_WDU),
1148 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST |
1149 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL |
1150 CMD_ERRCL_CPU | CMD_ERRCL_L3_WDU),
1151 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU |
1152 CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU |
1153 CMD_ERRCL_L3_WDU),
1154 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU |
1155 CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU |
1156 CMD_ERRCL_L3_WDU),
1157 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST |
1158 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
1159 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | CMD_ERRCL_L3_WDU),
1160 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU |
1161 CMD_ERRCL_EDU_ST | CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU),
1162 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU |
1163 CMD_ERRCL_EDU_ST | CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU),
1164 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST |
1165 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
1166 CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU),
1167 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU |
1168 CMD_ERRCL_EDU_BL | CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU),
1169 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU |
1170 CMD_ERRCL_EDU_BL | CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU),
1171 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST |
1172 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL |
1173 CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU),
1174 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU |
1175 CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL | CMD_ERRCL_UCU |
1176 CMD_ERRCL_L3_WDU),
1177 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU |
1178 CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL | CMD_ERRCL_UCU |
1179 CMD_ERRCL_L3_WDU),
1180 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST |
1181 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
1182 CMD_ERRCL_EDU_BL | CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU),
1183 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU |
1184 CMD_ERRCL_CPU | CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU),
1185 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU |
1186 CMD_ERRCL_CPU | CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU),
1187 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST |
1188 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_CPU |
1189 CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU),
1190 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU |
1191 CMD_ERRCL_EDU_ST | CMD_ERRCL_CPU | CMD_ERRCL_UCU |
1192 CMD_ERRCL_L3_WDU),
1193 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU |
1194 CMD_ERRCL_EDU_ST | CMD_ERRCL_CPU | CMD_ERRCL_UCU |
1195 CMD_ERRCL_L3_WDU),
1196 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST |
1197 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
1198 CMD_ERRCL_CPU | CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU),
1199 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU |
1200 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | CMD_ERRCL_UCU |
1201 CMD_ERRCL_L3_WDU),
1202 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU |
1203 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | CMD_ERRCL_UCU |
1204 CMD_ERRCL_L3_WDU),
1205 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST |
1206 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_BL |
1207 CMD_ERRCL_CPU | CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU),
1208 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST | CMD_ERRCL_WDU |
1209 CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU |
1210 CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU),
1211 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU |
1212 CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU |
1213 CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU),
1214 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_EDU_ST |
1215 CMD_ERRCL_L3_EDU_BL | CMD_ERRCL_WDU | CMD_ERRCL_EDU_ST |
1216 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | CMD_ERRCL_UCU |
1217 CMD_ERRCL_L3_WDU),
1219 /* L3_CPU: L3_UCU+WDU+(zero or more of EDU, CPU, UCU)+L3_WDU */
1220 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU
1221 | CMD_ERRCL_L3_WDU),
1222 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU |
1223 CMD_ERRCL_EDU_ST | CMD_ERRCL_L3_WDU),
1224 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU |
1225 CMD_ERRCL_EDU_BL | CMD_ERRCL_L3_WDU),
1226 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU |
1227 CMD_ERRCL_EDU_ST |CMD_ERRCL_EDU_BL | CMD_ERRCL_L3_WDU),
1228 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU |
1229 CMD_ERRCL_CPU | CMD_ERRCL_L3_WDU),
1230 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU |
1231 CMD_ERRCL_UCU | 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_CPU | CMD_ERRCL_L3_WDU),
1234 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU |
1235 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | CMD_ERRCL_L3_WDU),
1236 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU |
1237 CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU |
1238 CMD_ERRCL_L3_WDU),
1239 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU |
1240 CMD_ERRCL_EDU_ST | CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU),
1241 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU |
1242 CMD_ERRCL_EDU_BL | CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU),
1243 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU |
1244 CMD_ERRCL_EDU_ST | CMD_ERRCL_EDU_BL | CMD_ERRCL_UCU |
1245 CMD_ERRCL_L3_WDU),
1246 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU |
1247 CMD_ERRCL_CPU | CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU),
1248 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU |
1249 CMD_ERRCL_EDU_ST | CMD_ERRCL_CPU | CMD_ERRCL_UCU |
1250 CMD_ERRCL_L3_WDU),
1251 CMD_TRAIN(CMD_ERRCL_L3_CPU, CMD_ERRCL_L3_UCU | CMD_ERRCL_WDU |
1252 CMD_ERRCL_EDU_BL | CMD_ERRCL_CPU | CMD_ERRCL_UCU |
1253 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_EDU_BL | CMD_ERRCL_CPU |
1256 CMD_ERRCL_UCU | CMD_ERRCL_L3_WDU),
1257 #else /* sun4u */
1258 CMD_TRAIN(CMD_ERRCL_LDAC, CMD_ERRCL_LDWC),
1259 CMD_TRAIN(CMD_ERRCL_LDRC, CMD_ERRCL_LDWC),
1260 CMD_TRAIN(CMD_ERRCL_LDSC, CMD_ERRCL_LDWC),
1261 CMD_TRAIN(CMD_ERRCL_CBCE, CMD_ERRCL_LDWC),
1262 CMD_TRAIN(CMD_ERRCL_LDAU, CMD_ERRCL_LDWU),
1263 CMD_TRAIN(CMD_ERRCL_LDAU, CMD_ERRCL_WBUE),
1264 CMD_TRAIN(CMD_ERRCL_LDAU, CMD_ERRCL_DCDP),
1265 CMD_TRAIN(CMD_ERRCL_LDRU, CMD_ERRCL_LDWU),
1266 CMD_TRAIN(CMD_ERRCL_LDRU, CMD_ERRCL_WBUE),
1267 CMD_TRAIN(CMD_ERRCL_LDRU, CMD_ERRCL_DCDP),
1268 CMD_TRAIN(CMD_ERRCL_LDSU, CMD_ERRCL_LDWU),
1269 CMD_TRAIN(CMD_ERRCL_LDSU, CMD_ERRCL_WBUE),
1270 CMD_TRAIN(CMD_ERRCL_LDSU, CMD_ERRCL_DCDP),
1271 CMD_TRAIN(CMD_ERRCL_SBDLC, CMD_ERRCL_SBDPC),
1272 CMD_TRAIN(CMD_ERRCL_TCCP, CMD_ERRCL_TCCD),
1273 CMD_TRAIN(CMD_ERRCL_TCCD, CMD_ERRCL_TCCD),
1274 CMD_TRAIN(CMD_ERRCL_DBU, CMD_ERRCL_DCDP),
1275 CMD_TRAIN(CMD_ERRCL_DBU, CMD_ERRCL_ICDP),
1276 CMD_TRAIN(CMD_ERRCL_FBU, CMD_ERRCL_DCDP),
1277 CMD_TRAIN(CMD_ERRCL_FBU, CMD_ERRCL_ICDP),
1278 CMD_TRAIN(CMD_ERRCL_DAU, CMD_ERRCL_DCDP),
1279 CMD_TRAIN(CMD_ERRCL_DAU, CMD_ERRCL_ICDP),
1281 * sun4v also has the following trains, but the train
1282 * algorithm does an exhaustive search and compare
1283 * all pairs in the train mask, so we don't need
1284 * to define these trains
1285 * dl2nd->ldwu (wbue), dcdp
1286 * il2nd->ldwu (wbue), icdp
1287 * dxl2u->ldwu (wbue), dcdp
1288 * ixl2u->ldwu (wbue), icdp
1290 CMD_TRAIN(CMD_ERRCL_DL2ND, CMD_ERRCL_DCDP),
1291 CMD_TRAIN(CMD_ERRCL_DL2ND, CMD_ERRCL_LDWU),
1292 CMD_TRAIN(CMD_ERRCL_DL2ND, CMD_ERRCL_WBUE),
1293 CMD_TRAIN(CMD_ERRCL_IL2ND, CMD_ERRCL_ICDP),
1294 CMD_TRAIN(CMD_ERRCL_IL2ND, CMD_ERRCL_LDWU),
1295 CMD_TRAIN(CMD_ERRCL_IL2ND, CMD_ERRCL_WBUE),
1296 CMD_TRAIN(CMD_ERRCL_L2ND, CMD_ERRCL_LDWU),
1297 CMD_TRAIN(CMD_ERRCL_L2ND, CMD_ERRCL_WBUE),
1298 CMD_TRAIN(CMD_ERRCL_DL2U, CMD_ERRCL_DCDP),
1299 CMD_TRAIN(CMD_ERRCL_DL2U, CMD_ERRCL_LDWU),
1300 CMD_TRAIN(CMD_ERRCL_DL2U, CMD_ERRCL_WBUE),
1301 CMD_TRAIN(CMD_ERRCL_IL2U, CMD_ERRCL_ICDP),
1302 CMD_TRAIN(CMD_ERRCL_IL2U, CMD_ERRCL_LDWU),
1303 CMD_TRAIN(CMD_ERRCL_IL2U, CMD_ERRCL_WBUE),
1304 #endif /* sun4u */
1305 CMD_TRAIN(0, 0)
1308 cmd_errcl_t
1309 cmd_xxcu_train_match(cmd_errcl_t mask)
1311 int i;
1313 for (i = 0; cmd_xxcu_trains[i].tr_mask != 0; i++) {
1314 if (cmd_xxcu_trains[i].tr_mask == mask)
1315 return (cmd_xxcu_trains[i].tr_cause);
1318 return (0);
1321 cmd_xxcu_trw_t *
1322 cmd_trw_alloc(uint64_t ena, uint64_t afar)
1324 int i;
1326 for (i = 0; i < cmd.cmd_xxcu_ntrw; i++) {
1327 cmd_xxcu_trw_t *trw = &cmd.cmd_xxcu_trw[i];
1328 if (trw->trw_ena == NULL) {
1329 trw->trw_ena = ena;
1330 trw->trw_afar = afar;
1331 return (trw);
1335 return (NULL);
1338 void
1339 cmd_trw_write(fmd_hdl_t *hdl)
1341 fmd_buf_write(hdl, NULL, "waiters", cmd.cmd_xxcu_trw,
1342 cmd.cmd_xxcu_ntrw * sizeof (cmd_xxcu_trw_t));
1345 /*ARGSUSED*/
1346 void
1347 cmd_trw_ref(fmd_hdl_t *hdl, cmd_xxcu_trw_t *trw, cmd_errcl_t clcode)
1349 trw->trw_ref++;
1350 trw->trw_mask |= clcode;
1351 cmd_trw_write(hdl);
1354 void
1355 cmd_trw_deref(fmd_hdl_t *hdl, cmd_xxcu_trw_t *trw)
1357 if (trw->trw_ref == 0)
1358 fmd_hdl_abort(hdl, "attempt to deref trw with zero ref\n");
1360 if (--trw->trw_ref == 0)
1361 bzero(trw, sizeof (cmd_xxcu_trw_t));
1363 cmd_trw_write(hdl);
1366 void
1367 cmd_trw_restore(fmd_hdl_t *hdl)
1369 size_t sz = fmd_buf_size(hdl, NULL, "waiters");
1370 if (sz == cmd.cmd_xxcu_ntrw * sizeof (cmd_xxcu_trw_t)) {
1372 * Previous size == current size. In absence of
1373 * versioning, assume that the structure and # of elements
1374 * have not changed.
1376 fmd_buf_read(hdl, NULL, "waiters", cmd.cmd_xxcu_trw,
1377 cmd.cmd_xxcu_ntrw * sizeof (cmd_xxcu_trw_t));
1378 } else {
1380 * Previous size != current size. Something has changed;
1381 * hence we cannot rely on the contents of this buffer.
1382 * Delete the buffer and start fresh.
1384 fmd_buf_destroy(hdl, NULL, "waiters");
1385 fmd_buf_write(hdl, NULL, "waiters", cmd.cmd_xxcu_trw,
1386 cmd.cmd_xxcu_ntrw * sizeof (cmd_xxcu_trw_t));
1390 char *
1391 cmd_cpu_serdnm_create(fmd_hdl_t *hdl, cmd_cpu_t *cpu, const char *serdbase)
1393 char *nm;
1394 const char *fmt;
1395 size_t sz;
1396 if (cpu->cpu_level == CMD_CPU_LEVEL_THREAD) {
1397 fmt = "cpu_%d_%s_serd";
1398 sz = snprintf(NULL, 0, fmt, cpu->cpu_cpuid, serdbase) + 1;
1399 nm = fmd_hdl_alloc(hdl, sz, FMD_SLEEP);
1400 (void) snprintf(nm, sz, fmt, cpu->cpu_cpuid, serdbase);
1401 } else {
1402 fmt = "cpu_%d_%d_%s_serd";
1403 sz = snprintf(NULL, 0, fmt, cpu->cpu_cpuid, cpu->cpu_level,
1404 serdbase) + 1;
1405 nm = fmd_hdl_alloc(hdl, sz, FMD_SLEEP);
1406 (void) snprintf(nm, sz, fmt, cpu->cpu_cpuid, cpu->cpu_level,
1407 serdbase);
1410 return (nm);
1414 * cmd_cpu_create_faultlist is a combination of the former cmd_cpu_create_fault
1415 * and fmd_case_add_suspect. If a 'cpu' structure represents a set of threads
1416 * (level > CMD_CPU_LEVEL_THREAD), then we must add multiple faults to
1417 * this case, under loop control. Use call to cmd_cpu_create_faultlist to
1418 * replace the sequence
1420 * flt = cmd_cpu_create_fault(...);
1421 * fmd_case_add_suspect(hdl, cc->cp, flt);
1424 void
1425 cmd_cpu_create_faultlist(fmd_hdl_t *hdl, fmd_case_t *casep, cmd_cpu_t *cpu,
1426 const char *type, nvlist_t *rsrc, uint_t cert)
1428 char fltnm[64];
1429 uint32_t cpuinit, cpufinal, cpustep, i;
1430 nvlist_t *flt;
1431 #ifdef sun4v
1432 char *loc;
1433 nvlist_t *mb_rsrc;
1434 #endif
1436 (void) snprintf(fltnm, sizeof (fltnm), "fault.cpu.%s.%s",
1437 cmd_cpu_type2name(hdl, cpu->cpu_type), type);
1439 cpu->cpu_faulting = FMD_B_TRUE;
1440 cpu_buf_write(hdl, cpu);
1441 #ifdef sun4v
1443 loc = cmd_getfru_loc(hdl, cpu->cpu_asru_nvl);
1446 * Add motherboard fault to t5440 lfu suspect.list.
1448 if ((strstr(loc, CPUBOARD) != NULL) && (strstr(fltnm, "lfu") != NULL)) {
1449 /* get mb fmri from libtopo */
1450 mb_rsrc = init_mb(hdl);
1451 if (mb_rsrc != NULL) {
1452 fmd_hdl_debug(hdl, "cmd_cpu: create MB fault\n");
1453 cert = BK_LFUFAULT_CERT;
1454 flt = cmd_boardfru_create_fault(hdl, mb_rsrc, fltnm,
1455 cert, "MB");
1456 fmd_case_add_suspect(hdl, casep, flt);
1457 nvlist_free(mb_rsrc);
1460 #endif
1462 if (cpu->cpu_level > CMD_CPU_LEVEL_THREAD) {
1463 core2cpus(cpu->cpu_cpuid, cpu->cpu_type, cpu->cpu_level,
1464 &cpuinit, &cpufinal, &cpustep);
1465 for (i = cpuinit; i <= cpufinal; i += cpustep) {
1466 cmd_cpu_t *cpui = cpu_lookup_by_cpuid(i,
1467 CMD_CPU_LEVEL_THREAD);
1468 if (cpui == NULL) {
1469 nvlist_t *asru;
1470 if (nvlist_dup(cpu->cpu_asru_nvl,
1471 &asru, 0) != 0) {
1472 fmd_hdl_abort(hdl, "unable to alloc"
1473 "ASRU for thread in core\n");
1475 (void) nvlist_remove_all(asru,
1476 FM_FMRI_CPU_ID);
1477 if (nvlist_add_uint32(asru,
1478 FM_FMRI_CPU_ID, i) != 0) {
1479 fmd_hdl_abort(hdl,
1480 "unable to create thread struct\n");
1482 cpui = cpu_create(hdl, asru, i,
1483 CMD_CPU_LEVEL_THREAD, cpu->cpu_type);
1484 nvlist_free(asru);
1486 if (!fmd_nvl_fmri_present(hdl, cpui->cpu_asru_nvl))
1487 continue;
1488 cpui->cpu_faulting = FMD_B_TRUE;
1489 cpu_buf_write(hdl, cpui);
1490 flt = cmd_nvl_create_fault(hdl, fltnm, cert,
1491 cpui->cpu_asru_nvl, cpu->cpu_fru_nvl, rsrc);
1492 #ifdef sun4v
1493 flt = cmd_fault_add_location(hdl, flt, loc);
1494 #endif /* sun4v */
1495 fmd_case_add_suspect(hdl, casep, flt);
1497 } else {
1498 flt = cmd_nvl_create_fault(hdl, fltnm, cert,
1499 cpu->cpu_asru_nvl, cpu->cpu_fru_nvl, rsrc);
1500 #ifdef sun4v
1501 flt = cmd_fault_add_location(hdl, flt, loc);
1503 #endif /* sun4v */
1504 fmd_case_add_suspect(hdl, casep, flt);
1506 #ifdef sun4v
1507 if (loc != NULL)
1508 fmd_hdl_strfree(hdl, loc);
1509 #endif
1512 static void
1513 cmd_cpu_free(fmd_hdl_t *hdl, cmd_cpu_t *cpu, int destroy)
1515 int i;
1516 #ifdef sun4u
1517 cmd_Lxcache_t *Lxcache;
1518 #endif
1520 for (i = 0; i < sizeof (cmd_cpu_cases_t) / sizeof (cmd_case_t); i++) {
1521 cmd_case_t *cc = &(((cmd_case_t *)&cpu->cpu_cases)[i]);
1523 if (cc->cc_cp != NULL) {
1524 cmd_case_fini(hdl, cc->cc_cp, destroy);
1525 if (cc->cc_serdnm != NULL) {
1526 if (fmd_serd_exists(hdl, cc->cc_serdnm) &&
1527 destroy)
1528 fmd_serd_destroy(hdl, cc->cc_serdnm);
1529 fmd_hdl_strfree(hdl, cc->cc_serdnm);
1534 #ifdef sun4u
1536 * free Lxcache also.
1539 for (Lxcache = cmd_list_next(&cpu->cpu_Lxcaches); Lxcache != NULL;
1540 Lxcache = cmd_list_next(&cpu->cpu_Lxcaches)) {
1541 (void) cmd_Lxcache_free(hdl, cpu, Lxcache, destroy);
1543 cpu_uec_free(hdl, &cpu->cpu_uec, destroy);
1544 cpu_uec_free(hdl, &cpu->cpu_olduec, destroy);
1545 #endif /* sun4u */
1547 cmd_fmri_fini(hdl, &cpu->cpu_asru, destroy);
1548 cmd_fmri_fini(hdl, &cpu->cpu_fru, destroy);
1550 cmd_list_delete(&cmd.cmd_cpus, cpu);
1552 if (destroy)
1553 fmd_buf_destroy(hdl, NULL, cpu->cpu_bufname);
1554 fmd_hdl_free(hdl, cpu, sizeof (cmd_cpu_t));
1557 void
1558 cmd_cpu_destroy(fmd_hdl_t *hdl, cmd_cpu_t *cpu)
1560 cmd_cpu_free(hdl, cpu, FMD_B_TRUE);
1563 static cmd_cpu_t *
1564 cpu_lookup_by_cpuid(uint32_t cpuid, uint8_t level)
1566 cmd_cpu_t *cpu;
1568 for (cpu = cmd_list_next(&cmd.cmd_cpus); cpu != NULL;
1569 cpu = cmd_list_next(cpu)) {
1570 if ((cpu->cpu_cpuid == cpuid) &&
1571 (cpu->cpu_level == level))
1572 return (cpu);
1575 return (NULL);
1578 static nvlist_t *
1579 cpu_getfru(fmd_hdl_t *hdl, cmd_cpu_t *cp)
1581 char *frustr, *partstr, *serialstr;
1582 nvlist_t *nvlp;
1584 if ((frustr = cmd_cpu_getfrustr(hdl, cp)) == NULL) {
1585 return (NULL);
1587 partstr = cmd_cpu_getpartstr(hdl, cp);
1588 serialstr = cmd_cpu_getserialstr(hdl, cp);
1589 nvlp = cmd_cpu_mkfru(hdl, frustr, serialstr, partstr);
1590 fmd_hdl_strfree(hdl, frustr);
1591 fmd_hdl_strfree(hdl, partstr);
1592 fmd_hdl_strfree(hdl, serialstr);
1594 return (nvlp);
1597 static void
1598 cpu_buf_write(fmd_hdl_t *hdl, cmd_cpu_t *cpu)
1600 if (fmd_buf_size(hdl, NULL, cpu->cpu_bufname) !=
1601 sizeof (cmd_cpu_pers_t))
1602 fmd_buf_destroy(hdl, NULL, cpu->cpu_bufname);
1604 fmd_buf_write(hdl, NULL, cpu->cpu_bufname, &cpu->cpu_pers,
1605 sizeof (cmd_cpu_pers_t));
1608 static void
1609 cpu_buf_create(fmd_hdl_t *hdl, cmd_cpu_t *cpu)
1611 size_t sz;
1614 * We need to be tolerant of leaked CPU buffers, as their effects can
1615 * be severe. Consider the following scenario: we create a version 0
1616 * cmd_cpu_t in response to some error, commit it to a persistent
1617 * buffer, and then leak it. We then upgrade, and restart the DE using
1618 * version 1 cmd_cpu_t's. Another error comes along, for the same CPU
1619 * whose struct was leaked. Not knowing about the leaked buffer, we
1620 * create a new cmd_cpu_t for that CPU, and create a buffer for it. As
1621 * the v1 cmd_cpu_t is smaller than the v0 cmd_cpu_t, fmd will use the
1622 * pre-existing (leaked) buffer. We'll therefore have an x-byte, v1
1623 * cmd_cpu_t in a y-byte buffer, where y > x. Upon the next DE restart,
1624 * we'll attempt to restore the cmd_cpu_t, but will do version
1625 * validation using the size of the buffer (y). This won't match what
1626 * we're expecting (x), and the DE will abort.
1628 * To protect against such a scenario, we're going to check for and
1629 * remove the pre-existing cmd_cpu_t for this CPU, if one exists. While
1630 * this won't fix the leak, it'll allow us to continue functioning
1631 * properly in spite of it.
1633 if ((sz = fmd_buf_size(hdl, NULL, cpu->cpu_bufname)) != 0 &&
1634 sz != sizeof (cmd_cpu_pers_t)) {
1635 fmd_hdl_debug(hdl, "removing unexpected pre-existing cpu "
1636 "buffer %s (size %u bytes)\n", cpu->cpu_bufname, sz);
1637 fmd_buf_destroy(hdl, NULL, cpu->cpu_bufname);
1640 cpu_buf_write(hdl, cpu);
1643 static cmd_cpu_t *
1644 cpu_create(fmd_hdl_t *hdl, nvlist_t *asru, uint32_t cpuid, uint8_t level,
1645 cmd_cpu_type_t type)
1647 cmd_cpu_t *cpu;
1648 nvlist_t *fru;
1651 * No CPU state matches the CPU described in the ereport. Create a new
1652 * one, add it to the list, and pass it back.
1654 fmd_hdl_debug(hdl, "cpu_lookup: creating new cpuid %u\n", cpuid);
1655 CMD_STAT_BUMP(cpu_creat);
1657 cpu = fmd_hdl_zalloc(hdl, sizeof (cmd_cpu_t), FMD_SLEEP);
1658 cpu->cpu_nodetype = CMD_NT_CPU;
1659 cpu->cpu_cpuid = cpuid;
1660 cpu->cpu_level = level;
1661 cpu->cpu_type = type;
1662 cpu->cpu_version = CMD_CPU_VERSION;
1664 if (cpu->cpu_level == CMD_CPU_LEVEL_THREAD) {
1665 cmd_bufname(cpu->cpu_bufname, sizeof (cpu->cpu_bufname),
1666 "cpu_%d", cpu->cpu_cpuid);
1667 } else {
1668 cmd_bufname(cpu->cpu_bufname, sizeof (cpu->cpu_bufname),
1669 "cpu_%d_%d", cpu->cpu_cpuid, cpu->cpu_level);
1672 #ifdef sun4u
1673 cpu_uec_create(hdl, cpu, &cpu->cpu_uec, "cpu_uec_%d", cpu->cpu_cpuid);
1674 cpu_uec_create(hdl, cpu, &cpu->cpu_olduec, "cpu_olduec_%d",
1675 cpu->cpu_cpuid);
1676 #endif /* sun4u */
1678 if (cpu->cpu_level == CMD_CPU_LEVEL_THREAD) {
1679 cmd_fmri_init(hdl, &cpu->cpu_asru, asru, "cpu_asru_%d",
1680 cpu->cpu_cpuid);
1681 } else {
1682 cmd_fmri_init(hdl, &cpu->cpu_asru, asru, "cpu_asru_%d_%d",
1683 cpu->cpu_cpuid, cpu->cpu_level);
1686 if ((fru = cpu_getfru(hdl, cpu)) != NULL) {
1687 if (cpu->cpu_level == CMD_CPU_LEVEL_THREAD) {
1688 cmd_fmri_init(hdl, &cpu->cpu_fru, fru, "cpu_fru_%d",
1689 cpu->cpu_cpuid);
1690 } else {
1691 cmd_fmri_init(hdl, &cpu->cpu_fru, fru, "cpu_fru_%d_%d",
1692 cpu->cpu_cpuid, cpu->cpu_level);
1694 nvlist_free(fru);
1695 } else {
1696 if (cpu->cpu_level == CMD_CPU_LEVEL_THREAD) {
1697 cmd_fmri_init(hdl, &cpu->cpu_fru, asru, "cpu_fru_%d",
1698 cpu->cpu_cpuid);
1699 } else {
1700 cmd_fmri_init(hdl, &cpu->cpu_fru, asru, "cpu_fru_%d_%d",
1701 cpu->cpu_cpuid, cpu->cpu_level);
1705 cpu_buf_create(hdl, cpu);
1707 cmd_list_append(&cmd.cmd_cpus, cpu);
1709 return (cpu);
1713 * As its name implies, 'cpu_all_threads_invalid' determines if all cpu
1714 * threads (level 0) contained within the cpu structure are invalid.
1715 * This is done by checking all the (level 0) threads which may be
1716 * contained within this chip, core, or thread; if all are invalid, return
1717 * FMD_B_TRUE; if any are valid, return FMD_B_FALSE.
1721 cpu_all_threads_invalid(fmd_hdl_t *hdl, cmd_cpu_t *cpu)
1723 nvlist_t *asru;
1724 uint32_t cpuinit, cpufinal, cpustep, i;
1726 core2cpus(cpu->cpu_cpuid, cpu->cpu_type, cpu->cpu_level,
1727 &cpuinit, &cpufinal, &cpustep);
1729 if (cpuinit == cpufinal) {
1730 if (fmd_nvl_fmri_present(hdl, cpu->cpu_asru_nvl) &&
1731 !fmd_nvl_fmri_unusable(hdl, cpu->cpu_asru_nvl))
1732 return (FMD_B_FALSE);
1733 else return (FMD_B_TRUE);
1734 } else {
1736 if (nvlist_dup(cpu->cpu_asru_nvl, &asru, 0) != 0)
1737 fmd_hdl_abort(hdl, "cannot copy asru\n");
1738 for (i = cpuinit; i <= cpufinal; i += cpustep) {
1739 (void) nvlist_remove_all(asru, FM_FMRI_CPU_ID);
1740 if (nvlist_add_uint32(asru, FM_FMRI_CPU_ID, i) != 0) {
1741 fmd_hdl_abort(hdl, "cpu_all_threads_invalid: ",
1742 "cannot add thread %d to asru\n", i);
1744 if (fmd_nvl_fmri_present(hdl, asru) &&
1745 !fmd_nvl_fmri_unusable(hdl, asru)) {
1746 nvlist_free(asru);
1747 return (FMD_B_FALSE);
1751 nvlist_free(asru);
1752 return (FMD_B_TRUE);
1756 * Locate the state structure for this CPU, creating a new one if one doesn't
1757 * already exist. Before passing it back, we also need to validate it against
1758 * the current state of the world, checking to ensure that the CPU described by
1759 * the ereport, the CPU indicated in the cmd_cpu_t, and the CPU currently
1760 * residing at the indicated cpuid are the same. We do this by comparing the
1761 * serial IDs from the three entities.
1763 cmd_cpu_t *
1764 cmd_cpu_lookup(fmd_hdl_t *hdl, nvlist_t *asru, const char *class,
1765 uint8_t level)
1767 cmd_cpu_t *cpu;
1768 uint8_t vers;
1769 const char *scheme, *cpuname;
1770 uint32_t cpuid;
1771 cmd_cpu_type_t ct;
1773 if (fmd_nvl_fmri_expand(hdl, asru) < 0) {
1774 CMD_STAT_BUMP(bad_cpu_asru);
1775 return (NULL);
1778 if (nvlist_lookup_pairs(asru, 0,
1779 FM_VERSION, DATA_TYPE_UINT8, &vers,
1780 FM_FMRI_SCHEME, DATA_TYPE_STRING, &scheme,
1781 FM_FMRI_CPU_ID, DATA_TYPE_UINT32, &cpuid,
1782 NULL) != 0 || (vers != CPU_SCHEME_VERSION0 &&
1783 vers != CPU_SCHEME_VERSION1) ||
1784 strcmp(scheme, FM_FMRI_SCHEME_CPU) != 0) {
1785 CMD_STAT_BUMP(bad_cpu_asru);
1786 return (NULL);
1790 * 'cpuid' at this point refers to a thread, because it
1791 * was extracted from a detector FMRI
1794 cpuname = class + sizeof ("ereport.cpu");
1795 ct = cpu_nname2type(hdl, cpuname,
1796 (size_t)(strchr(cpuname, '.') - cpuname));
1798 cpu = cpu_lookup_by_cpuid(cmd_cpu2core(cpuid, ct, level), level);
1800 if (cpu != NULL &&
1801 cpu_all_threads_invalid(hdl, cpu) == FMD_B_TRUE) {
1802 fmd_hdl_debug(hdl, "cpu_lookup: discarding old state\n");
1803 cmd_cpu_destroy(hdl, cpu);
1804 cpu = NULL;
1808 * Check to see if the CPU described by the ereport has been removed
1809 * from the system. If it has, return to the caller without a CPU.
1811 if (!fmd_nvl_fmri_present(hdl, asru) ||
1812 fmd_nvl_fmri_unusable(hdl, asru)) {
1813 fmd_hdl_debug(hdl, "cpu_lookup: discarding old ereport\n");
1814 return (NULL);
1817 if (cpu == NULL) {
1818 cpu = cpu_create(hdl, asru,
1819 cmd_cpu2core(cpuid, ct, level), level, ct);
1822 return (cpu);
1825 cmd_cpu_t *
1826 cmd_cpu_lookup_from_detector(fmd_hdl_t *hdl, nvlist_t *nvl, const char *class,
1827 uint8_t level)
1829 nvlist_t *det;
1831 (void) nvlist_lookup_nvlist(nvl, FM_EREPORT_DETECTOR, &det);
1833 return (cmd_cpu_lookup(hdl, det, class, level));
1836 static cmd_cpu_t *
1837 cpu_v0tov3(fmd_hdl_t *hdl, cmd_cpu_0_t *old, size_t oldsz)
1839 cmd_cpu_t *new;
1841 if (oldsz != sizeof (cmd_cpu_0_t)) {
1842 fmd_hdl_abort(hdl, "size of state doesn't match size of "
1843 "version 0 state (%u bytes).\n", sizeof (cmd_cpu_0_t));
1846 new = fmd_hdl_zalloc(hdl, sizeof (cmd_cpu_t), FMD_SLEEP);
1847 new->cpu_header = old->cpu0_header;
1848 new->cpu_version = CMD_CPU_VERSION;
1849 new->cpu_cpuid = old->cpu0_cpuid;
1850 new->cpu_type = old->cpu0_type;
1851 new->cpu_faulting = old->cpu0_faulting;
1852 new->cpu_level = CMD_CPU_LEVEL_THREAD;
1853 new->cpu_asru = old->cpu0_asru;
1854 new->cpu_fru = old->cpu0_fru;
1855 new->cpu_uec = old->cpu0_uec;
1856 new->cpu_olduec = old->cpu0_olduec;
1858 fmd_hdl_free(hdl, old, oldsz);
1859 return (new);
1862 static cmd_cpu_t *
1863 cpu_v1tov3(fmd_hdl_t *hdl, cmd_cpu_1_t *old, size_t oldsz)
1865 cmd_cpu_t *new;
1867 if (oldsz != sizeof (cmd_cpu_1_t)) {
1868 fmd_hdl_abort(hdl, "size of state doesn't match size of "
1869 "version 1 state (%u bytes).\n", sizeof (cmd_cpu_1_t));
1872 new = fmd_hdl_zalloc(hdl, sizeof (cmd_cpu_t), FMD_SLEEP);
1873 new->cpu_header = old->cpu1_header;
1874 new->cpu_version = CMD_CPU_VERSION;
1875 new->cpu_cpuid = old->cpu1_cpuid;
1876 new->cpu_type = old->cpu1_type;
1877 new->cpu_faulting = old->cpu1_faulting;
1878 new->cpu_level = CMD_CPU_LEVEL_THREAD;
1879 new->cpu_asru = old->cpu1_asru;
1880 new->cpu_fru = old->cpu1_fru;
1881 new->cpu_uec = old->cpu1_uec;
1882 new->cpu_olduec = old->cpu1_olduec;
1884 fmd_hdl_free(hdl, old, oldsz);
1885 return (new);
1888 static cmd_cpu_t *
1889 cpu_v2tov3(fmd_hdl_t *hdl, cmd_cpu_2_t *old, size_t oldsz)
1891 cmd_cpu_t *new;
1893 if (oldsz != sizeof (cmd_cpu_2_t)) {
1894 fmd_hdl_abort(hdl, "size of state doesn't match size of "
1895 "version 2 state (%u bytes).\n", sizeof (cmd_cpu_2_t));
1898 new = fmd_hdl_zalloc(hdl, sizeof (cmd_cpu_t), FMD_SLEEP);
1900 new->cpu_header = old->cpu2_header;
1901 new->cpu_cpuid = old->cpu2_cpuid;
1902 new->cpu_type = old->cpu2_type;
1903 new->cpu_faulting = old->cpu2_faulting;
1904 new->cpu_asru = old->cpu2_asru;
1905 new->cpu_fru = old->cpu2_fru;
1906 new->cpu_uec = old->cpu2_uec;
1907 new->cpu_olduec = old->cpu2_olduec;
1908 new->cpu_version = CMD_CPU_VERSION;
1909 new->cpu_level = CMD_CPU_LEVEL_THREAD;
1910 fmd_hdl_free(hdl, old, oldsz);
1911 return (new);
1914 static cmd_cpu_t *
1915 cpu_wrapv3(fmd_hdl_t *hdl, cmd_cpu_pers_t *pers, size_t psz)
1917 cmd_cpu_t *cpu;
1919 if (psz != sizeof (cmd_cpu_pers_t)) {
1920 fmd_hdl_abort(hdl, "size of state doesn't match size of "
1921 "version 3 state (%u bytes).\n", sizeof (cmd_cpu_pers_t));
1924 cpu = fmd_hdl_zalloc(hdl, sizeof (cmd_cpu_t), FMD_SLEEP);
1925 bcopy(pers, cpu, sizeof (cmd_cpu_pers_t));
1926 fmd_hdl_free(hdl, pers, psz);
1927 return (cpu);
1930 static void
1931 cpu_case_restore(fmd_hdl_t *hdl, cmd_cpu_t *cpu, cmd_case_t *cc, fmd_case_t *cp,
1932 const char *serdbase)
1934 cmd_case_restore(hdl, cc, cp, cmd_cpu_serdnm_create(hdl, cpu,
1935 serdbase));
1938 cmd_cpu_t *
1939 cmd_restore_cpu_only(fmd_hdl_t *hdl, fmd_case_t *cp, char *cpu_hdr_bufname)
1941 cmd_cpu_t *cpu;
1943 for (cpu = cmd_list_next(&cmd.cmd_cpus); cpu != NULL;
1944 cpu = cmd_list_next(cpu)) {
1945 if (strcmp(cpu->cpu_bufname, cpu_hdr_bufname) == 0)
1946 break;
1949 if (cpu == NULL) {
1950 int migrated = 0;
1951 size_t cpusz;
1953 fmd_hdl_debug(hdl, "restoring cpu from %s\n", cpu_hdr_bufname);
1955 if ((cpusz = fmd_buf_size(hdl, NULL, cpu_hdr_bufname)) == 0) {
1956 if (fmd_case_solved(hdl, cp) ||
1957 fmd_case_closed(hdl, cp)) {
1958 fmd_hdl_debug(hdl, "cpu buffer %s from case %s "
1959 "not found. Case is already solved or "
1960 "closed\n",
1961 cpu_hdr_bufname, fmd_case_uuid(hdl, cp));
1962 return (NULL);
1963 } else {
1964 fmd_hdl_abort(hdl, "cpu referenced by case %s "
1965 "does not exist in saved state\n",
1966 fmd_case_uuid(hdl, cp));
1968 } else if (cpusz > CMD_CPU_MAXSIZE || cpusz < CMD_CPU_MINSIZE) {
1969 fmd_hdl_abort(hdl, "cpu buffer referenced by case %s "
1970 "is out of bounds (is %u bytes)\n",
1971 fmd_case_uuid(hdl, cp), cpusz);
1974 if ((cpu = cmd_buf_read(hdl, NULL, cpu_hdr_bufname,
1975 cpusz)) == NULL) {
1976 fmd_hdl_abort(hdl, "failed to read buf %s",
1977 cpu_hdr_bufname);
1980 fmd_hdl_debug(hdl, "found %d in version field\n",
1981 cpu->cpu_version);
1983 if (CMD_CPU_VERSIONED(cpu)) {
1984 switch (cpu->cpu_version) {
1985 case CMD_CPU_VERSION_1:
1986 cpu = cpu_v1tov3(hdl, (cmd_cpu_1_t *)cpu,
1987 cpusz);
1988 migrated = 1;
1989 break;
1990 case CMD_CPU_VERSION_2:
1991 cpu = cpu_v2tov3(hdl, (cmd_cpu_2_t *)cpu,
1992 cpusz);
1993 migrated = 1;
1994 break;
1995 case CMD_CPU_VERSION_3:
1996 cpu = cpu_wrapv3(hdl, (cmd_cpu_pers_t *)cpu,
1997 cpusz);
1998 break;
1999 default:
2000 fmd_hdl_abort(hdl, "unknown version (found %d) "
2001 "for cpu state referenced by case %s.\n",
2002 cpu->cpu_version, fmd_case_uuid(hdl, cp));
2003 break;
2005 } else {
2006 cpu = cpu_v0tov3(hdl, (cmd_cpu_0_t *)cpu, cpusz);
2007 migrated = 1;
2010 if (migrated) {
2011 CMD_STAT_BUMP(cpu_migrat);
2012 cpu_buf_write(hdl, cpu);
2015 cmd_fmri_restore(hdl, &cpu->cpu_asru);
2016 cmd_fmri_restore(hdl, &cpu->cpu_fru);
2017 #ifdef sun4u
2018 cpu_uec_restore(hdl, &cpu->cpu_uec);
2019 cpu_uec_restore(hdl, &cpu->cpu_olduec);
2021 if (cpu->cpu_uec.uec_cache != NULL)
2022 cpu_uec_flush(hdl, cpu);
2023 #endif /* sun4u */
2024 bzero(&cpu->cpu_xxu_retries, sizeof (cmd_list_t));
2026 cmd_list_append(&cmd.cmd_cpus, cpu);
2028 return (cpu);
2031 void *
2032 cmd_cpu_restore(fmd_hdl_t *hdl, fmd_case_t *cp, cmd_case_ptr_t *ptr)
2034 cmd_cpu_t *cpu;
2036 cpu = cmd_restore_cpu_only(hdl, cp, ptr->ptr_name);
2037 if (cpu == NULL)
2038 return (NULL);
2040 switch (ptr->ptr_subtype) {
2041 case CMD_PTR_CPU_ICACHE:
2042 cpu_case_restore(hdl, cpu, &cpu->cpu_icache, cp, "icache");
2043 break;
2044 case CMD_PTR_CPU_DCACHE:
2045 cpu_case_restore(hdl, cpu, &cpu->cpu_dcache, cp, "dcache");
2046 break;
2047 case CMD_PTR_CPU_PCACHE:
2048 cpu_case_restore(hdl, cpu, &cpu->cpu_pcache, cp, "pcache");
2049 break;
2050 case CMD_PTR_CPU_ITLB:
2051 cpu_case_restore(hdl, cpu, &cpu->cpu_itlb, cp, "itlb");
2052 break;
2053 case CMD_PTR_CPU_DTLB:
2054 cpu_case_restore(hdl, cpu, &cpu->cpu_dtlb, cp, "dtlb");
2055 break;
2056 case CMD_PTR_CPU_L2DATA:
2057 cpu_case_restore(hdl, cpu, &cpu->cpu_l2data, cp,
2058 cmd.cmd_l2data_serd.cs_name);
2059 break;
2060 case CMD_PTR_CPU_L2DATA_UERETRY:
2061 /* No longer used -- discard */
2062 break;
2063 case CMD_PTR_CPU_L2TAG:
2064 cpu_case_restore(hdl, cpu, &cpu->cpu_l2tag, cp, "l2tag");
2065 break;
2066 case CMD_PTR_CPU_L3DATA:
2067 cpu_case_restore(hdl, cpu, &cpu->cpu_l3data, cp,
2068 cmd.cmd_l3data_serd.cs_name);
2069 break;
2070 case CMD_PTR_CPU_L3DATA_UERETRY:
2071 /* No longer used -- discard */
2072 break;
2073 case CMD_PTR_CPU_L3TAG:
2074 cpu_case_restore(hdl, cpu, &cpu->cpu_l3tag, cp, "l3tag");
2075 break;
2076 case CMD_PTR_CPU_FPU:
2077 cpu_case_restore(hdl, cpu, &cpu->cpu_fpu, cp, "fpu");
2078 break;
2079 case CMD_PTR_CPU_XR_RETRY:
2080 cmd_xr_restore(hdl, cpu, cp);
2081 break;
2082 case CMD_PTR_CPU_IREG:
2083 cpu_case_restore(hdl, cpu, &cpu->cpu_ireg, cp, "ireg");
2084 break;
2085 case CMD_PTR_CPU_FREG:
2086 cpu_case_restore(hdl, cpu, &cpu->cpu_freg, cp, "freg");
2087 break;
2088 case CMD_PTR_CPU_MAU:
2089 cpu_case_restore(hdl, cpu, &cpu->cpu_mau, cp, "mau");
2090 break;
2091 case CMD_PTR_CPU_L2CTL:
2092 cpu_case_restore(hdl, cpu, &cpu->cpu_l2ctl, cp, "l2ctl");
2093 break;
2094 case CMD_PTR_CPU_MISC_REGS:
2095 cpu_case_restore(hdl, cpu, &cpu->cpu_misc_regs, cp,
2096 "misc_regs");
2097 break;
2098 case CMD_PTR_CPU_LFU:
2099 cpu_case_restore(hdl, cpu, &cpu->cpu_lfu, cp, "lfu");
2100 break;
2101 #ifdef sun4u
2102 case CMD_PTR_CPU_INV_SFSR:
2103 cpu_case_restore(hdl, cpu, &cpu->cpu_opl_invsfsr, cp,
2104 "opl_invsfsr");
2105 break;
2106 case CMD_PTR_CPU_UE_DET_CPU:
2107 cpu_case_restore(hdl, cpu, &cpu->cpu_oplue_detcpu, cp,
2108 "oplue_detcpu");
2109 break;
2110 case CMD_PTR_CPU_UE_DET_IO:
2111 cpu_case_restore(hdl, cpu, &cpu->cpu_oplue_detio, cp,
2112 "oplue_detio");
2113 break;
2114 case CMD_PTR_CPU_MTLB:
2115 cpu_case_restore(hdl, cpu, &cpu->cpu_opl_mtlb, cp,
2116 "opl_mtlb");
2117 break;
2118 case CMD_PTR_CPU_TLBP:
2119 cpu_case_restore(hdl, cpu, &cpu->cpu_opl_tlbp, cp,
2120 "opl_tlbp");
2121 break;
2122 case CMD_PTR_CPU_UGESR_INV_URG:
2123 cpu_case_restore(hdl, cpu, &cpu->cpu_opl_inv_urg, cp,
2124 "opl_inv_urg");
2125 break;
2126 case CMD_PTR_CPU_UGESR_CRE:
2127 cpu_case_restore(hdl, cpu, &cpu->cpu_opl_cre, cp,
2128 "opl_cre");
2129 break;
2130 case CMD_PTR_CPU_UGESR_TSB_CTX:
2131 cpu_case_restore(hdl, cpu, &cpu->cpu_opl_tsb_ctx, cp,
2132 "opl_tsb_ctx");
2133 break;
2134 case CMD_PTR_CPU_UGESR_TSBP:
2135 cpu_case_restore(hdl, cpu, &cpu->cpu_opl_tsbp, cp,
2136 "opl_tsbp");
2137 break;
2138 case CMD_PTR_CPU_UGESR_PSTATE:
2139 cpu_case_restore(hdl, cpu, &cpu->cpu_opl_pstate, cp,
2140 "opl_pstate");
2141 break;
2142 case CMD_PTR_CPU_UGESR_TSTATE:
2143 cpu_case_restore(hdl, cpu, &cpu->cpu_opl_tstate, cp,
2144 "opl_tstate");
2145 break;
2146 case CMD_PTR_CPU_UGESR_IUG_F:
2147 cpu_case_restore(hdl, cpu, &cpu->cpu_opl_iug_f, cp,
2148 "opl_iug_f");
2149 break;
2150 case CMD_PTR_CPU_UGESR_IUG_R:
2151 cpu_case_restore(hdl, cpu, &cpu->cpu_opl_iug_r, cp,
2152 "opl_iug_r");
2153 break;
2154 case CMD_PTR_CPU_UGESR_SDC:
2155 cpu_case_restore(hdl, cpu, &cpu->cpu_opl_sdc, cp,
2156 "opl_sdc");
2157 break;
2158 case CMD_PTR_CPU_UGESR_WDT:
2159 cpu_case_restore(hdl, cpu, &cpu->cpu_opl_wdt, cp,
2160 "opl_wdt");
2161 break;
2162 case CMD_PTR_CPU_UGESR_DTLB:
2163 cpu_case_restore(hdl, cpu, &cpu->cpu_opl_dtlb, cp,
2164 "opl_dtlb");
2165 break;
2166 case CMD_PTR_CPU_UGESR_ITLB:
2167 cpu_case_restore(hdl, cpu, &cpu->cpu_opl_itlb, cp,
2168 "opl_itlb");
2169 break;
2170 case CMD_PTR_CPU_UGESR_CORE_ERR:
2171 cpu_case_restore(hdl, cpu, &cpu->cpu_opl_core_err, cp,
2172 "opl_core_err");
2173 break;
2174 case CMD_PTR_CPU_UGESR_DAE:
2175 cpu_case_restore(hdl, cpu, &cpu->cpu_opl_dae, cp,
2176 "opl_dae");
2177 break;
2178 case CMD_PTR_CPU_UGESR_IAE:
2179 cpu_case_restore(hdl, cpu, &cpu->cpu_opl_iae, cp,
2180 "opl_iae");
2181 break;
2182 case CMD_PTR_CPU_UGESR_UGE:
2183 cpu_case_restore(hdl, cpu, &cpu->cpu_opl_uge, cp,
2184 "opl_uge");
2185 break;
2186 #endif /* sun4u */
2187 default:
2188 fmd_hdl_abort(hdl, "invalid %s subtype %d\n",
2189 ptr->ptr_name, ptr->ptr_subtype);
2192 return (cpu);
2195 void
2196 cmd_cpu_validate(fmd_hdl_t *hdl)
2198 cmd_xr_t *xr, *xrn;
2199 cmd_cpu_t *cpu, *cpun;
2201 for (cpu = cmd_list_next(&cmd.cmd_cpus); cpu != NULL;
2202 cpu = cmd_list_next(cpu)) {
2203 if (cpu_all_threads_invalid(hdl, cpu) == FMD_B_TRUE)
2204 cpu->cpu_flags |= CMD_CPU_F_DELETING;
2207 for (xr = cmd_list_next(&cmd.cmd_xxcu_redelivs); xr != NULL; xr = xrn) {
2208 xrn = cmd_list_next(xr);
2210 if (xr->xr_cpu->cpu_flags & CMD_CPU_F_DELETING)
2211 cmd_xr_destroy(hdl, xr);
2214 for (cpu = cmd_list_next(&cmd.cmd_cpus); cpu != NULL; cpu = cpun) {
2215 cpun = cmd_list_next(cpu);
2217 if (cpu->cpu_flags & CMD_CPU_F_DELETING)
2218 cmd_cpu_destroy(hdl, cpu);
2222 static void
2223 cmd_xxcu_timeout(fmd_hdl_t *hdl, id_t id)
2225 cmd_xr_t *xr;
2227 for (xr = cmd_list_next(&cmd.cmd_xxcu_redelivs); xr != NULL;
2228 xr = cmd_list_next(xr)) {
2229 if (xr->xr_id == id) {
2230 fmd_event_t *ep = fmd_case_getprincipal(hdl,
2231 xr->xr_case);
2232 xr->xr_hdlr(hdl, xr, ep);
2233 cmd_xr_deref(hdl, xr);
2234 return;
2239 /*ARGSUSED*/
2240 static void
2241 cmd_xxu_flush_timeout(fmd_hdl_t *hdl, id_t id)
2243 #ifdef sun4u
2244 cmd_cpu_t *cpu;
2246 for (cpu = cmd_list_next(&cmd.cmd_cpus); cpu != NULL;
2247 cpu = cmd_list_next(cpu)) {
2248 if (cpu->cpu_uec_flush == id) {
2249 cpu_uec_flush_finish(hdl, cpu);
2250 return;
2253 #else /* sun4u */
2254 return;
2255 #endif /* sun4u */
2258 void
2259 cmd_cpu_timeout(fmd_hdl_t *hdl, id_t id, void *type)
2261 switch ((uintptr_t)type) {
2262 case (uintptr_t)CMD_TIMERTYPE_CPU_UEC_FLUSH:
2263 cmd_xxu_flush_timeout(hdl, id);
2264 break;
2265 case (uintptr_t)CMD_TIMERTYPE_CPU_XR_WAITER:
2266 cmd_xxcu_timeout(hdl, id);
2267 break;
2271 static int
2272 cpu_gc_keep_one(fmd_hdl_t *hdl, cmd_cpu_t *cpu)
2274 int i;
2276 if (cpu_all_threads_invalid(hdl, cpu) == FMD_B_TRUE) {
2277 fmd_hdl_debug(hdl, "GC of CPU %d: no longer working\n",
2278 cpu->cpu_cpuid);
2279 return (0);
2282 for (i = 0; i < sizeof (cmd_cpu_cases_t) / sizeof (cmd_case_t); i++) {
2283 cmd_case_t *cp = &((cmd_case_t *)&cpu->cpu_cases)[i];
2285 if (cp->cc_cp == NULL || cp->cc_serdnm == NULL)
2286 continue;
2288 if (fmd_serd_exists(hdl, cp->cc_serdnm) &&
2289 !fmd_serd_empty(hdl, cp->cc_serdnm))
2290 return (1);
2293 if (cmd_list_next(&cpu->cpu_xxu_retries) != NULL)
2294 return (1);
2296 if (cpu->cpu_uec.uec_cache != NULL ||
2297 cpu->cpu_olduec.uec_cache != NULL)
2298 return (1);
2300 return (0);
2303 /*ARGSUSED*/
2304 void
2305 cmd_cpu_gc(fmd_hdl_t *hdl)
2307 cmd_cpu_t *cpu, *next;
2309 fmd_hdl_debug(hdl, "GC of CPUs\n");
2311 for (cpu = cmd_list_next(&cmd.cmd_cpus); cpu != NULL; cpu = next) {
2312 next = cmd_list_next(cpu);
2314 if (!cpu_gc_keep_one(hdl, cpu)) {
2315 fmd_hdl_debug(hdl, "GC of CPU %d: destroying\n",
2316 cpu->cpu_cpuid);
2317 continue;
2319 #ifdef sun4u
2320 if (cpu->cpu_uec.uec_cache != NULL)
2321 cpu_uec_flush(hdl, cpu);
2322 #endif /* sun4u */
2323 cpu->cpu_uec_nflushes = 0;
2327 void
2328 cmd_cpu_fini(fmd_hdl_t *hdl)
2330 cmd_cpu_t *cpu;
2332 while ((cpu = cmd_list_next(&cmd.cmd_cpus)) != NULL)
2333 cmd_cpu_free(hdl, cpu, FMD_B_FALSE);
2336 typedef struct {
2337 const char *fam_name;
2338 cpu_family_t fam_value;
2339 } famdata_t;
2341 static famdata_t famdata_tbl[] = {
2342 {"UltraSPARC-III", CMD_CPU_FAM_CHEETAH},
2343 {"UltraSPARC-IV", CMD_CPU_FAM_CHEETAH},
2344 {"UltraSPARC-T", CMD_CPU_FAM_NIAGARA},
2345 {"SPARC64-VI", CMD_CPU_FAM_SPARC64},
2346 {"SPARC64-VII", CMD_CPU_FAM_SPARC64}
2349 cpu_family_t
2350 cpu_family(char *knsp)
2352 int j;
2354 for (j = 0; j < sizeof (famdata_tbl)/sizeof (famdata_t); j++) {
2355 if (strncmp(knsp, famdata_tbl[j].fam_name,
2356 strlen(famdata_tbl[j].fam_name)) == 0) {
2357 return (famdata_tbl[j].fam_value);
2360 return (CMD_CPU_FAM_UNSUPPORTED);
2364 * Determine which CPU family this diagnosis is being run on.
2365 * This assumes that ereports are being generated by this system.
2368 cpu_family_t
2369 cmd_cpu_check_support(void)
2371 kstat_named_t *kn;
2372 kstat_ctl_t *kc;
2373 kstat_t *ksp;
2374 int i;
2376 if ((kc = kstat_open()) == NULL)
2377 return (CMD_CPU_FAM_UNSUPPORTED);
2379 for (ksp = kc->kc_chain; ksp != NULL; ksp = ksp->ks_next) {
2380 if (strcmp(ksp->ks_module, "cpu_info") != 0)
2381 continue;
2383 if (kstat_read(kc, ksp, NULL) == -1) {
2384 (void) kstat_close(kc);
2385 return (CMD_CPU_FAM_UNSUPPORTED);
2388 for (kn = ksp->ks_data, i = 0; i < ksp->ks_ndata; i++, kn++) {
2389 cpu_family_t family;
2390 if (strcmp(kn->name, "implementation") != 0)
2391 continue;
2392 family = cpu_family(KSTAT_NAMED_STR_PTR(kn));
2393 (void) kstat_close(kc);
2394 return (family);
2397 (void) kstat_close(kc);
2398 return (CMD_CPU_FAM_UNSUPPORTED);
2401 boolean_t
2402 cmd_cpu_ecache_support(void)
2404 cpu_family_t value;
2406 value = cmd_cpu_check_support();
2407 return (fam_info_tbl[value].ecache_flush_needed);
2411 * This function builds the fmri of the
2412 * given cpuid based on the cpu scheme.
2414 nvlist_t *
2415 cmd_cpu_fmri_create(uint32_t cpuid, uint8_t cpumask)
2417 nvlist_t *fmri;
2419 if ((errno = nvlist_alloc(&fmri, NV_UNIQUE_NAME, 0)) != 0)
2420 return (NULL);
2422 if (nvlist_add_uint8(fmri, FM_VERSION,
2423 FM_CPU_SCHEME_VERSION) != 0 || nvlist_add_string(fmri,
2424 FM_FMRI_SCHEME, FM_FMRI_SCHEME_CPU) != 0 ||
2425 nvlist_add_uint32(fmri, FM_FMRI_CPU_ID, cpuid) != 0 ||
2426 nvlist_add_uint8(fmri, FM_FMRI_CPU_MASK, cpumask) != 0) {
2427 nvlist_free(fmri);
2428 return (NULL);
2431 return (fmri);