17532SSean.Ye@Sun.COM /*
27532SSean.Ye@Sun.COM * CDDL HEADER START
37532SSean.Ye@Sun.COM *
47532SSean.Ye@Sun.COM * The contents of this file are subject to the terms of the
57532SSean.Ye@Sun.COM * Common Development and Distribution License (the "License").
67532SSean.Ye@Sun.COM * You may not use this file except in compliance with the License.
77532SSean.Ye@Sun.COM *
87532SSean.Ye@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97532SSean.Ye@Sun.COM * or http://www.opensolaris.org/os/licensing.
107532SSean.Ye@Sun.COM * See the License for the specific language governing permissions
117532SSean.Ye@Sun.COM * and limitations under the License.
127532SSean.Ye@Sun.COM *
137532SSean.Ye@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
147532SSean.Ye@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157532SSean.Ye@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
167532SSean.Ye@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
177532SSean.Ye@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
187532SSean.Ye@Sun.COM *
197532SSean.Ye@Sun.COM * CDDL HEADER END
207532SSean.Ye@Sun.COM */
217532SSean.Ye@Sun.COM
227532SSean.Ye@Sun.COM /*
23*12437SAdrian.Frost@Sun.COM * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
247532SSean.Ye@Sun.COM */
257532SSean.Ye@Sun.COM
267532SSean.Ye@Sun.COM #include <sys/types.h>
277532SSean.Ye@Sun.COM #include <sys/cmn_err.h>
287532SSean.Ye@Sun.COM #include <sys/errno.h>
297532SSean.Ye@Sun.COM #include <sys/log.h>
307532SSean.Ye@Sun.COM #include <sys/systm.h>
317532SSean.Ye@Sun.COM #include <sys/modctl.h>
327532SSean.Ye@Sun.COM #include <sys/errorq.h>
337532SSean.Ye@Sun.COM #include <sys/controlregs.h>
347532SSean.Ye@Sun.COM #include <sys/fm/util.h>
357532SSean.Ye@Sun.COM #include <sys/fm/protocol.h>
367532SSean.Ye@Sun.COM #include <sys/sysevent.h>
377532SSean.Ye@Sun.COM #include <sys/pghw.h>
387532SSean.Ye@Sun.COM #include <sys/cyclic.h>
397532SSean.Ye@Sun.COM #include <sys/pci_cfgspace.h>
407532SSean.Ye@Sun.COM #include <sys/mc_intel.h>
417532SSean.Ye@Sun.COM #include <sys/smbios.h>
427532SSean.Ye@Sun.COM #include "nb5000.h"
437532SSean.Ye@Sun.COM #include "nb_log.h"
447532SSean.Ye@Sun.COM #include "dimm_phys.h"
457532SSean.Ye@Sun.COM
4610049SVuong.Nguyen@Sun.COM int nb_check_validlog = 1;
4710049SVuong.Nguyen@Sun.COM
487532SSean.Ye@Sun.COM static uint32_t uerrcnt[2];
497532SSean.Ye@Sun.COM static uint32_t cerrcnta[2][2];
507532SSean.Ye@Sun.COM static uint32_t cerrcntb[2][2];
517532SSean.Ye@Sun.COM static uint32_t cerrcntc[2][2];
527532SSean.Ye@Sun.COM static uint32_t cerrcntd[2][2];
537532SSean.Ye@Sun.COM static nb_logout_t nb_log;
547532SSean.Ye@Sun.COM
557532SSean.Ye@Sun.COM struct mch_error_code {
567532SSean.Ye@Sun.COM int intel_error_list; /* error number in Chipset Error List */
577532SSean.Ye@Sun.COM uint32_t emask; /* mask for machine check */
587532SSean.Ye@Sun.COM uint32_t error_bit; /* error bit in fault register */
597532SSean.Ye@Sun.COM };
607532SSean.Ye@Sun.COM
617532SSean.Ye@Sun.COM static struct mch_error_code fat_fbd_error_code[] = {
627532SSean.Ye@Sun.COM { 23, EMASK_FBD_M23, ERR_FAT_FBD_M23 },
637532SSean.Ye@Sun.COM { 3, EMASK_FBD_M3, ERR_FAT_FBD_M3 },
647532SSean.Ye@Sun.COM { 2, EMASK_FBD_M2, ERR_FAT_FBD_M2 },
657532SSean.Ye@Sun.COM { 1, EMASK_FBD_M1, ERR_FAT_FBD_M1 }
667532SSean.Ye@Sun.COM };
677532SSean.Ye@Sun.COM
687532SSean.Ye@Sun.COM static int
intel_fat_fbd_err(uint32_t fat_fbd)697532SSean.Ye@Sun.COM intel_fat_fbd_err(uint32_t fat_fbd)
707532SSean.Ye@Sun.COM {
717532SSean.Ye@Sun.COM int rt = -1;
727532SSean.Ye@Sun.COM int nerr = 0;
737532SSean.Ye@Sun.COM uint32_t emask_fbd = 0;
747532SSean.Ye@Sun.COM int i;
757532SSean.Ye@Sun.COM int sz;
767532SSean.Ye@Sun.COM
777532SSean.Ye@Sun.COM sz = sizeof (fat_fbd_error_code) / sizeof (struct mch_error_code);
787532SSean.Ye@Sun.COM
797532SSean.Ye@Sun.COM for (i = 0; i < sz; i++) {
807532SSean.Ye@Sun.COM if (fat_fbd & fat_fbd_error_code[i].error_bit) {
817532SSean.Ye@Sun.COM rt = fat_fbd_error_code[i].intel_error_list;
827532SSean.Ye@Sun.COM emask_fbd |= fat_fbd_error_code[i].emask;
837532SSean.Ye@Sun.COM nerr++;
847532SSean.Ye@Sun.COM }
857532SSean.Ye@Sun.COM }
867532SSean.Ye@Sun.COM
877532SSean.Ye@Sun.COM if (emask_fbd)
887532SSean.Ye@Sun.COM nb_fbd_mask_mc(emask_fbd);
897532SSean.Ye@Sun.COM if (nerr > 1)
907532SSean.Ye@Sun.COM rt = -1;
917532SSean.Ye@Sun.COM return (rt);
927532SSean.Ye@Sun.COM }
937532SSean.Ye@Sun.COM
947532SSean.Ye@Sun.COM static char *
fat_memory_error(const nb_regs_t * rp,void * data)957532SSean.Ye@Sun.COM fat_memory_error(const nb_regs_t *rp, void *data)
967532SSean.Ye@Sun.COM {
977532SSean.Ye@Sun.COM int channel;
987532SSean.Ye@Sun.COM uint32_t ferr_fat_fbd, nrecmemb;
997532SSean.Ye@Sun.COM uint32_t nrecmema;
1007532SSean.Ye@Sun.COM char *intr = "nb.unknown";
1017532SSean.Ye@Sun.COM nb_mem_scatchpad_t *sp = &((nb_scatchpad_t *)data)->ms;
1027532SSean.Ye@Sun.COM
1037532SSean.Ye@Sun.COM ferr_fat_fbd = rp->nb.fat_fbd_regs.ferr_fat_fbd;
1047532SSean.Ye@Sun.COM if ((ferr_fat_fbd & ERR_FAT_FBD_MASK) == 0) {
1057532SSean.Ye@Sun.COM sp->intel_error_list =
1067532SSean.Ye@Sun.COM intel_fat_fbd_err(rp->nb.fat_fbd_regs.nerr_fat_fbd);
1077532SSean.Ye@Sun.COM sp->branch = -1;
1087532SSean.Ye@Sun.COM sp->channel = -1;
1097532SSean.Ye@Sun.COM sp->rank = -1;
1107532SSean.Ye@Sun.COM sp->dimm = -1;
1117532SSean.Ye@Sun.COM sp->bank = -1;
1127532SSean.Ye@Sun.COM sp->cas = -1;
1137532SSean.Ye@Sun.COM sp->ras = -1;
1147532SSean.Ye@Sun.COM sp->pa = -1LL;
1157532SSean.Ye@Sun.COM sp->offset = -1;
1167532SSean.Ye@Sun.COM return (intr);
1177532SSean.Ye@Sun.COM }
1187532SSean.Ye@Sun.COM sp->intel_error_list = intel_fat_fbd_err(ferr_fat_fbd);
1197532SSean.Ye@Sun.COM channel = (ferr_fat_fbd >> 28) & 3;
1207532SSean.Ye@Sun.COM sp->branch = channel >> 1;
1217532SSean.Ye@Sun.COM sp->channel = channel;
1227532SSean.Ye@Sun.COM if ((ferr_fat_fbd & (ERR_FAT_FBD_M2|ERR_FAT_FBD_M1)) != 0) {
1237532SSean.Ye@Sun.COM if ((ferr_fat_fbd & ERR_FAT_FBD_M1) != 0)
1247532SSean.Ye@Sun.COM intr = "nb.fbd.alert"; /* Alert on FB-DIMM M1 */
1257532SSean.Ye@Sun.COM else
1267532SSean.Ye@Sun.COM intr = "nb.fbd.crc"; /* CRC error FB_DIMM M2 */
1277532SSean.Ye@Sun.COM nrecmema = rp->nb.fat_fbd_regs.nrecmema;
1287532SSean.Ye@Sun.COM nrecmemb = rp->nb.fat_fbd_regs.nrecmemb;
1297532SSean.Ye@Sun.COM sp->rank = (nrecmema >> 8) & RANK_MASK;
1307532SSean.Ye@Sun.COM sp->dimm = sp->rank >> 1;
1317532SSean.Ye@Sun.COM sp->bank = (nrecmema >> 12) & BANK_MASK;
1327532SSean.Ye@Sun.COM sp->cas = (nrecmemb >> 16) & CAS_MASK;
1337532SSean.Ye@Sun.COM sp->ras = nrecmemb & RAS_MASK;
13410650SVuong.Nguyen@Sun.COM /*
13510650SVuong.Nguyen@Sun.COM * If driver was built with closed tree present then we will
13610650SVuong.Nguyen@Sun.COM * have Intel proprietary code for finding physaddr
13710650SVuong.Nguyen@Sun.COM */
13810650SVuong.Nguyen@Sun.COM if (&dimm_getphys) {
13910650SVuong.Nguyen@Sun.COM sp->pa = dimm_getphys((uint16_t)sp->branch,
14010650SVuong.Nguyen@Sun.COM (uint16_t)sp->rank, (uint64_t)sp->bank,
14110650SVuong.Nguyen@Sun.COM (uint64_t)sp->ras, (uint64_t)sp->cas);
14210650SVuong.Nguyen@Sun.COM if (sp->pa >= MAXPHYS_ADDR)
14310650SVuong.Nguyen@Sun.COM sp->pa = -1ULL;
14410650SVuong.Nguyen@Sun.COM } else {
14510650SVuong.Nguyen@Sun.COM sp->pa = -1ULL;
14610650SVuong.Nguyen@Sun.COM }
14710650SVuong.Nguyen@Sun.COM /*
14810650SVuong.Nguyen@Sun.COM * If there is an offset decoder use it otherwise encode
14910650SVuong.Nguyen@Sun.COM * rank/bank/ras/cas
15010650SVuong.Nguyen@Sun.COM */
15110650SVuong.Nguyen@Sun.COM if (&dimm_getoffset) {
15210650SVuong.Nguyen@Sun.COM sp->offset = dimm_getoffset(sp->branch, sp->rank,
15310650SVuong.Nguyen@Sun.COM sp->bank, sp->ras, sp->cas);
15410650SVuong.Nguyen@Sun.COM } else {
15510650SVuong.Nguyen@Sun.COM sp->offset = TCODE_OFFSET(sp->rank, sp->bank, sp->ras,
15610650SVuong.Nguyen@Sun.COM sp->cas);
15710650SVuong.Nguyen@Sun.COM }
1587532SSean.Ye@Sun.COM } else {
1597532SSean.Ye@Sun.COM if ((ferr_fat_fbd & ERR_FAT_FBD_M3) != 0)
1607532SSean.Ye@Sun.COM intr = "nb.fbd.otf"; /* thermal temp > Tmid M3 */
1617532SSean.Ye@Sun.COM else if ((ferr_fat_fbd & ERR_FAT_FBD_M23) != 0) {
1627532SSean.Ye@Sun.COM intr = "nb.fbd.reset_timeout";
1637532SSean.Ye@Sun.COM sp->channel = -1;
1647532SSean.Ye@Sun.COM }
1657532SSean.Ye@Sun.COM sp->rank = -1;
1667532SSean.Ye@Sun.COM sp->dimm = -1;
1677532SSean.Ye@Sun.COM sp->bank = -1;
1687532SSean.Ye@Sun.COM sp->cas = -1;
1697532SSean.Ye@Sun.COM sp->ras = -1;
1707532SSean.Ye@Sun.COM sp->pa = -1LL;
1717532SSean.Ye@Sun.COM sp->offset = -1;
1727532SSean.Ye@Sun.COM }
1737532SSean.Ye@Sun.COM return (intr);
1747532SSean.Ye@Sun.COM }
1757532SSean.Ye@Sun.COM
1767532SSean.Ye@Sun.COM
1777532SSean.Ye@Sun.COM static struct mch_error_code nf_fbd_error_code[] = {
1787532SSean.Ye@Sun.COM { 29, EMASK_FBD_M29, ERR_NF_FBD_M29 },
1797532SSean.Ye@Sun.COM { 28, EMASK_FBD_M28, ERR_NF_FBD_M28 },
1807532SSean.Ye@Sun.COM { 27, EMASK_FBD_M27, ERR_NF_FBD_M27 },
1817532SSean.Ye@Sun.COM { 26, EMASK_FBD_M26, ERR_NF_FBD_M26 },
1827532SSean.Ye@Sun.COM { 25, EMASK_FBD_M25, ERR_NF_FBD_M25 },
1837532SSean.Ye@Sun.COM { 24, EMASK_FBD_M24, ERR_NF_FBD_M24 },
1847532SSean.Ye@Sun.COM { 22, EMASK_FBD_M22, ERR_NF_FBD_M22 },
1857532SSean.Ye@Sun.COM { 21, EMASK_FBD_M21, ERR_NF_FBD_M21 },
1867532SSean.Ye@Sun.COM { 20, EMASK_FBD_M20, ERR_NF_FBD_M20 },
1877532SSean.Ye@Sun.COM { 19, EMASK_FBD_M19, ERR_NF_FBD_M19 },
1887532SSean.Ye@Sun.COM { 18, EMASK_FBD_M18, ERR_NF_FBD_M18 },
1897532SSean.Ye@Sun.COM { 17, EMASK_FBD_M17, ERR_NF_FBD_M17 },
1907532SSean.Ye@Sun.COM { 16, EMASK_FBD_M16, ERR_NF_FBD_M16 },
1917532SSean.Ye@Sun.COM { 15, EMASK_FBD_M15, ERR_NF_FBD_M15 },
1927532SSean.Ye@Sun.COM { 14, EMASK_FBD_M14, ERR_NF_FBD_M14 },
1937532SSean.Ye@Sun.COM { 13, EMASK_FBD_M13, ERR_NF_FBD_M13 },
1947532SSean.Ye@Sun.COM { 12, EMASK_FBD_M12, ERR_NF_FBD_M12 },
1957532SSean.Ye@Sun.COM { 11, EMASK_FBD_M11, ERR_NF_FBD_M11 },
1967532SSean.Ye@Sun.COM { 10, EMASK_FBD_M10, ERR_NF_FBD_M10 },
1977532SSean.Ye@Sun.COM { 9, EMASK_FBD_M9, ERR_NF_FBD_M9 },
1987532SSean.Ye@Sun.COM { 8, EMASK_FBD_M8, ERR_NF_FBD_M8 },
1997532SSean.Ye@Sun.COM { 7, EMASK_FBD_M7, ERR_NF_FBD_M7 },
2007532SSean.Ye@Sun.COM { 6, EMASK_FBD_M6, ERR_NF_FBD_M6 },
2017532SSean.Ye@Sun.COM { 5, EMASK_FBD_M5, ERR_NF_FBD_M5 },
2027532SSean.Ye@Sun.COM { 4, EMASK_FBD_M4, ERR_NF_FBD_M4 }
2037532SSean.Ye@Sun.COM };
2047532SSean.Ye@Sun.COM
2057532SSean.Ye@Sun.COM static int
intel_nf_fbd_err(uint32_t nf_fbd)2067532SSean.Ye@Sun.COM intel_nf_fbd_err(uint32_t nf_fbd)
2077532SSean.Ye@Sun.COM {
2087532SSean.Ye@Sun.COM int rt = -1;
2097532SSean.Ye@Sun.COM int nerr = 0;
2107532SSean.Ye@Sun.COM uint32_t emask_fbd = 0;
2117532SSean.Ye@Sun.COM int i;
2127532SSean.Ye@Sun.COM int sz;
2137532SSean.Ye@Sun.COM
2147532SSean.Ye@Sun.COM sz = sizeof (nf_fbd_error_code) / sizeof (struct mch_error_code);
2157532SSean.Ye@Sun.COM
2167532SSean.Ye@Sun.COM for (i = 0; i < sz; i++) {
2177532SSean.Ye@Sun.COM if (nf_fbd & nf_fbd_error_code[i].error_bit) {
2187532SSean.Ye@Sun.COM rt = nf_fbd_error_code[i].intel_error_list;
2197532SSean.Ye@Sun.COM emask_fbd |= nf_fbd_error_code[i].emask;
2207532SSean.Ye@Sun.COM nerr++;
2217532SSean.Ye@Sun.COM }
2227532SSean.Ye@Sun.COM }
2237532SSean.Ye@Sun.COM if (emask_fbd)
2247532SSean.Ye@Sun.COM nb_fbd_mask_mc(emask_fbd);
2257532SSean.Ye@Sun.COM if (nerr > 1)
2267532SSean.Ye@Sun.COM rt = -1;
2277532SSean.Ye@Sun.COM return (rt);
2287532SSean.Ye@Sun.COM }
2297532SSean.Ye@Sun.COM
2307532SSean.Ye@Sun.COM static char *
nf_memory_error(const nb_regs_t * rp,void * data)2317532SSean.Ye@Sun.COM nf_memory_error(const nb_regs_t *rp, void *data)
2327532SSean.Ye@Sun.COM {
2337532SSean.Ye@Sun.COM uint32_t ferr_nf_fbd, recmemb, redmemb;
2347532SSean.Ye@Sun.COM uint32_t recmema;
2357532SSean.Ye@Sun.COM int branch, channel, ecc_locator;
2367532SSean.Ye@Sun.COM char *intr = "nb.unknown";
2377532SSean.Ye@Sun.COM nb_mem_scatchpad_t *sp = &((nb_scatchpad_t *)data)->ms;
2387532SSean.Ye@Sun.COM
2397532SSean.Ye@Sun.COM sp->rank = -1;
2407532SSean.Ye@Sun.COM sp->dimm = -1;
2417532SSean.Ye@Sun.COM sp->bank = -1;
2427532SSean.Ye@Sun.COM sp->cas = -1;
2437532SSean.Ye@Sun.COM sp->ras = -1LL;
2447532SSean.Ye@Sun.COM sp->pa = -1LL;
2457532SSean.Ye@Sun.COM sp->offset = -1;
2467532SSean.Ye@Sun.COM ferr_nf_fbd = rp->nb.nf_fbd_regs.ferr_nf_fbd;
2477532SSean.Ye@Sun.COM if ((ferr_nf_fbd & ERR_NF_FBD_MASK) == 0) {
24810199SVuong.Nguyen@Sun.COM /* unknown ereport if a recognizable error was not found */
2497532SSean.Ye@Sun.COM sp->branch = -1;
2507532SSean.Ye@Sun.COM sp->channel = -1;
25110199SVuong.Nguyen@Sun.COM sp->intel_error_list = -1;
2527532SSean.Ye@Sun.COM return (intr);
2537532SSean.Ye@Sun.COM }
2547532SSean.Ye@Sun.COM sp->intel_error_list = intel_nf_fbd_err(ferr_nf_fbd);
2557532SSean.Ye@Sun.COM channel = (ferr_nf_fbd >> ERR_FBD_CH_SHIFT) & 3;
2567532SSean.Ye@Sun.COM branch = channel >> 1;
2577532SSean.Ye@Sun.COM sp->branch = branch;
2587532SSean.Ye@Sun.COM sp->channel = channel;
2597532SSean.Ye@Sun.COM if (ferr_nf_fbd & ERR_NF_FBD_MASK) {
2607532SSean.Ye@Sun.COM if (ferr_nf_fbd & ERR_NF_FBD_ECC_UE) {
2617532SSean.Ye@Sun.COM /*
2627532SSean.Ye@Sun.COM * uncorrectable ECC M4 - M12
2637532SSean.Ye@Sun.COM * we can only isolate to pair of dimms
2647532SSean.Ye@Sun.COM * for single dimm configuration let eversholt
2657532SSean.Ye@Sun.COM * sort it out with out needing a special rule
2667532SSean.Ye@Sun.COM */
2677532SSean.Ye@Sun.COM sp->channel = -1;
2687532SSean.Ye@Sun.COM recmema = rp->nb.nf_fbd_regs.recmema;
2697532SSean.Ye@Sun.COM recmemb = rp->nb.nf_fbd_regs.recmemb;
2707532SSean.Ye@Sun.COM sp->rank = (recmema >> 8) & RANK_MASK;
2717532SSean.Ye@Sun.COM sp->bank = (recmema >> 12) & BANK_MASK;
2727532SSean.Ye@Sun.COM sp->cas = (recmemb >> 16) & CAS_MASK;
2737532SSean.Ye@Sun.COM sp->ras = recmemb & RAS_MASK;
2747532SSean.Ye@Sun.COM intr = "nb.mem_ue";
2757532SSean.Ye@Sun.COM } else if (ferr_nf_fbd & ERR_NF_FBD_M13) {
2767532SSean.Ye@Sun.COM /*
2777532SSean.Ye@Sun.COM * write error M13
2787532SSean.Ye@Sun.COM * we can only isolate to pair of dimms
2797532SSean.Ye@Sun.COM */
2807532SSean.Ye@Sun.COM sp->channel = -1;
2817532SSean.Ye@Sun.COM if (nb_mode != NB_MEMORY_MIRROR) {
2827532SSean.Ye@Sun.COM recmema = rp->nb.nf_fbd_regs.recmema;
2837532SSean.Ye@Sun.COM sp->rank = (recmema >> 8) & RANK_MASK;
2847532SSean.Ye@Sun.COM sp->bank = (recmema >> 12) & BANK_MASK;
2857532SSean.Ye@Sun.COM sp->cas = (recmemb >> 16) & CAS_MASK;
2867532SSean.Ye@Sun.COM sp->ras = recmemb & RAS_MASK;
2877532SSean.Ye@Sun.COM }
2887532SSean.Ye@Sun.COM intr = "nb.fbd.ma"; /* memory alert */
2897532SSean.Ye@Sun.COM } else if (ferr_nf_fbd & ERR_NF_FBD_MA) { /* M14, M15 and M21 */
2907532SSean.Ye@Sun.COM intr = "nb.fbd.ch"; /* FBD on channel */
2917532SSean.Ye@Sun.COM } else if ((ferr_nf_fbd & ERR_NF_FBD_ECC_CE) != 0) {
2927532SSean.Ye@Sun.COM /* correctable ECC M17-M20 */
2937532SSean.Ye@Sun.COM recmema = rp->nb.nf_fbd_regs.recmema;
2947532SSean.Ye@Sun.COM recmemb = rp->nb.nf_fbd_regs.recmemb;
2957532SSean.Ye@Sun.COM sp->rank = (recmema >> 8) & RANK_MASK;
2967532SSean.Ye@Sun.COM redmemb = rp->nb.nf_fbd_regs.redmemb;
2977532SSean.Ye@Sun.COM ecc_locator = redmemb & 0x3ffff;
2987532SSean.Ye@Sun.COM if (ecc_locator & 0x1ff)
2997532SSean.Ye@Sun.COM sp->channel = branch << 1;
3007532SSean.Ye@Sun.COM else if (ecc_locator & 0x3fe00)
3017532SSean.Ye@Sun.COM sp->channel = (branch << 1) + 1;
3027532SSean.Ye@Sun.COM sp->dimm = sp->rank >> 1;
3037532SSean.Ye@Sun.COM sp->bank = (recmema >> 12) & BANK_MASK;
3047532SSean.Ye@Sun.COM sp->cas = (recmemb >> 16) & CAS_MASK;
3057532SSean.Ye@Sun.COM sp->ras = recmemb & RAS_MASK;
3067532SSean.Ye@Sun.COM intr = "nb.mem_ce";
3077532SSean.Ye@Sun.COM } else if ((ferr_nf_fbd & ERR_NF_FBD_SPARE) != 0) {
3087532SSean.Ye@Sun.COM /* spare dimm M27, M28 */
3097532SSean.Ye@Sun.COM intr = "nb.mem_ds";
3107532SSean.Ye@Sun.COM sp->channel = -1;
3117532SSean.Ye@Sun.COM if (rp->nb.nf_fbd_regs.spcps & SPCPS_SPARE_DEPLOYED) {
3127532SSean.Ye@Sun.COM sp->rank =
3137532SSean.Ye@Sun.COM SPCPS_FAILED_RANK(rp->nb.nf_fbd_regs.spcps);
3147532SSean.Ye@Sun.COM nb_used_spare_rank(sp->branch, sp->rank);
3157532SSean.Ye@Sun.COM nb_config_gen++;
3167532SSean.Ye@Sun.COM }
3177532SSean.Ye@Sun.COM } else if ((ferr_nf_fbd & ERR_NF_FBD_M22) != 0) {
3187532SSean.Ye@Sun.COM intr = "nb.spd"; /* SPD protocol */
3197532SSean.Ye@Sun.COM }
3207532SSean.Ye@Sun.COM }
3217532SSean.Ye@Sun.COM if (sp->ras != -1) {
32210650SVuong.Nguyen@Sun.COM /*
32310650SVuong.Nguyen@Sun.COM * If driver was built with closed tree present then we will
32410650SVuong.Nguyen@Sun.COM * have Intel proprietary code for finding physaddr
32510650SVuong.Nguyen@Sun.COM */
32610650SVuong.Nguyen@Sun.COM if (&dimm_getphys) {
32710650SVuong.Nguyen@Sun.COM sp->pa = dimm_getphys((uint16_t)sp->branch,
32810650SVuong.Nguyen@Sun.COM (uint16_t)sp->rank, (uint64_t)sp->bank,
32910650SVuong.Nguyen@Sun.COM (uint64_t)sp->ras, (uint64_t)sp->cas);
33010650SVuong.Nguyen@Sun.COM if (sp->pa >= MAXPHYS_ADDR)
33110650SVuong.Nguyen@Sun.COM sp->pa = -1ULL;
33210650SVuong.Nguyen@Sun.COM } else {
33310650SVuong.Nguyen@Sun.COM sp->pa = -1ULL;
33410650SVuong.Nguyen@Sun.COM }
33510650SVuong.Nguyen@Sun.COM if (&dimm_getoffset) {
33610650SVuong.Nguyen@Sun.COM sp->offset = dimm_getoffset(sp->branch, sp->rank,
33710650SVuong.Nguyen@Sun.COM sp->bank, sp->ras, sp->cas);
33810650SVuong.Nguyen@Sun.COM } else {
33910650SVuong.Nguyen@Sun.COM sp->offset = TCODE_OFFSET(sp->rank, sp->bank, sp->ras,
34010650SVuong.Nguyen@Sun.COM sp->cas);
34110650SVuong.Nguyen@Sun.COM }
3427532SSean.Ye@Sun.COM }
3437532SSean.Ye@Sun.COM return (intr);
3447532SSean.Ye@Sun.COM }
3457532SSean.Ye@Sun.COM
34610049SVuong.Nguyen@Sun.COM static struct mch_error_code nf_mem_error_code[] = {
34710049SVuong.Nguyen@Sun.COM { 21, EMASK_MEM_M21, ERR_NF_MEM_M21 },
34810049SVuong.Nguyen@Sun.COM { 20, EMASK_MEM_M20, ERR_NF_MEM_M20 },
34910049SVuong.Nguyen@Sun.COM { 18, EMASK_MEM_M18, ERR_NF_MEM_M18 },
35010049SVuong.Nguyen@Sun.COM { 16, EMASK_MEM_M16, ERR_NF_MEM_M16 },
35110049SVuong.Nguyen@Sun.COM { 15, EMASK_MEM_M15, ERR_NF_MEM_M15 },
35210049SVuong.Nguyen@Sun.COM { 14, EMASK_MEM_M14, ERR_NF_MEM_M14 },
35310049SVuong.Nguyen@Sun.COM { 12, EMASK_MEM_M12, ERR_NF_MEM_M12 },
35410049SVuong.Nguyen@Sun.COM { 11, EMASK_MEM_M11, ERR_NF_MEM_M11 },
35510049SVuong.Nguyen@Sun.COM { 10, EMASK_MEM_M10, ERR_NF_MEM_M10 },
35610049SVuong.Nguyen@Sun.COM { 6, EMASK_MEM_M6, ERR_NF_MEM_M6 },
35710049SVuong.Nguyen@Sun.COM { 5, EMASK_MEM_M5, ERR_NF_MEM_M5 },
35810049SVuong.Nguyen@Sun.COM { 4, EMASK_MEM_M4, ERR_NF_MEM_M4 },
35910049SVuong.Nguyen@Sun.COM { 1, EMASK_MEM_M1, ERR_NF_MEM_M1 }
36010049SVuong.Nguyen@Sun.COM };
36110049SVuong.Nguyen@Sun.COM
36210049SVuong.Nguyen@Sun.COM static int
intel_nf_mem_err(uint32_t nf_mem)36310049SVuong.Nguyen@Sun.COM intel_nf_mem_err(uint32_t nf_mem)
36410049SVuong.Nguyen@Sun.COM {
36510049SVuong.Nguyen@Sun.COM int rt = -1;
36610049SVuong.Nguyen@Sun.COM int nerr = 0;
36710049SVuong.Nguyen@Sun.COM uint32_t emask_mem = 0;
36810049SVuong.Nguyen@Sun.COM int i;
36910049SVuong.Nguyen@Sun.COM int sz;
37010049SVuong.Nguyen@Sun.COM
37110049SVuong.Nguyen@Sun.COM sz = sizeof (nf_mem_error_code) / sizeof (struct mch_error_code);
37210049SVuong.Nguyen@Sun.COM
37310049SVuong.Nguyen@Sun.COM for (i = 0; i < sz; i++) {
37410049SVuong.Nguyen@Sun.COM if (nf_mem & nf_mem_error_code[i].error_bit) {
37510049SVuong.Nguyen@Sun.COM rt = nf_mem_error_code[i].intel_error_list;
37610049SVuong.Nguyen@Sun.COM emask_mem |= nf_mem_error_code[i].emask;
37710049SVuong.Nguyen@Sun.COM nerr++;
37810049SVuong.Nguyen@Sun.COM }
37910049SVuong.Nguyen@Sun.COM }
38010049SVuong.Nguyen@Sun.COM if (emask_mem)
38110049SVuong.Nguyen@Sun.COM nb_mem_mask_mc(emask_mem);
38210049SVuong.Nguyen@Sun.COM if (nerr > 1)
38310049SVuong.Nguyen@Sun.COM rt = -1;
38410049SVuong.Nguyen@Sun.COM return (rt);
38510049SVuong.Nguyen@Sun.COM }
38610049SVuong.Nguyen@Sun.COM
38710049SVuong.Nguyen@Sun.COM static char *
nf_mem_error(const nb_regs_t * rp,void * data)38810049SVuong.Nguyen@Sun.COM nf_mem_error(const nb_regs_t *rp, void *data)
38910049SVuong.Nguyen@Sun.COM {
39010049SVuong.Nguyen@Sun.COM uint32_t ferr_nf_mem, recmema, recmemb;
39110049SVuong.Nguyen@Sun.COM uint32_t nrecmema, nrecmemb, validlog;
39210049SVuong.Nguyen@Sun.COM int channel;
39310049SVuong.Nguyen@Sun.COM char *intr = "nb.unknown";
39410049SVuong.Nguyen@Sun.COM nb_mem_scatchpad_t *sp = &((nb_scatchpad_t *)data)->ms;
39510049SVuong.Nguyen@Sun.COM
39610049SVuong.Nguyen@Sun.COM sp->rank = -1;
39710049SVuong.Nguyen@Sun.COM sp->dimm = -1;
39810049SVuong.Nguyen@Sun.COM sp->bank = -1;
39910049SVuong.Nguyen@Sun.COM sp->cas = -1;
40010049SVuong.Nguyen@Sun.COM sp->ras = -1LL;
40110049SVuong.Nguyen@Sun.COM sp->pa = -1LL;
40210049SVuong.Nguyen@Sun.COM sp->offset = -1;
40310049SVuong.Nguyen@Sun.COM ferr_nf_mem = rp->nb.nf_mem_regs.ferr_nf_mem;
40410049SVuong.Nguyen@Sun.COM if ((ferr_nf_mem & ERR_NF_MEM_MASK) == 0) {
40510049SVuong.Nguyen@Sun.COM /* no first error found */
40610049SVuong.Nguyen@Sun.COM sp->branch = -1;
40710049SVuong.Nguyen@Sun.COM sp->channel = -1;
40810049SVuong.Nguyen@Sun.COM sp->intel_error_list =
40910049SVuong.Nguyen@Sun.COM intel_nf_mem_err(rp->nb.nf_mem_regs.nerr_nf_mem);
41010049SVuong.Nguyen@Sun.COM return (intr);
41110049SVuong.Nguyen@Sun.COM }
41210049SVuong.Nguyen@Sun.COM sp->intel_error_list = intel_nf_mem_err(ferr_nf_mem);
41310049SVuong.Nguyen@Sun.COM
41410049SVuong.Nguyen@Sun.COM channel = (ferr_nf_mem >> ERR_MEM_CH_SHIFT) & 0x1;
41510049SVuong.Nguyen@Sun.COM sp->branch = channel;
41610049SVuong.Nguyen@Sun.COM sp->channel = -1;
41710049SVuong.Nguyen@Sun.COM if (ferr_nf_mem & ERR_NF_MEM_MASK) {
41810049SVuong.Nguyen@Sun.COM if (ferr_nf_mem & ERR_NF_MEM_ECC_UE) {
41910049SVuong.Nguyen@Sun.COM /*
42010049SVuong.Nguyen@Sun.COM * uncorrectable ECC M1,M4-M6,M10-M12
42110049SVuong.Nguyen@Sun.COM * There is only channel per branch
42210049SVuong.Nguyen@Sun.COM * Invalidate the channel number so the mem ereport
42310049SVuong.Nguyen@Sun.COM * has the same detector with existing 5000 ereports.
42410049SVuong.Nguyen@Sun.COM * so we can leverage the existing Everhsolt rule.
42510049SVuong.Nguyen@Sun.COM */
42610049SVuong.Nguyen@Sun.COM validlog = rp->nb.nf_mem_regs.validlog;
42710049SVuong.Nguyen@Sun.COM if (ferr_nf_mem & ERR_NF_MEM_M1) {
42810049SVuong.Nguyen@Sun.COM nrecmema = rp->nb.nf_mem_regs.nrecmema;
42910049SVuong.Nguyen@Sun.COM nrecmemb = rp->nb.nf_mem_regs.nrecmemb;
43010049SVuong.Nguyen@Sun.COM /* check if the nrecmem log is valid */
43110049SVuong.Nguyen@Sun.COM if (validlog & 0x1 || nb_check_validlog == 0) {
43210049SVuong.Nguyen@Sun.COM sp->rank = (nrecmema >> 8) & RANK_MASK;
43310049SVuong.Nguyen@Sun.COM sp->bank = (nrecmema >> 12) & BANK_MASK;
43410049SVuong.Nguyen@Sun.COM sp->cas = (nrecmemb >> 16) & CAS_MASK;
43510049SVuong.Nguyen@Sun.COM sp->ras = nrecmemb & RAS_MASK;
43610049SVuong.Nguyen@Sun.COM }
43710049SVuong.Nguyen@Sun.COM } else {
43810049SVuong.Nguyen@Sun.COM recmema = rp->nb.nf_mem_regs.recmema;
43910049SVuong.Nguyen@Sun.COM recmemb = rp->nb.nf_mem_regs.recmemb;
44010049SVuong.Nguyen@Sun.COM /* check if the recmem log is valid */
44110049SVuong.Nguyen@Sun.COM if (validlog & 0x2 || nb_check_validlog == 0) {
44210049SVuong.Nguyen@Sun.COM sp->rank = (recmema >> 8) & RANK_MASK;
44310049SVuong.Nguyen@Sun.COM sp->bank = (recmema >> 12) & BANK_MASK;
44410049SVuong.Nguyen@Sun.COM sp->cas = (recmemb >> 16) & CAS_MASK;
44510049SVuong.Nguyen@Sun.COM sp->ras = recmemb & RAS_MASK;
44610049SVuong.Nguyen@Sun.COM }
44710049SVuong.Nguyen@Sun.COM }
44810049SVuong.Nguyen@Sun.COM intr = "nb.ddr2_mem_ue";
44910049SVuong.Nguyen@Sun.COM } else if ((ferr_nf_mem & ERR_NF_MEM_ECC_CE) != 0) {
45010049SVuong.Nguyen@Sun.COM /* correctable ECC M14-M16 */
45110049SVuong.Nguyen@Sun.COM recmema = rp->nb.nf_mem_regs.recmema;
45210049SVuong.Nguyen@Sun.COM recmemb = rp->nb.nf_mem_regs.recmemb;
45310049SVuong.Nguyen@Sun.COM validlog = rp->nb.nf_mem_regs.validlog;
45410049SVuong.Nguyen@Sun.COM /* check if the recmem log is valid */
45510049SVuong.Nguyen@Sun.COM if (validlog & 0x2 || nb_check_validlog == 0) {
45610049SVuong.Nguyen@Sun.COM sp->channel = channel;
45710049SVuong.Nguyen@Sun.COM sp->rank = (recmema >> 8) & RANK_MASK;
45810049SVuong.Nguyen@Sun.COM sp->dimm = nb_rank2dimm(sp->channel, sp->rank);
45910049SVuong.Nguyen@Sun.COM sp->bank = (recmema >> 12) & BANK_MASK;
46010049SVuong.Nguyen@Sun.COM sp->cas = (recmemb >> 16) & CAS_MASK;
46110049SVuong.Nguyen@Sun.COM sp->ras = recmemb & RAS_MASK;
46210049SVuong.Nguyen@Sun.COM }
46310049SVuong.Nguyen@Sun.COM intr = "nb.ddr2_mem_ce";
46410049SVuong.Nguyen@Sun.COM } else if ((ferr_nf_mem & ERR_NF_MEM_SPARE) != 0) {
46510049SVuong.Nguyen@Sun.COM /* spare dimm M20, M21 */
46610049SVuong.Nguyen@Sun.COM intr = "nb.ddr2_mem_ds";
46710049SVuong.Nguyen@Sun.COM
46810049SVuong.Nguyen@Sun.COM /*
46910049SVuong.Nguyen@Sun.COM * The channel can be valid here.
47010049SVuong.Nguyen@Sun.COM * However, there is only one channel per branch and
47110049SVuong.Nguyen@Sun.COM * to leverage the eversolt rules of other chipsets,
47210049SVuong.Nguyen@Sun.COM * the channel is ignored and let the rule find it out
47310049SVuong.Nguyen@Sun.COM * from the topology.
47410049SVuong.Nguyen@Sun.COM */
47510049SVuong.Nguyen@Sun.COM if (rp->nb.nf_mem_regs.spcps & SPCPS_SPARE_DEPLOYED) {
47610049SVuong.Nguyen@Sun.COM sp->rank =
47710049SVuong.Nguyen@Sun.COM SPCPS_FAILED_RANK(rp->nb.nf_mem_regs.spcps);
47810049SVuong.Nguyen@Sun.COM nb_used_spare_rank(sp->branch, sp->rank);
47910049SVuong.Nguyen@Sun.COM nb_config_gen++;
48010049SVuong.Nguyen@Sun.COM }
48110049SVuong.Nguyen@Sun.COM } else if ((ferr_nf_mem & ERR_NF_MEM_M18) != 0) {
48210049SVuong.Nguyen@Sun.COM sp->channel = channel;
48310049SVuong.Nguyen@Sun.COM intr = "nb.ddr2_spd"; /* SPD protocol */
48410049SVuong.Nguyen@Sun.COM
48510049SVuong.Nguyen@Sun.COM }
48610049SVuong.Nguyen@Sun.COM }
48710049SVuong.Nguyen@Sun.COM if (sp->ras != -1) {
48810650SVuong.Nguyen@Sun.COM /*
48910650SVuong.Nguyen@Sun.COM * If driver was built with closed tree present then we will
49010650SVuong.Nguyen@Sun.COM * have Intel proprietary code for finding physaddr
49110650SVuong.Nguyen@Sun.COM */
49210650SVuong.Nguyen@Sun.COM if (&dimm_getphys) {
49310650SVuong.Nguyen@Sun.COM sp->pa = dimm_getphys((uint16_t)sp->branch,
49410650SVuong.Nguyen@Sun.COM (uint16_t)sp->rank, (uint64_t)sp->bank,
49510650SVuong.Nguyen@Sun.COM (uint64_t)sp->ras, (uint64_t)sp->cas);
49610650SVuong.Nguyen@Sun.COM if (sp->pa >= MAXPHYS_ADDR)
49710650SVuong.Nguyen@Sun.COM sp->pa = -1ULL;
49810650SVuong.Nguyen@Sun.COM } else {
49910650SVuong.Nguyen@Sun.COM sp->pa = -1ULL;
50010650SVuong.Nguyen@Sun.COM }
50110650SVuong.Nguyen@Sun.COM if (&dimm_getoffset) {
50210650SVuong.Nguyen@Sun.COM sp->offset = dimm_getoffset(sp->branch, sp->rank,
50310650SVuong.Nguyen@Sun.COM sp->bank, sp->ras, sp->cas);
50410650SVuong.Nguyen@Sun.COM } else {
50510650SVuong.Nguyen@Sun.COM sp->offset = TCODE_OFFSET(sp->rank, sp->bank, sp->ras,
50610650SVuong.Nguyen@Sun.COM sp->cas);
50710650SVuong.Nguyen@Sun.COM }
50810049SVuong.Nguyen@Sun.COM }
50910049SVuong.Nguyen@Sun.COM return (intr);
51010049SVuong.Nguyen@Sun.COM }
51110049SVuong.Nguyen@Sun.COM
5127532SSean.Ye@Sun.COM static struct mch_error_code fat_int_error_code[] = {
5137532SSean.Ye@Sun.COM { 14, EMASK_INT_B14, ERR_FAT_INT_B14 },
5147532SSean.Ye@Sun.COM { 12, EMASK_INT_B12, ERR_FAT_INT_B12 },
5157532SSean.Ye@Sun.COM { 25, EMASK_INT_B25, ERR_FAT_INT_B25 },
5167532SSean.Ye@Sun.COM { 23, EMASK_INT_B23, ERR_FAT_INT_B23 },
5177532SSean.Ye@Sun.COM { 21, EMASK_INT_B21, ERR_FAT_INT_B21 },
5187532SSean.Ye@Sun.COM { 7, EMASK_INT_B7, ERR_FAT_INT_B7 },
5197532SSean.Ye@Sun.COM { 4, EMASK_INT_B4, ERR_FAT_INT_B4 },
5207532SSean.Ye@Sun.COM { 3, EMASK_INT_B3, ERR_FAT_INT_B3 },
5217532SSean.Ye@Sun.COM { 2, EMASK_INT_B2, ERR_FAT_INT_B2 },
5227532SSean.Ye@Sun.COM { 1, EMASK_INT_B1, ERR_FAT_INT_B1 }
5237532SSean.Ye@Sun.COM };
5247532SSean.Ye@Sun.COM
5257532SSean.Ye@Sun.COM static struct mch_error_code nf_int_error_code[] = {
5267532SSean.Ye@Sun.COM { 27, 0, ERR_NF_INT_B27 },
5277532SSean.Ye@Sun.COM { 24, 0, ERR_NF_INT_B24 },
5287532SSean.Ye@Sun.COM { 22, EMASK_INT_B22, ERR_NF_INT_B22 },
5297532SSean.Ye@Sun.COM { 20, EMASK_INT_B20, ERR_NF_INT_B20 },
5307532SSean.Ye@Sun.COM { 19, EMASK_INT_B19, ERR_NF_INT_B19 },
5317532SSean.Ye@Sun.COM { 18, 0, ERR_NF_INT_B18 },
5327532SSean.Ye@Sun.COM { 17, 0, ERR_NF_INT_B17 },
5337532SSean.Ye@Sun.COM { 16, 0, ERR_NF_INT_B16 },
5347532SSean.Ye@Sun.COM { 11, EMASK_INT_B11, ERR_NF_INT_B11 },
5357532SSean.Ye@Sun.COM { 10, EMASK_INT_B10, ERR_NF_INT_B10 },
5367532SSean.Ye@Sun.COM { 9, EMASK_INT_B9, ERR_NF_INT_B9 },
5377532SSean.Ye@Sun.COM { 8, EMASK_INT_B8, ERR_NF_INT_B8 },
5387532SSean.Ye@Sun.COM { 6, EMASK_INT_B6, ERR_NF_INT_B6 },
5397532SSean.Ye@Sun.COM { 5, EMASK_INT_B5, ERR_NF_INT_B5 }
5407532SSean.Ye@Sun.COM };
5417532SSean.Ye@Sun.COM
5427532SSean.Ye@Sun.COM static int
intel_int_err(uint16_t err_fat_int,uint16_t err_nf_int)5437532SSean.Ye@Sun.COM intel_int_err(uint16_t err_fat_int, uint16_t err_nf_int)
5447532SSean.Ye@Sun.COM {
5457532SSean.Ye@Sun.COM int rt = -1;
5467532SSean.Ye@Sun.COM int nerr = 0;
5477532SSean.Ye@Sun.COM uint32_t emask_int = 0;
5487532SSean.Ye@Sun.COM int i;
5497532SSean.Ye@Sun.COM int sz;
5507532SSean.Ye@Sun.COM
5517532SSean.Ye@Sun.COM sz = sizeof (fat_int_error_code) / sizeof (struct mch_error_code);
5527532SSean.Ye@Sun.COM
5537532SSean.Ye@Sun.COM for (i = 0; i < sz; i++) {
5547532SSean.Ye@Sun.COM if (err_fat_int & fat_int_error_code[i].error_bit) {
5557532SSean.Ye@Sun.COM rt = fat_int_error_code[i].intel_error_list;
5567532SSean.Ye@Sun.COM emask_int |= fat_int_error_code[i].emask;
5577532SSean.Ye@Sun.COM nerr++;
5587532SSean.Ye@Sun.COM }
5597532SSean.Ye@Sun.COM }
5607532SSean.Ye@Sun.COM
5617532SSean.Ye@Sun.COM if (nb_chipset == INTEL_NB_5400 &&
5627532SSean.Ye@Sun.COM (err_nf_int & NERR_NF_5400_INT_B26) != 0) {
5637532SSean.Ye@Sun.COM err_nf_int &= ~NERR_NF_5400_INT_B26;
5647532SSean.Ye@Sun.COM rt = 26;
5657532SSean.Ye@Sun.COM nerr++;
5667532SSean.Ye@Sun.COM }
5677532SSean.Ye@Sun.COM
5689783SAdrian.Frost@Sun.COM if (rt)
5699783SAdrian.Frost@Sun.COM err_nf_int &= ~ERR_NF_INT_B18;
5709783SAdrian.Frost@Sun.COM
5717532SSean.Ye@Sun.COM sz = sizeof (nf_int_error_code) / sizeof (struct mch_error_code);
5727532SSean.Ye@Sun.COM
5737532SSean.Ye@Sun.COM for (i = 0; i < sz; i++) {
5747532SSean.Ye@Sun.COM if (err_nf_int & nf_int_error_code[i].error_bit) {
5757532SSean.Ye@Sun.COM rt = nf_int_error_code[i].intel_error_list;
5767532SSean.Ye@Sun.COM emask_int |= nf_int_error_code[i].emask;
5777532SSean.Ye@Sun.COM nerr++;
5787532SSean.Ye@Sun.COM }
5797532SSean.Ye@Sun.COM }
5807532SSean.Ye@Sun.COM
5817532SSean.Ye@Sun.COM if (emask_int)
5827532SSean.Ye@Sun.COM nb_int_mask_mc(emask_int);
5837532SSean.Ye@Sun.COM if (nerr > 1)
5847532SSean.Ye@Sun.COM rt = -1;
5857532SSean.Ye@Sun.COM return (rt);
5867532SSean.Ye@Sun.COM }
5877532SSean.Ye@Sun.COM
5889783SAdrian.Frost@Sun.COM static int
log_int_err(nb_regs_t * rp,int willpanic,int * interpose)5899839SAdrian.Frost@Sun.COM log_int_err(nb_regs_t *rp, int willpanic, int *interpose)
5907532SSean.Ye@Sun.COM {
5917532SSean.Ye@Sun.COM int t = 0;
5929783SAdrian.Frost@Sun.COM int rt = 0;
5937532SSean.Ye@Sun.COM
5947532SSean.Ye@Sun.COM rp->flag = NB_REG_LOG_INT;
5957532SSean.Ye@Sun.COM rp->nb.int_regs.ferr_fat_int = FERR_FAT_INT_RD(interpose);
5967532SSean.Ye@Sun.COM rp->nb.int_regs.ferr_nf_int = FERR_NF_INT_RD(&t);
5977532SSean.Ye@Sun.COM *interpose |= t;
5987532SSean.Ye@Sun.COM rp->nb.int_regs.nerr_fat_int = NERR_FAT_INT_RD(&t);
5997532SSean.Ye@Sun.COM *interpose |= t;
6007532SSean.Ye@Sun.COM rp->nb.int_regs.nerr_nf_int = NERR_NF_INT_RD(&t);
6017532SSean.Ye@Sun.COM *interpose |= t;
6027532SSean.Ye@Sun.COM rp->nb.int_regs.nrecint = NRECINT_RD();
6037532SSean.Ye@Sun.COM rp->nb.int_regs.recint = RECINT_RD();
6047532SSean.Ye@Sun.COM rp->nb.int_regs.nrecsf = NRECSF_RD();
6057532SSean.Ye@Sun.COM rp->nb.int_regs.recsf = RECSF_RD();
6067532SSean.Ye@Sun.COM
6079839SAdrian.Frost@Sun.COM if (!willpanic) {
6089839SAdrian.Frost@Sun.COM if (rp->nb.int_regs.ferr_fat_int || *interpose)
6099839SAdrian.Frost@Sun.COM FERR_FAT_INT_WR(rp->nb.int_regs.ferr_fat_int);
6109839SAdrian.Frost@Sun.COM if (rp->nb.int_regs.ferr_nf_int || *interpose)
6119839SAdrian.Frost@Sun.COM FERR_NF_INT_WR(rp->nb.int_regs.ferr_nf_int);
6129839SAdrian.Frost@Sun.COM if (rp->nb.int_regs.nerr_fat_int)
6139839SAdrian.Frost@Sun.COM NERR_FAT_INT_WR(rp->nb.int_regs.nerr_fat_int);
6149839SAdrian.Frost@Sun.COM if (rp->nb.int_regs.nerr_nf_int)
6159839SAdrian.Frost@Sun.COM NERR_NF_INT_WR(rp->nb.int_regs.nerr_nf_int);
6169839SAdrian.Frost@Sun.COM /*
6179839SAdrian.Frost@Sun.COM * if interpose write read-only registers to clear from pcii
6189839SAdrian.Frost@Sun.COM * cache
6199839SAdrian.Frost@Sun.COM */
6209839SAdrian.Frost@Sun.COM if (*interpose) {
6219839SAdrian.Frost@Sun.COM NRECINT_WR();
6229839SAdrian.Frost@Sun.COM RECINT_WR();
6239839SAdrian.Frost@Sun.COM NRECSF_WR();
6249839SAdrian.Frost@Sun.COM RECSF_WR();
6259839SAdrian.Frost@Sun.COM }
6267532SSean.Ye@Sun.COM }
6279783SAdrian.Frost@Sun.COM if (rp->nb.int_regs.ferr_fat_int == 0 &&
6289783SAdrian.Frost@Sun.COM rp->nb.int_regs.nerr_fat_int == 0 &&
6299783SAdrian.Frost@Sun.COM (rp->nb.int_regs.ferr_nf_int == ERR_NF_INT_B18 ||
6309783SAdrian.Frost@Sun.COM (rp->nb.int_regs.ferr_nf_int == 0 &&
6319783SAdrian.Frost@Sun.COM rp->nb.int_regs.nerr_nf_int == ERR_NF_INT_B18))) {
6329783SAdrian.Frost@Sun.COM rt = 1;
6339783SAdrian.Frost@Sun.COM }
6349783SAdrian.Frost@Sun.COM return (rt);
6357532SSean.Ye@Sun.COM }
6367532SSean.Ye@Sun.COM
6377532SSean.Ye@Sun.COM static void
log_thermal_err(nb_regs_t * rp,int willpanic,int * interpose)6389839SAdrian.Frost@Sun.COM log_thermal_err(nb_regs_t *rp, int willpanic, int *interpose)
6397532SSean.Ye@Sun.COM {
6407532SSean.Ye@Sun.COM int t = 0;
6417532SSean.Ye@Sun.COM
6427532SSean.Ye@Sun.COM rp->flag = NB_REG_LOG_THR;
6437532SSean.Ye@Sun.COM rp->nb.thr_regs.ferr_fat_thr = FERR_FAT_THR_RD(interpose);
6447532SSean.Ye@Sun.COM rp->nb.thr_regs.nerr_fat_thr = NERR_FAT_THR_RD(&t);
6457532SSean.Ye@Sun.COM *interpose |= t;
6467532SSean.Ye@Sun.COM rp->nb.thr_regs.ferr_nf_thr = FERR_NF_THR_RD(&t);
6477532SSean.Ye@Sun.COM *interpose |= t;
6487532SSean.Ye@Sun.COM rp->nb.thr_regs.nerr_nf_thr = NERR_NF_THR_RD(&t);
6497532SSean.Ye@Sun.COM *interpose |= t;
6507532SSean.Ye@Sun.COM rp->nb.thr_regs.ctsts = CTSTS_RD();
6517532SSean.Ye@Sun.COM rp->nb.thr_regs.thrtsts = THRTSTS_RD();
6527532SSean.Ye@Sun.COM
6539839SAdrian.Frost@Sun.COM if (!willpanic) {
6549839SAdrian.Frost@Sun.COM if (rp->nb.thr_regs.ferr_fat_thr || *interpose)
6559839SAdrian.Frost@Sun.COM FERR_FAT_THR_WR(rp->nb.thr_regs.ferr_fat_thr);
6569839SAdrian.Frost@Sun.COM if (rp->nb.thr_regs.nerr_fat_thr || *interpose)
6579839SAdrian.Frost@Sun.COM NERR_FAT_THR_WR(rp->nb.thr_regs.nerr_fat_thr);
6589839SAdrian.Frost@Sun.COM if (rp->nb.thr_regs.ferr_nf_thr || *interpose)
6599839SAdrian.Frost@Sun.COM FERR_NF_THR_WR(rp->nb.thr_regs.ferr_nf_thr);
6609839SAdrian.Frost@Sun.COM if (rp->nb.thr_regs.nerr_nf_thr || *interpose)
6619839SAdrian.Frost@Sun.COM NERR_NF_THR_WR(rp->nb.thr_regs.nerr_nf_thr);
6627532SSean.Ye@Sun.COM
6639839SAdrian.Frost@Sun.COM if (*interpose) {
6649839SAdrian.Frost@Sun.COM CTSTS_WR(rp->nb.thr_regs.ctsts);
6659839SAdrian.Frost@Sun.COM THRTSTS_WR(rp->nb.thr_regs.thrtsts);
6669839SAdrian.Frost@Sun.COM }
6677532SSean.Ye@Sun.COM }
6687532SSean.Ye@Sun.COM }
6697532SSean.Ye@Sun.COM
6707532SSean.Ye@Sun.COM static void
log_dma_err(nb_regs_t * rp,int * interpose)6717532SSean.Ye@Sun.COM log_dma_err(nb_regs_t *rp, int *interpose)
6727532SSean.Ye@Sun.COM {
6737532SSean.Ye@Sun.COM rp->flag = NB_REG_LOG_DMA;
6747532SSean.Ye@Sun.COM
6757532SSean.Ye@Sun.COM rp->nb.dma_regs.pcists = PCISTS_RD(interpose);
6767532SSean.Ye@Sun.COM rp->nb.dma_regs.pexdevsts = PCIDEVSTS_RD();
6777532SSean.Ye@Sun.COM }
6787532SSean.Ye@Sun.COM
6797532SSean.Ye@Sun.COM static struct mch_error_code fat_fsb_error_code[] = {
6807532SSean.Ye@Sun.COM { 9, EMASK_FSB_F9, ERR_FAT_FSB_F9 },
6817532SSean.Ye@Sun.COM { 2, EMASK_FSB_F2, ERR_FAT_FSB_F2 },
6827532SSean.Ye@Sun.COM { 1, EMASK_FSB_F1, ERR_FAT_FSB_F1 }
6837532SSean.Ye@Sun.COM };
6847532SSean.Ye@Sun.COM
6857532SSean.Ye@Sun.COM static struct mch_error_code nf_fsb_error_code[] = {
6867532SSean.Ye@Sun.COM { 8, EMASK_FSB_F8, ERR_NF_FSB_F8 },
6877532SSean.Ye@Sun.COM { 7, EMASK_FSB_F7, ERR_NF_FSB_F7 },
6887532SSean.Ye@Sun.COM { 6, EMASK_FSB_F6, ERR_NF_FSB_F6 }
6897532SSean.Ye@Sun.COM };
6907532SSean.Ye@Sun.COM
6917532SSean.Ye@Sun.COM static int
intel_fsb_err(int fsb,uint8_t err_fat_fsb,uint8_t err_nf_fsb)6927532SSean.Ye@Sun.COM intel_fsb_err(int fsb, uint8_t err_fat_fsb, uint8_t err_nf_fsb)
6937532SSean.Ye@Sun.COM {
6947532SSean.Ye@Sun.COM int rt = -1;
6957532SSean.Ye@Sun.COM int nerr = 0;
6967532SSean.Ye@Sun.COM uint16_t emask_fsb = 0;
6977532SSean.Ye@Sun.COM int i;
6987532SSean.Ye@Sun.COM int sz;
6997532SSean.Ye@Sun.COM
7007532SSean.Ye@Sun.COM sz = sizeof (fat_fsb_error_code) / sizeof (struct mch_error_code);
7017532SSean.Ye@Sun.COM
7027532SSean.Ye@Sun.COM for (i = 0; i < sz; i++) {
7037532SSean.Ye@Sun.COM if (err_fat_fsb & fat_fsb_error_code[i].error_bit) {
7047532SSean.Ye@Sun.COM rt = fat_fsb_error_code[i].intel_error_list;
7057532SSean.Ye@Sun.COM emask_fsb |= fat_fsb_error_code[i].emask;
7067532SSean.Ye@Sun.COM nerr++;
7077532SSean.Ye@Sun.COM }
7087532SSean.Ye@Sun.COM }
7097532SSean.Ye@Sun.COM
7107532SSean.Ye@Sun.COM sz = sizeof (nf_fsb_error_code) / sizeof (struct mch_error_code);
7117532SSean.Ye@Sun.COM
7127532SSean.Ye@Sun.COM for (i = 0; i < sz; i++) {
7137532SSean.Ye@Sun.COM if (err_nf_fsb & nf_fsb_error_code[i].error_bit) {
7147532SSean.Ye@Sun.COM rt = nf_fsb_error_code[i].intel_error_list;
7157532SSean.Ye@Sun.COM emask_fsb |= nf_fsb_error_code[i].emask;
7167532SSean.Ye@Sun.COM nerr++;
7177532SSean.Ye@Sun.COM }
7187532SSean.Ye@Sun.COM }
7197532SSean.Ye@Sun.COM
7207532SSean.Ye@Sun.COM if (emask_fsb)
7217532SSean.Ye@Sun.COM nb_fsb_mask_mc(fsb, emask_fsb);
7227532SSean.Ye@Sun.COM if (nerr > 1)
7237532SSean.Ye@Sun.COM rt = -1;
7247532SSean.Ye@Sun.COM return (rt);
7257532SSean.Ye@Sun.COM }
7267532SSean.Ye@Sun.COM
7277532SSean.Ye@Sun.COM static void
log_fsb_err(uint64_t ferr,nb_regs_t * rp,int willpanic,int * interpose)7289839SAdrian.Frost@Sun.COM log_fsb_err(uint64_t ferr, nb_regs_t *rp, int willpanic, int *interpose)
7297532SSean.Ye@Sun.COM {
7307532SSean.Ye@Sun.COM uint8_t fsb;
7317532SSean.Ye@Sun.COM int t = 0;
7327532SSean.Ye@Sun.COM
7337532SSean.Ye@Sun.COM fsb = GE_FERR_FSB(ferr);
7347532SSean.Ye@Sun.COM rp->flag = NB_REG_LOG_FSB;
7357532SSean.Ye@Sun.COM
7367532SSean.Ye@Sun.COM rp->nb.fsb_regs.fsb = fsb;
7377532SSean.Ye@Sun.COM rp->nb.fsb_regs.ferr_fat_fsb = FERR_FAT_FSB_RD(fsb, interpose);
7387532SSean.Ye@Sun.COM rp->nb.fsb_regs.ferr_nf_fsb = FERR_NF_FSB_RD(fsb, &t);
7397532SSean.Ye@Sun.COM *interpose |= t;
7407532SSean.Ye@Sun.COM rp->nb.fsb_regs.nerr_fat_fsb = NERR_FAT_FSB_RD(fsb, &t);
7417532SSean.Ye@Sun.COM *interpose |= t;
7427532SSean.Ye@Sun.COM rp->nb.fsb_regs.nerr_nf_fsb = NERR_NF_FSB_RD(fsb, &t);
7437532SSean.Ye@Sun.COM *interpose |= t;
7447532SSean.Ye@Sun.COM rp->nb.fsb_regs.nrecfsb = NRECFSB_RD(fsb);
7457532SSean.Ye@Sun.COM rp->nb.fsb_regs.nrecfsb_addr = NRECADDR_RD(fsb);
7467532SSean.Ye@Sun.COM rp->nb.fsb_regs.recfsb = RECFSB_RD(fsb);
7479839SAdrian.Frost@Sun.COM if (!willpanic) {
7489850SVuong.Nguyen@Sun.COM /* Clear the fatal/non-fatal first/next FSB errors */
7499839SAdrian.Frost@Sun.COM if (rp->nb.fsb_regs.ferr_fat_fsb || *interpose)
7509839SAdrian.Frost@Sun.COM FERR_FAT_FSB_WR(fsb, rp->nb.fsb_regs.ferr_fat_fsb);
7519839SAdrian.Frost@Sun.COM if (rp->nb.fsb_regs.ferr_nf_fsb || *interpose)
7529839SAdrian.Frost@Sun.COM FERR_NF_FSB_WR(fsb, rp->nb.fsb_regs.ferr_nf_fsb);
7539850SVuong.Nguyen@Sun.COM if (rp->nb.fsb_regs.nerr_fat_fsb || *interpose)
7549850SVuong.Nguyen@Sun.COM NERR_FAT_FSB_WR(fsb, rp->nb.fsb_regs.nerr_fat_fsb);
7559850SVuong.Nguyen@Sun.COM if (rp->nb.fsb_regs.nerr_nf_fsb || *interpose)
7569850SVuong.Nguyen@Sun.COM NERR_NF_FSB_WR(fsb, rp->nb.fsb_regs.nerr_nf_fsb);
7579850SVuong.Nguyen@Sun.COM
7589839SAdrian.Frost@Sun.COM /*
7599839SAdrian.Frost@Sun.COM * if interpose write read-only registers to clear from pcii
7609839SAdrian.Frost@Sun.COM * cache
7619839SAdrian.Frost@Sun.COM */
7629839SAdrian.Frost@Sun.COM if (*interpose) {
7639839SAdrian.Frost@Sun.COM NRECFSB_WR(fsb);
7649839SAdrian.Frost@Sun.COM NRECADDR_WR(fsb);
7659839SAdrian.Frost@Sun.COM RECFSB_WR(fsb);
7669839SAdrian.Frost@Sun.COM }
7677532SSean.Ye@Sun.COM }
7687532SSean.Ye@Sun.COM }
7697532SSean.Ye@Sun.COM
7707532SSean.Ye@Sun.COM static struct mch_error_code fat_pex_error_code[] = {
7717532SSean.Ye@Sun.COM { 19, EMASK_UNCOR_PEX_IO19, PEX_FAT_IO19 },
7727532SSean.Ye@Sun.COM { 18, EMASK_UNCOR_PEX_IO18, PEX_FAT_IO18 },
7737532SSean.Ye@Sun.COM { 10, EMASK_UNCOR_PEX_IO10, PEX_FAT_IO10 },
7747532SSean.Ye@Sun.COM { 9, EMASK_UNCOR_PEX_IO9, PEX_FAT_IO9 },
7757532SSean.Ye@Sun.COM { 8, EMASK_UNCOR_PEX_IO8, PEX_FAT_IO8 },
7767532SSean.Ye@Sun.COM { 7, EMASK_UNCOR_PEX_IO7, PEX_FAT_IO7 },
7777532SSean.Ye@Sun.COM { 6, EMASK_UNCOR_PEX_IO6, PEX_FAT_IO6 },
7787532SSean.Ye@Sun.COM { 5, EMASK_UNCOR_PEX_IO5, PEX_FAT_IO5 },
7797532SSean.Ye@Sun.COM { 4, EMASK_UNCOR_PEX_IO4, PEX_FAT_IO4 },
7807532SSean.Ye@Sun.COM { 3, EMASK_UNCOR_PEX_IO3, PEX_FAT_IO3 },
7817532SSean.Ye@Sun.COM { 2, EMASK_UNCOR_PEX_IO2, PEX_FAT_IO2 },
7827532SSean.Ye@Sun.COM { 0, EMASK_UNCOR_PEX_IO0, PEX_FAT_IO0 }
7837532SSean.Ye@Sun.COM };
7847532SSean.Ye@Sun.COM
7857532SSean.Ye@Sun.COM static struct mch_error_code fat_unit_pex_5400_error_code[] = {
7867532SSean.Ye@Sun.COM { 32, EMASK_UNIT_PEX_IO32, PEX_5400_FAT_IO32 },
7877532SSean.Ye@Sun.COM { 31, EMASK_UNIT_PEX_IO31, PEX_5400_FAT_IO31 },
7887532SSean.Ye@Sun.COM { 30, EMASK_UNIT_PEX_IO30, PEX_5400_FAT_IO30 },
7897532SSean.Ye@Sun.COM { 29, EMASK_UNIT_PEX_IO29, PEX_5400_FAT_IO29 },
7907532SSean.Ye@Sun.COM { 27, EMASK_UNIT_PEX_IO27, PEX_5400_FAT_IO27 },
7917532SSean.Ye@Sun.COM { 26, EMASK_UNIT_PEX_IO26, PEX_5400_FAT_IO26 },
7927532SSean.Ye@Sun.COM { 25, EMASK_UNIT_PEX_IO25, PEX_5400_FAT_IO25 },
7937532SSean.Ye@Sun.COM { 24, EMASK_UNIT_PEX_IO24, PEX_5400_FAT_IO24 },
7947532SSean.Ye@Sun.COM { 23, EMASK_UNIT_PEX_IO23, PEX_5400_FAT_IO23 },
7957532SSean.Ye@Sun.COM { 22, EMASK_UNIT_PEX_IO22, PEX_5400_FAT_IO22 },
7967532SSean.Ye@Sun.COM };
7977532SSean.Ye@Sun.COM
7987532SSean.Ye@Sun.COM static struct mch_error_code fat_pex_5400_error_code[] = {
7997532SSean.Ye@Sun.COM { 19, EMASK_UNCOR_PEX_IO19, PEX_5400_FAT_IO19 },
8007532SSean.Ye@Sun.COM { 18, EMASK_UNCOR_PEX_IO18, PEX_5400_FAT_IO18 },
8017532SSean.Ye@Sun.COM { 10, EMASK_UNCOR_PEX_IO10, PEX_5400_FAT_IO10 },
8027532SSean.Ye@Sun.COM { 9, EMASK_UNCOR_PEX_IO9, PEX_5400_FAT_IO9 },
8037532SSean.Ye@Sun.COM { 8, EMASK_UNCOR_PEX_IO8, PEX_5400_FAT_IO8 },
8047532SSean.Ye@Sun.COM { 7, EMASK_UNCOR_PEX_IO7, PEX_5400_FAT_IO7 },
8057532SSean.Ye@Sun.COM { 6, EMASK_UNCOR_PEX_IO6, PEX_5400_FAT_IO6 },
8067532SSean.Ye@Sun.COM { 5, EMASK_UNCOR_PEX_IO5, PEX_5400_FAT_IO5 },
8077532SSean.Ye@Sun.COM { 4, EMASK_UNCOR_PEX_IO4, PEX_5400_FAT_IO4 },
8087532SSean.Ye@Sun.COM { 2, EMASK_UNCOR_PEX_IO2, PEX_5400_FAT_IO2 },
8097532SSean.Ye@Sun.COM { 0, EMASK_UNCOR_PEX_IO0, PEX_5400_FAT_IO0 }
8107532SSean.Ye@Sun.COM };
8117532SSean.Ye@Sun.COM
8127532SSean.Ye@Sun.COM static struct mch_error_code fat_rp_5400_error_code[] = {
8137532SSean.Ye@Sun.COM { 1, EMASK_RP_PEX_IO1, PEX_5400_FAT_IO1 }
8147532SSean.Ye@Sun.COM };
8157532SSean.Ye@Sun.COM
8167532SSean.Ye@Sun.COM static struct mch_error_code fat_rp_error_code[] = {
8177532SSean.Ye@Sun.COM { 1, EMASK_RP_PEX_IO1, PEX_FAT_IO1 }
8187532SSean.Ye@Sun.COM };
8197532SSean.Ye@Sun.COM
8207532SSean.Ye@Sun.COM static struct mch_error_code uncor_pex_error_code[] = {
8217532SSean.Ye@Sun.COM { 19, EMASK_UNCOR_PEX_IO19, PEX_NF_IO19 },
8227532SSean.Ye@Sun.COM { 9, EMASK_UNCOR_PEX_IO9, PEX_NF_IO9 },
8237532SSean.Ye@Sun.COM { 8, EMASK_UNCOR_PEX_IO8, PEX_NF_IO8 },
8247532SSean.Ye@Sun.COM { 7, EMASK_UNCOR_PEX_IO7, PEX_NF_IO7 },
8257532SSean.Ye@Sun.COM { 6, EMASK_UNCOR_PEX_IO6, PEX_NF_IO6 },
8267532SSean.Ye@Sun.COM { 5, EMASK_UNCOR_PEX_IO5, PEX_NF_IO5 },
8277532SSean.Ye@Sun.COM { 4, EMASK_UNCOR_PEX_IO4, PEX_NF_IO4 },
8287532SSean.Ye@Sun.COM { 3, EMASK_UNCOR_PEX_IO3, PEX_NF_IO3 },
8297532SSean.Ye@Sun.COM { 0, EMASK_UNCOR_PEX_IO0, PEX_NF_IO0 }
8307532SSean.Ye@Sun.COM };
8317532SSean.Ye@Sun.COM
8327532SSean.Ye@Sun.COM static struct mch_error_code uncor_pex_5400_error_code[] = {
8337532SSean.Ye@Sun.COM { 33, EMASK_UNIT_PEX_IO33, PEX_5400_NF_IO33 },
8347532SSean.Ye@Sun.COM { 32, EMASK_UNIT_PEX_IO32, PEX_5400_NF_IO32 },
8357532SSean.Ye@Sun.COM { 31, EMASK_UNIT_PEX_IO31, PEX_5400_NF_IO31 },
8367532SSean.Ye@Sun.COM { 30, EMASK_UNIT_PEX_IO30, PEX_5400_NF_IO30 },
8377532SSean.Ye@Sun.COM { 29, EMASK_UNIT_PEX_IO29, PEX_5400_NF_IO29 },
8387532SSean.Ye@Sun.COM { 28, EMASK_UNIT_PEX_IO28, PEX_5400_NF_IO28 },
8397532SSean.Ye@Sun.COM { 27, EMASK_UNIT_PEX_IO27, PEX_5400_NF_IO27 },
8407532SSean.Ye@Sun.COM { 26, EMASK_UNIT_PEX_IO26, PEX_5400_NF_IO26 },
8417532SSean.Ye@Sun.COM { 25, EMASK_UNIT_PEX_IO25, PEX_5400_NF_IO25 },
8427532SSean.Ye@Sun.COM { 24, EMASK_UNIT_PEX_IO24, PEX_5400_NF_IO24 },
8437532SSean.Ye@Sun.COM { 23, EMASK_UNIT_PEX_IO23, PEX_5400_NF_IO23 },
8447532SSean.Ye@Sun.COM };
8457532SSean.Ye@Sun.COM
8467532SSean.Ye@Sun.COM static struct mch_error_code cor_pex_error_code[] = {
8477532SSean.Ye@Sun.COM { 20, EMASK_COR_PEX_IO20, PEX_5400_NF_IO20 },
8487532SSean.Ye@Sun.COM { 16, EMASK_COR_PEX_IO16, PEX_NF_IO16 },
8497532SSean.Ye@Sun.COM { 15, EMASK_COR_PEX_IO15, PEX_NF_IO15 },
8507532SSean.Ye@Sun.COM { 14, EMASK_COR_PEX_IO14, PEX_NF_IO14 },
8517532SSean.Ye@Sun.COM { 13, EMASK_COR_PEX_IO13, PEX_NF_IO13 },
8527532SSean.Ye@Sun.COM { 12, EMASK_COR_PEX_IO12, PEX_NF_IO12 },
8537532SSean.Ye@Sun.COM { 10, 0, PEX_NF_IO10 },
8547532SSean.Ye@Sun.COM { 2, 0, PEX_NF_IO2 }
8557532SSean.Ye@Sun.COM };
8567532SSean.Ye@Sun.COM
8577532SSean.Ye@Sun.COM static struct mch_error_code rp_pex_5400_error_code[] = {
8587532SSean.Ye@Sun.COM { 17, EMASK_RP_PEX_IO17, PEX_5400_NF_IO17 },
8597532SSean.Ye@Sun.COM { 11, EMASK_RP_PEX_IO11, PEX_5400_NF_IO11 }
8607532SSean.Ye@Sun.COM };
8617532SSean.Ye@Sun.COM
8627532SSean.Ye@Sun.COM static struct mch_error_code cor_pex_5400_error_code1[] = {
8637532SSean.Ye@Sun.COM { 19, EMASK_UNCOR_PEX_IO19, PEX_5400_NF_IO19 },
8647532SSean.Ye@Sun.COM { 10, EMASK_UNCOR_PEX_IO10, PEX_5400_NF_IO10 },
8657532SSean.Ye@Sun.COM { 9, EMASK_UNCOR_PEX_IO9, PEX_5400_NF_IO9 },
8667532SSean.Ye@Sun.COM { 8, EMASK_UNCOR_PEX_IO8, PEX_5400_NF_IO8 },
8677532SSean.Ye@Sun.COM { 7, EMASK_UNCOR_PEX_IO7, PEX_5400_NF_IO7 },
8687532SSean.Ye@Sun.COM { 6, EMASK_UNCOR_PEX_IO6, PEX_5400_NF_IO6 },
8697532SSean.Ye@Sun.COM { 5, EMASK_UNCOR_PEX_IO5, PEX_5400_NF_IO5 },
8707532SSean.Ye@Sun.COM { 4, EMASK_UNCOR_PEX_IO4, PEX_5400_NF_IO4 },
8717532SSean.Ye@Sun.COM { 2, EMASK_UNCOR_PEX_IO2, PEX_5400_NF_IO2 },
8727532SSean.Ye@Sun.COM { 0, EMASK_UNCOR_PEX_IO0, PEX_5400_NF_IO0 }
8737532SSean.Ye@Sun.COM };
8747532SSean.Ye@Sun.COM
8757532SSean.Ye@Sun.COM static struct mch_error_code cor_pex_5400_error_code2[] = {
8767532SSean.Ye@Sun.COM { 20, EMASK_COR_PEX_IO20, PEX_5400_NF_IO20 },
8777532SSean.Ye@Sun.COM { 16, EMASK_COR_PEX_IO16, PEX_5400_NF_IO16 },
8787532SSean.Ye@Sun.COM { 15, EMASK_COR_PEX_IO15, PEX_5400_NF_IO15 },
8797532SSean.Ye@Sun.COM { 14, EMASK_COR_PEX_IO14, PEX_5400_NF_IO14 },
8807532SSean.Ye@Sun.COM { 13, EMASK_COR_PEX_IO13, PEX_5400_NF_IO13 },
8817532SSean.Ye@Sun.COM { 12, EMASK_COR_PEX_IO12, PEX_5400_NF_IO12 }
8827532SSean.Ye@Sun.COM };
8837532SSean.Ye@Sun.COM
8847532SSean.Ye@Sun.COM static struct mch_error_code cor_pex_5400_error_code3[] = {
8857532SSean.Ye@Sun.COM { 33, EMASK_UNIT_PEX_IO33, PEX_5400_NF_IO33 },
8867532SSean.Ye@Sun.COM { 32, EMASK_UNIT_PEX_IO32, PEX_5400_NF_IO32 },
8877532SSean.Ye@Sun.COM { 31, EMASK_UNIT_PEX_IO31, PEX_5400_NF_IO31 },
8887532SSean.Ye@Sun.COM { 30, EMASK_UNIT_PEX_IO30, PEX_5400_NF_IO30 },
8897532SSean.Ye@Sun.COM { 29, EMASK_UNIT_PEX_IO29, PEX_5400_NF_IO29 },
8907532SSean.Ye@Sun.COM { 28, EMASK_UNIT_PEX_IO28, PEX_5400_NF_IO28 },
8917532SSean.Ye@Sun.COM { 27, EMASK_UNIT_PEX_IO27, PEX_5400_NF_IO27 },
8927532SSean.Ye@Sun.COM { 26, EMASK_UNIT_PEX_IO26, PEX_5400_NF_IO26 },
8937532SSean.Ye@Sun.COM { 25, EMASK_UNIT_PEX_IO25, PEX_5400_NF_IO25 },
8947532SSean.Ye@Sun.COM { 24, EMASK_UNIT_PEX_IO24, PEX_5400_NF_IO24 },
8957532SSean.Ye@Sun.COM { 23, EMASK_UNIT_PEX_IO23, PEX_5400_NF_IO23 }
8967532SSean.Ye@Sun.COM };
8977532SSean.Ye@Sun.COM
8987532SSean.Ye@Sun.COM static struct mch_error_code rp_pex_error_code[] = {
8997532SSean.Ye@Sun.COM { 17, EMASK_RP_PEX_IO17, PEX_NF_IO17 },
9007532SSean.Ye@Sun.COM { 11, EMASK_RP_PEX_IO11, PEX_NF_IO11 },
9017532SSean.Ye@Sun.COM };
9027532SSean.Ye@Sun.COM
9037532SSean.Ye@Sun.COM static int
intel_pex_err(uint32_t pex_fat,uint32_t pex_nf_cor)9047532SSean.Ye@Sun.COM intel_pex_err(uint32_t pex_fat, uint32_t pex_nf_cor)
9057532SSean.Ye@Sun.COM {
9067532SSean.Ye@Sun.COM int rt = -1;
9077532SSean.Ye@Sun.COM int nerr = 0;
9087532SSean.Ye@Sun.COM int i;
9097532SSean.Ye@Sun.COM int sz;
9107532SSean.Ye@Sun.COM
9117532SSean.Ye@Sun.COM sz = sizeof (fat_pex_error_code) / sizeof (struct mch_error_code);
9127532SSean.Ye@Sun.COM
9137532SSean.Ye@Sun.COM for (i = 0; i < sz; i++) {
9147532SSean.Ye@Sun.COM if (pex_fat & fat_pex_error_code[i].error_bit) {
9157532SSean.Ye@Sun.COM rt = fat_pex_error_code[i].intel_error_list;
9167532SSean.Ye@Sun.COM nerr++;
9177532SSean.Ye@Sun.COM }
9187532SSean.Ye@Sun.COM }
9197532SSean.Ye@Sun.COM sz = sizeof (fat_rp_error_code) / sizeof (struct mch_error_code);
9207532SSean.Ye@Sun.COM
9217532SSean.Ye@Sun.COM for (i = 0; i < sz; i++) {
9227532SSean.Ye@Sun.COM if (pex_fat & fat_rp_error_code[i].error_bit) {
9237532SSean.Ye@Sun.COM rt = fat_rp_error_code[i].intel_error_list;
9247532SSean.Ye@Sun.COM nerr++;
9257532SSean.Ye@Sun.COM }
9267532SSean.Ye@Sun.COM }
9277532SSean.Ye@Sun.COM sz = sizeof (uncor_pex_error_code) / sizeof (struct mch_error_code);
9287532SSean.Ye@Sun.COM
9297532SSean.Ye@Sun.COM for (i = 0; i < sz; i++) {
9307532SSean.Ye@Sun.COM if (pex_nf_cor & uncor_pex_error_code[i].error_bit) {
9317532SSean.Ye@Sun.COM rt = uncor_pex_error_code[i].intel_error_list;
9327532SSean.Ye@Sun.COM nerr++;
9337532SSean.Ye@Sun.COM }
9347532SSean.Ye@Sun.COM }
9357532SSean.Ye@Sun.COM
9367532SSean.Ye@Sun.COM sz = sizeof (cor_pex_error_code) / sizeof (struct mch_error_code);
9377532SSean.Ye@Sun.COM
9387532SSean.Ye@Sun.COM for (i = 0; i < sz; i++) {
9397532SSean.Ye@Sun.COM if (pex_nf_cor & cor_pex_error_code[i].error_bit) {
9407532SSean.Ye@Sun.COM rt = cor_pex_error_code[i].intel_error_list;
9417532SSean.Ye@Sun.COM nerr++;
9427532SSean.Ye@Sun.COM }
9437532SSean.Ye@Sun.COM }
9447532SSean.Ye@Sun.COM sz = sizeof (rp_pex_error_code) / sizeof (struct mch_error_code);
9457532SSean.Ye@Sun.COM
9467532SSean.Ye@Sun.COM for (i = 0; i < sz; i++) {
9477532SSean.Ye@Sun.COM if (pex_nf_cor & rp_pex_error_code[i].error_bit) {
9487532SSean.Ye@Sun.COM rt = rp_pex_error_code[i].intel_error_list;
9497532SSean.Ye@Sun.COM nerr++;
9507532SSean.Ye@Sun.COM }
9517532SSean.Ye@Sun.COM }
9527532SSean.Ye@Sun.COM
9537532SSean.Ye@Sun.COM if (nerr > 1)
9547532SSean.Ye@Sun.COM rt = -1;
9557532SSean.Ye@Sun.COM return (rt);
9567532SSean.Ye@Sun.COM }
9577532SSean.Ye@Sun.COM
9587532SSean.Ye@Sun.COM static struct mch_error_code fat_thr_error_code[] = {
9597532SSean.Ye@Sun.COM { 2, EMASK_THR_F2, ERR_FAT_THR_F2 },
9607532SSean.Ye@Sun.COM { 1, EMASK_THR_F1, ERR_FAT_THR_F1 }
9617532SSean.Ye@Sun.COM };
9627532SSean.Ye@Sun.COM
9637532SSean.Ye@Sun.COM static struct mch_error_code nf_thr_error_code[] = {
9647532SSean.Ye@Sun.COM { 5, EMASK_THR_F5, ERR_NF_THR_F5 },
9657532SSean.Ye@Sun.COM { 4, EMASK_THR_F4, ERR_NF_THR_F4 },
9667532SSean.Ye@Sun.COM { 3, EMASK_THR_F3, ERR_NF_THR_F3 }
9677532SSean.Ye@Sun.COM };
9687532SSean.Ye@Sun.COM
9697532SSean.Ye@Sun.COM static int
intel_thr_err(uint8_t err_fat_thr,uint8_t err_nf_thr)9707532SSean.Ye@Sun.COM intel_thr_err(uint8_t err_fat_thr, uint8_t err_nf_thr)
9717532SSean.Ye@Sun.COM {
9727532SSean.Ye@Sun.COM int rt = -1;
9737532SSean.Ye@Sun.COM int nerr = 0;
9747532SSean.Ye@Sun.COM uint16_t emask_thr = 0;
9757532SSean.Ye@Sun.COM int i;
9767532SSean.Ye@Sun.COM int sz;
9777532SSean.Ye@Sun.COM
9787532SSean.Ye@Sun.COM sz = sizeof (fat_thr_error_code) / sizeof (struct mch_error_code);
9797532SSean.Ye@Sun.COM
9807532SSean.Ye@Sun.COM for (i = 0; i < sz; i++) {
9817532SSean.Ye@Sun.COM if (err_fat_thr & fat_thr_error_code[i].error_bit) {
9827532SSean.Ye@Sun.COM rt = fat_thr_error_code[i].intel_error_list;
9837532SSean.Ye@Sun.COM emask_thr |= fat_thr_error_code[i].emask;
9847532SSean.Ye@Sun.COM nerr++;
9857532SSean.Ye@Sun.COM }
9867532SSean.Ye@Sun.COM }
9877532SSean.Ye@Sun.COM
9887532SSean.Ye@Sun.COM sz = sizeof (nf_thr_error_code) / sizeof (struct mch_error_code);
9897532SSean.Ye@Sun.COM
9907532SSean.Ye@Sun.COM for (i = 0; i < sz; i++) {
9917532SSean.Ye@Sun.COM if (err_nf_thr & nf_thr_error_code[i].error_bit) {
9927532SSean.Ye@Sun.COM rt = nf_thr_error_code[i].intel_error_list;
9937532SSean.Ye@Sun.COM emask_thr |= nf_thr_error_code[i].emask;
9947532SSean.Ye@Sun.COM nerr++;
9957532SSean.Ye@Sun.COM }
9967532SSean.Ye@Sun.COM }
9977532SSean.Ye@Sun.COM
9987532SSean.Ye@Sun.COM if (emask_thr)
9997532SSean.Ye@Sun.COM nb_thr_mask_mc(emask_thr);
10007532SSean.Ye@Sun.COM if (nerr > 1)
10017532SSean.Ye@Sun.COM rt = -1;
10027532SSean.Ye@Sun.COM return (rt);
10037532SSean.Ye@Sun.COM }
10047532SSean.Ye@Sun.COM
10057532SSean.Ye@Sun.COM static int
intel_pex_5400_err(uint32_t pex_fat,uint32_t pex_nf_cor)10067532SSean.Ye@Sun.COM intel_pex_5400_err(uint32_t pex_fat, uint32_t pex_nf_cor)
10077532SSean.Ye@Sun.COM {
10087532SSean.Ye@Sun.COM int rt = -1;
10097532SSean.Ye@Sun.COM int nerr = 0;
10107532SSean.Ye@Sun.COM int i;
10117532SSean.Ye@Sun.COM int sz;
10127532SSean.Ye@Sun.COM
10137532SSean.Ye@Sun.COM sz = sizeof (fat_pex_5400_error_code) / sizeof (struct mch_error_code);
10147532SSean.Ye@Sun.COM
10157532SSean.Ye@Sun.COM for (i = 0; i < sz; i++) {
10167532SSean.Ye@Sun.COM if (pex_fat & fat_pex_5400_error_code[i].error_bit) {
10177532SSean.Ye@Sun.COM rt = fat_pex_5400_error_code[i].intel_error_list;
10187532SSean.Ye@Sun.COM nerr++;
10197532SSean.Ye@Sun.COM }
10207532SSean.Ye@Sun.COM }
10217532SSean.Ye@Sun.COM sz = sizeof (fat_rp_5400_error_code) / sizeof (struct mch_error_code);
10227532SSean.Ye@Sun.COM
10237532SSean.Ye@Sun.COM for (i = 0; i < sz; i++) {
10247532SSean.Ye@Sun.COM if (pex_fat & fat_rp_5400_error_code[i].error_bit) {
10257532SSean.Ye@Sun.COM rt = fat_rp_5400_error_code[i].intel_error_list;
10267532SSean.Ye@Sun.COM nerr++;
10277532SSean.Ye@Sun.COM }
10287532SSean.Ye@Sun.COM }
10297532SSean.Ye@Sun.COM sz = sizeof (fat_unit_pex_5400_error_code) /
10307532SSean.Ye@Sun.COM sizeof (struct mch_error_code);
10317532SSean.Ye@Sun.COM
10327532SSean.Ye@Sun.COM for (i = 0; i < sz; i++) {
10337532SSean.Ye@Sun.COM if (pex_fat &
10347532SSean.Ye@Sun.COM fat_unit_pex_5400_error_code[i].error_bit) {
10357532SSean.Ye@Sun.COM rt = fat_unit_pex_5400_error_code[i].intel_error_list;
10367532SSean.Ye@Sun.COM nerr++;
10377532SSean.Ye@Sun.COM }
10387532SSean.Ye@Sun.COM }
10397532SSean.Ye@Sun.COM sz = sizeof (uncor_pex_5400_error_code) /
10407532SSean.Ye@Sun.COM sizeof (struct mch_error_code);
10417532SSean.Ye@Sun.COM
10427532SSean.Ye@Sun.COM for (i = 0; i < sz; i++) {
10437532SSean.Ye@Sun.COM if (pex_fat & uncor_pex_5400_error_code[i].error_bit) {
10447532SSean.Ye@Sun.COM rt = uncor_pex_5400_error_code[i].intel_error_list;
10457532SSean.Ye@Sun.COM nerr++;
10467532SSean.Ye@Sun.COM }
10477532SSean.Ye@Sun.COM }
10487532SSean.Ye@Sun.COM
10497532SSean.Ye@Sun.COM sz = sizeof (rp_pex_5400_error_code) / sizeof (struct mch_error_code);
10507532SSean.Ye@Sun.COM
10517532SSean.Ye@Sun.COM for (i = 0; i < sz; i++) {
10527532SSean.Ye@Sun.COM if (pex_nf_cor & rp_pex_5400_error_code[i].error_bit) {
10537532SSean.Ye@Sun.COM rt = rp_pex_5400_error_code[i].intel_error_list;
10547532SSean.Ye@Sun.COM nerr++;
10557532SSean.Ye@Sun.COM }
10567532SSean.Ye@Sun.COM }
10577532SSean.Ye@Sun.COM
10587532SSean.Ye@Sun.COM sz = sizeof (cor_pex_5400_error_code1) / sizeof (struct mch_error_code);
10597532SSean.Ye@Sun.COM
10607532SSean.Ye@Sun.COM for (i = 0; i < sz; i++) {
10617532SSean.Ye@Sun.COM if (pex_nf_cor & cor_pex_5400_error_code1[i].error_bit) {
10627532SSean.Ye@Sun.COM rt = cor_pex_5400_error_code1[i].intel_error_list;
10637532SSean.Ye@Sun.COM nerr++;
10647532SSean.Ye@Sun.COM }
10657532SSean.Ye@Sun.COM }
10667532SSean.Ye@Sun.COM
10677532SSean.Ye@Sun.COM sz = sizeof (cor_pex_5400_error_code2) / sizeof (struct mch_error_code);
10687532SSean.Ye@Sun.COM
10697532SSean.Ye@Sun.COM for (i = 0; i < sz; i++) {
10707532SSean.Ye@Sun.COM if (pex_nf_cor & cor_pex_5400_error_code2[i].error_bit) {
10717532SSean.Ye@Sun.COM rt = cor_pex_5400_error_code2[i].intel_error_list;
10727532SSean.Ye@Sun.COM nerr++;
10737532SSean.Ye@Sun.COM }
10747532SSean.Ye@Sun.COM }
10757532SSean.Ye@Sun.COM
10767532SSean.Ye@Sun.COM sz = sizeof (cor_pex_5400_error_code3) / sizeof (struct mch_error_code);
10777532SSean.Ye@Sun.COM
10787532SSean.Ye@Sun.COM for (i = 0; i < sz; i++) {
10797532SSean.Ye@Sun.COM if (pex_nf_cor & cor_pex_5400_error_code3[i].error_bit) {
10807532SSean.Ye@Sun.COM rt = cor_pex_5400_error_code3[i].intel_error_list;
10817532SSean.Ye@Sun.COM nerr++;
10827532SSean.Ye@Sun.COM }
10837532SSean.Ye@Sun.COM }
10847532SSean.Ye@Sun.COM
10857532SSean.Ye@Sun.COM if (nerr > 1)
10867532SSean.Ye@Sun.COM rt = -1;
10877532SSean.Ye@Sun.COM return (rt);
10887532SSean.Ye@Sun.COM }
10897532SSean.Ye@Sun.COM
1090*12437SAdrian.Frost@Sun.COM static int
log_pex_err(uint64_t ferr,nb_regs_t * rp,int willpanic,int * interpose)10919839SAdrian.Frost@Sun.COM log_pex_err(uint64_t ferr, nb_regs_t *rp, int willpanic, int *interpose)
10927532SSean.Ye@Sun.COM {
10937532SSean.Ye@Sun.COM uint8_t pex = (uint8_t)-1;
10947532SSean.Ye@Sun.COM int t = 0;
10957532SSean.Ye@Sun.COM
10967532SSean.Ye@Sun.COM rp->flag = NB_REG_LOG_PEX;
10977532SSean.Ye@Sun.COM pex = GE_ERR_PEX(ferr);
10987532SSean.Ye@Sun.COM
10997532SSean.Ye@Sun.COM rp->nb.pex_regs.pex = pex;
11007532SSean.Ye@Sun.COM rp->nb.pex_regs.pex_fat_ferr = PEX_FAT_FERR_RD(pex, interpose);
11017532SSean.Ye@Sun.COM rp->nb.pex_regs.pex_fat_nerr = PEX_FAT_NERR_RD(pex, &t);
11027532SSean.Ye@Sun.COM *interpose |= t;
11037532SSean.Ye@Sun.COM rp->nb.pex_regs.pex_nf_corr_ferr = PEX_NF_FERR_RD(pex, &t);
11047532SSean.Ye@Sun.COM *interpose |= t;
11057532SSean.Ye@Sun.COM rp->nb.pex_regs.pex_nf_corr_nerr = PEX_NF_NERR_RD(pex, &t);
11067532SSean.Ye@Sun.COM *interpose |= t;
1107*12437SAdrian.Frost@Sun.COM if (rp->nb.pex_regs.pex_fat_ferr == 0 &&
1108*12437SAdrian.Frost@Sun.COM rp->nb.pex_regs.pex_fat_nerr == 0 &&
1109*12437SAdrian.Frost@Sun.COM rp->nb.pex_regs.pex_nf_corr_ferr == 0 &&
1110*12437SAdrian.Frost@Sun.COM rp->nb.pex_regs.pex_nf_corr_nerr == 0)
1111*12437SAdrian.Frost@Sun.COM return (0);
11127532SSean.Ye@Sun.COM rp->nb.pex_regs.uncerrsev = UNCERRSEV_RD(pex);
11137532SSean.Ye@Sun.COM rp->nb.pex_regs.rperrsts = RPERRSTS_RD(pex);
11147532SSean.Ye@Sun.COM rp->nb.pex_regs.rperrsid = RPERRSID_RD(pex);
11157532SSean.Ye@Sun.COM if (pex != (uint8_t)-1)
11167532SSean.Ye@Sun.COM rp->nb.pex_regs.uncerrsts = UNCERRSTS_RD(pex);
11177532SSean.Ye@Sun.COM else
11187532SSean.Ye@Sun.COM rp->nb.pex_regs.uncerrsts = 0;
11197532SSean.Ye@Sun.COM rp->nb.pex_regs.aerrcapctrl = AERRCAPCTRL_RD(pex);
11207532SSean.Ye@Sun.COM rp->nb.pex_regs.corerrsts = CORERRSTS_RD(pex);
11217532SSean.Ye@Sun.COM rp->nb.pex_regs.pexdevsts = PEXDEVSTS_RD(pex);
11227532SSean.Ye@Sun.COM
11239839SAdrian.Frost@Sun.COM if (!willpanic) {
11249839SAdrian.Frost@Sun.COM if (rp->nb.pex_regs.pex_fat_ferr || *interpose)
11259839SAdrian.Frost@Sun.COM PEX_FAT_FERR_WR(pex, rp->nb.pex_regs.pex_fat_ferr);
11269839SAdrian.Frost@Sun.COM if (rp->nb.pex_regs.pex_fat_nerr)
11279839SAdrian.Frost@Sun.COM PEX_FAT_NERR_WR(pex, rp->nb.pex_regs.pex_fat_nerr);
11289839SAdrian.Frost@Sun.COM if (rp->nb.pex_regs.pex_nf_corr_ferr || *interpose)
11299839SAdrian.Frost@Sun.COM PEX_NF_FERR_WR(pex, rp->nb.pex_regs.pex_nf_corr_ferr);
11309839SAdrian.Frost@Sun.COM if (rp->nb.pex_regs.pex_nf_corr_nerr)
11319839SAdrian.Frost@Sun.COM PEX_NF_NERR_WR(pex, rp->nb.pex_regs.pex_nf_corr_nerr);
11329839SAdrian.Frost@Sun.COM if (*interpose)
11339839SAdrian.Frost@Sun.COM UNCERRSTS_WR(pex, rp->nb.pex_regs.uncerrsts);
11349839SAdrian.Frost@Sun.COM if (*interpose)
11359839SAdrian.Frost@Sun.COM RPERRSTS_WR(pex, rp->nb.pex_regs.rperrsts);
11369839SAdrian.Frost@Sun.COM if (*interpose)
11379839SAdrian.Frost@Sun.COM PEXDEVSTS_WR(pex, 0);
11389839SAdrian.Frost@Sun.COM }
1139*12437SAdrian.Frost@Sun.COM return (1);
11407532SSean.Ye@Sun.COM }
11417532SSean.Ye@Sun.COM
11427532SSean.Ye@Sun.COM static void
log_fat_fbd_err(nb_regs_t * rp,int willpanic,int * interpose)11439839SAdrian.Frost@Sun.COM log_fat_fbd_err(nb_regs_t *rp, int willpanic, int *interpose)
11447532SSean.Ye@Sun.COM {
11457532SSean.Ye@Sun.COM int channel, branch;
11467532SSean.Ye@Sun.COM int t = 0;
11477532SSean.Ye@Sun.COM
11487532SSean.Ye@Sun.COM rp->flag = NB_REG_LOG_FAT_FBD;
11497532SSean.Ye@Sun.COM rp->nb.fat_fbd_regs.ferr_fat_fbd = FERR_FAT_FBD_RD(interpose);
11507532SSean.Ye@Sun.COM channel = (rp->nb.fat_fbd_regs.ferr_fat_fbd >> 28) & 3;
11517532SSean.Ye@Sun.COM branch = channel >> 1;
11527532SSean.Ye@Sun.COM rp->nb.fat_fbd_regs.nerr_fat_fbd = NERR_FAT_FBD_RD(&t);
11537532SSean.Ye@Sun.COM *interpose |= t;
11547532SSean.Ye@Sun.COM rp->nb.fat_fbd_regs.nrecmema = NRECMEMA_RD(branch);
11557532SSean.Ye@Sun.COM rp->nb.fat_fbd_regs.nrecmemb = NRECMEMB_RD(branch);
11567532SSean.Ye@Sun.COM rp->nb.fat_fbd_regs.nrecfglog = NRECFGLOG_RD(branch);
11577532SSean.Ye@Sun.COM rp->nb.fat_fbd_regs.nrecfbda = NRECFBDA_RD(branch);
11587532SSean.Ye@Sun.COM rp->nb.fat_fbd_regs.nrecfbdb = NRECFBDB_RD(branch);
11597532SSean.Ye@Sun.COM rp->nb.fat_fbd_regs.nrecfbdc = NRECFBDC_RD(branch);
11607532SSean.Ye@Sun.COM rp->nb.fat_fbd_regs.nrecfbdd = NRECFBDD_RD(branch);
11617532SSean.Ye@Sun.COM rp->nb.fat_fbd_regs.nrecfbde = NRECFBDE_RD(branch);
11627532SSean.Ye@Sun.COM rp->nb.fat_fbd_regs.nrecfbdf = NRECFBDF_RD(branch);
11637532SSean.Ye@Sun.COM rp->nb.fat_fbd_regs.spcps = SPCPS_RD(branch);
11647532SSean.Ye@Sun.COM rp->nb.fat_fbd_regs.spcpc = SPCPC_RD(branch);
11657532SSean.Ye@Sun.COM rp->nb.fat_fbd_regs.uerrcnt = UERRCNT_RD(branch);
11667532SSean.Ye@Sun.COM rp->nb.fat_fbd_regs.uerrcnt_last = uerrcnt[branch];
11677532SSean.Ye@Sun.COM uerrcnt[branch] = rp->nb.fat_fbd_regs.uerrcnt;
11687532SSean.Ye@Sun.COM rp->nb.fat_fbd_regs.badrama = BADRAMA_RD(branch);
11697532SSean.Ye@Sun.COM rp->nb.fat_fbd_regs.badramb = BADRAMB_RD(branch);
11707532SSean.Ye@Sun.COM rp->nb.fat_fbd_regs.badcnt = BADCNT_RD(branch);
11719839SAdrian.Frost@Sun.COM if (!willpanic) {
11729839SAdrian.Frost@Sun.COM if (rp->nb.fat_fbd_regs.ferr_fat_fbd || *interpose)
11739839SAdrian.Frost@Sun.COM FERR_FAT_FBD_WR(rp->nb.fat_fbd_regs.ferr_fat_fbd);
11749839SAdrian.Frost@Sun.COM if (rp->nb.fat_fbd_regs.nerr_fat_fbd)
11759839SAdrian.Frost@Sun.COM NERR_FAT_FBD_WR(rp->nb.fat_fbd_regs.nerr_fat_fbd);
11769839SAdrian.Frost@Sun.COM /*
11779839SAdrian.Frost@Sun.COM * if interpose write read-only registers to clear from pcii
11789839SAdrian.Frost@Sun.COM * cache
11799839SAdrian.Frost@Sun.COM */
11809839SAdrian.Frost@Sun.COM if (*interpose) {
11819839SAdrian.Frost@Sun.COM NRECMEMA_WR(branch);
11829839SAdrian.Frost@Sun.COM NRECMEMB_WR(branch);
11839839SAdrian.Frost@Sun.COM NRECFGLOG_WR(branch);
11849839SAdrian.Frost@Sun.COM NRECFBDA_WR(branch);
11859839SAdrian.Frost@Sun.COM NRECFBDB_WR(branch);
11869839SAdrian.Frost@Sun.COM NRECFBDC_WR(branch);
11879839SAdrian.Frost@Sun.COM NRECFBDD_WR(branch);
11889839SAdrian.Frost@Sun.COM NRECFBDE_WR(branch);
11899839SAdrian.Frost@Sun.COM NRECFBDF_WR(branch);
11909839SAdrian.Frost@Sun.COM }
11917532SSean.Ye@Sun.COM }
11927532SSean.Ye@Sun.COM }
11937532SSean.Ye@Sun.COM
11947532SSean.Ye@Sun.COM static void
log_nf_fbd_err(nb_regs_t * rp,int willpanic,int * interpose)11959839SAdrian.Frost@Sun.COM log_nf_fbd_err(nb_regs_t *rp, int willpanic, int *interpose)
11967532SSean.Ye@Sun.COM {
11977532SSean.Ye@Sun.COM int channel, branch;
11987532SSean.Ye@Sun.COM int t = 0;
11997532SSean.Ye@Sun.COM
12007532SSean.Ye@Sun.COM rp->flag = NB_REG_LOG_NF_FBD;
12017532SSean.Ye@Sun.COM rp->nb.nf_fbd_regs.ferr_nf_fbd = FERR_NF_FBD_RD(interpose);
12027532SSean.Ye@Sun.COM channel = (rp->nb.nf_fbd_regs.ferr_nf_fbd >> 28) & 3;
12037532SSean.Ye@Sun.COM branch = channel >> 1;
12047532SSean.Ye@Sun.COM rp->nb.nf_fbd_regs.nerr_nf_fbd = NERR_NF_FBD_RD(&t);
12057532SSean.Ye@Sun.COM *interpose |= t;
12067532SSean.Ye@Sun.COM rp->nb.nf_fbd_regs.redmemb = REDMEMB_RD();
12077532SSean.Ye@Sun.COM rp->nb.nf_fbd_regs.recmema = RECMEMA_RD(branch);
12087532SSean.Ye@Sun.COM rp->nb.nf_fbd_regs.recmemb = RECMEMB_RD(branch);
12097532SSean.Ye@Sun.COM rp->nb.nf_fbd_regs.recfglog = RECFGLOG_RD(branch);
12107532SSean.Ye@Sun.COM rp->nb.nf_fbd_regs.recfbda = RECFBDA_RD(branch);
12117532SSean.Ye@Sun.COM rp->nb.nf_fbd_regs.recfbdb = RECFBDB_RD(branch);
12127532SSean.Ye@Sun.COM rp->nb.nf_fbd_regs.recfbdc = RECFBDC_RD(branch);
12137532SSean.Ye@Sun.COM rp->nb.nf_fbd_regs.recfbdd = RECFBDD_RD(branch);
12147532SSean.Ye@Sun.COM rp->nb.nf_fbd_regs.recfbde = RECFBDE_RD(branch);
12157532SSean.Ye@Sun.COM rp->nb.nf_fbd_regs.recfbdf = RECFBDF_RD(branch);
12167532SSean.Ye@Sun.COM rp->nb.nf_fbd_regs.spcps = SPCPS_RD(branch);
12177532SSean.Ye@Sun.COM rp->nb.nf_fbd_regs.spcpc = SPCPC_RD(branch);
12187532SSean.Ye@Sun.COM if (nb_chipset == INTEL_NB_7300 || nb_chipset == INTEL_NB_5400) {
12197532SSean.Ye@Sun.COM rp->nb.nf_fbd_regs.cerrcnta = CERRCNTA_RD(branch, channel);
12207532SSean.Ye@Sun.COM rp->nb.nf_fbd_regs.cerrcntb = CERRCNTB_RD(branch, channel);
12217532SSean.Ye@Sun.COM rp->nb.nf_fbd_regs.cerrcntc = CERRCNTC_RD(branch, channel);
12227532SSean.Ye@Sun.COM rp->nb.nf_fbd_regs.cerrcntd = CERRCNTD_RD(branch, channel);
12237532SSean.Ye@Sun.COM } else {
12247532SSean.Ye@Sun.COM rp->nb.nf_fbd_regs.cerrcnta = CERRCNT_RD(branch);
12257532SSean.Ye@Sun.COM rp->nb.nf_fbd_regs.cerrcntb = 0;
12267532SSean.Ye@Sun.COM rp->nb.nf_fbd_regs.cerrcntc = 0;
12277532SSean.Ye@Sun.COM rp->nb.nf_fbd_regs.cerrcntd = 0;
12287532SSean.Ye@Sun.COM }
12297532SSean.Ye@Sun.COM rp->nb.nf_fbd_regs.cerrcnta_last = cerrcnta[branch][channel & 1];
12307532SSean.Ye@Sun.COM rp->nb.nf_fbd_regs.cerrcntb_last = cerrcntb[branch][channel & 1];
12317532SSean.Ye@Sun.COM rp->nb.nf_fbd_regs.cerrcntc_last = cerrcntc[branch][channel & 1];
12327532SSean.Ye@Sun.COM rp->nb.nf_fbd_regs.cerrcntd_last = cerrcntd[branch][channel & 1];
12337532SSean.Ye@Sun.COM cerrcnta[branch][channel & 1] = rp->nb.nf_fbd_regs.cerrcnta;
12347532SSean.Ye@Sun.COM cerrcntb[branch][channel & 1] = rp->nb.nf_fbd_regs.cerrcntb;
12357532SSean.Ye@Sun.COM cerrcntc[branch][channel & 1] = rp->nb.nf_fbd_regs.cerrcntc;
12367532SSean.Ye@Sun.COM cerrcntd[branch][channel & 1] = rp->nb.nf_fbd_regs.cerrcntd;
12377532SSean.Ye@Sun.COM rp->nb.nf_fbd_regs.badrama = BADRAMA_RD(branch);
12387532SSean.Ye@Sun.COM rp->nb.nf_fbd_regs.badramb = BADRAMB_RD(branch);
12397532SSean.Ye@Sun.COM rp->nb.nf_fbd_regs.badcnt = BADCNT_RD(branch);
12409839SAdrian.Frost@Sun.COM if (!willpanic) {
12419839SAdrian.Frost@Sun.COM if (rp->nb.nf_fbd_regs.ferr_nf_fbd || *interpose)
12429839SAdrian.Frost@Sun.COM FERR_NF_FBD_WR(rp->nb.nf_fbd_regs.ferr_nf_fbd);
12439839SAdrian.Frost@Sun.COM if (rp->nb.nf_fbd_regs.nerr_nf_fbd)
12449839SAdrian.Frost@Sun.COM NERR_NF_FBD_WR(rp->nb.nf_fbd_regs.nerr_nf_fbd);
12459839SAdrian.Frost@Sun.COM /*
12469839SAdrian.Frost@Sun.COM * if interpose write read-only registers to clear from pcii
12479839SAdrian.Frost@Sun.COM * cache
12489839SAdrian.Frost@Sun.COM */
12499839SAdrian.Frost@Sun.COM if (*interpose) {
12509839SAdrian.Frost@Sun.COM RECMEMA_WR(branch);
12519839SAdrian.Frost@Sun.COM RECMEMB_WR(branch);
12529839SAdrian.Frost@Sun.COM RECFGLOG_WR(branch);
12539839SAdrian.Frost@Sun.COM RECFBDA_WR(branch);
12549839SAdrian.Frost@Sun.COM RECFBDB_WR(branch);
12559839SAdrian.Frost@Sun.COM RECFBDC_WR(branch);
12569839SAdrian.Frost@Sun.COM RECFBDD_WR(branch);
12579839SAdrian.Frost@Sun.COM RECFBDE_WR(branch);
12589839SAdrian.Frost@Sun.COM RECFBDF_WR(branch);
12599839SAdrian.Frost@Sun.COM SPCPS_WR(branch);
12609839SAdrian.Frost@Sun.COM }
12617532SSean.Ye@Sun.COM }
12627532SSean.Ye@Sun.COM }
12637532SSean.Ye@Sun.COM
126410760SVuong.Nguyen@Sun.COM static int
log_nf_mem_err(nb_regs_t * rp,int willpanic,int * interpose)126510049SVuong.Nguyen@Sun.COM log_nf_mem_err(nb_regs_t *rp, int willpanic, int *interpose)
126610049SVuong.Nguyen@Sun.COM {
126710049SVuong.Nguyen@Sun.COM int channel, branch;
126810049SVuong.Nguyen@Sun.COM int t = 0;
126910760SVuong.Nguyen@Sun.COM int rt = 0;
127010049SVuong.Nguyen@Sun.COM
127110049SVuong.Nguyen@Sun.COM rp->flag = NB_REG_LOG_NF_MEM;
127210049SVuong.Nguyen@Sun.COM
127310049SVuong.Nguyen@Sun.COM /* Memmory err registers */
127410049SVuong.Nguyen@Sun.COM rp->nb.nf_mem_regs.ferr_nf_mem = FERR_NF_MEM_RD(interpose);
127510049SVuong.Nguyen@Sun.COM channel = (rp->nb.nf_mem_regs.ferr_nf_mem >> 28) & 0x1;
127610049SVuong.Nguyen@Sun.COM branch = channel;
127710049SVuong.Nguyen@Sun.COM rp->nb.nf_mem_regs.nerr_nf_mem = NERR_NF_MEM_RD(&t);
127810049SVuong.Nguyen@Sun.COM *interpose |= t;
127910049SVuong.Nguyen@Sun.COM rp->nb.nf_mem_regs.redmema = MEM_REDMEMA_RD(branch);
128010049SVuong.Nguyen@Sun.COM rp->nb.nf_mem_regs.redmemb = MEM_REDMEMB_RD(branch);
128110049SVuong.Nguyen@Sun.COM rp->nb.nf_mem_regs.recmema = MEM_RECMEMA_RD(branch);
128210049SVuong.Nguyen@Sun.COM rp->nb.nf_mem_regs.recmemb = MEM_RECMEMB_RD(branch);
128310049SVuong.Nguyen@Sun.COM rp->nb.nf_mem_regs.nrecmema = MEM_NRECMEMA_RD(branch);
128410049SVuong.Nguyen@Sun.COM rp->nb.nf_mem_regs.nrecmemb = MEM_NRECMEMB_RD(branch);
128510049SVuong.Nguyen@Sun.COM
128610049SVuong.Nguyen@Sun.COM /* spare rank */
128710049SVuong.Nguyen@Sun.COM rp->nb.nf_mem_regs.spcps = SPCPS_RD(branch);
128810049SVuong.Nguyen@Sun.COM rp->nb.nf_mem_regs.spcpc = SPCPC_RD(branch);
128910049SVuong.Nguyen@Sun.COM
129010049SVuong.Nguyen@Sun.COM /* RAS registers */
129110049SVuong.Nguyen@Sun.COM rp->nb.nf_mem_regs.cerrcnt = MEM_CERRCNT_RD(branch);
129210049SVuong.Nguyen@Sun.COM rp->nb.nf_mem_regs.cerrcnt_ext = (uint32_t)MEM_CERRCNT_EXT_RD(branch);
129310049SVuong.Nguyen@Sun.COM rp->nb.nf_mem_regs.cerrcnt_last = cerrcnta[branch][channel & 1];
129410049SVuong.Nguyen@Sun.COM rp->nb.nf_mem_regs.cerrcnt_ext_last = cerrcntb[branch][channel & 1];
129510049SVuong.Nguyen@Sun.COM cerrcnta[branch][channel & 1] = rp->nb.nf_mem_regs.cerrcnt;
129610049SVuong.Nguyen@Sun.COM cerrcntb[branch][channel & 1] = rp->nb.nf_mem_regs.cerrcnt_ext;
129710049SVuong.Nguyen@Sun.COM rp->nb.nf_mem_regs.badram = BADRAMA_RD(branch);
129810049SVuong.Nguyen@Sun.COM rp->nb.nf_mem_regs.badcnt = BADCNT_RD(branch);
129910049SVuong.Nguyen@Sun.COM rp->nb.nf_mem_regs.validlog = VALIDLOG_RD(branch);
130010049SVuong.Nguyen@Sun.COM
130110049SVuong.Nguyen@Sun.COM if (!willpanic) {
130210049SVuong.Nguyen@Sun.COM if (rp->nb.nf_mem_regs.ferr_nf_mem || *interpose)
130310049SVuong.Nguyen@Sun.COM FERR_NF_MEM_WR(rp->nb.nf_mem_regs.ferr_nf_mem);
130410049SVuong.Nguyen@Sun.COM if (rp->nb.nf_mem_regs.nerr_nf_mem)
130510049SVuong.Nguyen@Sun.COM NERR_NF_MEM_WR(rp->nb.nf_mem_regs.nerr_nf_mem);
130610049SVuong.Nguyen@Sun.COM /*
130710049SVuong.Nguyen@Sun.COM * if interpose, write read-only registers to clear from pci
130810049SVuong.Nguyen@Sun.COM * cache
130910049SVuong.Nguyen@Sun.COM */
131010049SVuong.Nguyen@Sun.COM if (*interpose) {
131110049SVuong.Nguyen@Sun.COM MEM_NRECMEMA_WR(branch);
131210049SVuong.Nguyen@Sun.COM MEM_NRECMEMB_WR(branch);
131310049SVuong.Nguyen@Sun.COM MEM_REDMEMA_WR(branch);
131410049SVuong.Nguyen@Sun.COM MEM_REDMEMB_WR(branch);
131510049SVuong.Nguyen@Sun.COM MEM_RECMEMA_WR(branch);
131610049SVuong.Nguyen@Sun.COM MEM_RECMEMB_WR(branch);
131710049SVuong.Nguyen@Sun.COM SPCPS_WR(branch);
131810049SVuong.Nguyen@Sun.COM }
131910049SVuong.Nguyen@Sun.COM }
132010760SVuong.Nguyen@Sun.COM if (nb_mode == NB_MEMORY_SINGLE_CHANNEL && channel != 0) {
132110760SVuong.Nguyen@Sun.COM /*
132210760SVuong.Nguyen@Sun.COM * In the single channel mode, all dimms are on the channel 0.
132310760SVuong.Nguyen@Sun.COM * Invalidate this error if the channel number is invalid.
132410760SVuong.Nguyen@Sun.COM */
132510760SVuong.Nguyen@Sun.COM rt = 1;
132610760SVuong.Nguyen@Sun.COM }
132710760SVuong.Nguyen@Sun.COM return (rt);
132810049SVuong.Nguyen@Sun.COM }
132910049SVuong.Nguyen@Sun.COM
133010049SVuong.Nguyen@Sun.COM static void
log_ferr(uint64_t ferr,uint32_t * nerrp,nb_logout_t * log,int willpanic)13317532SSean.Ye@Sun.COM log_ferr(uint64_t ferr, uint32_t *nerrp, nb_logout_t *log, int willpanic)
13327532SSean.Ye@Sun.COM {
13337532SSean.Ye@Sun.COM nb_regs_t *rp = &log->nb_regs;
13347532SSean.Ye@Sun.COM uint32_t nerr = *nerrp;
13357532SSean.Ye@Sun.COM int interpose = 0;
13369783SAdrian.Frost@Sun.COM int spurious = 0;
13377532SSean.Ye@Sun.COM
13387532SSean.Ye@Sun.COM log->acl_timestamp = gethrtime_waitfree();
13397532SSean.Ye@Sun.COM if ((ferr & (GE_PCIEX_FATAL | GE_PCIEX_NF)) != 0) {
13407532SSean.Ye@Sun.COM *nerrp = nerr & ~(GE_PCIEX_FATAL | GE_PCIEX_NF);
1341*12437SAdrian.Frost@Sun.COM if (log_pex_err(ferr, rp, willpanic, &interpose) == 0)
1342*12437SAdrian.Frost@Sun.COM return;
13437532SSean.Ye@Sun.COM } else if ((ferr & GE_FBD_FATAL) != 0) {
13449839SAdrian.Frost@Sun.COM log_fat_fbd_err(rp, willpanic, &interpose);
13457532SSean.Ye@Sun.COM *nerrp = nerr & ~GE_NERR_FBD_FATAL;
13467532SSean.Ye@Sun.COM } else if ((ferr & GE_FBD_NF) != 0) {
13479839SAdrian.Frost@Sun.COM log_nf_fbd_err(rp, willpanic, &interpose);
13487532SSean.Ye@Sun.COM *nerrp = nerr & ~GE_NERR_FBD_NF;
134910049SVuong.Nguyen@Sun.COM } else if ((ferr & GE_MEM_NF) != 0) {
135010760SVuong.Nguyen@Sun.COM spurious = log_nf_mem_err(rp, willpanic, &interpose);
135110049SVuong.Nguyen@Sun.COM *nerrp = nerr & ~GE_NERR_MEM_NF;
13527532SSean.Ye@Sun.COM } else if ((ferr & (GE_FERR_FSB_FATAL | GE_FERR_FSB_NF)) != 0) {
13539839SAdrian.Frost@Sun.COM log_fsb_err(ferr, rp, willpanic, &interpose);
13547532SSean.Ye@Sun.COM *nerrp = nerr & ~(GE_NERR_FSB_FATAL | GE_NERR_FSB_NF);
13557532SSean.Ye@Sun.COM } else if ((ferr & (GE_DMA_FATAL | GE_DMA_NF)) != 0) {
13567532SSean.Ye@Sun.COM log_dma_err(rp, &interpose);
13577532SSean.Ye@Sun.COM *nerrp = nerr & ~(GE_DMA_FATAL | GE_DMA_NF);
13587532SSean.Ye@Sun.COM } else if ((ferr & (GE_INT_FATAL | GE_INT_NF)) != 0) {
13599839SAdrian.Frost@Sun.COM spurious = log_int_err(rp, willpanic, &interpose);
13607532SSean.Ye@Sun.COM *nerrp = nerr & ~(GE_INT_FATAL | GE_INT_NF);
13617532SSean.Ye@Sun.COM } else if (nb_chipset == INTEL_NB_5400 &&
13627532SSean.Ye@Sun.COM (ferr & (GE_FERR_THERMAL_FATAL | GE_FERR_THERMAL_NF)) != 0) {
13639839SAdrian.Frost@Sun.COM log_thermal_err(rp, willpanic, &interpose);
13647532SSean.Ye@Sun.COM *nerrp = nerr & ~(GE_FERR_THERMAL_FATAL | GE_FERR_THERMAL_NF);
13657532SSean.Ye@Sun.COM }
13667532SSean.Ye@Sun.COM if (interpose)
13677532SSean.Ye@Sun.COM log->type = "inject";
13687532SSean.Ye@Sun.COM else
13697532SSean.Ye@Sun.COM log->type = "error";
13709783SAdrian.Frost@Sun.COM if (!spurious) {
13719783SAdrian.Frost@Sun.COM errorq_dispatch(nb_queue, log, sizeof (nb_logout_t),
13729783SAdrian.Frost@Sun.COM willpanic ? ERRORQ_SYNC : ERRORQ_ASYNC);
13739783SAdrian.Frost@Sun.COM }
13747532SSean.Ye@Sun.COM }
13757532SSean.Ye@Sun.COM
13767532SSean.Ye@Sun.COM static void
log_nerr(uint32_t * errp,nb_logout_t * log,int willpanic)13777532SSean.Ye@Sun.COM log_nerr(uint32_t *errp, nb_logout_t *log, int willpanic)
13787532SSean.Ye@Sun.COM {
13797532SSean.Ye@Sun.COM uint32_t err;
13807532SSean.Ye@Sun.COM nb_regs_t *rp = &log->nb_regs;
13817532SSean.Ye@Sun.COM int interpose = 0;
13829783SAdrian.Frost@Sun.COM int spurious = 0;
13837532SSean.Ye@Sun.COM
13847532SSean.Ye@Sun.COM err = *errp;
13857532SSean.Ye@Sun.COM log->acl_timestamp = gethrtime_waitfree();
13867532SSean.Ye@Sun.COM if ((err & (GE_PCIEX_FATAL | GE_PCIEX_NF)) != 0) {
13877532SSean.Ye@Sun.COM *errp = err & ~(GE_PCIEX_FATAL | GE_PCIEX_NF);
1388*12437SAdrian.Frost@Sun.COM if (log_pex_err(err, rp, willpanic, &interpose) == 0)
1389*12437SAdrian.Frost@Sun.COM return;
13907532SSean.Ye@Sun.COM } else if ((err & GE_NERR_FBD_FATAL) != 0) {
13919839SAdrian.Frost@Sun.COM log_fat_fbd_err(rp, willpanic, &interpose);
13927532SSean.Ye@Sun.COM *errp = err & ~GE_NERR_FBD_FATAL;
13937532SSean.Ye@Sun.COM } else if ((err & GE_NERR_FBD_NF) != 0) {
13949839SAdrian.Frost@Sun.COM log_nf_fbd_err(rp, willpanic, &interpose);
13957532SSean.Ye@Sun.COM *errp = err & ~GE_NERR_FBD_NF;
139610049SVuong.Nguyen@Sun.COM } else if ((err & GE_NERR_MEM_NF) != 0) {
139710760SVuong.Nguyen@Sun.COM spurious = log_nf_mem_err(rp, willpanic, &interpose);
139810049SVuong.Nguyen@Sun.COM *errp = err & ~GE_NERR_MEM_NF;
13997532SSean.Ye@Sun.COM } else if ((err & (GE_NERR_FSB_FATAL | GE_NERR_FSB_NF)) != 0) {
14009839SAdrian.Frost@Sun.COM log_fsb_err(GE_NERR_TO_FERR_FSB(err), rp, willpanic,
14019839SAdrian.Frost@Sun.COM &interpose);
14027532SSean.Ye@Sun.COM *errp = err & ~(GE_NERR_FSB_FATAL | GE_NERR_FSB_NF);
14037532SSean.Ye@Sun.COM } else if ((err & (GE_DMA_FATAL | GE_DMA_NF)) != 0) {
14047532SSean.Ye@Sun.COM log_dma_err(rp, &interpose);
14057532SSean.Ye@Sun.COM *errp = err & ~(GE_DMA_FATAL | GE_DMA_NF);
14067532SSean.Ye@Sun.COM } else if ((err & (GE_INT_FATAL | GE_INT_NF)) != 0) {
14079839SAdrian.Frost@Sun.COM spurious = log_int_err(rp, willpanic, &interpose);
14087532SSean.Ye@Sun.COM *errp = err & ~(GE_INT_FATAL | GE_INT_NF);
14097532SSean.Ye@Sun.COM }
14107532SSean.Ye@Sun.COM if (interpose)
14117532SSean.Ye@Sun.COM log->type = "inject";
14127532SSean.Ye@Sun.COM else
14137532SSean.Ye@Sun.COM log->type = "error";
14149783SAdrian.Frost@Sun.COM if (!spurious) {
14159783SAdrian.Frost@Sun.COM errorq_dispatch(nb_queue, log, sizeof (nb_logout_t),
14169783SAdrian.Frost@Sun.COM willpanic ? ERRORQ_SYNC : ERRORQ_ASYNC);
14179783SAdrian.Frost@Sun.COM }
14187532SSean.Ye@Sun.COM }
14197532SSean.Ye@Sun.COM
14207532SSean.Ye@Sun.COM /*ARGSUSED*/
14217532SSean.Ye@Sun.COM void
nb_error_trap(cmi_hdl_t hdl,boolean_t ismc,boolean_t willpanic)14227532SSean.Ye@Sun.COM nb_error_trap(cmi_hdl_t hdl, boolean_t ismc, boolean_t willpanic)
14237532SSean.Ye@Sun.COM {
14247532SSean.Ye@Sun.COM uint64_t ferr;
14257532SSean.Ye@Sun.COM uint32_t nerr, err;
14267532SSean.Ye@Sun.COM int nmc = 0;
14277532SSean.Ye@Sun.COM int i;
14287532SSean.Ye@Sun.COM
14297532SSean.Ye@Sun.COM if (mutex_tryenter(&nb_mutex) == 0)
14307532SSean.Ye@Sun.COM return;
14317532SSean.Ye@Sun.COM
14327532SSean.Ye@Sun.COM nerr = NERR_GLOBAL_RD();
14337532SSean.Ye@Sun.COM err = nerr;
14347532SSean.Ye@Sun.COM for (i = 0; i < NB_MAX_ERRORS; i++) {
14357532SSean.Ye@Sun.COM ferr = FERR_GLOBAL_RD();
14367532SSean.Ye@Sun.COM nb_log.nb_regs.chipset = nb_chipset;
14377532SSean.Ye@Sun.COM nb_log.nb_regs.ferr = ferr;
14387532SSean.Ye@Sun.COM nb_log.nb_regs.nerr = nerr;
14397532SSean.Ye@Sun.COM if (ferr) {
14407532SSean.Ye@Sun.COM log_ferr(ferr, &err, &nb_log, willpanic);
14417532SSean.Ye@Sun.COM FERR_GLOBAL_WR(ferr);
14427532SSean.Ye@Sun.COM nmc++;
14437532SSean.Ye@Sun.COM } else if (err) {
14447532SSean.Ye@Sun.COM log_nerr(&err, &nb_log, willpanic);
14457532SSean.Ye@Sun.COM nmc++;
14467532SSean.Ye@Sun.COM }
14477532SSean.Ye@Sun.COM }
14487532SSean.Ye@Sun.COM if (nerr) {
14497532SSean.Ye@Sun.COM NERR_GLOBAL_WR(nerr);
14507532SSean.Ye@Sun.COM }
14517532SSean.Ye@Sun.COM if (nmc == 0 && nb_mask_mc_set)
14527532SSean.Ye@Sun.COM nb_mask_mc_reset();
14537532SSean.Ye@Sun.COM mutex_exit(&nb_mutex);
14547532SSean.Ye@Sun.COM }
14557532SSean.Ye@Sun.COM
14567532SSean.Ye@Sun.COM static void
nb_fsb_err_payload(const nb_regs_t * nb_regs,nvlist_t * payload,nb_scatchpad_t * data)14577532SSean.Ye@Sun.COM nb_fsb_err_payload(const nb_regs_t *nb_regs, nvlist_t *payload,
14587532SSean.Ye@Sun.COM nb_scatchpad_t *data)
14597532SSean.Ye@Sun.COM {
14607532SSean.Ye@Sun.COM int intel_error_list;
14617532SSean.Ye@Sun.COM char buf[32];
14627532SSean.Ye@Sun.COM
14637532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FSB,
14647532SSean.Ye@Sun.COM DATA_TYPE_UINT8, nb_regs->nb.fsb_regs.fsb, NULL);
14657532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_FAT_FSB,
14667532SSean.Ye@Sun.COM DATA_TYPE_UINT8, nb_regs->nb.fsb_regs.ferr_fat_fsb, NULL);
14677532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_FAT_FSB,
14687532SSean.Ye@Sun.COM DATA_TYPE_UINT8, nb_regs->nb.fsb_regs.nerr_fat_fsb, NULL);
14697532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_NF_FSB,
14707532SSean.Ye@Sun.COM DATA_TYPE_UINT8, nb_regs->nb.fsb_regs.ferr_nf_fsb, NULL);
14717532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_NF_FSB,
14727532SSean.Ye@Sun.COM DATA_TYPE_UINT8, nb_regs->nb.fsb_regs.nerr_nf_fsb, NULL);
14737532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFSB,
14747532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.fsb_regs.nrecfsb, NULL);
14757532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFSB_ADDR,
14767532SSean.Ye@Sun.COM DATA_TYPE_UINT64, nb_regs->nb.fsb_regs.nrecfsb_addr, NULL);
14777532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECFSB,
14787532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.fsb_regs.recfsb, NULL);
14797532SSean.Ye@Sun.COM intel_error_list = data->intel_error_list;
14807532SSean.Ye@Sun.COM if (intel_error_list >= 0)
14817532SSean.Ye@Sun.COM (void) snprintf(buf, sizeof (buf), "F%d", intel_error_list);
14827532SSean.Ye@Sun.COM else
14837532SSean.Ye@Sun.COM (void) snprintf(buf, sizeof (buf), "Multiple or unknown error");
14847532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_ERROR_NO,
14857532SSean.Ye@Sun.COM DATA_TYPE_STRING, buf, NULL);
14867532SSean.Ye@Sun.COM }
14877532SSean.Ye@Sun.COM
14887532SSean.Ye@Sun.COM static void
nb_pex_err_payload(const nb_regs_t * nb_regs,nvlist_t * payload,nb_scatchpad_t * data)14897532SSean.Ye@Sun.COM nb_pex_err_payload(const nb_regs_t *nb_regs, nvlist_t *payload,
14907532SSean.Ye@Sun.COM nb_scatchpad_t *data)
14917532SSean.Ye@Sun.COM {
14927532SSean.Ye@Sun.COM int intel_error_list;
14937532SSean.Ye@Sun.COM char buf[32];
14947532SSean.Ye@Sun.COM
14957532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_PEX,
14967532SSean.Ye@Sun.COM DATA_TYPE_UINT8, nb_regs->nb.pex_regs.pex, NULL);
14977532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_PEX_FAT_FERR,
14987532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.pex_regs.pex_fat_ferr, NULL);
14997532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_PEX_FAT_NERR,
15007532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.pex_regs.pex_fat_nerr, NULL);
15017532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_PEX_NF_CORR_FERR,
15027532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.pex_regs.pex_nf_corr_ferr, NULL);
15037532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_PEX_NF_CORR_NERR,
15047532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.pex_regs.pex_nf_corr_nerr, NULL);
15057532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_UNCERRSEV,
15067532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.pex_regs.uncerrsev, NULL);
15077532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RPERRSTS,
15087532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.pex_regs.rperrsts, NULL);
15097532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RPERRSID,
15107532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.pex_regs.rperrsid, NULL);
15117532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_UNCERRSTS,
15127532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.pex_regs.uncerrsts, NULL);
15137532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_AERRCAPCTRL,
15147532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.pex_regs.aerrcapctrl, NULL);
15157532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CORERRSTS,
15167532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.pex_regs.corerrsts, NULL);
15177532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_PEXDEVSTS,
15187532SSean.Ye@Sun.COM DATA_TYPE_UINT16, nb_regs->nb.pex_regs.pexdevsts, NULL);
15197532SSean.Ye@Sun.COM intel_error_list = data->intel_error_list;
15207532SSean.Ye@Sun.COM if (intel_error_list >= 0)
15217532SSean.Ye@Sun.COM (void) snprintf(buf, sizeof (buf), "IO%d", intel_error_list);
15227532SSean.Ye@Sun.COM else
15237532SSean.Ye@Sun.COM (void) snprintf(buf, sizeof (buf), "Multiple or unknown error");
15247532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_ERROR_NO,
15257532SSean.Ye@Sun.COM DATA_TYPE_STRING, buf, NULL);
15267532SSean.Ye@Sun.COM }
15277532SSean.Ye@Sun.COM
15287532SSean.Ye@Sun.COM static void
nb_int_err_payload(const nb_regs_t * nb_regs,nvlist_t * payload,nb_scatchpad_t * data)15297532SSean.Ye@Sun.COM nb_int_err_payload(const nb_regs_t *nb_regs, nvlist_t *payload,
15307532SSean.Ye@Sun.COM nb_scatchpad_t *data)
15317532SSean.Ye@Sun.COM {
15327532SSean.Ye@Sun.COM int intel_error_list;
15337532SSean.Ye@Sun.COM char buf[32];
15347532SSean.Ye@Sun.COM
15357532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_FAT_INT,
15367532SSean.Ye@Sun.COM DATA_TYPE_UINT16, nb_regs->nb.int_regs.ferr_fat_int, NULL);
15377532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_NF_INT,
15387532SSean.Ye@Sun.COM DATA_TYPE_UINT16, nb_regs->nb.int_regs.ferr_nf_int, NULL);
15397532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_FAT_INT,
15407532SSean.Ye@Sun.COM DATA_TYPE_UINT16, nb_regs->nb.int_regs.nerr_fat_int, NULL);
15417532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_NF_INT,
15427532SSean.Ye@Sun.COM DATA_TYPE_UINT16, nb_regs->nb.int_regs.nerr_nf_int, NULL);
15437532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECINT,
15447532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.int_regs.nrecint, NULL);
15457532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECINT,
15467532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.int_regs.recint, NULL);
15477532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECSF,
15487532SSean.Ye@Sun.COM DATA_TYPE_UINT64, nb_regs->nb.int_regs.nrecsf, NULL);
15497532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECSF,
15507532SSean.Ye@Sun.COM DATA_TYPE_UINT64, nb_regs->nb.int_regs.recsf, NULL);
15517532SSean.Ye@Sun.COM intel_error_list = data->intel_error_list;
15527532SSean.Ye@Sun.COM if (intel_error_list >= 0)
15537532SSean.Ye@Sun.COM (void) snprintf(buf, sizeof (buf), "B%d", intel_error_list);
15547532SSean.Ye@Sun.COM else
15557532SSean.Ye@Sun.COM (void) snprintf(buf, sizeof (buf), "Multiple or unknown error");
15567532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_ERROR_NO,
15577532SSean.Ye@Sun.COM DATA_TYPE_STRING, buf, NULL);
15587532SSean.Ye@Sun.COM }
15597532SSean.Ye@Sun.COM
15607532SSean.Ye@Sun.COM static void
nb_fat_fbd_err_payload(const nb_regs_t * nb_regs,nvlist_t * payload,nb_scatchpad_t * data)15617532SSean.Ye@Sun.COM nb_fat_fbd_err_payload(const nb_regs_t *nb_regs, nvlist_t *payload,
15627532SSean.Ye@Sun.COM nb_scatchpad_t *data)
15637532SSean.Ye@Sun.COM {
15647532SSean.Ye@Sun.COM nb_mem_scatchpad_t *sp;
15657532SSean.Ye@Sun.COM char buf[32];
15667532SSean.Ye@Sun.COM
15677532SSean.Ye@Sun.COM sp = &((nb_scatchpad_t *)data)->ms;
15687532SSean.Ye@Sun.COM
15697532SSean.Ye@Sun.COM if (sp->ras != -1) {
15707532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BANK,
15717532SSean.Ye@Sun.COM DATA_TYPE_INT32, sp->bank, NULL);
15727532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CAS,
15737532SSean.Ye@Sun.COM DATA_TYPE_INT32, sp->cas, NULL);
15747532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RAS,
15757532SSean.Ye@Sun.COM DATA_TYPE_INT32, sp->ras, NULL);
15767532SSean.Ye@Sun.COM if (sp->offset != -1LL) {
15777532SSean.Ye@Sun.COM fm_payload_set(payload, FM_FMRI_MEM_OFFSET,
15787532SSean.Ye@Sun.COM DATA_TYPE_UINT64, sp->offset, NULL);
15797532SSean.Ye@Sun.COM }
15807532SSean.Ye@Sun.COM if (sp->pa != -1LL) {
15817532SSean.Ye@Sun.COM fm_payload_set(payload, FM_FMRI_MEM_PHYSADDR,
15827532SSean.Ye@Sun.COM DATA_TYPE_UINT64, sp->pa, NULL);
15837532SSean.Ye@Sun.COM }
15847532SSean.Ye@Sun.COM }
15857532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_FAT_FBD,
15867532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.ferr_fat_fbd, NULL);
15877532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_FAT_FBD,
15887532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nerr_fat_fbd, NULL);
15897532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECMEMA,
15907532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecmema, NULL);
15917532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECMEMB,
15927532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecmemb, NULL);
15937532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFGLOG,
15947532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecfglog, NULL);
15957532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFBDA,
15967532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecfbda, NULL);
15977532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFBDB,
15987532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecfbdb, NULL);
15997532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFBDC,
16007532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecfbdc, NULL);
16017532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFBDD,
16027532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecfbdd, NULL);
16037532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFBDE,
16047532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecfbde, NULL);
16057532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECFBDF,
16067532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.nrecfbdf, NULL);
16077532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_SPCPS,
16087532SSean.Ye@Sun.COM DATA_TYPE_UINT8, nb_regs->nb.fat_fbd_regs.spcps, NULL);
16097532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_SPCPC,
16107532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.spcpc, NULL);
16117532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_UERRCNT,
16127532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.uerrcnt, NULL);
16137532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_UERRCNT_LAST,
16147532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.uerrcnt_last, NULL);
16157532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BADRAMA,
16167532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.badrama, NULL);
16177532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BADRAMB,
16187532SSean.Ye@Sun.COM DATA_TYPE_UINT16, nb_regs->nb.fat_fbd_regs.badramb, NULL);
16197532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BADCNT,
16207532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.fat_fbd_regs.badcnt, NULL);
16217532SSean.Ye@Sun.COM
16227532SSean.Ye@Sun.COM if (sp->intel_error_list >= 0)
16237532SSean.Ye@Sun.COM (void) snprintf(buf, sizeof (buf), "M%d", sp->intel_error_list);
16247532SSean.Ye@Sun.COM else
16257532SSean.Ye@Sun.COM (void) snprintf(buf, sizeof (buf), "Multiple or unknown error");
16267532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_ERROR_NO,
16277532SSean.Ye@Sun.COM DATA_TYPE_STRING, buf, NULL);
16287532SSean.Ye@Sun.COM }
16297532SSean.Ye@Sun.COM
16307532SSean.Ye@Sun.COM static void
nb_nf_fbd_err_payload(const nb_regs_t * nb_regs,nvlist_t * payload,nb_scatchpad_t * data)16317532SSean.Ye@Sun.COM nb_nf_fbd_err_payload(const nb_regs_t *nb_regs, nvlist_t *payload,
16327532SSean.Ye@Sun.COM nb_scatchpad_t *data)
16337532SSean.Ye@Sun.COM {
16347532SSean.Ye@Sun.COM nb_mem_scatchpad_t *sp;
16357532SSean.Ye@Sun.COM char buf[32];
16367532SSean.Ye@Sun.COM
16377532SSean.Ye@Sun.COM sp = &((nb_scatchpad_t *)data)->ms;
16387532SSean.Ye@Sun.COM
16397532SSean.Ye@Sun.COM if (sp->dimm == -1 && sp->rank != -1) {
16407532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RANK,
16417532SSean.Ye@Sun.COM DATA_TYPE_INT32, sp->rank, NULL);
16427532SSean.Ye@Sun.COM }
16437532SSean.Ye@Sun.COM if (sp->ras != -1) {
16447532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BANK,
16457532SSean.Ye@Sun.COM DATA_TYPE_INT32, sp->bank, NULL);
16467532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CAS,
16477532SSean.Ye@Sun.COM DATA_TYPE_INT32, sp->cas, NULL);
16487532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RAS,
16497532SSean.Ye@Sun.COM DATA_TYPE_INT32, sp->ras, NULL);
16507532SSean.Ye@Sun.COM if (sp->offset != -1LL) {
16517532SSean.Ye@Sun.COM fm_payload_set(payload, FM_FMRI_MEM_OFFSET,
16527532SSean.Ye@Sun.COM DATA_TYPE_UINT64, sp->offset, NULL);
16537532SSean.Ye@Sun.COM }
16547532SSean.Ye@Sun.COM if (sp->pa != -1LL) {
16557532SSean.Ye@Sun.COM fm_payload_set(payload, FM_FMRI_MEM_PHYSADDR,
16567532SSean.Ye@Sun.COM DATA_TYPE_UINT64, sp->pa, NULL);
16577532SSean.Ye@Sun.COM }
16587532SSean.Ye@Sun.COM }
16597532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_NF_FBD,
16607532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.ferr_nf_fbd, NULL);
16617532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_NF_FBD,
16627532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.nerr_nf_fbd, NULL);
16637532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECMEMA,
16647532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recmema, NULL);
16657532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECMEMB,
16667532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recmemb, NULL);
16677532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECFGLOG,
16687532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recfglog, NULL);
16697532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECFBDA,
16707532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recfbda, NULL);
16717532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECFBDB,
16727532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recfbdb, NULL);
16737532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECFBDC,
16747532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recfbdc, NULL);
16757532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECFBDD,
16767532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recfbdd, NULL);
16777532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECFBDE,
16787532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recfbde, NULL);
16797532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECFBDF,
16807532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.recfbdf, NULL);
16817532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_SPCPS,
16827532SSean.Ye@Sun.COM DATA_TYPE_UINT8, nb_regs->nb.nf_fbd_regs.spcps, NULL);
16837532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_SPCPC,
16847532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.spcpc, NULL);
16857532SSean.Ye@Sun.COM if (nb_chipset == INTEL_NB_7300 || nb_chipset == INTEL_NB_5400) {
16867532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNTA,
16877532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.cerrcnta, NULL);
16887532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNTB,
16897532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.cerrcntb, NULL);
16907532SSean.Ye@Sun.COM if (nb_chipset == INTEL_NB_7300) {
16917532SSean.Ye@Sun.COM fm_payload_set(payload,
16927532SSean.Ye@Sun.COM FM_EREPORT_PAYLOAD_NAME_CERRCNTC,
16937532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.cerrcntc,
16947532SSean.Ye@Sun.COM NULL);
16957532SSean.Ye@Sun.COM fm_payload_set(payload,
16967532SSean.Ye@Sun.COM FM_EREPORT_PAYLOAD_NAME_CERRCNTD,
16977532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.cerrcntd,
16987532SSean.Ye@Sun.COM NULL);
16997532SSean.Ye@Sun.COM }
17007532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNTA_LAST,
17017532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.cerrcnta_last,
17027532SSean.Ye@Sun.COM NULL);
17037532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNTB_LAST,
17047532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.cerrcntb_last,
17057532SSean.Ye@Sun.COM NULL);
17067532SSean.Ye@Sun.COM if (nb_chipset == INTEL_NB_7300) {
17077532SSean.Ye@Sun.COM fm_payload_set(payload,
17087532SSean.Ye@Sun.COM FM_EREPORT_PAYLOAD_NAME_CERRCNTC_LAST,
17097532SSean.Ye@Sun.COM DATA_TYPE_UINT32,
17107532SSean.Ye@Sun.COM nb_regs->nb.nf_fbd_regs.cerrcntc_last, NULL);
17117532SSean.Ye@Sun.COM fm_payload_set(payload,
17127532SSean.Ye@Sun.COM FM_EREPORT_PAYLOAD_NAME_CERRCNTD_LAST,
17137532SSean.Ye@Sun.COM DATA_TYPE_UINT32,
17147532SSean.Ye@Sun.COM nb_regs->nb.nf_fbd_regs.cerrcntd_last, NULL);
17157532SSean.Ye@Sun.COM }
17167532SSean.Ye@Sun.COM } else {
17177532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNT,
17187532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.cerrcnta, NULL);
17197532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNT_LAST,
17207532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.cerrcnta_last,
17217532SSean.Ye@Sun.COM NULL);
17227532SSean.Ye@Sun.COM }
17237532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BADRAMA,
17247532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.badrama, NULL);
17257532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BADRAMB,
17267532SSean.Ye@Sun.COM DATA_TYPE_UINT16, nb_regs->nb.nf_fbd_regs.badramb, NULL);
17277532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BADCNT,
17287532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.nf_fbd_regs.badcnt, NULL);
17297532SSean.Ye@Sun.COM
17307532SSean.Ye@Sun.COM if (sp->intel_error_list >= 0)
17317532SSean.Ye@Sun.COM (void) snprintf(buf, sizeof (buf), "M%d", sp->intel_error_list);
17327532SSean.Ye@Sun.COM else
17337532SSean.Ye@Sun.COM (void) snprintf(buf, sizeof (buf), "Multiple or unknown error");
17347532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_ERROR_NO,
17357532SSean.Ye@Sun.COM DATA_TYPE_STRING, buf, NULL);
17367532SSean.Ye@Sun.COM }
17377532SSean.Ye@Sun.COM
17387532SSean.Ye@Sun.COM static void
nb_nf_mem_err_payload(const nb_regs_t * nb_regs,nvlist_t * payload,nb_scatchpad_t * data)173910049SVuong.Nguyen@Sun.COM nb_nf_mem_err_payload(const nb_regs_t *nb_regs, nvlist_t *payload,
174010049SVuong.Nguyen@Sun.COM nb_scatchpad_t *data)
174110049SVuong.Nguyen@Sun.COM {
174210049SVuong.Nguyen@Sun.COM nb_mem_scatchpad_t *sp;
174310049SVuong.Nguyen@Sun.COM char buf[32];
174410049SVuong.Nguyen@Sun.COM
174510049SVuong.Nguyen@Sun.COM sp = &((nb_scatchpad_t *)data)->ms;
174610049SVuong.Nguyen@Sun.COM
174710049SVuong.Nguyen@Sun.COM if (sp->dimm == -1 && sp->rank != -1) {
174810049SVuong.Nguyen@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RANK,
174910049SVuong.Nguyen@Sun.COM DATA_TYPE_INT32, sp->rank, NULL);
175010049SVuong.Nguyen@Sun.COM }
175110049SVuong.Nguyen@Sun.COM if (sp->ras != -1) {
175210049SVuong.Nguyen@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BANK,
175310049SVuong.Nguyen@Sun.COM DATA_TYPE_INT32, sp->bank, NULL);
175410049SVuong.Nguyen@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CAS,
175510049SVuong.Nguyen@Sun.COM DATA_TYPE_INT32, sp->cas, NULL);
175610049SVuong.Nguyen@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RAS,
175710049SVuong.Nguyen@Sun.COM DATA_TYPE_INT32, sp->ras, NULL);
175810049SVuong.Nguyen@Sun.COM if (sp->offset != -1LL) {
175910049SVuong.Nguyen@Sun.COM fm_payload_set(payload, FM_FMRI_MEM_OFFSET,
176010049SVuong.Nguyen@Sun.COM DATA_TYPE_UINT64, sp->offset, NULL);
176110049SVuong.Nguyen@Sun.COM }
176210049SVuong.Nguyen@Sun.COM if (sp->pa != -1LL) {
176310049SVuong.Nguyen@Sun.COM fm_payload_set(payload, FM_FMRI_MEM_PHYSADDR,
176410049SVuong.Nguyen@Sun.COM DATA_TYPE_UINT64, sp->pa, NULL);
176510049SVuong.Nguyen@Sun.COM }
176610049SVuong.Nguyen@Sun.COM }
176710049SVuong.Nguyen@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_NF_MEM,
176810049SVuong.Nguyen@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.ferr_nf_mem, NULL);
176910049SVuong.Nguyen@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_NF_MEM,
177010049SVuong.Nguyen@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.nerr_nf_mem, NULL);
177110049SVuong.Nguyen@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECMEMA,
177210049SVuong.Nguyen@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.recmema, NULL);
177310049SVuong.Nguyen@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_RECMEMB,
177410049SVuong.Nguyen@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.recmemb, NULL);
177510049SVuong.Nguyen@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_REDMEMA,
177610049SVuong.Nguyen@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.redmema, NULL);
177710049SVuong.Nguyen@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_REDMEMB,
177810049SVuong.Nguyen@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.redmemb, NULL);
177910049SVuong.Nguyen@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECMEMA,
178010049SVuong.Nguyen@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.nrecmema, NULL);
178110049SVuong.Nguyen@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NRECMEMB,
178210049SVuong.Nguyen@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.nrecmemb, NULL);
178310049SVuong.Nguyen@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_SPCPS,
178410049SVuong.Nguyen@Sun.COM DATA_TYPE_UINT8, nb_regs->nb.nf_mem_regs.spcps, NULL);
178510049SVuong.Nguyen@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_SPCPC,
178610049SVuong.Nguyen@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.spcpc, NULL);
178710049SVuong.Nguyen@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNT,
178810049SVuong.Nguyen@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.cerrcnt, NULL);
178910049SVuong.Nguyen@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNT_LAST,
179010049SVuong.Nguyen@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.cerrcnt_last, NULL);
179110049SVuong.Nguyen@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNT_EXT,
179210049SVuong.Nguyen@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.cerrcnt_ext, NULL);
179310049SVuong.Nguyen@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CERRCNT_EXT_LAST,
179410049SVuong.Nguyen@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.cerrcnt_ext_last, NULL);
179510049SVuong.Nguyen@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BADRAM,
179610049SVuong.Nguyen@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.badram, NULL);
179710049SVuong.Nguyen@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_BADCNT,
179810049SVuong.Nguyen@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.badcnt, NULL);
179910049SVuong.Nguyen@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_VALIDLOG,
180010049SVuong.Nguyen@Sun.COM DATA_TYPE_UINT32, nb_regs->nb.nf_mem_regs.validlog, NULL);
180110049SVuong.Nguyen@Sun.COM
180210049SVuong.Nguyen@Sun.COM if (sp->intel_error_list >= 0)
180310049SVuong.Nguyen@Sun.COM (void) snprintf(buf, sizeof (buf), "M%d", sp->intel_error_list);
180410049SVuong.Nguyen@Sun.COM else
180510049SVuong.Nguyen@Sun.COM (void) snprintf(buf, sizeof (buf), "Multiple or unknown error");
180610049SVuong.Nguyen@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_ERROR_NO,
180710049SVuong.Nguyen@Sun.COM DATA_TYPE_STRING, buf, NULL);
180810049SVuong.Nguyen@Sun.COM }
180910049SVuong.Nguyen@Sun.COM
181010049SVuong.Nguyen@Sun.COM static void
nb_dma_err_payload(const nb_regs_t * nb_regs,nvlist_t * payload)18117532SSean.Ye@Sun.COM nb_dma_err_payload(const nb_regs_t *nb_regs, nvlist_t *payload)
18127532SSean.Ye@Sun.COM {
18137532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_PCISTS,
18147532SSean.Ye@Sun.COM DATA_TYPE_UINT16, nb_regs->nb.dma_regs.pcists, NULL);
18157532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_PEXDEVSTS,
18167532SSean.Ye@Sun.COM DATA_TYPE_UINT16, nb_regs->nb.dma_regs.pexdevsts, NULL);
18177532SSean.Ye@Sun.COM }
18187532SSean.Ye@Sun.COM
18197532SSean.Ye@Sun.COM static void
nb_thr_err_payload(const nb_regs_t * nb_regs,nvlist_t * payload,nb_scatchpad_t * data)18207532SSean.Ye@Sun.COM nb_thr_err_payload(const nb_regs_t *nb_regs, nvlist_t *payload,
18217532SSean.Ye@Sun.COM nb_scatchpad_t *data)
18227532SSean.Ye@Sun.COM {
18237532SSean.Ye@Sun.COM char buf[32];
18247532SSean.Ye@Sun.COM
18257532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_FAT_THR,
18267532SSean.Ye@Sun.COM DATA_TYPE_UINT8, nb_regs->nb.thr_regs.ferr_fat_thr, NULL);
18277532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_FAT_THR,
18287532SSean.Ye@Sun.COM DATA_TYPE_UINT8, nb_regs->nb.thr_regs.nerr_fat_thr, NULL);
18297532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_NF_THR,
18307532SSean.Ye@Sun.COM DATA_TYPE_UINT8, nb_regs->nb.thr_regs.ferr_nf_thr, NULL);
18317532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_NF_THR,
18327532SSean.Ye@Sun.COM DATA_TYPE_UINT8, nb_regs->nb.thr_regs.nerr_nf_thr, NULL);
18337532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_CTSTS,
18347532SSean.Ye@Sun.COM DATA_TYPE_UINT8, nb_regs->nb.thr_regs.ctsts, NULL);
18357532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_THRTSTS,
18367532SSean.Ye@Sun.COM DATA_TYPE_UINT16, nb_regs->nb.thr_regs.thrtsts, NULL);
18377532SSean.Ye@Sun.COM if (data->intel_error_list >= 0) {
18387532SSean.Ye@Sun.COM (void) snprintf(buf, sizeof (buf), "TH%d",
18397532SSean.Ye@Sun.COM data->intel_error_list);
18407532SSean.Ye@Sun.COM } else {
18417532SSean.Ye@Sun.COM (void) snprintf(buf, sizeof (buf), "Multiple or unknown error");
18427532SSean.Ye@Sun.COM }
18437532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_ERROR_NO,
18447532SSean.Ye@Sun.COM DATA_TYPE_STRING, buf, NULL);
18457532SSean.Ye@Sun.COM }
18467532SSean.Ye@Sun.COM
18477532SSean.Ye@Sun.COM static void
nb_ereport_add_logout(nvlist_t * payload,const nb_logout_t * acl,nb_scatchpad_t * data)18487532SSean.Ye@Sun.COM nb_ereport_add_logout(nvlist_t *payload, const nb_logout_t *acl,
18497532SSean.Ye@Sun.COM nb_scatchpad_t *data)
18507532SSean.Ye@Sun.COM {
18517532SSean.Ye@Sun.COM const nb_regs_t *nb_regs = &acl->nb_regs;
18527532SSean.Ye@Sun.COM
18537532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_MC_TYPE,
18547532SSean.Ye@Sun.COM DATA_TYPE_STRING, acl->type, NULL);
18557532SSean.Ye@Sun.COM switch (nb_regs->flag) {
18567532SSean.Ye@Sun.COM case NB_REG_LOG_FSB:
18577532SSean.Ye@Sun.COM nb_fsb_err_payload(nb_regs, payload, data);
18587532SSean.Ye@Sun.COM break;
18597532SSean.Ye@Sun.COM case NB_REG_LOG_PEX:
18607532SSean.Ye@Sun.COM nb_pex_err_payload(nb_regs, payload, data);
18617532SSean.Ye@Sun.COM break;
18627532SSean.Ye@Sun.COM case NB_REG_LOG_INT:
18637532SSean.Ye@Sun.COM nb_int_err_payload(nb_regs, payload, data);
18647532SSean.Ye@Sun.COM break;
18657532SSean.Ye@Sun.COM case NB_REG_LOG_FAT_FBD:
18667532SSean.Ye@Sun.COM nb_fat_fbd_err_payload(nb_regs, payload, data);
18677532SSean.Ye@Sun.COM break;
18687532SSean.Ye@Sun.COM case NB_REG_LOG_NF_FBD:
18697532SSean.Ye@Sun.COM nb_nf_fbd_err_payload(nb_regs, payload, data);
18707532SSean.Ye@Sun.COM break;
18717532SSean.Ye@Sun.COM case NB_REG_LOG_DMA:
18727532SSean.Ye@Sun.COM nb_dma_err_payload(nb_regs, payload);
18737532SSean.Ye@Sun.COM break;
18747532SSean.Ye@Sun.COM case NB_REG_LOG_THR:
18757532SSean.Ye@Sun.COM nb_thr_err_payload(nb_regs, payload, data);
18767532SSean.Ye@Sun.COM break;
187710049SVuong.Nguyen@Sun.COM case NB_REG_LOG_NF_MEM:
187810049SVuong.Nguyen@Sun.COM nb_nf_mem_err_payload(nb_regs, payload, data);
187910049SVuong.Nguyen@Sun.COM break;
18807532SSean.Ye@Sun.COM default:
18817532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_FERR_GLOBAL,
18827532SSean.Ye@Sun.COM DATA_TYPE_UINT64, nb_regs->ferr, NULL);
18837532SSean.Ye@Sun.COM fm_payload_set(payload, FM_EREPORT_PAYLOAD_NAME_NERR_GLOBAL,
18847532SSean.Ye@Sun.COM DATA_TYPE_UINT32, nb_regs->nerr, NULL);
18857532SSean.Ye@Sun.COM break;
18867532SSean.Ye@Sun.COM }
18877532SSean.Ye@Sun.COM }
18887532SSean.Ye@Sun.COM
18897532SSean.Ye@Sun.COM void
nb_fsb_report(const nb_regs_t * nb_regs,char * class,nvlist_t * detector,nb_scatchpad_t * data)18907532SSean.Ye@Sun.COM nb_fsb_report(const nb_regs_t *nb_regs, char *class, nvlist_t *detector,
18917532SSean.Ye@Sun.COM nb_scatchpad_t *data)
18927532SSean.Ye@Sun.COM {
18937532SSean.Ye@Sun.COM int chip;
18947532SSean.Ye@Sun.COM
18957532SSean.Ye@Sun.COM if (nb_chipset == INTEL_NB_7300)
18967532SSean.Ye@Sun.COM chip = nb_regs->nb.fsb_regs.fsb * 2;
18977532SSean.Ye@Sun.COM else
18987532SSean.Ye@Sun.COM chip = nb_regs->nb.fsb_regs.fsb;
18997532SSean.Ye@Sun.COM fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 2,
19007532SSean.Ye@Sun.COM "motherboard", 0, "chip", chip);
19017532SSean.Ye@Sun.COM
19027532SSean.Ye@Sun.COM if (nb_regs->nb.fsb_regs.ferr_fat_fsb == 0 &&
19037532SSean.Ye@Sun.COM nb_regs->nb.fsb_regs.ferr_nf_fsb == 0) {
19047532SSean.Ye@Sun.COM data->intel_error_list = intel_fsb_err(nb_regs->nb.fsb_regs.fsb,
19057532SSean.Ye@Sun.COM nb_regs->nb.fsb_regs.nerr_fat_fsb,
19067532SSean.Ye@Sun.COM nb_regs->nb.fsb_regs.nerr_nf_fsb);
19077532SSean.Ye@Sun.COM } else {
19087532SSean.Ye@Sun.COM data->intel_error_list = intel_fsb_err(nb_regs->nb.fsb_regs.fsb,
19097532SSean.Ye@Sun.COM nb_regs->nb.fsb_regs.ferr_fat_fsb,
19107532SSean.Ye@Sun.COM nb_regs->nb.fsb_regs.ferr_nf_fsb);
19117532SSean.Ye@Sun.COM }
19127532SSean.Ye@Sun.COM (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s.%s",
19137532SSean.Ye@Sun.COM FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, "nb", "fsb");
19147532SSean.Ye@Sun.COM }
19157532SSean.Ye@Sun.COM
19167532SSean.Ye@Sun.COM void
nb_pex_report(const nb_regs_t * nb_regs,char * class,nvlist_t * detector,nb_scatchpad_t * data)19177532SSean.Ye@Sun.COM nb_pex_report(const nb_regs_t *nb_regs, char *class, nvlist_t *detector,
19187532SSean.Ye@Sun.COM nb_scatchpad_t *data)
19197532SSean.Ye@Sun.COM {
19207532SSean.Ye@Sun.COM int hostbridge;
19217532SSean.Ye@Sun.COM
19227532SSean.Ye@Sun.COM if (nb_regs->nb.pex_regs.pex == 0) {
19237532SSean.Ye@Sun.COM fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 1,
19247532SSean.Ye@Sun.COM "motherboard", 0);
19257532SSean.Ye@Sun.COM } else {
19267532SSean.Ye@Sun.COM hostbridge = nb_regs->nb.pex_regs.pex - 1;
19277532SSean.Ye@Sun.COM fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 2,
19287532SSean.Ye@Sun.COM "motherboard", 0,
19297532SSean.Ye@Sun.COM "hostbridge", hostbridge);
19307532SSean.Ye@Sun.COM }
19317532SSean.Ye@Sun.COM
19327532SSean.Ye@Sun.COM if (nb_regs->nb.pex_regs.pex_fat_ferr == 0 &&
19337532SSean.Ye@Sun.COM nb_regs->nb.pex_regs.pex_nf_corr_ferr == 0) {
19347532SSean.Ye@Sun.COM if (nb_chipset == INTEL_NB_5400) {
19357532SSean.Ye@Sun.COM data->intel_error_list =
19367532SSean.Ye@Sun.COM intel_pex_5400_err(
19377532SSean.Ye@Sun.COM nb_regs->nb.pex_regs.pex_fat_nerr,
19387532SSean.Ye@Sun.COM nb_regs->nb.pex_regs.pex_nf_corr_nerr);
19397532SSean.Ye@Sun.COM } else {
19407532SSean.Ye@Sun.COM data->intel_error_list =
19417532SSean.Ye@Sun.COM intel_pex_err(nb_regs->nb.pex_regs.pex_fat_nerr,
19427532SSean.Ye@Sun.COM nb_regs->nb.pex_regs.pex_nf_corr_nerr);
19437532SSean.Ye@Sun.COM }
19447532SSean.Ye@Sun.COM } else {
19457532SSean.Ye@Sun.COM if (nb_chipset == INTEL_NB_5400) {
19467532SSean.Ye@Sun.COM data->intel_error_list =
19477532SSean.Ye@Sun.COM intel_pex_5400_err(
19487532SSean.Ye@Sun.COM nb_regs->nb.pex_regs.pex_fat_ferr,
19497532SSean.Ye@Sun.COM nb_regs->nb.pex_regs.pex_nf_corr_ferr);
19507532SSean.Ye@Sun.COM } else {
19517532SSean.Ye@Sun.COM data->intel_error_list =
19527532SSean.Ye@Sun.COM intel_pex_err(nb_regs->nb.pex_regs.pex_fat_ferr,
19537532SSean.Ye@Sun.COM nb_regs->nb.pex_regs.pex_nf_corr_ferr);
19547532SSean.Ye@Sun.COM }
19557532SSean.Ye@Sun.COM }
19567532SSean.Ye@Sun.COM
19577532SSean.Ye@Sun.COM if (nb_regs->nb.pex_regs.pex == 0) {
19587532SSean.Ye@Sun.COM (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s.%s",
19597532SSean.Ye@Sun.COM FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, "nb", "esi");
19607532SSean.Ye@Sun.COM } else {
19617532SSean.Ye@Sun.COM (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s.%s",
19627532SSean.Ye@Sun.COM FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, "nb", "pex");
19637532SSean.Ye@Sun.COM }
19647532SSean.Ye@Sun.COM }
19657532SSean.Ye@Sun.COM
19667532SSean.Ye@Sun.COM void
nb_int_report(const nb_regs_t * nb_regs,char * class,nvlist_t * detector,void * data)19677532SSean.Ye@Sun.COM nb_int_report(const nb_regs_t *nb_regs, char *class, nvlist_t *detector,
19687532SSean.Ye@Sun.COM void *data)
19697532SSean.Ye@Sun.COM {
19707532SSean.Ye@Sun.COM fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 1,
19717532SSean.Ye@Sun.COM "motherboard", 0);
19727532SSean.Ye@Sun.COM
19737532SSean.Ye@Sun.COM if (nb_regs->nb.int_regs.ferr_fat_int == 0 &&
19747532SSean.Ye@Sun.COM nb_regs->nb.int_regs.ferr_nf_int == 0) {
19757532SSean.Ye@Sun.COM ((nb_scatchpad_t *)data)->intel_error_list =
19767532SSean.Ye@Sun.COM intel_int_err(nb_regs->nb.int_regs.nerr_fat_int,
19777532SSean.Ye@Sun.COM nb_regs->nb.int_regs.nerr_nf_int);
19787532SSean.Ye@Sun.COM } else {
19797532SSean.Ye@Sun.COM ((nb_scatchpad_t *)data)->intel_error_list =
19807532SSean.Ye@Sun.COM intel_int_err(nb_regs->nb.int_regs.ferr_fat_int,
19817532SSean.Ye@Sun.COM nb_regs->nb.int_regs.ferr_nf_int);
19827532SSean.Ye@Sun.COM }
19837532SSean.Ye@Sun.COM (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s.%s",
19847532SSean.Ye@Sun.COM FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, "nb", "ie");
19857532SSean.Ye@Sun.COM }
19867532SSean.Ye@Sun.COM
19877532SSean.Ye@Sun.COM void
nb_fat_fbd_report(const nb_regs_t * nb_regs,char * class,nvlist_t * detector,void * data)19887532SSean.Ye@Sun.COM nb_fat_fbd_report(const nb_regs_t *nb_regs, char *class, nvlist_t *detector,
19897532SSean.Ye@Sun.COM void *data)
19907532SSean.Ye@Sun.COM {
19917532SSean.Ye@Sun.COM char *intr;
19927532SSean.Ye@Sun.COM nb_mem_scatchpad_t *sp;
19937532SSean.Ye@Sun.COM
19947532SSean.Ye@Sun.COM intr = fat_memory_error(nb_regs, data);
19957532SSean.Ye@Sun.COM sp = &((nb_scatchpad_t *)data)->ms;
19967532SSean.Ye@Sun.COM
19977532SSean.Ye@Sun.COM if (sp->dimm != -1) {
19987532SSean.Ye@Sun.COM fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 5,
19997532SSean.Ye@Sun.COM "motherboard", 0,
20007532SSean.Ye@Sun.COM "memory-controller", sp->branch,
20017532SSean.Ye@Sun.COM "dram-channel", sp->channel,
20027532SSean.Ye@Sun.COM "dimm", sp->dimm,
20037532SSean.Ye@Sun.COM "rank", sp->rank);
20047532SSean.Ye@Sun.COM } else if (sp->channel != -1) {
20057532SSean.Ye@Sun.COM fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 3,
20067532SSean.Ye@Sun.COM "motherboard", 0,
20077532SSean.Ye@Sun.COM "memory-controller", sp->branch,
20087532SSean.Ye@Sun.COM "dram-channel", sp->channel);
20097532SSean.Ye@Sun.COM } else if (sp->branch != -1) {
20107532SSean.Ye@Sun.COM fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 2,
20117532SSean.Ye@Sun.COM "motherboard", 0,
20127532SSean.Ye@Sun.COM "memory-controller", sp->branch);
20137532SSean.Ye@Sun.COM } else {
20147532SSean.Ye@Sun.COM fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 1,
20157532SSean.Ye@Sun.COM "motherboard", 0);
20167532SSean.Ye@Sun.COM }
20177532SSean.Ye@Sun.COM
20187532SSean.Ye@Sun.COM (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s",
20197532SSean.Ye@Sun.COM FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, intr);
20207532SSean.Ye@Sun.COM }
20217532SSean.Ye@Sun.COM
20227532SSean.Ye@Sun.COM void
nb_nf_fbd_report(const nb_regs_t * nb_regs,char * class,nvlist_t * detector,void * data)20237532SSean.Ye@Sun.COM nb_nf_fbd_report(const nb_regs_t *nb_regs, char *class, nvlist_t *detector,
20247532SSean.Ye@Sun.COM void *data)
20257532SSean.Ye@Sun.COM {
20267532SSean.Ye@Sun.COM char *intr;
20277532SSean.Ye@Sun.COM nb_mem_scatchpad_t *sp;
20287532SSean.Ye@Sun.COM
20297532SSean.Ye@Sun.COM intr = nf_memory_error(nb_regs, data);
20307532SSean.Ye@Sun.COM sp = &((nb_scatchpad_t *)data)->ms;
20317532SSean.Ye@Sun.COM
20327532SSean.Ye@Sun.COM if (sp->dimm != -1) {
20337532SSean.Ye@Sun.COM fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 5,
20347532SSean.Ye@Sun.COM "motherboard", 0,
20357532SSean.Ye@Sun.COM "memory-controller", sp->branch,
20367532SSean.Ye@Sun.COM "dram-channel", sp->channel,
20377532SSean.Ye@Sun.COM "dimm", sp->dimm,
20387532SSean.Ye@Sun.COM "rank", sp->rank);
20397532SSean.Ye@Sun.COM } else if (sp->channel != -1) {
20407532SSean.Ye@Sun.COM fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 3,
20417532SSean.Ye@Sun.COM "motherboard", 0,
20427532SSean.Ye@Sun.COM "memory-controller", sp->branch,
20437532SSean.Ye@Sun.COM "dram-channel", sp->channel);
20447532SSean.Ye@Sun.COM } else if (sp->branch != -1) {
20457532SSean.Ye@Sun.COM fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 2,
20467532SSean.Ye@Sun.COM "motherboard", 0,
20477532SSean.Ye@Sun.COM "memory-controller", sp->branch);
20487532SSean.Ye@Sun.COM } else {
20497532SSean.Ye@Sun.COM fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 1,
20507532SSean.Ye@Sun.COM "motherboard", 0);
20517532SSean.Ye@Sun.COM }
20527532SSean.Ye@Sun.COM
20537532SSean.Ye@Sun.COM (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s",
20547532SSean.Ye@Sun.COM FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, intr);
20557532SSean.Ye@Sun.COM }
20567532SSean.Ye@Sun.COM
20577532SSean.Ye@Sun.COM void
nb_dma_report(char * class,nvlist_t * detector)20587532SSean.Ye@Sun.COM nb_dma_report(char *class, nvlist_t *detector)
20597532SSean.Ye@Sun.COM {
20607532SSean.Ye@Sun.COM fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 1,
20617532SSean.Ye@Sun.COM "motherboard", 0);
20627532SSean.Ye@Sun.COM
20637532SSean.Ye@Sun.COM (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s.%s",
20647532SSean.Ye@Sun.COM FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, "nb", "dma");
20657532SSean.Ye@Sun.COM }
20667532SSean.Ye@Sun.COM
20677532SSean.Ye@Sun.COM void
nb_thr_report(const nb_regs_t * nb_regs,char * class,nvlist_t * detector,void * data)20687532SSean.Ye@Sun.COM nb_thr_report(const nb_regs_t *nb_regs, char *class, nvlist_t *detector,
20697532SSean.Ye@Sun.COM void *data)
20707532SSean.Ye@Sun.COM {
20717532SSean.Ye@Sun.COM ((nb_scatchpad_t *)data)->intel_error_list =
20727532SSean.Ye@Sun.COM intel_thr_err(nb_regs->nb.thr_regs.ferr_fat_thr,
20737532SSean.Ye@Sun.COM nb_regs->nb.thr_regs.ferr_nf_thr);
20747532SSean.Ye@Sun.COM fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 1,
20757532SSean.Ye@Sun.COM "motherboard", 0);
20767532SSean.Ye@Sun.COM
20777532SSean.Ye@Sun.COM (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s.%s",
20787532SSean.Ye@Sun.COM FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, "nb", "otf");
20797532SSean.Ye@Sun.COM }
20807532SSean.Ye@Sun.COM
208110049SVuong.Nguyen@Sun.COM void
nb_nf_mem_report(const nb_regs_t * nb_regs,char * class,nvlist_t * detector,void * data)208210049SVuong.Nguyen@Sun.COM nb_nf_mem_report(const nb_regs_t *nb_regs, char *class, nvlist_t *detector,
208310049SVuong.Nguyen@Sun.COM void *data)
208410049SVuong.Nguyen@Sun.COM {
208510049SVuong.Nguyen@Sun.COM char *intr;
208610049SVuong.Nguyen@Sun.COM nb_mem_scatchpad_t *sp;
208710049SVuong.Nguyen@Sun.COM
208810049SVuong.Nguyen@Sun.COM intr = nf_mem_error(nb_regs, data);
208910049SVuong.Nguyen@Sun.COM sp = &((nb_scatchpad_t *)data)->ms;
209010049SVuong.Nguyen@Sun.COM
209110049SVuong.Nguyen@Sun.COM if (sp->dimm != -1) {
209210049SVuong.Nguyen@Sun.COM fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 5,
209310049SVuong.Nguyen@Sun.COM "motherboard", 0,
209410049SVuong.Nguyen@Sun.COM "memory-controller", sp->branch,
209510049SVuong.Nguyen@Sun.COM "dram-channel", sp->channel,
209610049SVuong.Nguyen@Sun.COM "dimm", sp->dimm,
209710049SVuong.Nguyen@Sun.COM "rank", sp->rank);
209810049SVuong.Nguyen@Sun.COM } else if (sp->channel != -1) {
209910049SVuong.Nguyen@Sun.COM fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 3,
210010049SVuong.Nguyen@Sun.COM "motherboard", 0,
210110049SVuong.Nguyen@Sun.COM "memory-controller", sp->branch,
210210049SVuong.Nguyen@Sun.COM "dram-channel", sp->channel);
210310049SVuong.Nguyen@Sun.COM } else if (sp->branch != -1) {
210410049SVuong.Nguyen@Sun.COM fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 2,
210510049SVuong.Nguyen@Sun.COM "motherboard", 0,
210610049SVuong.Nguyen@Sun.COM "memory-controller", sp->branch);
210710049SVuong.Nguyen@Sun.COM } else {
210810049SVuong.Nguyen@Sun.COM fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 1,
210910049SVuong.Nguyen@Sun.COM "motherboard", 0);
211010049SVuong.Nguyen@Sun.COM }
211110049SVuong.Nguyen@Sun.COM
211210049SVuong.Nguyen@Sun.COM (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s",
211310049SVuong.Nguyen@Sun.COM FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, intr);
211410049SVuong.Nguyen@Sun.COM }
211510049SVuong.Nguyen@Sun.COM
21167532SSean.Ye@Sun.COM
21177532SSean.Ye@Sun.COM nvlist_t *
nb_report(const nb_regs_t * nb_regs,char * class,nv_alloc_t * nva,void * scratch)21187532SSean.Ye@Sun.COM nb_report(const nb_regs_t *nb_regs, char *class, nv_alloc_t *nva, void *scratch)
21197532SSean.Ye@Sun.COM {
21207532SSean.Ye@Sun.COM nvlist_t *detector = fm_nvlist_create(nva);
21217532SSean.Ye@Sun.COM
21227532SSean.Ye@Sun.COM switch (nb_regs->flag) {
21237532SSean.Ye@Sun.COM case NB_REG_LOG_FSB:
21247532SSean.Ye@Sun.COM nb_fsb_report(nb_regs, class, detector, scratch);
21257532SSean.Ye@Sun.COM break;
21267532SSean.Ye@Sun.COM case NB_REG_LOG_PEX:
21277532SSean.Ye@Sun.COM nb_pex_report(nb_regs, class, detector, scratch);
21287532SSean.Ye@Sun.COM break;
21297532SSean.Ye@Sun.COM case NB_REG_LOG_INT:
21307532SSean.Ye@Sun.COM nb_int_report(nb_regs, class, detector, scratch);
21317532SSean.Ye@Sun.COM break;
21327532SSean.Ye@Sun.COM case NB_REG_LOG_FAT_FBD:
21337532SSean.Ye@Sun.COM nb_fat_fbd_report(nb_regs, class, detector, scratch);
21347532SSean.Ye@Sun.COM break;
21357532SSean.Ye@Sun.COM case NB_REG_LOG_NF_FBD:
21367532SSean.Ye@Sun.COM nb_nf_fbd_report(nb_regs, class, detector, scratch);
21377532SSean.Ye@Sun.COM break;
21387532SSean.Ye@Sun.COM case NB_REG_LOG_DMA:
21397532SSean.Ye@Sun.COM nb_dma_report(class, detector);
21407532SSean.Ye@Sun.COM break;
21417532SSean.Ye@Sun.COM case NB_REG_LOG_THR:
21427532SSean.Ye@Sun.COM nb_thr_report(nb_regs, class, detector, scratch);
21437532SSean.Ye@Sun.COM break;
214410049SVuong.Nguyen@Sun.COM case NB_REG_LOG_NF_MEM:
214510049SVuong.Nguyen@Sun.COM nb_nf_mem_report(nb_regs, class, detector, scratch);
214610049SVuong.Nguyen@Sun.COM break;
21477532SSean.Ye@Sun.COM default:
21487532SSean.Ye@Sun.COM fm_fmri_hc_set(detector, FM_HC_SCHEME_VERSION, NULL, NULL, 1,
21497532SSean.Ye@Sun.COM "motherboard", 0);
21507532SSean.Ye@Sun.COM
21517532SSean.Ye@Sun.COM (void) snprintf(class, FM_MAX_CLASS, "%s.%s.%s.%s",
21527532SSean.Ye@Sun.COM FM_ERROR_CPU, FM_EREPORT_CPU_INTEL, "nb", "unknown");
21537532SSean.Ye@Sun.COM }
21547532SSean.Ye@Sun.COM return (detector);
21557532SSean.Ye@Sun.COM }
21567532SSean.Ye@Sun.COM
21577532SSean.Ye@Sun.COM /*ARGSUSED*/
21587532SSean.Ye@Sun.COM void
nb_drain(void * ignored,const void * data,const errorq_elem_t * eqe)21597532SSean.Ye@Sun.COM nb_drain(void *ignored, const void *data, const errorq_elem_t *eqe)
21607532SSean.Ye@Sun.COM {
21617532SSean.Ye@Sun.COM nb_logout_t *acl = (nb_logout_t *)data;
21627532SSean.Ye@Sun.COM errorq_elem_t *eqep, *scr_eqep;
21637532SSean.Ye@Sun.COM nvlist_t *ereport, *detector;
21647532SSean.Ye@Sun.COM nv_alloc_t *nva = NULL;
21657532SSean.Ye@Sun.COM char buf[FM_MAX_CLASS];
21667532SSean.Ye@Sun.COM nb_scatchpad_t nb_scatchpad;
21677532SSean.Ye@Sun.COM
21687532SSean.Ye@Sun.COM if (panicstr) {
21697532SSean.Ye@Sun.COM if ((eqep = errorq_reserve(ereport_errorq)) == NULL)
21707532SSean.Ye@Sun.COM return;
21717532SSean.Ye@Sun.COM ereport = errorq_elem_nvl(ereport_errorq, eqep);
21727532SSean.Ye@Sun.COM /*
21737532SSean.Ye@Sun.COM * Now try to allocate another element for scratch space and
21747532SSean.Ye@Sun.COM * use that for further scratch space (eg for constructing
21757532SSean.Ye@Sun.COM * nvlists to add the main ereport). If we can't reserve
21767532SSean.Ye@Sun.COM * a scratch element just fallback to working within the
21777532SSean.Ye@Sun.COM * element we already have, and hope for the best. All this
21787532SSean.Ye@Sun.COM * is necessary because the fixed buffer nv allocator does
21797532SSean.Ye@Sun.COM * not reclaim freed space and nvlist construction is
21807532SSean.Ye@Sun.COM * expensive.
21817532SSean.Ye@Sun.COM */
21827532SSean.Ye@Sun.COM if ((scr_eqep = errorq_reserve(ereport_errorq)) != NULL)
21837532SSean.Ye@Sun.COM nva = errorq_elem_nva(ereport_errorq, scr_eqep);
21847532SSean.Ye@Sun.COM else
21857532SSean.Ye@Sun.COM nva = errorq_elem_nva(ereport_errorq, eqep);
21867532SSean.Ye@Sun.COM } else {
21877532SSean.Ye@Sun.COM ereport = fm_nvlist_create(NULL);
21887532SSean.Ye@Sun.COM }
21897532SSean.Ye@Sun.COM detector = nb_report(&acl->nb_regs, buf, nva, &nb_scatchpad);
21907532SSean.Ye@Sun.COM if (detector == NULL)
21917532SSean.Ye@Sun.COM return;
21927532SSean.Ye@Sun.COM fm_ereport_set(ereport, FM_EREPORT_VERSION, buf,
21937532SSean.Ye@Sun.COM fm_ena_generate(acl->acl_timestamp, FM_ENA_FMT1), detector, NULL);
21947532SSean.Ye@Sun.COM /*
21957532SSean.Ye@Sun.COM * We're done with 'detector' so reclaim the scratch space.
21967532SSean.Ye@Sun.COM */
21977532SSean.Ye@Sun.COM if (panicstr) {
21987532SSean.Ye@Sun.COM fm_nvlist_destroy(detector, FM_NVA_RETAIN);
21997532SSean.Ye@Sun.COM nv_alloc_reset(nva);
22007532SSean.Ye@Sun.COM } else {
22017532SSean.Ye@Sun.COM fm_nvlist_destroy(detector, FM_NVA_FREE);
22027532SSean.Ye@Sun.COM }
22037532SSean.Ye@Sun.COM
22047532SSean.Ye@Sun.COM /*
22057532SSean.Ye@Sun.COM * Encode the error-specific data that was saved in the logout area.
22067532SSean.Ye@Sun.COM */
22077532SSean.Ye@Sun.COM nb_ereport_add_logout(ereport, acl, &nb_scatchpad);
22087532SSean.Ye@Sun.COM
22097532SSean.Ye@Sun.COM if (panicstr) {
22107532SSean.Ye@Sun.COM errorq_commit(ereport_errorq, eqep, ERRORQ_SYNC);
22117532SSean.Ye@Sun.COM if (scr_eqep)
22127532SSean.Ye@Sun.COM errorq_cancel(ereport_errorq, scr_eqep);
22137532SSean.Ye@Sun.COM } else {
22147532SSean.Ye@Sun.COM (void) fm_ereport_post(ereport, EVCH_TRYHARD);
22157532SSean.Ye@Sun.COM fm_nvlist_destroy(ereport, FM_NVA_FREE);
22167532SSean.Ye@Sun.COM }
22177532SSean.Ye@Sun.COM }
2218