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 /*
23 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25
26 #include <sys/types.h>
27 #include <sys/cmn_err.h>
28 #include <sys/errno.h>
29 #include <sys/log.h>
30 #include <sys/systm.h>
31 #include <sys/modctl.h>
32 #include <sys/errorq.h>
33 #include <sys/controlregs.h>
34 #include <sys/fm/util.h>
35 #include <sys/fm/protocol.h>
36 #include <sys/sysevent.h>
37 #include <sys/pghw.h>
38 #include <sys/cyclic.h>
39 #include <sys/pci_cfgspace.h>
40 #include <sys/mc_intel.h>
41 #include <sys/smbios.h>
42 #include "nb5000.h"
43 #include "nb_log.h"
44 #include "dimm_phys.h"
45
46 int nb_check_validlog = 1;
47
48 static uint32_t uerrcnt[2];
49 static uint32_t cerrcnta[2][2];
50 static uint32_t cerrcntb[2][2];
51 static uint32_t cerrcntc[2][2];
52 static uint32_t cerrcntd[2][2];
53 static nb_logout_t nb_log;
54
55 struct mch_error_code {
56 int intel_error_list; /* error number in Chipset Error List */
57 uint32_t emask; /* mask for machine check */
58 uint32_t error_bit; /* error bit in fault register */
59 };
60
61 static struct mch_error_code fat_fbd_error_code[] = {
62 { 23, EMASK_FBD_M23, ERR_FAT_FBD_M23 },
63 { 3, EMASK_FBD_M3, ERR_FAT_FBD_M3 },
64 { 2, EMASK_FBD_M2, ERR_FAT_FBD_M2 },
65 { 1, EMASK_FBD_M1, ERR_FAT_FBD_M1 }
66 };
67
68 static int
intel_fat_fbd_err(uint32_t fat_fbd)69 intel_fat_fbd_err(uint32_t fat_fbd)
70 {
71 int rt = -1;
72 int nerr = 0;
73 uint32_t emask_fbd = 0;
74 int i;
75 int sz;
76
77 sz = sizeof (fat_fbd_error_code) / sizeof (struct mch_error_code);
78
79 for (i = 0; i < sz; i++) {
80 if (fat_fbd & fat_fbd_error_code[i].error_bit) {
81 rt = fat_fbd_error_code[i].intel_error_list;
82 emask_fbd |= fat_fbd_error_code[i].emask;
83 nerr++;
84 }
85 }
86
87 if (emask_fbd)
88 nb_fbd_mask_mc(emask_fbd);
89 if (nerr > 1)
90 rt = -1;
91 return (rt);
92 }
93
94 static char *
fat_memory_error(const nb_regs_t * rp,void * data)95 fat_memory_error(const nb_regs_t *rp, void *data)
96 {
97 int channel;
98 uint32_t ferr_fat_fbd, nrecmemb;
99 uint32_t nrecmema;
100 char *intr = "nb.unknown";
101 nb_mem_scatchpad_t *sp = &((nb_scatchpad_t *)data)->ms;
102
103 ferr_fat_fbd = rp->nb.fat_fbd_regs.ferr_fat_fbd;
104 if ((ferr_fat_fbd & ERR_FAT_FBD_MASK) == 0) {
105 sp->intel_error_list =
106 intel_fat_fbd_err(rp->nb.fat_fbd_regs.nerr_fat_fbd);
107 sp->branch = -1;
108 sp->channel = -1;
109 sp->rank = -1;
110 sp->dimm = -1;
111 sp->bank = -1;
112 sp->cas = -1;
113 sp->ras = -1;
114 sp->pa = -1LL;
115 sp->offset = -1;
116 return (intr);
117 }
118 sp->intel_error_list = intel_fat_fbd_err(ferr_fat_fbd);
119 channel = (ferr_fat_fbd >> 28) & 3;
120 sp->branch = channel >> 1;
121 sp->channel = channel;
122 if ((ferr_fat_fbd & (ERR_FAT_FBD_M2|ERR_FAT_FBD_M1)) != 0) {
123 if ((ferr_fat_fbd & ERR_FAT_FBD_M1) != 0)
124 intr = "nb.fbd.alert"; /* Alert on FB-DIMM M1 */
125 else
126 intr = "nb.fbd.crc"; /* CRC error FB_DIMM M2 */
127 nrecmema = rp->nb.fat_fbd_regs.nrecmema;
128 nrecmemb = rp->nb.fat_fbd_regs.nrecmemb;
129 sp->rank = (nrecmema >> 8) & RANK_MASK;
130 sp->dimm = sp->rank >> 1;
131 sp->bank = (nrecmema >> 12) & BANK_MASK;
132 sp->cas = (nrecmemb >> 16) & CAS_MASK;
133 sp->ras = nrecmemb & RAS_MASK;
134 /*
135 * If driver was built with closed tree present then we will
136 * have Intel proprietary code for finding physaddr
137 */
138 if (&dimm_getphys) {
139 sp->pa = dimm_getphys((uint16_t)sp->branch,
140 (uint16_t)sp->rank, (uint64_t)sp->bank,
141 (uint64_t)sp->ras, (uint64_t)sp->cas);
142 if (sp->pa >= MAXPHYS_ADDR)
143 sp->pa = -1ULL;
144 } else {
145 sp->pa = -1ULL;
146 }
147 /*
148 * If there is an offset decoder use it otherwise encode
149 * rank/bank/ras/cas
150 */
151 if (&dimm_getoffset) {
152 sp->offset = dimm_getoffset(sp->branch, sp->rank,
153 sp->bank, sp->ras, sp->cas);
154 } else {
155 sp->offset = TCODE_OFFSET(sp->rank, sp->bank, sp->ras,
156 sp->cas);
157 }
158 } else {
159 if ((ferr_fat_fbd & ERR_FAT_FBD_M3) != 0)
160 intr = "nb.fbd.otf"; /* thermal temp > Tmid M3 */
161 else if ((ferr_fat_fbd & ERR_FAT_FBD_M23) != 0) {
162 intr = "nb.fbd.reset_timeout";
163 sp->channel = -1;
164 }
165 sp->rank = -1;
166 sp->dimm = -1;
167 sp->bank = -1;
168 sp->cas = -1;
169 sp->ras = -1;
170 sp->pa = -1LL;
171 sp->offset = -1;
172 }
173 return (intr);
174 }
175
176
177 static struct mch_error_code nf_fbd_error_code[] = {
178 { 29, EMASK_FBD_M29, ERR_NF_FBD_M29 },
179 { 28, EMASK_FBD_M28, ERR_NF_FBD_M28 },
180 { 27, EMASK_FBD_M27, ERR_NF_FBD_M27 },
181 { 26, EMASK_FBD_M26, ERR_NF_FBD_M26 },
182 { 25, EMASK_FBD_M25, ERR_NF_FBD_M25 },
183 { 24, EMASK_FBD_M24, ERR_NF_FBD_M24 },
184 { 22, EMASK_FBD_M22, ERR_NF_FBD_M22 },
185 { 21, EMASK_FBD_M21, ERR_NF_FBD_M21 },
186 { 20, EMASK_FBD_M20, ERR_NF_FBD_M20 },
187 { 19, EMASK_FBD_M19, ERR_NF_FBD_M19 },
188 { 18, EMASK_FBD_M18, ERR_NF_FBD_M18 },
189 { 17, EMASK_FBD_M17, ERR_NF_FBD_M17 },
190 { 16, EMASK_FBD_M16, ERR_NF_FBD_M16 },
191 { 15, EMASK_FBD_M15, ERR_NF_FBD_M15 },
192 { 14, EMASK_FBD_M14, ERR_NF_FBD_M14 },
193 { 13, EMASK_FBD_M13, ERR_NF_FBD_M13 },
194 { 12, EMASK_FBD_M12, ERR_NF_FBD_M12 },
195 { 11, EMASK_FBD_M11, ERR_NF_FBD_M11 },
196 { 10, EMASK_FBD_M10, ERR_NF_FBD_M10 },
197 { 9, EMASK_FBD_M9, ERR_NF_FBD_M9 },
198 { 8, EMASK_FBD_M8, ERR_NF_FBD_M8 },
199 { 7, EMASK_FBD_M7, ERR_NF_FBD_M7 },
200 { 6, EMASK_FBD_M6, ERR_NF_FBD_M6 },
201 { 5, EMASK_FBD_M5, ERR_NF_FBD_M5 },
202 { 4, EMASK_FBD_M4, ERR_NF_FBD_M4 }
203 };
204
205 static int
intel_nf_fbd_err(uint32_t nf_fbd)206 intel_nf_fbd_err(uint32_t nf_fbd)
207 {
208 int rt = -1;
209 int nerr = 0;
210 uint32_t emask_fbd = 0;
211 int i;
212 int sz;
213
214 sz = sizeof (nf_fbd_error_code) / sizeof (struct mch_error_code);
215
216 for (i = 0; i < sz; i++) {
217 if (nf_fbd & nf_fbd_error_code[i].error_bit) {
218 rt = nf_fbd_error_code[i].intel_error_list;
219 emask_fbd |= nf_fbd_error_code[i].emask;
220 nerr++;
221 }
222 }
223 if (emask_fbd)
224 nb_fbd_mask_mc(emask_fbd);
225 if (nerr > 1)
226 rt = -1;
227 return (rt);
228 }
229
230 static char *
nf_memory_error(const nb_regs_t * rp,void * data)231 nf_memory_error(const nb_regs_t *rp, void *data)
232 {
233 uint32_t ferr_nf_fbd, recmemb, redmemb;
234 uint32_t recmema;
235 int branch, channel, ecc_locator;
236 char *intr = "nb.unknown";
237 nb_mem_scatchpad_t *sp = &((nb_scatchpad_t *)data)->ms;
238
239 sp->rank = -1;
240 sp->dimm = -1;
241 sp->bank = -1;
242 sp->cas = -1;
243 sp->ras = -1LL;
244 sp->pa = -1LL;
245 sp->offset = -1;
246 ferr_nf_fbd = rp->nb.nf_fbd_regs.ferr_nf_fbd;
247 if ((ferr_nf_fbd & ERR_NF_FBD_MASK) == 0) {
248 /* unknown ereport if a recognizable error was not found */
249 sp->branch = -1;
250 sp->channel = -1;
251 sp->intel_error_list = -1;
252 return (intr);
253 }
254 sp->intel_error_list = intel_nf_fbd_err(ferr_nf_fbd);
255 channel = (ferr_nf_fbd >> ERR_FBD_CH_SHIFT) & 3;
256 branch = channel >> 1;
257 sp->branch = branch;
258 sp->channel = channel;
259 if (ferr_nf_fbd & ERR_NF_FBD_MASK) {
260 if (ferr_nf_fbd & ERR_NF_FBD_ECC_UE) {
261 /*
262 * uncorrectable ECC M4 - M12
263 * we can only isolate to pair of dimms
264 * for single dimm configuration let eversholt
265 * sort it out with out needing a special rule
266 */
267 sp->channel = -1;
268 recmema = rp->nb.nf_fbd_regs.recmema;
269 recmemb = rp->nb.nf_fbd_regs.recmemb;
270 sp->rank = (recmema >> 8) & RANK_MASK;
271 sp->bank = (recmema >> 12) & BANK_MASK;
272 sp->cas = (recmemb >> 16) & CAS_MASK;
273 sp->ras = recmemb & RAS_MASK;
274 intr = "nb.mem_ue";
275 } else if (ferr_nf_fbd & ERR_NF_FBD_M13) {
276 /*
277 * write error M13
278 * we can only isolate to pair of dimms
279 */
280 sp->channel = -1;
281 if (nb_mode != NB_MEMORY_MIRROR) {
282 recmema = rp->nb.nf_fbd_regs.recmema;
283 recmemb = rp->nb.nf_fbd_regs.recmemb;
284 sp->rank = (recmema >> 8) & RANK_MASK;
285 sp->bank = (recmema >> 12) & BANK_MASK;
286 sp->cas = (recmemb >> 16) & CAS_MASK;
287 sp->ras = recmemb & RAS_MASK;
288 }
289 intr = "nb.fbd.ma"; /* memory alert */
290 } else if (ferr_nf_fbd & ERR_NF_FBD_MA) { /* M14, M15 and M21 */
291 intr = "nb.fbd.ch"; /* FBD on channel */
292 } else if ((ferr_nf_fbd & ERR_NF_FBD_ECC_CE) != 0) {
293 /* correctable ECC M17-M20 */
294 recmema = rp->nb.nf_fbd_regs.recmema;
295 recmemb = rp->nb.nf_fbd_regs.recmemb;
296 sp->rank = (recmema >> 8) & RANK_MASK;
297 redmemb = rp->nb.nf_fbd_regs.redmemb;
298 ecc_locator = redmemb & 0x3ffff;
299 if (ecc_locator & 0x1ff)
300 sp->channel = branch << 1;
301 else if (ecc_locator & 0x3fe00)
302 sp->channel = (branch << 1) + 1;
303 sp->dimm = sp->rank >> 1;
304 sp->bank = (recmema >> 12) & BANK_MASK;
305 sp->cas = (recmemb >> 16) & CAS_MASK;
306 sp->ras = recmemb & RAS_MASK;
307 intr = "nb.mem_ce";
308 } else if ((ferr_nf_fbd & ERR_NF_FBD_SPARE) != 0) {
309 /* spare dimm M27, M28 */
310 intr = "nb.mem_ds";
311 sp->channel = -1;
312 if (rp->nb.nf_fbd_regs.spcps & SPCPS_SPARE_DEPLOYED) {
313 sp->rank =
314 SPCPS_FAILED_RANK(rp->nb.nf_fbd_regs.spcps);
315 nb_used_spare_rank(sp->branch, sp->rank);
316 nb_config_gen++;
317 }
318 } else if ((ferr_nf_fbd & ERR_NF_FBD_M22) != 0) {
319 intr = "nb.spd"; /* SPD protocol */
320 }
321 }
322 if (sp->ras != -1) {
323 /*
324 * If driver was built with closed tree present then we will
325 * have Intel proprietary code for finding physaddr
326 */
327 if (&dimm_getphys) {
328 sp->pa = dimm_getphys((uint16_t)sp->branch,
329 (uint16_t)sp->rank, (uint64_t)sp->bank,
330 (uint64_t)sp->ras, (uint64_t)sp->cas);
331 if (sp->pa >= MAXPHYS_ADDR)
332 sp->pa = -1ULL;
333 } else {
334 sp->pa = -1ULL;
335 }
336 if (&dimm_getoffset) {
337 sp->offset = dimm_getoffset(sp->branch, sp->rank,
338 sp->bank, sp->ras, sp->cas);
339 } else {
340 sp->offset = TCODE_OFFSET(sp->rank, sp->bank, sp->ras,
341 sp->cas);
342 }
343 }
344 return (intr);
345 }
346
347 static struct mch_error_code nf_mem_error_code[] = {
348 { 21, EMASK_MEM_M21, ERR_NF_MEM_M21 },
349 { 20, EMASK_MEM_M20, ERR_NF_MEM_M20 },
350 { 18, EMASK_MEM_M18, ERR_NF_MEM_M18 },
351 { 16, EMASK_MEM_M16, ERR_NF_MEM_M16 },
352 { 15, EMASK_MEM_M15, ERR_NF_MEM_M15 },
353 { 14, EMASK_MEM_M14, ERR_NF_MEM_M14 },
354 { 12, EMASK_MEM_M12, ERR_NF_MEM_M12 },
355 { 11, EMASK_MEM_M11, ERR_NF_MEM_M11 },
356 { 10, EMASK_MEM_M10, ERR_NF_MEM_M10 },
357 { 6, EMASK_MEM_M6, ERR_NF_MEM_M6 },
358 { 5, EMASK_MEM_M5, ERR_NF_MEM_M5 },
359 { 4, EMASK_MEM_M4, ERR_NF_MEM_M4 },
360 { 1, EMASK_MEM_M1, ERR_NF_MEM_M1 }
361 };
362
363 static int
intel_nf_mem_err(uint32_t nf_mem)364 intel_nf_mem_err(uint32_t nf_mem)
365 {
366 int rt = -1;
367 int nerr = 0;
368 uint32_t emask_mem = 0;
369 int i;
370 int sz;
371
372 sz = sizeof (nf_mem_error_code) / sizeof (struct mch_error_code);
373
374 for (i = 0; i < sz; i++) {
375 if (nf_mem & nf_mem_error_code[i].error_bit) {
376 rt = nf_mem_error_code[i].intel_error_list;
377 emask_mem |= nf_mem_error_code[i].emask;
378 nerr++;
379 }
380 }
381 if (emask_mem)
382 nb_mem_mask_mc(emask_mem);
383 if (nerr > 1)
384 rt = -1;
385 return (rt);
386 }
387
388 static char *
nf_mem_error(const nb_regs_t * rp,void * data)389 nf_mem_error(const nb_regs_t *rp, void *data)
390 {
391 uint32_t ferr_nf_mem, recmema, recmemb;
392 uint32_t nrecmema, nrecmemb, validlog;
393 int channel;
394 char *intr = "nb.unknown";
395 nb_mem_scatchpad_t *sp = &((nb_scatchpad_t *)data)->ms;
396
397 sp->rank = -1;
398 sp->dimm = -1;
399 sp->bank = -1;
400 sp->cas = -1;
401 sp->ras = -1LL;
402 sp->pa = -1LL;
403 sp->offset = -1;
404 ferr_nf_mem = rp->nb.nf_mem_regs.ferr_nf_mem;
405 if ((ferr_nf_mem & ERR_NF_MEM_MASK) == 0) {
406 /* no first error found */
407 sp->branch = -1;
408 sp->channel = -1;
409 sp->intel_error_list =
410 intel_nf_mem_err(rp->nb.nf_mem_regs.nerr_nf_mem);
411 return (intr);
412 }
413 sp->intel_error_list = intel_nf_mem_err(ferr_nf_mem);
414
415 channel = (ferr_nf_mem >> ERR_MEM_CH_SHIFT) & 0x1;
416 sp->branch = channel;
417 sp->channel = -1;
418 if (ferr_nf_mem & ERR_NF_MEM_MASK) {
419 if (ferr_nf_mem & ERR_NF_MEM_ECC_UE) {
420 /*
421 * uncorrectable ECC M1,M4-M6,M10-M12
422 * There is only channel per branch
423 * Invalidate the channel number so the mem ereport
424 * has the same detector with existing 5000 ereports.
425 * so we can leverage the existing Everhsolt rule.
426 */
427 validlog = rp->nb.nf_mem_regs.validlog;
428 if (ferr_nf_mem & ERR_NF_MEM_M1) {
429 nrecmema = rp->nb.nf_mem_regs.nrecmema;
430 nrecmemb = rp->nb.nf_mem_regs.nrecmemb;
431 /* check if the nrecmem log is valid */
432 if (validlog & 0x1 || nb_check_validlog == 0) {
433 sp->rank = (nrecmema >> 8) & RANK_MASK;
434 sp->bank = (nrecmema >> 12) & BANK_MASK;
435 sp->cas = (nrecmemb >> 16) & CAS_MASK;
436 sp->ras = nrecmemb & RAS_MASK;
437 }
438 } else {
439 recmema = rp->nb.nf_mem_regs.recmema;
440 recmemb = rp->nb.nf_mem_regs.recmemb;
441 /* check if the recmem log is valid */
442 if (validlog & 0x2 || nb_check_validlog == 0) {
443 sp->rank = (recmema >> 8) & RANK_MASK;
444 sp->bank = (recmema >> 12) & BANK_MASK;
445 sp->cas = (recmemb >> 16) & CAS_MASK;
446 sp->ras = recmemb & RAS_MASK;
447 }
448 }
449 intr = "nb.ddr2_mem_ue";
450 } else if ((ferr_nf_mem & ERR_NF_MEM_ECC_CE) != 0) {
451 /* correctable ECC M14-M16 */
452 recmema = rp->nb.nf_mem_regs.recmema;
453 recmemb = rp->nb.nf_mem_regs.recmemb;
454 validlog = rp->nb.nf_mem_regs.validlog;
455 /* check if the recmem log is valid */
456 if (validlog & 0x2 || nb_check_validlog == 0) {
457 sp->channel = channel;
458 sp->rank = (recmema >> 8) & RANK_MASK;
459 sp->dimm = nb_rank2dimm(sp->channel, sp->rank);
460 sp->bank = (recmema >> 12) & BANK_MASK;
461 sp->cas = (recmemb >> 16) & CAS_MASK;
462 sp->ras = recmemb & RAS_MASK;
463 }
464 intr = "nb.ddr2_mem_ce";
465 } else if ((ferr_nf_mem & ERR_NF_MEM_SPARE) != 0) {
466 /* spare dimm M20, M21 */
467 intr = "nb.ddr2_mem_ds";
468
469 /*
470 * The channel can be valid here.
471 * However, there is only one channel per branch and
472 * to leverage the eversolt rules of other chipsets,
473 * the channel is ignored and let the rule find it out
474 * from the topology.
475 */
476 if (rp->nb.nf_mem_regs.spcps & SPCPS_SPARE_DEPLOYED) {
477 sp->rank =
478 SPCPS_FAILED_RANK(rp->nb.nf_mem_regs.spcps);
479 nb_used_spare_rank(sp->branch, sp->rank);
480 nb_config_gen++;
481 }
482 } else if ((ferr_nf_mem & ERR_NF_MEM_M18) != 0) {
483 sp->channel = channel;
484 intr = "nb.ddr2_spd"; /* SPD protocol */
485
486 }
487 }
488 if (sp->ras != -1) {
489 /*
490 * If driver was built with closed tree present then we will
491 * have Intel proprietary code for finding physaddr
492 */
493 if (&dimm_getphys) {
494 sp->pa = dimm_getphys((uint16_t)sp->branch,
495 (uint16_t)sp->rank, (uint64_t)sp->bank,
496 (uint64_t)sp->ras, (uint64_t)sp->cas);
497 if (sp->pa >= MAXPHYS_ADDR)
498 sp->pa = -1ULL;
499 } else {
500 sp->pa = -1ULL;
501 }
502 if (&dimm_getoffset) {
503 sp->offset = dimm_getoffset(sp->branch, sp->rank,
504 sp->bank, sp->ras, sp->cas);
505 } else {
506 sp->offset = TCODE_OFFSET(sp->rank, sp->bank, sp->ras,
507 sp->cas);
508 }
509 }
510 return (intr);
511 }
512
513 static struct mch_error_code fat_int_error_code[] = {
514 { 14, EMASK_INT_B14, ERR_FAT_INT_B14 },
515 { 12, EMASK_INT_B12, ERR_FAT_INT_B12 },
516 { 25, EMASK_INT_B25, ERR_FAT_INT_B25 },
517 { 23, EMASK_INT_B23, ERR_FAT_INT_B23 },
518 { 21, EMASK_INT_B21, ERR_FAT_INT_B21 },
519 { 7, EMASK_INT_B7, ERR_FAT_INT_B7 },
520 { 4, EMASK_INT_B4, ERR_FAT_INT_B4 },
521 { 3, EMASK_INT_B3, ERR_FAT_INT_B3 },
522 { 2, EMASK_INT_B2, ERR_FAT_INT_B2 },
523 { 1, EMASK_INT_B1, ERR_FAT_INT_B1 }
524 };
525
526 static struct mch_error_code nf_int_error_code[] = {
527 { 27, 0, ERR_NF_INT_B27 },
528 { 24, 0, ERR_NF_INT_B24 },
529 { 22, EMASK_INT_B22, ERR_NF_INT_B22 },
530 { 20, EMASK_INT_B20, ERR_NF_INT_B20 },
531 { 19, EMASK_INT_B19, ERR_NF_INT_B19 },
532 { 18, 0, ERR_NF_INT_B18 },
533 { 17, 0, ERR_NF_INT_B17 },
534 { 16, 0, ERR_NF_INT_B16 },
535 { 11, EMASK_INT_B11, ERR_NF_INT_B11 },
536 { 10, EMASK_INT_B10, ERR_NF_INT_B10 },
537 { 9, EMASK_INT_B9, ERR_NF_INT_B9 },
538 { 8, EMASK_INT_B8, ERR_NF_INT_B8 },
539 { 6, EMASK_INT_B6, ERR_NF_INT_B6 },
540 { 5, EMASK_INT_B5, ERR_NF_INT_B5 }
541 };
542
543 static int
intel_int_err(uint16_t err_fat_int,uint16_t err_nf_int)544 intel_int_err(uint16_t err_fat_int, uint16_t err_nf_int)
545 {
546 int rt = -1;
547 int nerr = 0;
548 uint32_t emask_int = 0;
549 int i;
550 int sz;
551
552 sz = sizeof (fat_int_error_code) / sizeof (struct mch_error_code);
553
554 for (i = 0; i < sz; i++) {
555 if (err_fat_int & fat_int_error_code[i].error_bit) {
556 rt = fat_int_error_code[i].intel_error_list;
557 emask_int |= fat_int_error_code[i].emask;
558 nerr++;
559 }
560 }
561
562 if (nb_chipset == INTEL_NB_5400 &&
563 (err_nf_int & NERR_NF_5400_INT_B26) != 0) {
564 err_nf_int &= ~NERR_NF_5400_INT_B26;
565 rt = 26;
566 nerr++;
567 }
568
569 if (rt)
570 err_nf_int &= ~ERR_NF_INT_B18;
571
572 sz = sizeof (nf_int_error_code) / sizeof (struct mch_error_code);
573
574 for (i = 0; i < sz; i++) {
575 if (err_nf_int & nf_int_error_code[i].error_bit) {
576 rt = nf_int_error_code[i].intel_error_list;
577 emask_int |= nf_int_error_code[i].emask;
578 nerr++;
579 }
580 }
581
582 if (emask_int)
583 nb_int_mask_mc(emask_int);
584 if (nerr > 1)
585 rt = -1;
586 return (rt);
587 }
588
589 static int
log_int_err(nb_regs_t * rp,int willpanic,int * interpose)590 log_int_err(nb_regs_t *rp, int willpanic, int *interpose)
591 {
592 int t = 0;
593 int rt = 0;
594
595 rp->flag = NB_REG_LOG_INT;
596 rp->nb.int_regs.ferr_fat_int = FERR_FAT_INT_RD(interpose);
597 rp->nb.int_regs.ferr_nf_int = FERR_NF_INT_RD(&t);
598 *interpose |= t;
599 rp->nb.int_regs.nerr_fat_int = NERR_FAT_INT_RD(&t);
600 *interpose |= t;
601 rp->nb.int_regs.nerr_nf_int = NERR_NF_INT_RD(&t);
602 *interpose |= t;
603 rp->nb.int_regs.nrecint = NRECINT_RD();
604 rp->nb.int_regs.recint = RECINT_RD();
605 rp->nb.int_regs.nrecsf = NRECSF_RD();
606 rp->nb.int_regs.recsf = RECSF_RD();
607
608 if (!willpanic) {
609 if (rp->nb.int_regs.ferr_fat_int || *interpose)
610 FERR_FAT_INT_WR(rp->nb.int_regs.ferr_fat_int);
611 if (rp->nb.int_regs.ferr_nf_int || *interpose)
612 FERR_NF_INT_WR(rp->nb.int_regs.ferr_nf_int);
613 if (rp->nb.int_regs.nerr_fat_int)
614 NERR_FAT_INT_WR(rp->nb.int_regs.nerr_fat_int);
615 if (rp->nb.int_regs.nerr_nf_int)
616 NERR_NF_INT_WR(rp->nb.int_regs.nerr_nf_int);
617 /*
618 * if interpose write read-only registers to clear from pcii
619 * cache
620 */
621 if (*interpose) {
622 NRECINT_WR();
623 RECINT_WR();
624 NRECSF_WR();
625 RECSF_WR();
626 }
627 }
628 if (rp->nb.int_regs.ferr_fat_int == 0 &&
629 rp->nb.int_regs.nerr_fat_int == 0 &&
630 (rp->nb.int_regs.ferr_nf_int == ERR_NF_INT_B18 ||
631 (rp->nb.int_regs.ferr_nf_int == 0 &&
632 rp->nb.int_regs.nerr_nf_int == ERR_NF_INT_B18))) {
633 rt = 1;
634 }
635 return (rt);
636 }
637
638 static void
log_thermal_err(nb_regs_t * rp,int willpanic,int * interpose)639 log_thermal_err(nb_regs_t *rp, int willpanic, int *interpose)
640 {
641 int t = 0;
642
643 rp->flag = NB_REG_LOG_THR;
644 rp->nb.thr_regs.ferr_fat_thr = FERR_FAT_THR_RD(interpose);
645 rp->nb.thr_regs.nerr_fat_thr = NERR_FAT_THR_RD(&t);
646 *interpose |= t;
647 rp->nb.thr_regs.ferr_nf_thr = FERR_NF_THR_RD(&t);
648 *interpose |= t;
649 rp->nb.thr_regs.nerr_nf_thr = NERR_NF_THR_RD(&t);
650 *interpose |= t;
651 rp->nb.thr_regs.ctsts = CTSTS_RD();
652 rp->nb.thr_regs.thrtsts = THRTSTS_RD();
653
654 if (!willpanic) {
655 if (rp->nb.thr_regs.ferr_fat_thr || *interpose)
656 FERR_FAT_THR_WR(rp->nb.thr_regs.ferr_fat_thr);
657 if (rp->nb.thr_regs.nerr_fat_thr || *interpose)
658 NERR_FAT_THR_WR(rp->nb.thr_regs.nerr_fat_thr);
659 if (rp->nb.thr_regs.ferr_nf_thr || *interpose)
660 FERR_NF_THR_WR(rp->nb.thr_regs.ferr_nf_thr);
661 if (rp->nb.thr_regs.nerr_nf_thr || *interpose)
662 NERR_NF_THR_WR(rp->nb.thr_regs.nerr_nf_thr);
663
664 if (*interpose) {
665 CTSTS_WR(rp->nb.thr_regs.ctsts);
666 THRTSTS_WR(rp->nb.thr_regs.thrtsts);
667 }
668 }
669 }
670
671 static void
log_dma_err(nb_regs_t * rp,int * interpose)672 log_dma_err(nb_regs_t *rp, int *interpose)
673 {
674 rp->flag = NB_REG_LOG_DMA;
675
676 rp->nb.dma_regs.pcists = PCISTS_RD(interpose);
677 rp->nb.dma_regs.pexdevsts = PCIDEVSTS_RD();
678 }
679
680 static struct mch_error_code fat_fsb_error_code[] = {
681 { 9, EMASK_FSB_F9, ERR_FAT_FSB_F9 },
682 { 2, EMASK_FSB_F2, ERR_FAT_FSB_F2 },
683 { 1, EMASK_FSB_F1, ERR_FAT_FSB_F1 }
684 };
685
686 static struct mch_error_code nf_fsb_error_code[] = {
687 { 8, EMASK_FSB_F8, ERR_NF_FSB_F8 },
688 { 7, EMASK_FSB_F7, ERR_NF_FSB_F7 },
689 { 6, EMASK_FSB_F6, ERR_NF_FSB_F6 }
690 };
691
692 static int
intel_fsb_err(int fsb,uint8_t err_fat_fsb,uint8_t err_nf_fsb)693 intel_fsb_err(int fsb, uint8_t err_fat_fsb, uint8_t err_nf_fsb)
694 {
695 int rt = -1;
696 int nerr = 0;
697 uint16_t emask_fsb = 0;
698 int i;
699 int sz;
700
701 sz = sizeof (fat_fsb_error_code) / sizeof (struct mch_error_code);
702
703 for (i = 0; i < sz; i++) {
704 if (err_fat_fsb & fat_fsb_error_code[i].error_bit) {
705 rt = fat_fsb_error_code[i].intel_error_list;
706 emask_fsb |= fat_fsb_error_code[i].emask;
707 nerr++;
708 }
709 }
710
711 sz = sizeof (nf_fsb_error_code) / sizeof (struct mch_error_code);
712
713 for (i = 0; i < sz; i++) {
714 if (err_nf_fsb & nf_fsb_error_code[i].error_bit) {
715 rt = nf_fsb_error_code[i].intel_error_list;
716 emask_fsb |= nf_fsb_error_code[i].emask;
717 nerr++;
718 }
719 }
720
721 if (emask_fsb)
722 nb_fsb_mask_mc(fsb, emask_fsb);
723 if (nerr > 1)
724 rt = -1;
725 return (rt);
726 }
727
728 static void
log_fsb_err(uint64_t ferr,nb_regs_t * rp,int willpanic,int * interpose)729 log_fsb_err(uint64_t ferr, nb_regs_t *rp, int willpanic, int *interpose)
730 {
731 uint8_t fsb;
732 int t = 0;
733
734 fsb = GE_FERR_FSB(ferr);
735 rp->flag = NB_REG_LOG_FSB;
736
737 rp->nb.fsb_regs.fsb = fsb;
738 rp->nb.fsb_regs.ferr_fat_fsb = FERR_FAT_FSB_RD(fsb, interpose);
739 rp->nb.fsb_regs.ferr_nf_fsb = FERR_NF_FSB_RD(fsb, &t);
740 *interpose |= t;
741 rp->nb.fsb_regs.nerr_fat_fsb = NERR_FAT_FSB_RD(fsb, &t);
742 *interpose |= t;
743 rp->nb.fsb_regs.nerr_nf_fsb = NERR_NF_FSB_RD(fsb, &t);
744 *interpose |= t;
745 rp->nb.fsb_regs.nrecfsb = NRECFSB_RD(fsb);
746 rp->nb.fsb_regs.nrecfsb_addr = NRECADDR_RD(fsb);
747 rp->nb.fsb_regs.recfsb = RECFSB_RD(fsb);
748 if (!willpanic) {
749 /* Clear the fatal/non-fatal first/next FSB errors */
750 if (rp->nb.fsb_regs.ferr_fat_fsb || *interpose)
751 FERR_FAT_FSB_WR(fsb, rp->nb.fsb_regs.ferr_fat_fsb);
752 if (rp->nb.fsb_regs.ferr_nf_fsb || *interpose)
753 FERR_NF_FSB_WR(fsb, rp->nb.fsb_regs.ferr_nf_fsb);
754 if (rp->nb.fsb_regs.nerr_fat_fsb || *interpose)
755 NERR_FAT_FSB_WR(fsb, rp->nb.fsb_regs.nerr_fat_fsb);
756 if (rp->nb.fsb_regs.nerr_nf_fsb || *interpose)
757 NERR_NF_FSB_WR(fsb, rp->nb.fsb_regs.nerr_nf_fsb);
758
759 /*
760 * if interpose write read-only registers to clear from pcii
761 * cache
762 */
763 if (*interpose) {
764 NRECFSB_WR(fsb);
765 NRECADDR_WR(fsb);
766 RECFSB_WR(fsb);
767 }
768 }
769 }
770
771 static struct mch_error_code fat_pex_error_code[] = {
772 { 19, EMASK_UNCOR_PEX_IO19, PEX_FAT_IO19 },
773 { 18, EMASK_UNCOR_PEX_IO18, PEX_FAT_IO18 },
774 { 10, EMASK_UNCOR_PEX_IO10, PEX_FAT_IO10 },
775 { 9, EMASK_UNCOR_PEX_IO9, PEX_FAT_IO9 },
776 { 8, EMASK_UNCOR_PEX_IO8, PEX_FAT_IO8 },
777 { 7, EMASK_UNCOR_PEX_IO7, PEX_FAT_IO7 },
778 { 6, EMASK_UNCOR_PEX_IO6, PEX_FAT_IO6 },
779 { 5, EMASK_UNCOR_PEX_IO5, PEX_FAT_IO5 },
780 { 4, EMASK_UNCOR_PEX_IO4, PEX_FAT_IO4 },
781 { 3, EMASK_UNCOR_PEX_IO3, PEX_FAT_IO3 },
782 { 2, EMASK_UNCOR_PEX_IO2, PEX_FAT_IO2 },
783 { 0, EMASK_UNCOR_PEX_IO0, PEX_FAT_IO0 }
784 };
785
786 static struct mch_error_code fat_unit_pex_5400_error_code[] = {
787 { 32, EMASK_UNIT_PEX_IO32, PEX_5400_FAT_IO32 },
788 { 31, EMASK_UNIT_PEX_IO31, PEX_5400_FAT_IO31 },
789 { 30, EMASK_UNIT_PEX_IO30, PEX_5400_FAT_IO30 },
790 { 29, EMASK_UNIT_PEX_IO29, PEX_5400_FAT_IO29 },
791 { 27, EMASK_UNIT_PEX_IO27, PEX_5400_FAT_IO27 },
792 { 26, EMASK_UNIT_PEX_IO26, PEX_5400_FAT_IO26 },
793 { 25, EMASK_UNIT_PEX_IO25, PEX_5400_FAT_IO25 },
794 { 24, EMASK_UNIT_PEX_IO24, PEX_5400_FAT_IO24 },
795 { 23, EMASK_UNIT_PEX_IO23, PEX_5400_FAT_IO23 },
796 { 22, EMASK_UNIT_PEX_IO22, PEX_5400_FAT_IO22 },
797 };
798
799 static struct mch_error_code fat_pex_5400_error_code[] = {
800 { 19, EMASK_UNCOR_PEX_IO19, PEX_5400_FAT_IO19 },
801 { 18, EMASK_UNCOR_PEX_IO18, PEX_5400_FAT_IO18 },
802 { 10, EMASK_UNCOR_PEX_IO10, PEX_5400_FAT_IO10 },
803 { 9, EMASK_UNCOR_PEX_IO9, PEX_5400_FAT_IO9 },
804 { 8, EMASK_UNCOR_PEX_IO8, PEX_5400_FAT_IO8 },
805 { 7, EMASK_UNCOR_PEX_IO7, PEX_5400_FAT_IO7 },
806 { 6, EMASK_UNCOR_PEX_IO6, PEX_5400_FAT_IO6 },
807 { 5, EMASK_UNCOR_PEX_IO5, PEX_5400_FAT_IO5 },
808 { 4, EMASK_UNCOR_PEX_IO4, PEX_5400_FAT_IO4 },
809 { 2, EMASK_UNCOR_PEX_IO2, PEX_5400_FAT_IO2 },
810 { 0, EMASK_UNCOR_PEX_IO0, PEX_5400_FAT_IO0 }
811 };
812
813 static struct mch_error_code fat_rp_5400_error_code[] = {
814 { 1, EMASK_RP_PEX_IO1, PEX_5400_FAT_IO1 }
815 };
816
817 static struct mch_error_code fat_rp_error_code[] = {
818 { 1, EMASK_RP_PEX_IO1, PEX_FAT_IO1 }
819 };
820
821 static struct mch_error_code uncor_pex_error_code[] = {
822 { 19, EMASK_UNCOR_PEX_IO19, PEX_NF_IO19 },
823 { 9, EMASK_UNCOR_PEX_IO9, PEX_NF_IO9 },
824 { 8, EMASK_UNCOR_PEX_IO8, PEX_NF_IO8 },
825 { 7, EMASK_UNCOR_PEX_IO7, PEX_NF_IO7 },
826 { 6, EMASK_UNCOR_PEX_IO6, PEX_NF_IO6 },
827 { 5, EMASK_UNCOR_PEX_IO5, PEX_NF_IO5 },
828 { 4, EMASK_UNCOR_PEX_IO4, PEX_NF_IO4 },
829 { 3, EMASK_UNCOR_PEX_IO3, PEX_NF_IO3 },
830 { 0, EMASK_UNCOR_PEX_IO0, PEX_NF_IO0 }
831 };
832
833 static struct mch_error_code uncor_pex_5400_error_code[] = {
834 { 33, EMASK_UNIT_PEX_IO33, PEX_5400_NF_IO33 },
835 { 32, EMASK_UNIT_PEX_IO32, PEX_5400_NF_IO32 },
836 { 31, EMASK_UNIT_PEX_IO31, PEX_5400_NF_IO31 },
837 { 30, EMASK_UNIT_PEX_IO30, PEX_5400_NF_IO30 },
838 { 29, EMASK_UNIT_PEX_IO29, PEX_5400_NF_IO29 },
839 { 28, EMASK_UNIT_PEX_IO28, PEX_5400_NF_IO28 },
840 { 27, EMASK_UNIT_PEX_IO27, PEX_5400_NF_IO27 },
841 { 26, EMASK_UNIT_PEX_IO26, PEX_5400_NF_IO26 },
842 { 25, EMASK_UNIT_PEX_IO25, PEX_5400_NF_IO25 },
843 { 24, EMASK_UNIT_PEX_IO24, PEX_5400_NF_IO24 },
844 { 23, EMASK_UNIT_PEX_IO23, PEX_5400_NF_IO23 },
845 };
846
847 static struct mch_error_code cor_pex_error_code[] = {
848 { 20, EMASK_COR_PEX_IO20, PEX_5400_NF_IO20 },
849 { 16, EMASK_COR_PEX_IO16, PEX_NF_IO16 },
850 { 15, EMASK_COR_PEX_IO15, PEX_NF_IO15 },
851 { 14, EMASK_COR_PEX_IO14, PEX_NF_IO14 },
852 { 13, EMASK_COR_PEX_IO13, PEX_NF_IO13 },
853 { 12, EMASK_COR_PEX_IO12, PEX_NF_IO12 },
854 { 10, 0, PEX_NF_IO10 },
855 { 2, 0, PEX_NF_IO2 }
856 };
857
858 static struct mch_error_code rp_pex_5400_error_code[] = {
859 { 17, EMASK_RP_PEX_IO17, PEX_5400_NF_IO17 },
860 { 11, EMASK_RP_PEX_IO11, PEX_5400_NF_IO11 }
861 };
862
863 static struct mch_error_code cor_pex_5400_error_code1[] = {
864 { 19, EMASK_UNCOR_PEX_IO19, PEX_5400_NF_IO19 },
865 { 10, EMASK_UNCOR_PEX_IO10, PEX_5400_NF_IO10 },
866 { 9, EMASK_UNCOR_PEX_IO9, PEX_5400_NF_IO9 },
867 { 8, EMASK_UNCOR_PEX_IO8, PEX_5400_NF_IO8 },
868 { 7, EMASK_UNCOR_PEX_IO7, PEX_5400_NF_IO7 },
869 { 6, EMASK_UNCOR_PEX_IO6, PEX_5400_NF_IO6 },
870 { 5, EMASK_UNCOR_PEX_IO5, PEX_5400_NF_IO5 },
871 { 4, EMASK_UNCOR_PEX_IO4, PEX_5400_NF_IO4 },
872 { 2, EMASK_UNCOR_PEX_IO2, PEX_5400_NF_IO2 },
873 { 0, EMASK_UNCOR_PEX_IO0, PEX_5400_NF_IO0 }
874 };
875
876 static struct mch_error_code cor_pex_5400_error_code2[] = {
877 { 20, EMASK_COR_PEX_IO20, PEX_5400_NF_IO20 },
878 { 16, EMASK_COR_PEX_IO16, PEX_5400_NF_IO16 },
879 { 15, EMASK_COR_PEX_IO15, PEX_5400_NF_IO15 },
880 { 14, EMASK_COR_PEX_IO14, PEX_5400_NF_IO14 },
881 { 13, EMASK_COR_PEX_IO13, PEX_5400_NF_IO13 },
882 { 12, EMASK_COR_PEX_IO12, PEX_5400_NF_IO12 }
883 };
884
885 static struct mch_error_code cor_pex_5400_error_code3[] = {
886 { 33, EMASK_UNIT_PEX_IO33, PEX_5400_NF_IO33 },
887 { 32, EMASK_UNIT_PEX_IO32, PEX_5400_NF_IO32 },
888 { 31, EMASK_UNIT_PEX_IO31, PEX_5400_NF_IO31 },
889 { 30, EMASK_UNIT_PEX_IO30, PEX_5400_NF_IO30 },
890 { 29, EMASK_UNIT_PEX_IO29, PEX_5400_NF_IO29 },
891 { 28, EMASK_UNIT_PEX_IO28, PEX_5400_NF_IO28 },
892 { 27, EMASK_UNIT_PEX_IO27, PEX_5400_NF_IO27 },
893 { 26, EMASK_UNIT_PEX_IO26, PEX_5400_NF_IO26 },
894 { 25, EMASK_UNIT_PEX_IO25, PEX_5400_NF_IO25 },
895 { 24, EMASK_UNIT_PEX_IO24, PEX_5400_NF_IO24 },
896 { 23, EMASK_UNIT_PEX_IO23, PEX_5400_NF_IO23 }
897 };
898
899 static struct mch_error_code rp_pex_error_code[] = {
900 { 17, EMASK_RP_PEX_IO17, PEX_NF_IO17 },
901 { 11, EMASK_RP_PEX_IO11, PEX_NF_IO11 },
902 };
903
904 static int
intel_pex_err(uint32_t pex_fat,uint32_t pex_nf_cor)905 intel_pex_err(uint32_t pex_fat, uint32_t pex_nf_cor)
906 {
907 int rt = -1;
908 int nerr = 0;
909 int i;
910 int sz;
911
912 sz = sizeof (fat_pex_error_code) / sizeof (struct mch_error_code);
913
914 for (i = 0; i < sz; i++) {
915 if (pex_fat & fat_pex_error_code[i].error_bit) {
916 rt = fat_pex_error_code[i].intel_error_list;
917 nerr++;
918 }
919 }
920 sz = sizeof (fat_rp_error_code) / sizeof (struct mch_error_code);
921
922 for (i = 0; i < sz; i++) {
923 if (pex_fat & fat_rp_error_code[i].error_bit) {
924 rt = fat_rp_error_code[i].intel_error_list;
925 nerr++;
926 }
927 }
928 sz = sizeof (uncor_pex_error_code) / sizeof (struct mch_error_code);
929
930 for (i = 0; i < sz; i++) {
931 if (pex_nf_cor & uncor_pex_error_code[i].error_bit) {
932 rt = uncor_pex_error_code[i].intel_error_list;
933 nerr++;
934 }
935 }
936
937 sz = sizeof (cor_pex_error_code) / sizeof (struct mch_error_code);
938
939 for (i = 0; i < sz; i++) {
940 if (pex_nf_cor & cor_pex_error_code[i].error_bit) {
941 rt = cor_pex_error_code[i].intel_error_list;
942 nerr++;
943 }
944 }
945 sz = sizeof (rp_pex_error_code) / sizeof (struct mch_error_code);
946
947 for (i = 0; i < sz; i++) {
948 if (pex_nf_cor & rp_pex_error_code[i].error_bit) {
949 rt = rp_pex_error_code[i].intel_error_list;
950 nerr++;
951 }
952 }
953
954 if (nerr > 1)
955 rt = -1;
956 return (rt);
957 }
958
959 static struct mch_error_code fat_thr_error_code[] = {
960 { 2, EMASK_THR_F2, ERR_FAT_THR_F2 },
961 { 1, EMASK_THR_F1, ERR_FAT_THR_F1 }
962 };
963
964 static struct mch_error_code nf_thr_error_code[] = {
965 { 5, EMASK_THR_F5, ERR_NF_THR_F5 },
966 { 4, EMASK_THR_F4, ERR_NF_THR_F4 },
967 { 3, EMASK_THR_F3, ERR_NF_THR_F3 }
968 };
969
970 static int
intel_thr_err(uint8_t err_fat_thr,uint8_t err_nf_thr)971 intel_thr_err(uint8_t err_fat_thr, uint8_t err_nf_thr)
972 {
973 int rt = -1;
974 int nerr = 0;
975 uint16_t emask_thr = 0;
976 int i;
977 int sz;
978
979 sz = sizeof (fat_thr_error_code) / sizeof (struct mch_error_code);
980
981 for (i = 0; i < sz; i++) {
982 if (err_fat_thr & fat_thr_error_code[i].error_bit) {
983 rt = fat_thr_error_code[i].intel_error_list;
984 emask_thr |= fat_thr_error_code[i].emask;
985 nerr++;
986 }
987 }
988
989 sz = sizeof (nf_thr_error_code) / sizeof (struct mch_error_code);
990
991 for (i = 0; i < sz; i++) {
992 if (err_nf_thr & nf_thr_error_code[i].error_bit) {
993 rt = nf_thr_error_code[i].intel_error_list;
994 emask_thr |= nf_thr_error_code[i].emask;
995 nerr++;
996 }
997 }
998
999 if (emask_thr)
1000 nb_thr_mask_mc(emask_thr);
1001 if (nerr > 1)
1002 rt = -1;
1003 return (rt);
1004 }
1005
1006 static int
intel_pex_5400_err(uint32_t pex_fat,uint32_t pex_nf_cor)1007 intel_pex_5400_err(uint32_t pex_fat, uint32_t pex_nf_cor)
1008 {
1009 int rt = -1;
1010 int nerr = 0;
1011 int i;
1012 int sz;
1013
1014 sz = sizeof (fat_pex_5400_error_code) / sizeof (struct mch_error_code);
1015
1016 for (i = 0; i < sz; i++) {
1017 if (pex_fat & fat_pex_5400_error_code[i].error_bit) {
1018 rt = fat_pex_5400_error_code[i].intel_error_list;
1019 nerr++;
1020 }
1021 }
1022 sz = sizeof (fat_rp_5400_error_code) / sizeof (struct mch_error_code);
1023
1024 for (i = 0; i < sz; i++) {
1025 if (pex_fat & fat_rp_5400_error_code[i].error_bit) {
1026 rt = fat_rp_5400_error_code[i].intel_error_list;
1027 nerr++;
1028 }
1029 }
1030 sz = sizeof (fat_unit_pex_5400_error_code) /
1031 sizeof (struct mch_error_code);
1032
1033 for (i = 0; i < sz; i++) {
1034 if (pex_fat &
1035 fat_unit_pex_5400_error_code[i].error_bit) {
1036 rt = fat_unit_pex_5400_error_code[i].intel_error_list;
1037 nerr++;
1038 }
1039 }
1040 sz = sizeof (uncor_pex_5400_error_code) /
1041 sizeof (struct mch_error_code);
1042
1043 for (i = 0; i < sz; i++) {
1044 if (pex_fat & uncor_pex_5400_error_code[i].error_bit) {
1045 rt = uncor_pex_5400_error_code[i].intel_error_list;
1046 nerr++;
1047 }
1048 }
1049
1050 sz = sizeof (rp_pex_5400_error_code) / sizeof (struct mch_error_code);
1051
1052 for (i = 0; i < sz; i++) {
1053 if (pex_nf_cor & rp_pex_5400_error_code[i].error_bit) {
1054 rt = rp_pex_5400_error_code[i].intel_error_list;
1055 nerr++;
1056 }
1057 }
1058
1059 sz = sizeof (cor_pex_5400_error_code1) / sizeof (struct mch_error_code);
1060
1061 for (i = 0; i < sz; i++) {
1062 if (pex_nf_cor & cor_pex_5400_error_code1[i].error_bit) {
1063 rt = cor_pex_5400_error_code1[i].intel_error_list;
1064 nerr++;
1065 }
1066 }
1067
1068 sz = sizeof (cor_pex_5400_error_code2) / sizeof (struct mch_error_code);
1069
1070 for (i = 0; i < sz; i++) {
1071 if (pex_nf_cor & cor_pex_5400_error_code2[i].error_bit) {
1072 rt = cor_pex_5400_error_code2[i].intel_error_list;
1073 nerr++;
1074 }
1075 }
1076
1077 sz = sizeof (cor_pex_5400_error_code3) / sizeof (struct mch_error_code);
1078
1079 for (i = 0; i < sz; i++) {
1080 if (pex_nf_cor & cor_pex_5400_error_code3[i].error_bit) {
1081 rt = cor_pex_5400_error_code3[i].intel_error_list;
1082 nerr++;
1083 }
1084 }
1085
1086 if (nerr > 1)
1087 rt = -1;
1088 return (rt);
1089 }
1090
1091 static int
log_pex_err(uint64_t ferr,nb_regs_t * rp,int willpanic,int * interpose)1092 log_pex_err(uint64_t ferr, nb_regs_t *rp, int willpanic, int *interpose)
1093 {
1094 uint8_t pex = (uint8_t)-1;
1095 int t = 0;
1096
1097 rp->flag = NB_REG_LOG_PEX;
1098 pex = GE_ERR_PEX(ferr);
1099
1100 rp->nb.pex_regs.pex = pex;
1101 rp->nb.pex_regs.pex_fat_ferr = PEX_FAT_FERR_RD(pex, interpose);
1102 rp->nb.pex_regs.pex_fat_nerr = PEX_FAT_NERR_RD(pex, &t);
1103 *interpose |= t;
1104 rp->nb.pex_regs.pex_nf_corr_ferr = PEX_NF_FERR_RD(pex, &t);
1105 *interpose |= t;
1106 rp->nb.pex_regs.pex_nf_corr_nerr = PEX_NF_NERR_RD(pex, &t);
1107 *interpose |= t;
1108 if (rp->nb.pex_regs.pex_fat_ferr == 0 &&
1109 rp->nb.pex_regs.pex_fat_nerr == 0 &&
1110 rp->nb.pex_regs.pex_nf_corr_ferr == 0 &&
1111 rp->nb.pex_regs.pex_nf_corr_nerr == 0)
1112 return (0);
1113 rp->nb.pex_regs.uncerrsev = UNCERRSEV_RD(pex);
1114 rp->nb.pex_regs.rperrsts = RPERRSTS_RD(pex);
1115 rp->nb.pex_regs.rperrsid = RPERRSID_RD(pex);
1116 if (pex != (uint8_t)-1)
1117 rp->nb.pex_regs.uncerrsts = UNCERRSTS_RD(pex);
1118 else
1119 rp->nb.pex_regs.uncerrsts = 0;
1120 rp->nb.pex_regs.aerrcapctrl = AERRCAPCTRL_RD(pex);
1121 rp->nb.pex_regs.corerrsts = CORERRSTS_RD(pex);
1122 rp->nb.pex_regs.pexdevsts = PEXDEVSTS_RD(pex);
1123
1124 if (!willpanic) {
1125 if (rp->nb.pex_regs.pex_fat_ferr || *interpose)
1126 PEX_FAT_FERR_WR(pex, rp->nb.pex_regs.pex_fat_ferr);
1127 if (rp->nb.pex_regs.pex_fat_nerr)
1128 PEX_FAT_NERR_WR(pex, rp->nb.pex_regs.pex_fat_nerr);
1129 if (rp->nb.pex_regs.pex_nf_corr_ferr || *interpose)
1130 PEX_NF_FERR_WR(pex, rp->nb.pex_regs.pex_nf_corr_ferr);
1131 if (rp->nb.pex_regs.pex_nf_corr_nerr)
1132 PEX_NF_NERR_WR(pex, rp->nb.pex_regs.pex_nf_corr_nerr);
1133 if (*interpose)
1134 UNCERRSTS_WR(pex, rp->nb.pex_regs.uncerrsts);
1135 if (*interpose)
1136 RPERRSTS_WR(pex, rp->nb.pex_regs.rperrsts);
1137 if (*interpose)
1138 PEXDEVSTS_WR(pex, 0);
1139 }
1140 return (1);
1141 }
1142
1143 static void
log_fat_fbd_err(nb_regs_t * rp,int willpanic,int * interpose)1144 log_fat_fbd_err(nb_regs_t *rp, int willpanic, int *interpose)
1145 {
1146 int channel, branch;
1147 int t = 0;
1148
1149 rp->flag = NB_REG_LOG_FAT_FBD;
1150 rp->nb.fat_fbd_regs.ferr_fat_fbd = FERR_FAT_FBD_RD(interpose);
1151 channel = (rp->nb.fat_fbd_regs.ferr_fat_fbd >> 28) & 3;
1152 branch = channel >> 1;
1153 rp->nb.fat_fbd_regs.nerr_fat_fbd = NERR_FAT_FBD_RD(&t);
1154 *interpose |= t;
1155 rp->nb.fat_fbd_regs.nrecmema = NRECMEMA_RD(branch);
1156 rp->nb.fat_fbd_regs.nrecmemb = NRECMEMB_RD(branch);
1157 rp->nb.fat_fbd_regs.nrecfglog = NRECFGLOG_RD(branch);
1158 rp->nb.fat_fbd_regs.nrecfbda = NRECFBDA_RD(branch);
1159 rp->nb.fat_fbd_regs.nrecfbdb = NRECFBDB_RD(branch);
1160 rp->nb.fat_fbd_regs.nrecfbdc = NRECFBDC_RD(branch);
1161 rp->nb.fat_fbd_regs.nrecfbdd = NRECFBDD_RD(branch);
1162 rp->nb.fat_fbd_regs.nrecfbde = NRECFBDE_RD(branch);
1163 rp->nb.fat_fbd_regs.nrecfbdf = NRECFBDF_RD(branch);
1164 rp->nb.fat_fbd_regs.spcps = SPCPS_RD(branch);
1165 rp->nb.fat_fbd_regs.spcpc = SPCPC_RD(branch);
1166 rp->nb.fat_fbd_regs.uerrcnt = UERRCNT_RD(branch);
1167 rp->nb.fat_fbd_regs.uerrcnt_last = uerrcnt[branch];
1168 uerrcnt[branch] = rp->nb.fat_fbd_regs.uerrcnt;
1169 rp->nb.fat_fbd_regs.badrama = BADRAMA_RD(branch);
1170 rp->nb.fat_fbd_regs.badramb = BADRAMB_RD(branch);
1171 rp->nb.fat_fbd_regs.badcnt = BADCNT_RD(branch);
1172 if (!willpanic) {
1173 if (rp->nb.fat_fbd_regs.ferr_fat_fbd || *interpose)
1174 FERR_FAT_FBD_WR(rp->nb.fat_fbd_regs.ferr_fat_fbd);
1175 if (rp->nb.fat_fbd_regs.nerr_fat_fbd)
1176 NERR_FAT_FBD_WR(rp->nb.fat_fbd_regs.nerr_fat_fbd);
1177 /*
1178 * if interpose write read-only registers to clear from pcii
1179 * cache
1180 */
1181 if (*interpose) {
1182 NRECMEMA_WR(branch);
1183 NRECMEMB_WR(branch);
1184 NRECFGLOG_WR(branch);
1185 NRECFBDA_WR(branch);
1186 NRECFBDB_WR(branch);
1187 NRECFBDC_WR(branch);
1188 NRECFBDD_WR(branch);
1189 NRECFBDE_WR(branch);
1190 NRECFBDF_WR(branch);
1191 }
1192 }
1193 }
1194
1195 static void
log_nf_fbd_err(nb_regs_t * rp,int willpanic,int * interpose)1196 log_nf_fbd_err(nb_regs_t *rp, int willpanic, int *interpose)
1197 {
1198 int channel, branch;
1199 int t = 0;
1200
1201 rp->flag = NB_REG_LOG_NF_FBD;
1202 rp->nb.nf_fbd_regs.ferr_nf_fbd = FERR_NF_FBD_RD(interpose);
1203 channel = (rp->nb.nf_fbd_regs.ferr_nf_fbd >> 28) & 3;
1204 branch = channel >> 1;
1205 rp->nb.nf_fbd_regs.nerr_nf_fbd = NERR_NF_FBD_RD(&t);
1206 *interpose |= t;
1207 rp->nb.nf_fbd_regs.redmemb = REDMEMB_RD();
1208 rp->nb.nf_fbd_regs.recmema = RECMEMA_RD(branch);
1209 rp->nb.nf_fbd_regs.recmemb = RECMEMB_RD(branch);
1210 rp->nb.nf_fbd_regs.recfglog = RECFGLOG_RD(branch);
1211 rp->nb.nf_fbd_regs.recfbda = RECFBDA_RD(branch);
1212 rp->nb.nf_fbd_regs.recfbdb = RECFBDB_RD(branch);
1213 rp->nb.nf_fbd_regs.recfbdc = RECFBDC_RD(branch);
1214 rp->nb.nf_fbd_regs.recfbdd = RECFBDD_RD(branch);
1215 rp->nb.nf_fbd_regs.recfbde = RECFBDE_RD(branch);
1216 rp->nb.nf_fbd_regs.recfbdf = RECFBDF_RD(branch);
1217 rp->nb.nf_fbd_regs.spcps = SPCPS_RD(branch);
1218 rp->nb.nf_fbd_regs.spcpc = SPCPC_RD(branch);
1219 if (nb_chipset == INTEL_NB_7300 || nb_chipset == INTEL_NB_5400) {
1220 rp->nb.nf_fbd_regs.cerrcnta = CERRCNTA_RD(branch, channel);
1221 rp->nb.nf_fbd_regs.cerrcntb = CERRCNTB_RD(branch, channel);
1222 rp->nb.nf_fbd_regs.cerrcntc = CERRCNTC_RD(branch, channel);
1223 rp->nb.nf_fbd_regs.cerrcntd = CERRCNTD_RD(branch, channel);
1224 } else {
1225 rp->nb.nf_fbd_regs.cerrcnta = CERRCNT_RD(branch);
1226 rp->nb.nf_fbd_regs.cerrcntb = 0;
1227 rp->nb.nf_fbd_regs.cerrcntc = 0;
1228 rp->nb.nf_fbd_regs.cerrcntd = 0;
1229 }
1230 rp->nb.nf_fbd_regs.cerrcnta_last = cerrcnta[branch][channel & 1];
1231 rp->nb.nf_fbd_regs.cerrcntb_last = cerrcntb[branch][channel & 1];
1232 rp->nb.nf_fbd_regs.cerrcntc_last = cerrcntc[branch][channel & 1];
1233 rp->nb.nf_fbd_regs.cerrcntd_last = cerrcntd[branch][channel & 1];
1234 cerrcnta[branch][channel & 1] = rp->nb.nf_fbd_regs.cerrcnta;
1235 cerrcntb[branch][channel & 1] = rp->nb.nf_fbd_regs.cerrcntb;
1236 cerrcntc[branch][channel & 1] = rp->nb.nf_fbd_regs.cerrcntc;
1237 cerrcntd[branch][channel & 1] = rp->nb.nf_fbd_regs.cerrcntd;
1238 rp->nb.nf_fbd_regs.badrama = BADRAMA_RD(branch);
1239 rp->nb.nf_fbd_regs.badramb = BADRAMB_RD(branch);
1240 rp->nb.nf_fbd_regs.badcnt = BADCNT_RD(branch);
1241 if (!willpanic) {
1242 if (rp->nb.nf_fbd_regs.ferr_nf_fbd || *interpose)
1243 FERR_NF_FBD_WR(rp->nb.nf_fbd_regs.ferr_nf_fbd);
1244 if (rp->nb.nf_fbd_regs.nerr_nf_fbd)
1245 NERR_NF_FBD_WR(rp->nb.nf_fbd_regs.nerr_nf_fbd);
1246 /*
1247 * if interpose write read-only registers to clear from pcii
1248 * cache
1249 */
1250 if (*interpose) {
1251 RECMEMA_WR(branch);
1252 RECMEMB_WR(branch);
1253 RECFGLOG_WR(branch);
1254 RECFBDA_WR(branch);
1255 RECFBDB_WR(branch);
1256 RECFBDC_WR(branch);
1257 RECFBDD_WR(branch);
1258 RECFBDE_WR(branch);
1259 RECFBDF_WR(branch);
1260 SPCPS_WR(branch);
1261 }
1262 }
1263 }
1264
1265 static int
log_nf_mem_err(nb_regs_t * rp,int willpanic,int * interpose)1266 log_nf_mem_err(nb_regs_t *rp, int willpanic, int *interpose)
1267 {
1268 int channel, branch;
1269 int t = 0;
1270 int rt = 0;
1271
1272 rp->flag = NB_REG_LOG_NF_MEM;
1273
1274 /* Memmory err registers */
1275 rp->nb.nf_mem_regs.ferr_nf_mem = FERR_NF_MEM_RD(interpose);
1276 channel = (rp->nb.nf_mem_regs.ferr_nf_mem >> 28) & 0x1;
1277 branch = channel;
1278 rp->nb.nf_mem_regs.nerr_nf_mem = NERR_NF_MEM_RD(&t);
1279 *interpose |= t;
1280 rp->nb.nf_mem_regs.redmema = MEM_REDMEMA_RD(branch);
1281 rp->nb.nf_mem_regs.redmemb = MEM_REDMEMB_RD(branch);
1282 rp->nb.nf_mem_regs.recmema = MEM_RECMEMA_RD(branch);
1283 rp->nb.nf_mem_regs.recmemb = MEM_RECMEMB_RD(branch);
1284 rp->nb.nf_mem_regs.nrecmema = MEM_NRECMEMA_RD(branch);
1285 rp->nb.nf_mem_regs.nrecmemb = MEM_NRECMEMB_RD(branch);
1286
1287 /* spare rank */
1288 rp->nb.nf_mem_regs.spcps = SPCPS_RD(branch);
1289 rp->nb.nf_mem_regs.spcpc = SPCPC_RD(branch);
1290
1291 /* RAS registers */
1292 rp->nb.nf_mem_regs.cerrcnt = MEM_CERRCNT_RD(branch);
1293 rp->nb.nf_mem_regs.cerrcnt_ext = (uint32_t)MEM_CERRCNT_EXT_RD(branch);
1294 rp->nb.nf_mem_regs.cerrcnt_last = cerrcnta[branch][channel & 1];
1295 rp->nb.nf_mem_regs.cerrcnt_ext_last = cerrcntb[branch][channel & 1];
1296 cerrcnta[branch][channel & 1] = rp->nb.nf_mem_regs.cerrcnt;
1297 cerrcntb[branch][channel & 1] = rp->nb.nf_mem_regs.cerrcnt_ext;
1298 rp->nb.nf_mem_regs.badram = BADRAMA_RD(branch);
1299 rp->nb.nf_mem_regs.badcnt = BADCNT_RD(branch);
1300 rp->nb.nf_mem_regs.validlog = VALIDLOG_RD(branch);
1301
1302 if (!willpanic) {
1303 if (rp->nb.nf_mem_regs.ferr_nf_mem || *interpose)
1304 FERR_NF_MEM_WR(rp->nb.nf_mem_regs.ferr_nf_mem);
1305 if (rp->nb.nf_mem_regs.nerr_nf_mem)
1306 NERR_NF_MEM_WR(rp->nb.nf_mem_regs.nerr_nf_mem);
1307 /*
1308 * if interpose, write read-only registers to clear from pci
1309 * cache
1310 */
1311 if (*interpose) {
1312 MEM_NRECMEMA_WR(branch);
1313 MEM_NRECMEMB_WR(branch);
1314 MEM_REDMEMA_WR(branch);
1315 MEM_REDMEMB_WR(branch);
1316 MEM_RECMEMA_WR(branch);
1317 MEM_RECMEMB_WR(branch);
1318 SPCPS_WR(branch);
1319 }
1320 }
1321 if (nb_mode == NB_MEMORY_SINGLE_CHANNEL && channel != 0) {
1322 /*
1323 * In the single channel mode, all dimms are on the channel 0.
1324 * Invalidate this error if the channel number is invalid.
1325 */
1326 rt = 1;
1327 }
1328 return (rt);
1329 }
1330
1331 static void
log_ferr(uint64_t ferr,uint32_t * nerrp,nb_logout_t * log,int willpanic)1332 log_ferr(uint64_t ferr, uint32_t *nerrp, nb_logout_t *log, int willpanic)
1333 {
1334 nb_regs_t *rp = &log->nb_regs;
1335 uint32_t nerr = *nerrp;
1336 int interpose = 0;
1337 int spurious = 0;
1338
1339 log->acl_timestamp = gethrtime_waitfree();
1340 if ((ferr & (GE_PCIEX_FATAL | GE_PCIEX_NF)) != 0) {
1341 *nerrp = nerr & ~(GE_PCIEX_FATAL | GE_PCIEX_NF);
1342 if (log_pex_err(ferr, rp, willpanic, &interpose) == 0)
1343 return;
1344 } else if ((ferr & GE_FBD_FATAL) != 0) {
1345 log_fat_fbd_err(rp, willpanic, &interpose);
1346 *nerrp = nerr & ~GE_NERR_FBD_FATAL;
1347 } else if ((ferr & GE_FBD_NF) != 0) {
1348 log_nf_fbd_err(rp, willpanic, &interpose);
1349 *nerrp = nerr & ~GE_NERR_FBD_NF;
1350 } else if ((ferr & GE_MEM_NF) != 0) {
1351 spurious = log_nf_mem_err(rp, willpanic, &interpose);
1352 *nerrp = nerr & ~GE_NERR_MEM_NF;
1353 } else if ((ferr & (GE_FERR_FSB_FATAL | GE_FERR_FSB_NF)) != 0) {
1354 log_fsb_err(ferr, rp, willpanic, &interpose);
1355 *nerrp = nerr & ~(GE_NERR_FSB_FATAL | GE_NERR_FSB_NF);
1356 } else if ((ferr & (GE_DMA_FATAL | GE_DMA_NF)) != 0) {
1357 log_dma_err(rp, &interpose);
1358 *nerrp = nerr & ~(GE_DMA_FATAL | GE_DMA_NF);
1359 } else if ((ferr & (GE_INT_FATAL | GE_INT_NF)) != 0) {
1360 spurious = log_int_err(rp, willpanic, &interpose);
1361 *nerrp = nerr & ~(GE_INT_FATAL | GE_INT_NF);
1362 } else if (nb_chipset == INTEL_NB_5400 &&
1363 (ferr & (GE_FERR_THERMAL_FATAL | GE_FERR_THERMAL_NF)) != 0) {
1364 log_thermal_err(rp, willpanic, &interpose);
1365 *nerrp = nerr & ~(GE_FERR_THERMAL_FATAL | GE_FERR_THERMAL_NF);
1366 }
1367 if (interpose)
1368 log->type = "inject";
1369 else
1370 log->type = "error";
1371 if (!spurious) {
1372 errorq_dispatch(nb_queue, log, sizeof (nb_logout_t),
1373 willpanic ? ERRORQ_SYNC : ERRORQ_ASYNC);
1374 }
1375 }
1376
1377 static void
log_nerr(uint32_t * errp,nb_logout_t * log,int willpanic)1378 log_nerr(uint32_t *errp, nb_logout_t *log, int willpanic)
1379 {
1380 uint32_t err;
1381 nb_regs_t *rp = &log->nb_regs;
1382 int interpose = 0;
1383 int spurious = 0;
1384
1385 err = *errp;
1386 log->acl_timestamp = gethrtime_waitfree();
1387 if ((err & (GE_PCIEX_FATAL | GE_PCIEX_NF)) != 0) {
1388 *errp = err & ~(GE_PCIEX_FATAL | GE_PCIEX_NF);
1389 if (log_pex_err(err, rp, willpanic, &interpose) == 0)
1390 return;
1391 } else if ((err & GE_NERR_FBD_FATAL) != 0) {
1392 log_fat_fbd_err(rp, willpanic, &interpose);
1393 *errp = err & ~GE_NERR_FBD_FATAL;
1394 } else if ((err & GE_NERR_FBD_NF) != 0) {
1395 log_nf_fbd_err(rp, willpanic, &interpose);
1396 *errp = err & ~GE_NERR_FBD_NF;
1397 } else if ((err & GE_NERR_MEM_NF) != 0) {
1398 spurious = log_nf_mem_err(rp, willpanic, &interpose);
1399 *errp = err & ~GE_NERR_MEM_NF;
1400 } else if ((err & (GE_NERR_FSB_FATAL | GE_NERR_FSB_NF)) != 0) {
1401 log_fsb_err(GE_NERR_TO_FERR_FSB(err), rp, willpanic,
1402 &interpose);
1403 *errp = err & ~(GE_NERR_FSB_FATAL | GE_NERR_FSB_NF);
1404 } else if ((err & (GE_DMA_FATAL | GE_DMA_NF)) != 0) {
1405 log_dma_err(rp, &interpose);
1406 *errp = err & ~(GE_DMA_FATAL | GE_DMA_NF);
1407 } else if ((err & (GE_INT_FATAL | GE_INT_NF)) != 0) {
1408 spurious = log_int_err(rp, willpanic, &interpose);
1409 *errp = err & ~(GE_INT_FATAL | GE_INT_NF);
1410 }
1411 if (interpose)
1412 log->type = "inject";
1413 else
1414 log->type = "error";
1415 if (!spurious) {
1416 errorq_dispatch(nb_queue, log, sizeof (nb_logout_t),
1417 willpanic ? ERRORQ_SYNC : ERRORQ_ASYNC);
1418 }
1419 }
1420
1421 /*ARGSUSED*/
1422 void
nb_error_trap(cmi_hdl_t hdl,boolean_t ismc,boolean_t willpanic)1423 nb_error_trap(cmi_hdl_t hdl, boolean_t ismc, boolean_t willpanic)
1424 {
1425 uint64_t ferr;
1426 uint32_t nerr, err;
1427 int nmc = 0;
1428 int i;
1429
1430 if (mutex_tryenter(&nb_mutex) == 0)
1431 return;
1432
1433 nerr = NERR_GLOBAL_RD();
1434 err = nerr;
1435 for (i = 0; i < NB_MAX_ERRORS; i++) {
1436 ferr = FERR_GLOBAL_RD();
1437 nb_log.nb_regs.chipset = nb_chipset;
1438 nb_log.nb_regs.ferr = ferr;
1439 nb_log.nb_regs.nerr = nerr;
1440 if (ferr) {
1441 log_ferr(ferr, &err, &nb_log, willpanic);
1442 FERR_GLOBAL_WR(ferr);
1443 nmc++;
1444 } else if (err) {
1445 log_nerr(&err, &nb_log, willpanic);
1446 nmc++;
1447 }
1448 }
1449 if (nerr) {
1450 NERR_GLOBAL_WR(nerr);
1451 }
1452 if (nmc == 0 && nb_mask_mc_set)
1453 nb_mask_mc_reset();
1454 mutex_exit(&nb_mutex);
1455 }
1456
1457 static void
nb_fsb_err_payload(const nb_regs_t * nb_regs,nvlist_t * payload,nb_scatchpad_t * data)1458 nb_fsb_err_payload(const nb_regs_t *nb_regs, nvlist_t *payload,
1459 nb_scatchpad_t *data)
1460 {
1461 int intel_error_list;
1462 char buf[32];
1463
1464 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FSB,
1465 DATA_TYPE_UINT8, nb_regs->nb.fsb_regs.fsb, NULL);
1466 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_FAT_FSB,
1467 DATA_TYPE_UINT8, nb_regs->nb.fsb_regs.ferr_fat_fsb, NULL);
1468 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_FAT_FSB,
1469 DATA_TYPE_UINT8, nb_regs->nb.fsb_regs.nerr_fat_fsb, NULL);
1470 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_NF_FSB,
1471 DATA_TYPE_UINT8, nb_regs->nb.fsb_regs.ferr_nf_fsb, NULL);
1472 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_NF_FSB,
1473 DATA_TYPE_UINT8, nb_regs->nb.fsb_regs.nerr_nf_fsb, NULL);
1474 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFSB,
1475 DATA_TYPE_UINT32, nb_regs->nb.fsb_regs.nrecfsb, NULL);
1476 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFSB_ADDR,
1477 DATA_TYPE_UINT64, nb_regs->nb.fsb_regs.nrecfsb_addr, NULL);
1478 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECFSB,
1479 DATA_TYPE_UINT32, nb_regs->nb.fsb_regs.recfsb, NULL);
1480 intel_error_list = data->intel_error_list;
1481 if (intel_error_list >= 0)
1482 (void) snprintf(buf, sizeof (buf), "F%d", intel_error_list);
1483 else
1484 (void) snprintf(buf, sizeof (buf), "Multiple or unknown error");
1485 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_ERROR_NO,
1486 DATA_TYPE_STRING, buf, NULL);
1487 }
1488
1489 static void
nb_pex_err_payload(const nb_regs_t * nb_regs,nvlist_t * payload,nb_scatchpad_t * data)1490 nb_pex_err_payload(const nb_regs_t *nb_regs, nvlist_t *payload,
1491 nb_scatchpad_t *data)
1492 {
1493 int intel_error_list;
1494 char buf[32];
1495
1496 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_PEX,
1497 DATA_TYPE_UINT8, nb_regs->nb.pex_regs.pex, NULL);
1498 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_PEX_FAT_FERR,
1499 DATA_TYPE_UINT32, nb_regs->nb.pex_regs.pex_fat_ferr, NULL);
1500 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_PEX_FAT_NERR,
1501 DATA_TYPE_UINT32, nb_regs->nb.pex_regs.pex_fat_nerr, NULL);
1502 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_PEX_NF_CORR_FERR,
1503 DATA_TYPE_UINT32, nb_regs->nb.pex_regs.pex_nf_corr_ferr, NULL);
1504 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_PEX_NF_CORR_NERR,
1505 DATA_TYPE_UINT32, nb_regs->nb.pex_regs.pex_nf_corr_nerr, NULL);
1506 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_UNCERRSEV,
1507 DATA_TYPE_UINT32, nb_regs->nb.pex_regs.uncerrsev, NULL);
1508 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RPERRSTS,
1509 DATA_TYPE_UINT32, nb_regs->nb.pex_regs.rperrsts, NULL);
1510 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RPERRSID,
1511 DATA_TYPE_UINT32, nb_regs->nb.pex_regs.rperrsid, NULL);
1512 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_UNCERRSTS,
1513 DATA_TYPE_UINT32, nb_regs->nb.pex_regs.uncerrsts, NULL);
1514 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_AERRCAPCTRL,
1515 DATA_TYPE_UINT32, nb_regs->nb.pex_regs.aerrcapctrl, NULL);
1516 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CORERRSTS,
1517 DATA_TYPE_UINT32, nb_regs->nb.pex_regs.corerrsts, NULL);
1518 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_PEXDEVSTS,
1519 DATA_TYPE_UINT16, nb_regs->nb.pex_regs.pexdevsts, NULL);
1520 intel_error_list = data->intel_error_list;
1521 if (intel_error_list >= 0)
1522 (void) snprintf(buf, sizeof (buf), "IO%d", intel_error_list);
1523 else
1524 (void) snprintf(buf, sizeof (buf), "Multiple or unknown error");
1525 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_ERROR_NO,
1526 DATA_TYPE_STRING, buf, NULL);
1527 }
1528
1529 static void
nb_int_err_payload(const nb_regs_t * nb_regs,nvlist_t * payload,nb_scatchpad_t * data)1530 nb_int_err_payload(const nb_regs_t *nb_regs, nvlist_t *payload,
1531 nb_scatchpad_t *data)
1532 {
1533 int intel_error_list;
1534 char buf[32];
1535
1536 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_FAT_INT,
1537 DATA_TYPE_UINT16, nb_regs->nb.int_regs.ferr_fat_int, NULL);
1538 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_NF_INT,
1539 DATA_TYPE_UINT16, nb_regs->nb.int_regs.ferr_nf_int, NULL);
1540 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_FAT_INT,
1541 DATA_TYPE_UINT16, nb_regs->nb.int_regs.nerr_fat_int, NULL);
1542 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_NF_INT,
1543 DATA_TYPE_UINT16, nb_regs->nb.int_regs.nerr_nf_int, NULL);
1544 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECINT,
1545 DATA_TYPE_UINT32, nb_regs->nb.int_regs.nrecint, NULL);
1546 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECINT,
1547 DATA_TYPE_UINT32, nb_regs->nb.int_regs.recint, NULL);
1548 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECSF,
1549 DATA_TYPE_UINT64, nb_regs->nb.int_regs.nrecsf, NULL);
1550 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECSF,
1551 DATA_TYPE_UINT64, nb_regs->nb.int_regs.recsf, NULL);
1552 intel_error_list = data->intel_error_list;
1553 if (intel_error_list >= 0)
1554 (void) snprintf(buf, sizeof (buf), "B%d", intel_error_list);
1555 else
1556 (void) snprintf(buf, sizeof (buf), "Multiple or unknown error");
1557 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_ERROR_NO,
1558 DATA_TYPE_STRING, buf, NULL);
1559 }
1560
1561 static void
nb_fat_fbd_err_payload(const nb_regs_t * nb_regs,nvlist_t * payload,nb_scatchpad_t * data)1562 nb_fat_fbd_err_payload(const nb_regs_t *nb_regs, nvlist_t *payload,
1563 nb_scatchpad_t *data)
1564 {
1565 nb_mem_scatchpad_t *sp;
1566 char buf[32];
1567
1568 sp = &((nb_scatchpad_t *)data)->ms;
1569
1570 if (sp->ras != -1) {
1571 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BANK,
1572 DATA_TYPE_INT32, sp->bank, NULL);
1573 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CAS,
1574 DATA_TYPE_INT32, sp->cas, NULL);
1575 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RAS,
1576 DATA_TYPE_INT32, sp->ras, NULL);
1577 if (sp->offset != -1LL) {
1578 fm_payload_set(payload, FM_FMRI_MEM_OFFSET,
1579 DATA_TYPE_UINT64, sp->offset, NULL);
1580 }
1581 if (sp->pa != -1LL) {
1582 fm_payload_set(payload, FM_FMRI_MEM_PHYSADDR,
1583 DATA_TYPE_UINT64, sp->pa, NULL);
1584 }
1585 }
1586 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_FAT_FBD,
1587 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.ferr_fat_fbd, NULL);
1588 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_FAT_FBD,
1589 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nerr_fat_fbd, NULL);
1590 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECMEMA,
1591 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecmema, NULL);
1592 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECMEMB,
1593 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecmemb, NULL);
1594 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFGLOG,
1595 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecfglog, NULL);
1596 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFBDA,
1597 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecfbda, NULL);
1598 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFBDB,
1599 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecfbdb, NULL);
1600 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFBDC,
1601 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecfbdc, NULL);
1602 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFBDD,
1603 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecfbdd, NULL);
1604 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFBDE,
1605 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecfbde, NULL);
1606 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFBDF,
1607 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecfbdf, NULL);
1608 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_SPCPS,
1609 DATA_TYPE_UINT8, nb_regs->nb.fat_fbd_regs.spcps, NULL);
1610 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_SPCPC,
1611 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.spcpc, NULL);
1612 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_UERRCNT,
1613 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.uerrcnt, NULL);
1614 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_UERRCNT_LAST,
1615 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.uerrcnt_last, NULL);
1616 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BADRAMA,
1617 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.badrama, NULL);
1618 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BADRAMB,
1619 DATA_TYPE_UINT16, nb_regs->nb.fat_fbd_regs.badramb, NULL);
1620 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BADCNT,
1621 DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.badcnt, NULL);
1622
1623 if (sp->intel_error_list >= 0)
1624 (void) snprintf(buf, sizeof (buf), "M%d", sp->intel_error_list);
1625 else
1626 (void) snprintf(buf, sizeof (buf), "Multiple or unknown error");
1627 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_ERROR_NO,
1628 DATA_TYPE_STRING, buf, NULL);
1629 }
1630
1631 static void
nb_nf_fbd_err_payload(const nb_regs_t * nb_regs,nvlist_t * payload,nb_scatchpad_t * data)1632 nb_nf_fbd_err_payload(const nb_regs_t *nb_regs, nvlist_t *payload,
1633 nb_scatchpad_t *data)
1634 {
1635 nb_mem_scatchpad_t *sp;
1636 char buf[32];
1637
1638 sp = &((nb_scatchpad_t *)data)->ms;
1639
1640 if (sp->dimm == -1 && sp->rank != -1) {
1641 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RANK,
1642 DATA_TYPE_INT32, sp->rank, NULL);
1643 }
1644 if (sp->ras != -1) {
1645 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BANK,
1646 DATA_TYPE_INT32, sp->bank, NULL);
1647 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CAS,
1648 DATA_TYPE_INT32, sp->cas, NULL);
1649 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RAS,
1650 DATA_TYPE_INT32, sp->ras, NULL);
1651 if (sp->offset != -1LL) {
1652 fm_payload_set(payload, FM_FMRI_MEM_OFFSET,
1653 DATA_TYPE_UINT64, sp->offset, NULL);
1654 }
1655 if (sp->pa != -1LL) {
1656 fm_payload_set(payload, FM_FMRI_MEM_PHYSADDR,
1657 DATA_TYPE_UINT64, sp->pa, NULL);
1658 }
1659 }
1660 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_NF_FBD,
1661 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.ferr_nf_fbd, NULL);
1662 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_NF_FBD,
1663 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.nerr_nf_fbd, NULL);
1664 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECMEMA,
1665 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recmema, NULL);
1666 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECMEMB,
1667 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recmemb, NULL);
1668 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECFGLOG,
1669 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recfglog, NULL);
1670 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECFBDA,
1671 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recfbda, NULL);
1672 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECFBDB,
1673 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recfbdb, NULL);
1674 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECFBDC,
1675 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recfbdc, NULL);
1676 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECFBDD,
1677 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recfbdd, NULL);
1678 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECFBDE,
1679 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recfbde, NULL);
1680 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECFBDF,
1681 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recfbdf, NULL);
1682 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_SPCPS,
1683 DATA_TYPE_UINT8, nb_regs->nb.nf_fbd_regs.spcps, NULL);
1684 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_SPCPC,
1685 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.spcpc, NULL);
1686 if (nb_chipset == INTEL_NB_7300 || nb_chipset == INTEL_NB_5400) {
1687 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNTA,
1688 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.cerrcnta, NULL);
1689 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNTB,
1690 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.cerrcntb, NULL);
1691 if (nb_chipset == INTEL_NB_7300) {
1692 fm_payload_set(payload,
1693 FM_EREPORT_PAYLOAD_NAME_CERRCNTC,
1694 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.cerrcntc,
1695 NULL);
1696 fm_payload_set(payload,
1697 FM_EREPORT_PAYLOAD_NAME_CERRCNTD,
1698 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.cerrcntd,
1699 NULL);
1700 }
1701 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNTA_LAST,
1702 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.cerrcnta_last,
1703 NULL);
1704 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNTB_LAST,
1705 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.cerrcntb_last,
1706 NULL);
1707 if (nb_chipset == INTEL_NB_7300) {
1708 fm_payload_set(payload,
1709 FM_EREPORT_PAYLOAD_NAME_CERRCNTC_LAST,
1710 DATA_TYPE_UINT32,
1711 nb_regs->nb.nf_fbd_regs.cerrcntc_last, NULL);
1712 fm_payload_set(payload,
1713 FM_EREPORT_PAYLOAD_NAME_CERRCNTD_LAST,
1714 DATA_TYPE_UINT32,
1715 nb_regs->nb.nf_fbd_regs.cerrcntd_last, NULL);
1716 }
1717 } else {
1718 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNT,
1719 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.cerrcnta, NULL);
1720 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNT_LAST,
1721 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.cerrcnta_last,
1722 NULL);
1723 }
1724 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BADRAMA,
1725 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.badrama, NULL);
1726 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BADRAMB,
1727 DATA_TYPE_UINT16, nb_regs->nb.nf_fbd_regs.badramb, NULL);
1728 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BADCNT,
1729 DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.badcnt, NULL);
1730
1731 if (sp->intel_error_list >= 0)
1732 (void) snprintf(buf, sizeof (buf), "M%d", sp->intel_error_list);
1733 else
1734 (void) snprintf(buf, sizeof (buf), "Multiple or unknown error");
1735 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_ERROR_NO,
1736 DATA_TYPE_STRING, buf, NULL);
1737 }
1738
1739 static void
nb_nf_mem_err_payload(const nb_regs_t * nb_regs,nvlist_t * payload,nb_scatchpad_t * data)1740 nb_nf_mem_err_payload(const nb_regs_t *nb_regs, nvlist_t *payload,
1741 nb_scatchpad_t *data)
1742 {
1743 nb_mem_scatchpad_t *sp;
1744 char buf[32];
1745
1746 sp = &((nb_scatchpad_t *)data)->ms;
1747
1748 if (sp->dimm == -1 && sp->rank != -1) {
1749 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RANK,
1750 DATA_TYPE_INT32, sp->rank, NULL);
1751 }
1752 if (sp->ras != -1) {
1753 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BANK,
1754 DATA_TYPE_INT32, sp->bank, NULL);
1755 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CAS,
1756 DATA_TYPE_INT32, sp->cas, NULL);
1757 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RAS,
1758 DATA_TYPE_INT32, sp->ras, NULL);
1759 if (sp->offset != -1LL) {
1760 fm_payload_set(payload, FM_FMRI_MEM_OFFSET,
1761 DATA_TYPE_UINT64, sp->offset, NULL);
1762 }
1763 if (sp->pa != -1LL) {
1764 fm_payload_set(payload, FM_FMRI_MEM_PHYSADDR,
1765 DATA_TYPE_UINT64, sp->pa, NULL);
1766 }
1767 }
1768 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_NF_MEM,
1769 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.ferr_nf_mem, NULL);
1770 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_NF_MEM,
1771 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.nerr_nf_mem, NULL);
1772 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECMEMA,
1773 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.recmema, NULL);
1774 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECMEMB,
1775 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.recmemb, NULL);
1776 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_REDMEMA,
1777 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.redmema, NULL);
1778 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_REDMEMB,
1779 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.redmemb, NULL);
1780 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECMEMA,
1781 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.nrecmema, NULL);
1782 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECMEMB,
1783 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.nrecmemb, NULL);
1784 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_SPCPS,
1785 DATA_TYPE_UINT8, nb_regs->nb.nf_mem_regs.spcps, NULL);
1786 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_SPCPC,
1787 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.spcpc, NULL);
1788 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNT,
1789 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.cerrcnt, NULL);
1790 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNT_LAST,
1791 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.cerrcnt_last, NULL);
1792 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNT_EXT,
1793 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.cerrcnt_ext, NULL);
1794 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNT_EXT_LAST,
1795 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.cerrcnt_ext_last, NULL);
1796 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BADRAM,
1797 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.badram, NULL);
1798 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BADCNT,
1799 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.badcnt, NULL);
1800 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_VALIDLOG,
1801 DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.validlog, NULL);
1802
1803 if (sp->intel_error_list >= 0)
1804 (void) snprintf(buf, sizeof (buf), "M%d", sp->intel_error_list);
1805 else
1806 (void) snprintf(buf, sizeof (buf), "Multiple or unknown error");
1807 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_ERROR_NO,
1808 DATA_TYPE_STRING, buf, NULL);
1809 }
1810
1811 static void
nb_dma_err_payload(const nb_regs_t * nb_regs,nvlist_t * payload)1812 nb_dma_err_payload(const nb_regs_t *nb_regs, nvlist_t *payload)
1813 {
1814 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_PCISTS,
1815 DATA_TYPE_UINT16, nb_regs->nb.dma_regs.pcists, NULL);
1816 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_PEXDEVSTS,
1817 DATA_TYPE_UINT16, nb_regs->nb.dma_regs.pexdevsts, NULL);
1818 }
1819
1820 static void
nb_thr_err_payload(const nb_regs_t * nb_regs,nvlist_t * payload,nb_scatchpad_t * data)1821 nb_thr_err_payload(const nb_regs_t *nb_regs, nvlist_t *payload,
1822 nb_scatchpad_t *data)
1823 {
1824 char buf[32];
1825
1826 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_FAT_THR,
1827 DATA_TYPE_UINT8, nb_regs->nb.thr_regs.ferr_fat_thr, NULL);
1828 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_FAT_THR,
1829 DATA_TYPE_UINT8, nb_regs->nb.thr_regs.nerr_fat_thr, NULL);
1830 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_NF_THR,
1831 DATA_TYPE_UINT8, nb_regs->nb.thr_regs.ferr_nf_thr, NULL);
1832 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_NF_THR,
1833 DATA_TYPE_UINT8, nb_regs->nb.thr_regs.nerr_nf_thr, NULL);
1834 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CTSTS,
1835 DATA_TYPE_UINT8, nb_regs->nb.thr_regs.ctsts, NULL);
1836 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_THRTSTS,
1837 DATA_TYPE_UINT16, nb_regs->nb.thr_regs.thrtsts, NULL);
1838 if (data->intel_error_list >= 0) {
1839 (void) snprintf(buf, sizeof (buf), "TH%d",
1840 data->intel_error_list);
1841 } else {
1842 (void) snprintf(buf, sizeof (buf), "Multiple or unknown error");
1843 }
1844 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_ERROR_NO,
1845 DATA_TYPE_STRING, buf, NULL);
1846 }
1847
1848 static void
nb_ereport_add_logout(nvlist_t * payload,const nb_logout_t * acl,nb_scatchpad_t * data)1849 nb_ereport_add_logout(nvlist_t *payload, const nb_logout_t *acl,
1850 nb_scatchpad_t *data)
1851 {
1852 const nb_regs_t *nb_regs = &acl->nb_regs;
1853
1854 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_MC_TYPE,
1855 DATA_TYPE_STRING, acl->type, NULL);
1856 switch (nb_regs->flag) {
1857 case NB_REG_LOG_FSB:
1858 nb_fsb_err_payload(nb_regs, payload, data);
1859 break;
1860 case NB_REG_LOG_PEX:
1861 nb_pex_err_payload(nb_regs, payload, data);
1862 break;
1863 case NB_REG_LOG_INT:
1864 nb_int_err_payload(nb_regs, payload, data);
1865 break;
1866 case NB_REG_LOG_FAT_FBD:
1867 nb_fat_fbd_err_payload(nb_regs, payload, data);
1868 break;
1869 case NB_REG_LOG_NF_FBD:
1870 nb_nf_fbd_err_payload(nb_regs, payload, data);
1871 break;
1872 case NB_REG_LOG_DMA:
1873 nb_dma_err_payload(nb_regs, payload);
1874 break;
1875 case NB_REG_LOG_THR:
1876 nb_thr_err_payload(nb_regs, payload, data);
1877 break;
1878 case NB_REG_LOG_NF_MEM:
1879 nb_nf_mem_err_payload(nb_regs, payload, data);
1880 break;
1881 default:
1882 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_GLOBAL,
1883 DATA_TYPE_UINT64, nb_regs->ferr, NULL);
1884 fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_GLOBAL,
1885 DATA_TYPE_UINT32, nb_regs->nerr, NULL);
1886 break;
1887 }
1888 }
1889
1890 void
nb_fsb_report(const nb_regs_t * nb_regs,char * class,nvlist_t * detector,nb_scatchpad_t * data)1891 nb_fsb_report(const nb_regs_t *nb_regs, char *class, nvlist_t *detector,
1892 nb_scatchpad_t *data)
1893 {
1894 int chip;
1895
1896 if (nb_chipset == INTEL_NB_7300)
1897 chip = nb_regs->nb.fsb_regs.fsb * 2;
1898 else
1899 chip = nb_regs->nb.fsb_regs.fsb;
1900 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 2,
1901 "motherboard", 0, "chip", chip);
1902
1903 if (nb_regs->nb.fsb_regs.ferr_fat_fsb == 0 &&
1904 nb_regs->nb.fsb_regs.ferr_nf_fsb == 0) {
1905 data->intel_error_list = intel_fsb_err(nb_regs->nb.fsb_regs.fsb,
1906 nb_regs->nb.fsb_regs.nerr_fat_fsb,
1907 nb_regs->nb.fsb_regs.nerr_nf_fsb);
1908 } else {
1909 data->intel_error_list = intel_fsb_err(nb_regs->nb.fsb_regs.fsb,
1910 nb_regs->nb.fsb_regs.ferr_fat_fsb,
1911 nb_regs->nb.fsb_regs.ferr_nf_fsb);
1912 }
1913 (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s.%s",
1914 FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, "nb", "fsb");
1915 }
1916
1917 void
nb_pex_report(const nb_regs_t * nb_regs,char * class,nvlist_t * detector,nb_scatchpad_t * data)1918 nb_pex_report(const nb_regs_t *nb_regs, char *class, nvlist_t *detector,
1919 nb_scatchpad_t *data)
1920 {
1921 int hostbridge;
1922
1923 if (nb_regs->nb.pex_regs.pex == 0) {
1924 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 1,
1925 "motherboard", 0);
1926 } else {
1927 hostbridge = nb_regs->nb.pex_regs.pex - 1;
1928 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 2,
1929 "motherboard", 0,
1930 "hostbridge", hostbridge);
1931 }
1932
1933 if (nb_regs->nb.pex_regs.pex_fat_ferr == 0 &&
1934 nb_regs->nb.pex_regs.pex_nf_corr_ferr == 0) {
1935 if (nb_chipset == INTEL_NB_5400) {
1936 data->intel_error_list =
1937 intel_pex_5400_err(
1938 nb_regs->nb.pex_regs.pex_fat_nerr,
1939 nb_regs->nb.pex_regs.pex_nf_corr_nerr);
1940 } else {
1941 data->intel_error_list =
1942 intel_pex_err(nb_regs->nb.pex_regs.pex_fat_nerr,
1943 nb_regs->nb.pex_regs.pex_nf_corr_nerr);
1944 }
1945 } else {
1946 if (nb_chipset == INTEL_NB_5400) {
1947 data->intel_error_list =
1948 intel_pex_5400_err(
1949 nb_regs->nb.pex_regs.pex_fat_ferr,
1950 nb_regs->nb.pex_regs.pex_nf_corr_ferr);
1951 } else {
1952 data->intel_error_list =
1953 intel_pex_err(nb_regs->nb.pex_regs.pex_fat_ferr,
1954 nb_regs->nb.pex_regs.pex_nf_corr_ferr);
1955 }
1956 }
1957
1958 if (nb_regs->nb.pex_regs.pex == 0) {
1959 (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s.%s",
1960 FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, "nb", "esi");
1961 } else {
1962 (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s.%s",
1963 FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, "nb", "pex");
1964 }
1965 }
1966
1967 void
nb_int_report(const nb_regs_t * nb_regs,char * class,nvlist_t * detector,void * data)1968 nb_int_report(const nb_regs_t *nb_regs, char *class, nvlist_t *detector,
1969 void *data)
1970 {
1971 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 1,
1972 "motherboard", 0);
1973
1974 if (nb_regs->nb.int_regs.ferr_fat_int == 0 &&
1975 nb_regs->nb.int_regs.ferr_nf_int == 0) {
1976 ((nb_scatchpad_t *)data)->intel_error_list =
1977 intel_int_err(nb_regs->nb.int_regs.nerr_fat_int,
1978 nb_regs->nb.int_regs.nerr_nf_int);
1979 } else {
1980 ((nb_scatchpad_t *)data)->intel_error_list =
1981 intel_int_err(nb_regs->nb.int_regs.ferr_fat_int,
1982 nb_regs->nb.int_regs.ferr_nf_int);
1983 }
1984 (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s.%s",
1985 FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, "nb", "ie");
1986 }
1987
1988 void
nb_fat_fbd_report(const nb_regs_t * nb_regs,char * class,nvlist_t * detector,void * data)1989 nb_fat_fbd_report(const nb_regs_t *nb_regs, char *class, nvlist_t *detector,
1990 void *data)
1991 {
1992 char *intr;
1993 nb_mem_scatchpad_t *sp;
1994
1995 intr = fat_memory_error(nb_regs, data);
1996 sp = &((nb_scatchpad_t *)data)->ms;
1997
1998 if (sp->dimm != -1) {
1999 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 5,
2000 "motherboard", 0,
2001 "memory-controller", sp->branch,
2002 "dram-channel", sp->channel,
2003 "dimm", sp->dimm,
2004 "rank", sp->rank);
2005 } else if (sp->channel != -1) {
2006 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 3,
2007 "motherboard", 0,
2008 "memory-controller", sp->branch,
2009 "dram-channel", sp->channel);
2010 } else if (sp->branch != -1) {
2011 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 2,
2012 "motherboard", 0,
2013 "memory-controller", sp->branch);
2014 } else {
2015 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 1,
2016 "motherboard", 0);
2017 }
2018
2019 (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s",
2020 FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, intr);
2021 }
2022
2023 void
nb_nf_fbd_report(const nb_regs_t * nb_regs,char * class,nvlist_t * detector,void * data)2024 nb_nf_fbd_report(const nb_regs_t *nb_regs, char *class, nvlist_t *detector,
2025 void *data)
2026 {
2027 char *intr;
2028 nb_mem_scatchpad_t *sp;
2029
2030 intr = nf_memory_error(nb_regs, data);
2031 sp = &((nb_scatchpad_t *)data)->ms;
2032
2033 if (sp->dimm != -1) {
2034 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 5,
2035 "motherboard", 0,
2036 "memory-controller", sp->branch,
2037 "dram-channel", sp->channel,
2038 "dimm", sp->dimm,
2039 "rank", sp->rank);
2040 } else if (sp->channel != -1) {
2041 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 3,
2042 "motherboard", 0,
2043 "memory-controller", sp->branch,
2044 "dram-channel", sp->channel);
2045 } else if (sp->branch != -1) {
2046 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 2,
2047 "motherboard", 0,
2048 "memory-controller", sp->branch);
2049 } else {
2050 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 1,
2051 "motherboard", 0);
2052 }
2053
2054 (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s",
2055 FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, intr);
2056 }
2057
2058 void
nb_dma_report(char * class,nvlist_t * detector)2059 nb_dma_report(char *class, nvlist_t *detector)
2060 {
2061 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 1,
2062 "motherboard", 0);
2063
2064 (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s.%s",
2065 FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, "nb", "dma");
2066 }
2067
2068 void
nb_thr_report(const nb_regs_t * nb_regs,char * class,nvlist_t * detector,void * data)2069 nb_thr_report(const nb_regs_t *nb_regs, char *class, nvlist_t *detector,
2070 void *data)
2071 {
2072 ((nb_scatchpad_t *)data)->intel_error_list =
2073 intel_thr_err(nb_regs->nb.thr_regs.ferr_fat_thr,
2074 nb_regs->nb.thr_regs.ferr_nf_thr);
2075 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 1,
2076 "motherboard", 0);
2077
2078 (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s.%s",
2079 FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, "nb", "otf");
2080 }
2081
2082 void
nb_nf_mem_report(const nb_regs_t * nb_regs,char * class,nvlist_t * detector,void * data)2083 nb_nf_mem_report(const nb_regs_t *nb_regs, char *class, nvlist_t *detector,
2084 void *data)
2085 {
2086 char *intr;
2087 nb_mem_scatchpad_t *sp;
2088
2089 intr = nf_mem_error(nb_regs, data);
2090 sp = &((nb_scatchpad_t *)data)->ms;
2091
2092 if (sp->dimm != -1) {
2093 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 5,
2094 "motherboard", 0,
2095 "memory-controller", sp->branch,
2096 "dram-channel", sp->channel,
2097 "dimm", sp->dimm,
2098 "rank", sp->rank);
2099 } else if (sp->channel != -1) {
2100 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 3,
2101 "motherboard", 0,
2102 "memory-controller", sp->branch,
2103 "dram-channel", sp->channel);
2104 } else if (sp->branch != -1) {
2105 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 2,
2106 "motherboard", 0,
2107 "memory-controller", sp->branch);
2108 } else {
2109 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 1,
2110 "motherboard", 0);
2111 }
2112
2113 (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s",
2114 FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, intr);
2115 }
2116
2117
2118 nvlist_t *
nb_report(const nb_regs_t * nb_regs,char * class,nv_alloc_t * nva,void * scratch)2119 nb_report(const nb_regs_t *nb_regs, char *class, nv_alloc_t *nva, void *scratch)
2120 {
2121 nvlist_t *detector = fm_nvlist_create(nva);
2122
2123 switch (nb_regs->flag) {
2124 case NB_REG_LOG_FSB:
2125 nb_fsb_report(nb_regs, class, detector, scratch);
2126 break;
2127 case NB_REG_LOG_PEX:
2128 nb_pex_report(nb_regs, class, detector, scratch);
2129 break;
2130 case NB_REG_LOG_INT:
2131 nb_int_report(nb_regs, class, detector, scratch);
2132 break;
2133 case NB_REG_LOG_FAT_FBD:
2134 nb_fat_fbd_report(nb_regs, class, detector, scratch);
2135 break;
2136 case NB_REG_LOG_NF_FBD:
2137 nb_nf_fbd_report(nb_regs, class, detector, scratch);
2138 break;
2139 case NB_REG_LOG_DMA:
2140 nb_dma_report(class, detector);
2141 break;
2142 case NB_REG_LOG_THR:
2143 nb_thr_report(nb_regs, class, detector, scratch);
2144 break;
2145 case NB_REG_LOG_NF_MEM:
2146 nb_nf_mem_report(nb_regs, class, detector, scratch);
2147 break;
2148 default:
2149 fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 1,
2150 "motherboard", 0);
2151
2152 (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s.%s",
2153 FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, "nb", "unknown");
2154 }
2155 return (detector);
2156 }
2157
2158 /*ARGSUSED*/
2159 void
nb_drain(void * ignored,const void * data,const errorq_elem_t * eqe)2160 nb_drain(void *ignored, const void *data, const errorq_elem_t *eqe)
2161 {
2162 nb_logout_t *acl = (nb_logout_t *)data;
2163 errorq_elem_t *eqep, *scr_eqep;
2164 nvlist_t *ereport, *detector;
2165 nv_alloc_t *nva = NULL;
2166 char buf[FM_MAX_CLASS];
2167 nb_scatchpad_t nb_scatchpad;
2168
2169 eqep = NULL;
2170 scr_eqep = NULL;
2171 if (panicstr) {
2172 if ((eqep = errorq_reserve(ereport_errorq)) == NULL)
2173 return;
2174 ereport = errorq_elem_nvl(ereport_errorq, eqep);
2175 /*
2176 * Now try to allocate another element for scratch space and
2177 * use that for further scratch space (eg for constructing
2178 * nvlists to add the main ereport). If we can't reserve
2179 * a scratch element just fallback to working within the
2180 * element we already have, and hope for the best. All this
2181 * is necessary because the fixed buffer nv allocator does
2182 * not reclaim freed space and nvlist construction is
2183 * expensive.
2184 */
2185 if ((scr_eqep = errorq_reserve(ereport_errorq)) != NULL)
2186 nva = errorq_elem_nva(ereport_errorq, scr_eqep);
2187 else
2188 nva = errorq_elem_nva(ereport_errorq, eqep);
2189 } else {
2190 ereport = fm_nvlist_create(NULL);
2191 }
2192 detector = nb_report(&acl->nb_regs, buf, nva, &nb_scatchpad);
2193 if (detector == NULL)
2194 return;
2195 fm_ereport_set(ereport, FM_EREPORT_VERSION, buf,
2196 fm_ena_generate(acl->acl_timestamp, FM_ENA_FMT1), detector, NULL);
2197 /*
2198 * We're done with 'detector' so reclaim the scratch space.
2199 */
2200 if (panicstr) {
2201 fm_nvlist_destroy(detector, FM_NVA_RETAIN);
2202 nv_alloc_reset(nva);
2203 } else {
2204 fm_nvlist_destroy(detector, FM_NVA_FREE);
2205 }
2206
2207 /*
2208 * Encode the error-specific data that was saved in the logout area.
2209 */
2210 nb_ereport_add_logout(ereport, acl, &nb_scatchpad);
2211
2212 if (panicstr) {
2213 errorq_commit(ereport_errorq, eqep, ERRORQ_SYNC);
2214 if (scr_eqep)
2215 errorq_cancel(ereport_errorq, scr_eqep);
2216 } else {
2217 (void) fm_ereport_post(ereport, EVCH_TRYHARD);
2218 fm_nvlist_destroy(ereport, FM_NVA_FREE);
2219 }
2220 }
2221