xref: /onnv-gate/usr/src/cmd/fm/modules/sun4/cpumem-diagnosis/cmd_main.c (revision 12731:89d0ecf088f0)
1600Stsien /*
2600Stsien  * CDDL HEADER START
3600Stsien  *
4600Stsien  * The contents of this file are subject to the terms of the
51717Swesolows  * Common Development and Distribution License (the "License").
61717Swesolows  * You may not use this file except in compliance with the License.
7600Stsien  *
8600Stsien  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9600Stsien  * or http://www.opensolaris.org/os/licensing.
10600Stsien  * See the License for the specific language governing permissions
11600Stsien  * and limitations under the License.
12600Stsien  *
13600Stsien  * When distributing Covered Code, include this CDDL HEADER in each
14600Stsien  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15600Stsien  * If applicable, add the following below this CDDL HEADER, with the
16600Stsien  * fields enclosed by brackets "[]" replaced with your own identifying
17600Stsien  * information: Portions Copyright [yyyy] [name of copyright owner]
18600Stsien  *
19600Stsien  * CDDL HEADER END
20600Stsien  */
21600Stsien /*
2212467STrang.Do@Sun.COM  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
23600Stsien  */
24600Stsien 
25600Stsien /*
265037Sjl139090  * CPU/Memory error diagnosis engine for the UltraSPARC III, IV, T1,
275037Sjl139090  * SPARC64 VI and SPARC64 VII families of processors.
28600Stsien  */
29600Stsien 
30600Stsien #include <cmd_state.h>
31600Stsien #include <cmd_cpu.h>
32962Stsien 
33962Stsien #ifdef sun4u
34600Stsien #include <cmd_ecache.h>
356330Sjc25722 #include <cmd_Lxcache.h>
36962Stsien #endif /* sun4u */
37962Stsien 
38600Stsien #include <cmd_mem.h>
39600Stsien #include <cmd_page.h>
40600Stsien #include <cmd_dimm.h>
411186Sayznaga #ifdef sun4u
421186Sayznaga #include <cmd_dp.h>
431772Sjl139090 #include <cmd_opl.h>
441186Sayznaga #endif
45600Stsien #include <cmd_bank.h>
46600Stsien #include <cmd.h>
47600Stsien 
48600Stsien #include <errno.h>
49600Stsien #include <string.h>
50600Stsien #include <unistd.h>
51600Stsien #include <strings.h>
52600Stsien #include <fm/fmd_api.h>
534934Stsien #include <fm/libtopo.h>
54600Stsien #include <sys/fm/protocol.h>
55600Stsien #include <sys/async.h>
56600Stsien 
572072Svn83148 #ifdef	sun4v
582072Svn83148 #include <sys/fm/ldom.h>
592072Svn83148 static fmd_hdl_t *init_hdl;
602072Svn83148 ldom_hdl_t *cpumem_diagnosis_lhp;
612072Svn83148 #endif
622072Svn83148 
63600Stsien cmd_t cmd;
64600Stsien 
651794Sav145390 #ifdef sun4u
661794Sav145390 cmd_list_t opl_cpu_list;
671794Sav145390 #endif	/* sun4u */
681794Sav145390 
69600Stsien typedef struct cmd_subscriber {
70600Stsien 	const char *subr_class;
71600Stsien 	cmd_evdisp_t (*subr_func)(fmd_hdl_t *, fmd_event_t *, nvlist_t *,
72600Stsien 	    const char *, cmd_errcl_t);
73600Stsien 	cmd_errcl_t subr_arg;
74600Stsien 	cmd_evdisp_stat_t subr_stat;
75600Stsien } cmd_subscriber_t;
76600Stsien 
77730Sdb35262 /*ARGSUSED*/
78730Sdb35262 cmd_evdisp_t
cmd_nop(fmd_hdl_t * hdl,fmd_event_t * ep,nvlist_t * nvl,const char * class,cmd_errcl_t clcode)79730Sdb35262 cmd_nop(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class,
80730Sdb35262     cmd_errcl_t clcode)
81730Sdb35262 {
82730Sdb35262 	return (CMD_EVD_UNUSED);
83730Sdb35262 }
84730Sdb35262 
8511786SLouis.Tsien@Sun.COM #ifdef sun4u
8611786SLouis.Tsien@Sun.COM /*
8711786SLouis.Tsien@Sun.COM  * It used to be that cmd_opluecpu_detio() was called directly, with a
8811786SLouis.Tsien@Sun.COM  * 'class' argument of ereport.io.oberon.xxx.  But the code underlying
8911786SLouis.Tsien@Sun.COM  * cmd_opluecpu_detio() assumed that the class would always be of the form
9011786SLouis.Tsien@Sun.COM  * ereport.cpu.<cputype>.<subclass>.
9111786SLouis.Tsien@Sun.COM  *
9211786SLouis.Tsien@Sun.COM  * Rather than generalizing the underlying code, the following adjusts the
9311786SLouis.Tsien@Sun.COM  * input to cmd_opluecpu_detio() so that it conforms to the above expectation.
9411786SLouis.Tsien@Sun.COM  */
9511786SLouis.Tsien@Sun.COM 
9611786SLouis.Tsien@Sun.COM /*ARGSUSED*/
9711786SLouis.Tsien@Sun.COM cmd_evdisp_t
opl_opluecpu_detio(fmd_hdl_t * hdl,fmd_event_t * ep,nvlist_t * nvl,const char * class,cmd_errcl_t clcode)9811786SLouis.Tsien@Sun.COM opl_opluecpu_detio(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl,
9911786SLouis.Tsien@Sun.COM     const char *class, cmd_errcl_t clcode)
10011786SLouis.Tsien@Sun.COM {
10111786SLouis.Tsien@Sun.COM 	return (cmd_opluecpu_detio(hdl, ep, nvl,
10211786SLouis.Tsien@Sun.COM 	    "ereport.cpu.SPARC64-VI.", clcode));
10311786SLouis.Tsien@Sun.COM }
10411786SLouis.Tsien@Sun.COM #endif	/* sun4u */
10511786SLouis.Tsien@Sun.COM 
106600Stsien static cmd_subscriber_t cmd_subscribers[] = {
107962Stsien #ifdef sun4u
1082400Stsien 	{ "ereport.cpu.*.ucc", 		cmd_xxc,	CMD_ERRCL_UCC |
1092400Stsien     CMD_CPU_LEVEL_CORE },
1102400Stsien 	{ "ereport.cpu.*.ucu",		cmd_xxu,	CMD_ERRCL_UCU |
1112400Stsien     CMD_CPU_LEVEL_CORE },
1122400Stsien 	{ "ereport.cpu.*.cpc",		cmd_xxc,	CMD_ERRCL_CPC |
1132400Stsien     CMD_CPU_LEVEL_CORE },
1142400Stsien 	{ "ereport.cpu.*.cpu",		cmd_xxu,	CMD_ERRCL_CPU |
1152400Stsien     CMD_CPU_LEVEL_CORE },
1162400Stsien 	{ "ereport.cpu.*.wdc",		cmd_xxc,	CMD_ERRCL_WDC |
1172400Stsien     CMD_CPU_LEVEL_CORE },
1182400Stsien 	{ "ereport.cpu.*.wdu",		cmd_xxu,	CMD_ERRCL_WDU |
1192400Stsien     CMD_CPU_LEVEL_CORE },
1202400Stsien 	{ "ereport.cpu.*.edc",		cmd_xxc,	CMD_ERRCL_EDC |
1212400Stsien     CMD_CPU_LEVEL_CORE },
1222400Stsien 	{ "ereport.cpu.*.edu-st",	cmd_xxu,	CMD_ERRCL_EDU_ST |
1232400Stsien     CMD_CPU_LEVEL_CORE },
1242400Stsien 	{ "ereport.cpu.*.edu-bl",	cmd_xxu,	CMD_ERRCL_EDU_BL |
1252400Stsien     CMD_CPU_LEVEL_CORE },
1262400Stsien 	{ "ereport.cpu.*.l3-ucc", 	cmd_xxc,	CMD_ERRCL_L3_UCC |
1272400Stsien     CMD_CPU_LEVEL_CORE },
1282400Stsien 	{ "ereport.cpu.*.l3-ucu",	cmd_xxu,	CMD_ERRCL_L3_UCU |
1292400Stsien     CMD_CPU_LEVEL_CORE },
1302400Stsien 	{ "ereport.cpu.*.l3-cpc",	cmd_xxc,	CMD_ERRCL_L3_CPC |
1312400Stsien     CMD_CPU_LEVEL_CORE },
1322400Stsien 	{ "ereport.cpu.*.l3-cpu",	cmd_xxu,	CMD_ERRCL_L3_CPU |
1332400Stsien     CMD_CPU_LEVEL_CORE },
1342400Stsien 	{ "ereport.cpu.*.l3-wdc",	cmd_xxc,	CMD_ERRCL_L3_WDC |
1352400Stsien     CMD_CPU_LEVEL_CORE },
1362400Stsien 	{ "ereport.cpu.*.l3-wdu",	cmd_xxu,	CMD_ERRCL_L3_WDU |
1372400Stsien     CMD_CPU_LEVEL_CORE },
1382400Stsien 	{ "ereport.cpu.*.l3-edc",	cmd_xxc,	CMD_ERRCL_L3_EDC |
1392400Stsien     CMD_CPU_LEVEL_CORE },
1402400Stsien 	{ "ereport.cpu.*.l3-edu-st",	cmd_xxu,	CMD_ERRCL_L3_EDU_ST |
1412400Stsien     CMD_CPU_LEVEL_CORE },
1422400Stsien 	{ "ereport.cpu.*.l3-edu-bl",	cmd_xxu,	CMD_ERRCL_L3_EDU_BL |
1432400Stsien     CMD_CPU_LEVEL_CORE },
1442400Stsien 	{ "ereport.cpu.*.l3-mecc",	cmd_xxu,	CMD_ERRCL_L3_MECC |
1452400Stsien     CMD_CPU_LEVEL_CORE },
146600Stsien 	{ "ereport.cpu.*.ipe",		cmd_icache },
147600Stsien 	{ "ereport.cpu.*.idspe",	cmd_icache },
148600Stsien 	{ "ereport.cpu.*.itspe",	cmd_icache },
149600Stsien 	{ "ereport.cpu.*.dpe",		cmd_dcache },
150600Stsien 	{ "ereport.cpu.*.ddspe",	cmd_dcache },
151600Stsien 	{ "ereport.cpu.*.dtspe",	cmd_dcache },
152600Stsien 	{ "ereport.cpu.*.pdspe",	cmd_pcache },
153600Stsien 	{ "ereport.cpu.*.itlbpe",	cmd_itlb },
154600Stsien 	{ "ereport.cpu.*.dtlbpe",	cmd_dtlb },
1556330Sjc25722 	{ "ereport.cpu.*.thce",		cmd_txce, CMD_CPU_LEVEL_CORE },
156600Stsien 	{ "ereport.cpu.*.tsce",		cmd_txce },
1576330Sjc25722 	{ "ereport.cpu.*.l3-thce",	cmd_l3_thce, CMD_CPU_LEVEL_CORE },
158600Stsien 	{ "ereport.cpu.*.ce",		cmd_ce },
159600Stsien 	{ "ereport.cpu.*.emc",		cmd_ce },
160600Stsien 	{ "ereport.cpu.*.ue",		cmd_ue },
161600Stsien 	{ "ereport.cpu.*.due",		cmd_ue },
162600Stsien 	{ "ereport.cpu.*.emu",		cmd_ue },
163600Stsien 	{ "ereport.cpu.*.frc",		cmd_frx,	CMD_ERRCL_FRC },
164600Stsien 	{ "ereport.cpu.*.rce",		cmd_rxe,	CMD_ERRCL_RCE },
165600Stsien 	{ "ereport.cpu.*.fru",		cmd_frx,	CMD_ERRCL_FRU },
166600Stsien 	{ "ereport.cpu.*.rue",		cmd_rxe,	CMD_ERRCL_RUE },
167600Stsien 	{ "ereport.cpu.*.eti",		cmd_txce },
168600Stsien 	{ "ereport.cpu.*.etc",		cmd_txce },
169600Stsien 	{ "ereport.io.*.ecc.drce",	cmd_ioxe,	CMD_ERRCL_IOCE },
170600Stsien 	{ "ereport.io.*.ecc.dwce",	cmd_ioxe,	CMD_ERRCL_IOCE },
171600Stsien 	{ "ereport.io.*.ecc.drue",	cmd_ioxe,	CMD_ERRCL_IOUE },
172600Stsien 	{ "ereport.io.*.ecc.dwue",	cmd_ioxe,	CMD_ERRCL_IOUE },
173600Stsien 	{ "ereport.io.*.ecc.s-drce",	cmd_ioxe_sec },
174600Stsien 	{ "ereport.io.*.ecc.s-dwce",	cmd_ioxe_sec },
175600Stsien 	{ "ereport.io.*.ecc.s-drue",	cmd_ioxe_sec },
176600Stsien 	{ "ereport.io.*.ecc.s-dwue",	cmd_ioxe_sec },
1772260Sjc25722 	{ "ereport.io.fire.jbc.ce_asyn", cmd_ioxe,	CMD_ERRCL_IOCE },
1782260Sjc25722 	{ "ereport.io.fire.jbc.ue_asyn", cmd_ioxe,	CMD_ERRCL_IOUE },
1791186Sayznaga 	{ "ereport.asic.*.cds.cds-dp", 	cmd_dp_cds },
1801186Sayznaga 	{ "ereport.asic.*.dx.dx-dp",	cmd_dp_dx },
1811186Sayznaga 	{ "ereport.asic.*.sdi.sdi-dp", 	cmd_dp_ex },
1821186Sayznaga 	{ "ereport.asic.*.cp.cp-dp", 	cmd_dp_cp },
1831186Sayznaga 	{ "ereport.asic.*.rp.rp-dp", 	cmd_dp_cp },
1841794Sav145390 	{ "ereport.asic.mac.mi-ue",			cmd_opl_mac_common },
1851794Sav145390 	{ "ereport.asic.mac.ptrl-ue",			cmd_opl_mac_common },
1861794Sav145390 	{ "ereport.asic.mac.mi-ce",			cmd_opl_mac_common },
1871794Sav145390 	{ "ereport.asic.mac.ptrl-ce",			cmd_opl_mac_common },
1885275Stsien 	{ "ereport.asic.mac.ptrl-ice",			cmd_opl_mac_common },
1891794Sav145390 	{ "ereport.asic.mac.mi-cmpe",			cmd_opl_mac_common },
1901794Sav145390 	{ "ereport.asic.mac.ptrl-cmpe",			cmd_opl_mac_common },
1911794Sav145390 	{ "ereport.asic.mac.mi-sue",			cmd_opl_mac_common },
1921794Sav145390 	{ "ereport.asic.mac.ptrl-sue",			cmd_opl_mac_common },
1931794Sav145390 	{ "ereport.asic.mac.mi-mue",			cmd_opl_mac_common },
1941794Sav145390 	{ "ereport.asic.mac.ptrl-mue",			cmd_opl_mac_common },
1951794Sav145390 	{ "ereport.cpu.*.ue-mem",			cmd_opl_cpu_mem },
1961772Sjl139090 	{ "ereport.cpu.*.ue-channel",			cmd_nop },
1971794Sav145390 	{ "ereport.cpu.*.ue-cpu",			cmd_opluecpu_detcpu },
1981772Sjl139090 	{ "ereport.cpu.*.ue-path",			cmd_nop },
1991794Sav145390 	{ "ereport.cpu.*.inv-sfsr",			cmd_oplinv_sfsr },
2001772Sjl139090 	{ "ereport.cpu.*.berr",				cmd_nop },
2011772Sjl139090 	{ "ereport.cpu.*.bto",				cmd_nop },
2021794Sav145390 	{ "ereport.cpu.*.mtlb",				cmd_oplmtlb },
2031794Sav145390 	{ "ereport.cpu.*.tlbp",				cmd_opltlbp },
2045037Sjl139090 	{ "ereport.cpu.*.inv-uge",			cmd_oplinv_urg },
2051772Sjl139090 	{ "ereport.cpu.*.cre",				cmd_oplcre },
2061772Sjl139090 	{ "ereport.cpu.*.tsb-ctx",			cmd_opltsb_ctx },
2071772Sjl139090 	{ "ereport.cpu.*.tsbp",				cmd_opltsbp },
2081772Sjl139090 	{ "ereport.cpu.*.pstate",			cmd_oplpstate },
2091772Sjl139090 	{ "ereport.cpu.*.tstate",			cmd_opltstate },
2101772Sjl139090 	{ "ereport.cpu.*.iug-f",			cmd_opliug_f },
2111772Sjl139090 	{ "ereport.cpu.*.iug-r",			cmd_opliug_r },
2121772Sjl139090 	{ "ereport.cpu.*.sdc",				cmd_oplsdc },
2131772Sjl139090 	{ "ereport.cpu.*.wdt",				cmd_oplwdt },
2141772Sjl139090 	{ "ereport.cpu.*.dtlb",				cmd_opldtlb },
2151772Sjl139090 	{ "ereport.cpu.*.itlb",				cmd_oplitlb },
2161772Sjl139090 	{ "ereport.cpu.*.core-err",			cmd_oplcore_err },
2171772Sjl139090 	{ "ereport.cpu.*.dae",				cmd_opldae },
2181772Sjl139090 	{ "ereport.cpu.*.iae",				cmd_opliae },
2191772Sjl139090 	{ "ereport.cpu.*.uge",				cmd_opluge },
2201794Sav145390 	{ "ereport.io.oberon.ubc.dmarduea-mem",		cmd_opl_io_mem },
2211772Sjl139090 	{ "ereport.io.oberon.ubc.dmarduea-channel",	cmd_nop },
22211786SLouis.Tsien@Sun.COM 	{ "ereport.io.oberon.ubc.dmarduea-cpu",		opl_opluecpu_detio },
2231772Sjl139090 	{ "ereport.io.oberon.ubc.dmarduea-path",	cmd_nop },
2241794Sav145390 	{ "ereport.io.oberon.ubc.dmardueb-mem",		cmd_opl_io_mem },
2251772Sjl139090 	{ "ereport.io.oberon.ubc.dmardueb-channel",	cmd_nop },
22611786SLouis.Tsien@Sun.COM 	{ "ereport.io.oberon.ubc.dmardueb-cpu",		opl_opluecpu_detio },
2271772Sjl139090 	{ "ereport.io.oberon.ubc.dmardueb-path",	cmd_nop },
2281794Sav145390 	{ "ereport.io.oberon.ubc.piowtue-mem",		cmd_opl_io_mem },
2291772Sjl139090 	{ "ereport.io.oberon.ubc.piowtue-channel",	cmd_nop },
23011786SLouis.Tsien@Sun.COM 	{ "ereport.io.oberon.ubc.piowtue-cpu",		opl_opluecpu_detio },
2311772Sjl139090 	{ "ereport.io.oberon.ubc.piowtue-path",		cmd_nop },
2321794Sav145390 	{ "ereport.io.oberon.ubc.piowbeue-mem",		cmd_opl_io_mem },
2331772Sjl139090 	{ "ereport.io.oberon.ubc.piowbeue-channel",	cmd_nop },
23411786SLouis.Tsien@Sun.COM 	{ "ereport.io.oberon.ubc.piowbeue-cpu",		opl_opluecpu_detio },
2351772Sjl139090 	{ "ereport.io.oberon.ubc.piowbeue-path",	cmd_nop },
2361794Sav145390 	{ "ereport.io.oberon.ubc.piorbeue-mem",		cmd_opl_io_mem },
2371772Sjl139090 	{ "ereport.io.oberon.ubc.piorbeue-channel",	cmd_nop },
23811786SLouis.Tsien@Sun.COM 	{ "ereport.io.oberon.ubc.piorbeue-cpu",		opl_opluecpu_detio },
2391772Sjl139090 	{ "ereport.io.oberon.ubc.piorbeue-path",	cmd_nop },
2406429Svs195195 	{ "ereport.cpu.*.fpu.fpscrub",	cmd_fps },
241962Stsien #else /* i.e. sun4v */
242962Stsien 	{ "ereport.cpu.*.irc",		cmd_irc },
243962Stsien 	{ "ereport.cpu.*.iru", 		cmd_iru },
244962Stsien 	{ "ereport.cpu.*.frc",		cmd_frc },
245962Stsien 	{ "ereport.cpu.*.fru",		cmd_fru },
246962Stsien 	{ "ereport.cpu.*.mau",		cmd_mau },
2472400Stsien 	{ "ereport.cpu.*.imdu",		cmd_itlb,	CMD_CPU_LEVEL_CORE },
2482400Stsien 	{ "ereport.cpu.*.dmdu",		cmd_dtlb,	CMD_CPU_LEVEL_CORE },
2492400Stsien 	{ "ereport.cpu.*.dmsu",		cmd_dtlb,	CMD_CPU_LEVEL_CORE },
2502400Stsien 	{ "ereport.cpu.*.imtu",		cmd_itlb,	CMD_CPU_LEVEL_CORE },
2512400Stsien 	{ "ereport.cpu.*.dmtu",		cmd_dtlb,	CMD_CPU_LEVEL_CORE },
2522400Stsien 	{ "ereport.cpu.*.itc",		cmd_icache,	CMD_CPU_LEVEL_CORE },
2532400Stsien 	{ "ereport.cpu.*.idc",		cmd_icache,	CMD_CPU_LEVEL_CORE },
2542400Stsien 	{ "ereport.cpu.*.dtc",		cmd_dcache,	CMD_CPU_LEVEL_CORE },
2552400Stsien 	{ "ereport.cpu.*.ddc",		cmd_dcache,	CMD_CPU_LEVEL_CORE },
2563325Ssd77468 	{ "ereport.cpu.*.irfc",		cmd_irc },
2573325Ssd77468 	{ "ereport.cpu.*.irfu",		cmd_iru },
2583325Ssd77468 	{ "ereport.cpu.*.frfc",		cmd_frc },
2593325Ssd77468 	{ "ereport.cpu.*.frfu",		cmd_fru },
2603325Ssd77468 
2613325Ssd77468 
2623325Ssd77468 
2633325Ssd77468 
2643325Ssd77468 
2653325Ssd77468 	{ "ereport.cpu.*.mamu",		cmd_mau,	CMD_CPU_LEVEL_CORE },
2663325Ssd77468 	{ "ereport.cpu.*.ittm",		cmd_itlb,	CMD_CPU_LEVEL_CORE },
2673325Ssd77468 	{ "ereport.cpu.*.ittp",		cmd_itlb,	CMD_CPU_LEVEL_CORE },
2683325Ssd77468 	{ "ereport.cpu.*.itdp",		cmd_itlb,	CMD_CPU_LEVEL_CORE },
2693325Ssd77468 	{ "ereport.cpu.*.itmu",		cmd_itlb,	CMD_CPU_LEVEL_CORE },
2703325Ssd77468 	{ "ereport.cpu.*.dttm",		cmd_dtlb,	CMD_CPU_LEVEL_CORE },
2713325Ssd77468 	{ "ereport.cpu.*.dttp",		cmd_dtlb,	CMD_CPU_LEVEL_CORE },
2723325Ssd77468 	{ "ereport.cpu.*.dtdp",		cmd_dtlb,	CMD_CPU_LEVEL_CORE },
2733325Ssd77468 	{ "ereport.cpu.*.dtmu",		cmd_dtlb,	CMD_CPU_LEVEL_CORE },
2743325Ssd77468 	{ "ereport.cpu.*.icvp",		cmd_icache,	CMD_CPU_LEVEL_CORE },
2753325Ssd77468 	{ "ereport.cpu.*.ictp",		cmd_icache,	CMD_CPU_LEVEL_CORE },
2763325Ssd77468 	{ "ereport.cpu.*.ictm",		cmd_icache,	CMD_CPU_LEVEL_CORE },
2776369Std122701 	{ "ereport.cpu.*.icdp",		cmd_xxc,
2786369Std122701 	    CMD_ERRCL_ICDP | CMD_CPU_LEVEL_CORE },
2793325Ssd77468 	{ "ereport.cpu.*.dcvp",		cmd_dcache,	CMD_CPU_LEVEL_CORE },
2803325Ssd77468 	{ "ereport.cpu.*.dctp",		cmd_dcache,	CMD_CPU_LEVEL_CORE },
2813325Ssd77468 	{ "ereport.cpu.*.dctm",		cmd_dcache,	CMD_CPU_LEVEL_CORE },
2826369Std122701 	{ "ereport.cpu.*.dcdp",		cmd_xxc,
2836369Std122701 	    CMD_ERRCL_DCDP | CMD_CPU_LEVEL_CORE },
2843325Ssd77468 	{ "ereport.cpu.*.itl2c",	cmd_xxc,	CMD_ERRCL_LDAC |
2853325Ssd77468 		CMD_CPU_LEVEL_CHIP },
2863325Ssd77468 	{ "ereport.cpu.*.dtl2c",	cmd_xxc,	CMD_ERRCL_LDAC |
2873325Ssd77468 		CMD_CPU_LEVEL_CHIP },
2883325Ssd77468 	{ "ereport.cpu.*.icl2c",	cmd_xxc,	CMD_ERRCL_LDAC |
2893325Ssd77468 		CMD_CPU_LEVEL_CHIP },
2903325Ssd77468 	{ "ereport.cpu.*.dcl2c",	cmd_xxc,	CMD_ERRCL_LDAC |
2913325Ssd77468 		CMD_CPU_LEVEL_CHIP },
2923325Ssd77468 	{ "ereport.cpu.*.mal2c",	cmd_xxc,	CMD_ERRCL_LDAC |
2933325Ssd77468 		CMD_CPU_LEVEL_CHIP },
2943325Ssd77468 	{ "ereport.cpu.*.cwql2c",	cmd_xxc,	CMD_ERRCL_LDAC |
2953325Ssd77468 		CMD_CPU_LEVEL_CHIP },
2963325Ssd77468 	{ "ereport.cpu.*.lvc",		cmd_txce,	CMD_CPU_LEVEL_CHIP },
2976369Std122701 	{ "ereport.cpu.*.itl2u",	cmd_xxu,	CMD_ERRCL_IL2U |
2983325Ssd77468 		CMD_CPU_LEVEL_CHIP },
2996369Std122701 	{ "ereport.cpu.*.dtl2u",	cmd_xxu,	CMD_ERRCL_DL2U |
3003325Ssd77468 		CMD_CPU_LEVEL_CHIP },
3016369Std122701 	{ "ereport.cpu.*.icl2u",	cmd_xxu,	CMD_ERRCL_IL2U |
3023325Ssd77468 		CMD_CPU_LEVEL_CHIP },
3036369Std122701 	{ "ereport.cpu.*.dcl2u",	cmd_xxu,	CMD_ERRCL_DL2U |
3043325Ssd77468 		CMD_CPU_LEVEL_CHIP },
3053325Ssd77468 	{ "ereport.cpu.*.mal2u",	cmd_xxu,	CMD_ERRCL_LDAU |
3063325Ssd77468 		CMD_CPU_LEVEL_CHIP },
3073325Ssd77468 	{ "ereport.cpu.*.cwql2u",	cmd_xxu,	CMD_ERRCL_LDAU |
3083325Ssd77468 		CMD_CPU_LEVEL_CHIP },
3094735Std122701 	{ "ereport.cpu.*.lvf",		cmd_l2ctl,	CMD_CPU_LEVEL_CHIP },
3104735Std122701 	{ "ereport.cpu.*.lrf",		cmd_l2ctl,	CMD_CPU_LEVEL_CHIP },
3115138Std122701 	{ "ereport.cpu.*.ltu",		cmd_l2ctl,	CMD_CPU_LEVEL_CHIP },
3126369Std122701 	{ "ereport.cpu.*.itl2nd",	cmd_nop_train,	CMD_ERRCL_IL2ND },
3136369Std122701 	{ "ereport.cpu.*.dtl2nd",	cmd_nop_train,	CMD_ERRCL_DL2ND },
3146369Std122701 	{ "ereport.cpu.*.icl2nd",	cmd_nop_train,	CMD_ERRCL_IL2ND },
3156369Std122701 	{ "ereport.cpu.*.dcl2nd",	cmd_nop_train,	CMD_ERRCL_DL2ND },
3166369Std122701 	{ "ereport.cpu.*.l2nd",		cmd_nop_train,	CMD_ERRCL_L2ND },
3176369Std122701 	{ "ereport.cpu.*.mal2nd",	cmd_nop_train,	CMD_ERRCL_L2ND },
3186369Std122701 	{ "ereport.cpu.*.cwql2nd",	cmd_nop_train,	CMD_ERRCL_L2ND },
3192400Stsien 	{ "ereport.cpu.*.ldac",		cmd_xxc, 	CMD_ERRCL_LDAC |
3202400Stsien 	    CMD_CPU_LEVEL_CHIP },
3216369Std122701 	{ "ereport.cpu.*.ldwc",		cmd_xxc,	CMD_ERRCL_LDWC |
3226369Std122701 	    CMD_CPU_LEVEL_CHIP },
3232400Stsien 	{ "ereport.cpu.*.ldrc",		cmd_xxc,	CMD_ERRCL_LDRC |
3242400Stsien 	    CMD_CPU_LEVEL_CHIP },
3252400Stsien 	{ "ereport.cpu.*.ldsc", 	cmd_xxc,	CMD_ERRCL_LDSC |
3262400Stsien 	    CMD_CPU_LEVEL_CHIP },
3275138Std122701 	{ "ereport.cpu.*.ltc",		cmd_txce,	CMD_CPU_LEVEL_CHIP },
3282400Stsien 	{ "ereport.cpu.*.ldau",		cmd_xxu, 	CMD_ERRCL_LDAU |
3292400Stsien 	    CMD_CPU_LEVEL_CHIP },
3306369Std122701 	{ "ereport.cpu.*.ldwu",		cmd_xxu,	CMD_ERRCL_LDWU |
3316369Std122701 	    CMD_CPU_LEVEL_CHIP },
3322400Stsien 	{ "ereport.cpu.*.ldru",		cmd_xxu,	CMD_ERRCL_LDRU |
3332400Stsien 	    CMD_CPU_LEVEL_CHIP },
3342400Stsien 	{ "ereport.cpu.*.ldsu",		cmd_xxu,	CMD_ERRCL_LDSU |
3352400Stsien 	    CMD_CPU_LEVEL_CHIP },
3365138Std122701 	{ "ereport.cpu.*.lvu",		cmd_l2ctl, 	CMD_CPU_LEVEL_CHIP },
3375138Std122701 	{ "ereport.cpu.*.lru",		cmd_l2ctl,	CMD_CPU_LEVEL_CHIP },
3384759Ssd77468 	{ "ereport.cpu.*.fbr",		cmd_fb },
3396369Std122701 	{ "ereport.cpu.*.fbu",		cmd_fb_train,	CMD_ERRCL_FBU },
340962Stsien 	{ "ereport.cpu.*.dac",		cmd_ce,		CMD_ERRCL_DAC },
341962Stsien 	{ "ereport.cpu.*.dsc",		cmd_ce,		CMD_ERRCL_DSC },
3426369Std122701 	{ "ereport.cpu.*.dau",		cmd_ue_train,	CMD_ERRCL_DAU },
34311069STrang.Do@Sun.COM 	{ "ereport.cpu.*.dbu",		cmd_fw_defect,	CMD_ERRCL_DBU },
344962Stsien 	{ "ereport.cpu.*.dsu",		cmd_ue,		CMD_ERRCL_DSU },
3454735Std122701 	{ "ereport.cpu.*.sbdpc",	cmd_miscregs_train,
3464735Std122701 	    CMD_ERRCL_SBDPC | CMD_CPU_LEVEL_THREAD },
3474735Std122701 	{ "ereport.cpu.*.sbdlc",	cmd_miscregs_train,
3484735Std122701 	    CMD_ERRCL_SBDLC | CMD_CPU_LEVEL_THREAD },
3493325Ssd77468 	{ "ereport.cpu.*.sbdpu",	cmd_miscregs_ue,
3503325Ssd77468 	    CMD_CPU_LEVEL_THREAD },
3513325Ssd77468 	{ "ereport.cpu.*.sbdlu",	cmd_miscregs_ue,
3523325Ssd77468 	    CMD_CPU_LEVEL_THREAD },
3533325Ssd77468 	{ "ereport.cpu.*.sbdio",	cmd_miscregs_ue,
3543325Ssd77468 	    CMD_CPU_LEVEL_THREAD },
3553325Ssd77468 	{ "ereport.cpu.*.sbapp",	cmd_miscregs_ue,
3563325Ssd77468 	    CMD_CPU_LEVEL_THREAD },
3575430Ssd77468 	{ "ereport.cpu.*.mrau",		cmd_miscregs_ue,
3585430Ssd77468 	    CMD_CPU_LEVEL_THREAD },
3594735Std122701 	{ "ereport.cpu.*.scac",		cmd_miscregs_train,
3604735Std122701 	    CMD_ERRCL_SBDPC | CMD_CPU_LEVEL_THREAD },
3613325Ssd77468 	{ "ereport.cpu.*.scau",		cmd_miscregs_ue,
3623325Ssd77468 	    CMD_CPU_LEVEL_THREAD },
3634735Std122701 	{ "ereport.cpu.*.tccp",		cmd_miscregs_train,
3644735Std122701 	    CMD_ERRCL_TCCP | CMD_CPU_LEVEL_THREAD },
3654735Std122701 	{ "ereport.cpu.*.tccd",		cmd_miscregs_train,
3664735Std122701 	    CMD_ERRCL_TCCD | CMD_CPU_LEVEL_THREAD },
3673325Ssd77468 	{ "ereport.cpu.*.tcup",		cmd_miscregs_ue,
3683325Ssd77468 	    CMD_CPU_LEVEL_THREAD },
3693325Ssd77468 	{ "ereport.cpu.*.tcud",		cmd_miscregs_ue,
3703325Ssd77468 	    CMD_CPU_LEVEL_THREAD },
3714735Std122701 	{ "ereport.cpu.*.tsac",		cmd_miscregs_train,
3724735Std122701 	    CMD_ERRCL_SBDPC | CMD_CPU_LEVEL_THREAD },
3733325Ssd77468 	{ "ereport.cpu.*.tsau",		cmd_miscregs_ue,
3743325Ssd77468 	    CMD_CPU_LEVEL_THREAD },
3756369Std122701 	{ "ereport.cpu.*.cbce",		cmd_xxc,	CMD_ERRCL_CBCE |
3766369Std122701 	    CMD_CPU_LEVEL_CHIP },
3774759Ssd77468 	{ "ereport.cpu.*.dce",		cmd_nop },
3786369Std122701 	{ "ereport.cpu.*.wbue",		cmd_xxu,	CMD_ERRCL_WBUE |
3796369Std122701 	    CMD_CPU_LEVEL_CHIP },
3804759Ssd77468 	{ "ereport.cpu.*.lfu-slf",	cmd_lfu_ce,	CMD_CPU_LEVEL_CHIP },
3814759Ssd77468 	{ "ereport.cpu.*.lfu-rtf",	cmd_lfu_ue,	CMD_CPU_LEVEL_CHIP },
3824759Ssd77468 	{ "ereport.cpu.*.lfu-tto",	cmd_lfu_ue,	CMD_CPU_LEVEL_CHIP },
3834759Ssd77468 	{ "ereport.cpu.*.lfu-cto",	cmd_lfu_ue,	CMD_CPU_LEVEL_CHIP },
3844759Ssd77468 	{ "ereport.cpu.*.lfu-mlf",	cmd_lfu_ue,	CMD_CPU_LEVEL_CHIP },
3854759Ssd77468 	{ "ereport.cpu.*.frack",	cmd_lfu_pe,	CMD_CPU_LEVEL_CHIP },
3864759Ssd77468 	{ "ereport.cpu.*.fsr",		cmd_lfu_pe,	CMD_CPU_LEVEL_CHIP },
3874759Ssd77468 	{ "ereport.cpu.*.fdr", 		cmd_lfu_pe,	CMD_CPU_LEVEL_CHIP },
3884759Ssd77468 	{ "ereport.cpu.*.to",  		cmd_lfu_pe,	CMD_CPU_LEVEL_CHIP },
3894759Ssd77468 	{ "ereport.cpu.*.snptyp",	cmd_lfu_pe,	CMD_CPU_LEVEL_CHIP },
39011069STrang.Do@Sun.COM 	{ "ereport.fm.ferg.invalid",	cmd_fw_defect },
391962Stsien #endif /* sun4u */
392962Stsien 	{ "ereport.cpu.*.fpu.hwcopy",	cmd_fpu },
393600Stsien 	{ NULL, NULL }
394600Stsien };
395600Stsien 
396600Stsien static void
cmd_recv(fmd_hdl_t * hdl,fmd_event_t * ep,nvlist_t * nvl,const char * class)397600Stsien cmd_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class)
398600Stsien {
399600Stsien 	cmd_subscriber_t *sp;
400600Stsien 	int disp;
401600Stsien 
402600Stsien 	fmd_hdl_debug(hdl, "cmd_recv: begin: %s\n", strrchr(class, '.') + 1);
403600Stsien 
404600Stsien 	for (sp = cmd_subscribers; sp->subr_class != NULL; sp++) {
405600Stsien 		if (fmd_nvl_class_match(hdl, nvl, sp->subr_class)) {
406600Stsien 			disp = sp->subr_func(hdl, ep, nvl, class, sp->subr_arg);
407600Stsien 			((fmd_stat_t *)&sp->subr_stat)[disp].fmds_value.ui64++;
408600Stsien 			fmd_hdl_debug(hdl, "cmd_recv: done: %s (disp %d)\n",
409600Stsien 			    strrchr(class, '.') + 1, disp);
410600Stsien 			return;
411600Stsien 		}
412600Stsien 	}
413600Stsien 
414600Stsien 	fmd_hdl_debug(hdl, "cmd_recv: dropping %s - unable to handle\n", class);
415600Stsien }
416600Stsien 
417600Stsien static void
cmd_timeout(fmd_hdl_t * hdl,id_t id,void * arg)418600Stsien cmd_timeout(fmd_hdl_t *hdl, id_t id, void *arg)
419600Stsien {
4201186Sayznaga 	uintptr_t	timertype = (uintptr_t)arg;
4211186Sayznaga 
4221186Sayznaga 	switch (timertype) {
4231186Sayznaga 		case CMD_TIMERTYPE_MEM:
4241186Sayznaga 			cmd_mem_timeout(hdl, id);
4251186Sayznaga 			break;
4261186Sayznaga 
4271186Sayznaga #ifdef sun4u
4281186Sayznaga 		case CMD_TIMERTYPE_DP:
4291186Sayznaga 
4301186Sayznaga 			cmd_dp_timeout(hdl, id);
4311186Sayznaga 			break;
43210784Ssinanallur.balasubramanian@sun.com 		case CMD_TIMERTYPE_ANONYMOUS_TAG_ERROR:
43310784Ssinanallur.balasubramanian@sun.com 
43410784Ssinanallur.balasubramanian@sun.com 			cmd_Lxcache_anonymous_tag_error_timeout(hdl, id);
43510784Ssinanallur.balasubramanian@sun.com 			break;
4361186Sayznaga #endif
4371186Sayznaga 
4381186Sayznaga 		case CMD_TIMERTYPE_CPU_UEC_FLUSH:
4391186Sayznaga 		case CMD_TIMERTYPE_CPU_XR_WAITER:
4401186Sayznaga 			cmd_cpu_timeout(hdl, id, (void *)timertype);
4411186Sayznaga 			break;
4421186Sayznaga 
4431186Sayznaga 		default:
4441186Sayznaga 			break;
4451186Sayznaga 	}
446600Stsien }
447600Stsien 
448600Stsien static void
cmd_close(fmd_hdl_t * hdl,fmd_case_t * cp)449600Stsien cmd_close(fmd_hdl_t *hdl, fmd_case_t *cp)
450600Stsien {
451600Stsien 	cmd_case_closer_t *cl = fmd_case_getspecific(hdl, cp);
452600Stsien 	const char *uuid = fmd_case_uuid(hdl, cp);
453600Stsien 
454600Stsien 	/*
455600Stsien 	 * Our active cases all have closers registered in case-specific data.
456600Stsien 	 * Cases in the process of closing (for which we've freed all associated
457600Stsien 	 * data, but which haven't had an fmd-initiated fmdo_close callback)
458600Stsien 	 * have had their case-specific data nulled out.
459600Stsien 	 */
460600Stsien 	fmd_hdl_debug(hdl, "close case %s%s\n", uuid,
461600Stsien 	    (cl == NULL ? " (no cl)" : ""));
462600Stsien 
463600Stsien 	if (cl != NULL)
464600Stsien 		cl->cl_func(hdl, cl->cl_arg);
465600Stsien }
466600Stsien 
467600Stsien static void
cmd_gc(fmd_hdl_t * hdl)468600Stsien cmd_gc(fmd_hdl_t *hdl)
469600Stsien {
470600Stsien 	cmd_cpu_gc(hdl);
471600Stsien 	cmd_mem_gc(hdl);
4726330Sjc25722 #ifdef sun4u
4736330Sjc25722 	cmd_Lxcache_gc(hdl);
4746330Sjc25722 #endif
475600Stsien }
476600Stsien 
4772400Stsien static cmd_stat_t cmd_stats = {
478600Stsien 	{ "bad_det", FMD_TYPE_UINT64, "detector missing or malformed" },
479600Stsien 	{ "bad_cpu_asru", FMD_TYPE_UINT64, "CPU ASRU missing or malformed" },
480600Stsien 	{ "bad_mem_asru", FMD_TYPE_UINT64, "memory ASRU missing or malformed" },
481600Stsien 	{ "bad_close", FMD_TYPE_UINT64, "case close for nonexistent case" },
482600Stsien 	{ "old_erpt", FMD_TYPE_UINT64, "ereport out of date wrt hardware" },
483600Stsien 	{ "cpu_creat", FMD_TYPE_UINT64, "created new cpu structure" },
484600Stsien 	{ "dimm_creat", FMD_TYPE_UINT64, "created new mem module structure" },
485600Stsien 	{ "bank_creat", FMD_TYPE_UINT64, "created new mem bank structure" },
486600Stsien 	{ "page_creat", FMD_TYPE_UINT64, "created new page structure" },
487*12731STrang.Do@Sun.COM 	{ "cache_creat", FMD_TYPE_UINT64, "created new cache structure" },
488600Stsien 	{ "ce_unknown", FMD_TYPE_UINT64, "unknown CEs" },
489600Stsien 	{ "ce_interm", FMD_TYPE_UINT64, "intermittent CEs" },
490600Stsien 	{ "ce_ppersis", FMD_TYPE_UINT64, "possibly persistent CEs" },
491600Stsien 	{ "ce_persis", FMD_TYPE_UINT64, "persistent CEs" },
492600Stsien 	{ "ce_leaky", FMD_TYPE_UINT64, "leaky CEs" },
493600Stsien 	{ "ce_psticky_noptnr", FMD_TYPE_UINT64,
494600Stsien 	    "possibly sticky CEs, no partner test" },
495600Stsien 	{ "ce_psticky_ptnrnoerr", FMD_TYPE_UINT64,
496600Stsien 	    "possibly sticky CEs, partner sees no CE" },
497600Stsien 	{ "ce_psticky_ptnrclrd", FMD_TYPE_UINT64,
498600Stsien 	    "possibly sticky CEs, partner can clear CE" },
499600Stsien 	{ "ce_sticky", FMD_TYPE_UINT64, "sticky CEs" },
500600Stsien 	{ "xxu_ue_match", FMD_TYPE_UINT64, "xxUs obviated by UEs" },
501600Stsien 	{ "xxu_retr_flt", FMD_TYPE_UINT64, "xxUs obviated by faults" },
502600Stsien 	{ "cpu_migrat", FMD_TYPE_UINT64, "CPUs migrated to new version" },
503600Stsien 	{ "dimm_migrat", FMD_TYPE_UINT64, "DIMMs migrated to new version" },
5041186Sayznaga 	{ "bank_migrat", FMD_TYPE_UINT64, "banks migrated to new version" },
5051186Sayznaga #ifdef sun4u
5061186Sayznaga 	{ "dp_ignored_ce", FMD_TYPE_UINT64,
5071186Sayznaga 	    "memory CEs ignored due to DP error or fault" },
5081186Sayznaga 	{ "dp_ignored_ue", FMD_TYPE_UINT64,
5091186Sayznaga 	    "memory UEs ignored due to DP fault" },
5101186Sayznaga 	{ "dp_deferred_ue", FMD_TYPE_UINT64,
5111186Sayznaga 	    "memory UEs deferred due to DP error" },
5121186Sayznaga #endif
5134759Ssd77468 #ifdef sun4v
5144759Ssd77468 	{ "branch_creat", FMD_TYPE_UINT64, "created new mem branch structure" },
5154759Ssd77468 #endif
516600Stsien };
517600Stsien 
518600Stsien static const fmd_prop_t fmd_props[] = {
5192289Smb91622 	{ "icache_n", FMD_TYPE_UINT32, "8" },
520600Stsien 	{ "icache_t", FMD_TYPE_TIME, "168h" },
5212289Smb91622 	{ "dcache_n", FMD_TYPE_UINT32, "8" },
522600Stsien 	{ "dcache_t", FMD_TYPE_TIME, "168h" },
523600Stsien 	{ "pcache_n", FMD_TYPE_UINT32, "2" },
524600Stsien 	{ "pcache_t", FMD_TYPE_TIME, "168h" },
5253325Ssd77468 #ifdef sun4u
526600Stsien 	{ "itlb_n", FMD_TYPE_UINT32, "2" },
527600Stsien 	{ "itlb_t", FMD_TYPE_TIME, "168h" },
528600Stsien 	{ "dtlb_n", FMD_TYPE_UINT32, "2" },
529600Stsien 	{ "dtlb_t", FMD_TYPE_TIME, "168h" },
5302289Smb91622 	{ "l2tag_n", FMD_TYPE_UINT32, "4" },
5312289Smb91622 	{ "l2tag_t", FMD_TYPE_TIME, "1h" },
5322289Smb91622 	{ "l2data_n", FMD_TYPE_UINT32, "12" },
5332289Smb91622 	{ "l2data_t", FMD_TYPE_TIME, "1h" },
5343325Ssd77468 #else
5353325Ssd77468 	{ "itlb_n", FMD_TYPE_UINT32, "8" },
5363325Ssd77468 	{ "itlb_t", FMD_TYPE_TIME, "168h" },
5373325Ssd77468 	{ "dtlb_n", FMD_TYPE_UINT32, "8" },
5383325Ssd77468 	{ "dtlb_t", FMD_TYPE_TIME, "168h" },
5393325Ssd77468 	{ "l2tag_n", FMD_TYPE_UINT32, "8" },
5403325Ssd77468 	{ "l2tag_t", FMD_TYPE_TIME, "20h" },
5413325Ssd77468 	{ "l2data_n", FMD_TYPE_UINT32, "8" },
5423325Ssd77468 	{ "l2data_t", FMD_TYPE_TIME, "2h" },
5433325Ssd77468 #endif
5442289Smb91622 	{ "l3tag_n", FMD_TYPE_UINT32, "4" },
5452289Smb91622 	{ "l3tag_t", FMD_TYPE_TIME, "1h" },
5462289Smb91622 	{ "l3data_n", FMD_TYPE_UINT32, "12" },
5472289Smb91622 	{ "l3data_t", FMD_TYPE_TIME, "1h" },
548600Stsien 	{ "ce_n", FMD_TYPE_UINT32, "2" },
549600Stsien 	{ "ce_t", FMD_TYPE_TIME, "72h" },
5503325Ssd77468 	{ "ireg_n", FMD_TYPE_UINT32, "8" },
551962Stsien 	{ "ireg_t", FMD_TYPE_TIME, "168h" },
5523325Ssd77468 	{ "freg_n", FMD_TYPE_UINT32, "8" },
553962Stsien 	{ "freg_t", FMD_TYPE_TIME, "168h" },
5543325Ssd77468 	{ "mau_n", FMD_TYPE_UINT32, "0" },
555962Stsien 	{ "mau_t", FMD_TYPE_TIME, "168h" },
5563325Ssd77468 	{ "misc_regs_n", FMD_TYPE_UINT32, "8"},
5573325Ssd77468 	{ "misc_regs_t", FMD_TYPE_TIME, "168h" },
558600Stsien 	{ "iorxefrx_window", FMD_TYPE_TIME, "3s" },
5596369Std122701 #ifdef sun4u
560600Stsien 	{ "xxcu_trdelay", FMD_TYPE_TIME, "200ms" },
5616369Std122701 #else
5626369Std122701 	{ "xxcu_trdelay", FMD_TYPE_TIME, "15s"},
5636369Std122701 #endif /* sun4u */
564600Stsien 	{ "xxcu_restart_delay", FMD_TYPE_TIME, "1s" },
565600Stsien 	{ "num_xxcu_waiters", FMD_TYPE_UINT32, "128" },
566600Stsien 	{ "thresh_tpct_sysmem", FMD_TYPE_UINT64, "100" },
567600Stsien 	{ "thresh_abs_sysmem", FMD_TYPE_UINT64, "0" },
568600Stsien 	{ "thresh_abs_badrw", FMD_TYPE_UINT64, "128" },
5692652Sav145390 	{ "max_perm_ce_dimm", FMD_TYPE_UINT32, "128" },
57012467STrang.Do@Sun.COM 	{ "low_ce_thresh", FMD_TYPE_UINT32, "128" },
57112467STrang.Do@Sun.COM 	{ "hi_ce_thresh", FMD_TYPE_UINT32, "512" },
57212467STrang.Do@Sun.COM 	{ "dupce", FMD_TYPE_UINT32, "120"},
57312467STrang.Do@Sun.COM 	{ "nupos", FMD_TYPE_UINT32, "4"},
5744759Ssd77468 #ifdef sun4v
5754759Ssd77468 	{ "fbr_n", FMD_TYPE_UINT32, "14" },
5764759Ssd77468 	{ "fbr_t", FMD_TYPE_TIME, "30min"},
5776369Std122701 	/* delta_ena value = 0x500000000nsec ~= 22sec */
5786369Std122701 	{ "delta_ena", FMD_TYPE_UINT64, "0x50000000000000"},
5794759Ssd77468 #endif
580600Stsien 	{ NULL, 0, NULL }
581600Stsien };
582600Stsien 
583600Stsien static const fmd_hdl_ops_t fmd_ops = {
584600Stsien 	cmd_recv,	/* fmdo_recv */
585600Stsien 	cmd_timeout,	/* fmdo_timeout */
586600Stsien 	cmd_close,	/* fmdo_close */
587600Stsien 	NULL,		/* fmdo_stats */
588600Stsien 	cmd_gc		/* fmdo_gc */
589600Stsien };
590600Stsien 
591600Stsien static const fmd_hdl_info_t fmd_info = {
5921772Sjl139090 	"CPU/Memory Diagnosis", CMD_VERSION, &fmd_ops, fmd_props
593600Stsien };
594600Stsien 
595600Stsien static const struct cmd_evdisp_name {
596600Stsien 	const char *evn_name;
597600Stsien 	const char *evn_desc;
598600Stsien } cmd_evdisp_names[] = {
599600Stsien 	{ "%s", "ok %s ereports" },			/* CMD_EVD_OK */
600600Stsien 	{ "bad_%s", "bad %s ereports" },		/* CMD_EVD_BAD */
601600Stsien 	{ "unused_%s", "unused %s ereports" },		/* CMD_EVD_UNUSED */
602600Stsien 	{ "redun_%s", "redundant %s ereports" },	/* CMD_EVD_REDUN */
603600Stsien };
604600Stsien 
605600Stsien void
_fmd_fini(fmd_hdl_t * hdl)606600Stsien _fmd_fini(fmd_hdl_t *hdl)
607600Stsien {
6082072Svn83148 
6092072Svn83148 #ifdef	sun4v
6102072Svn83148 	ldom_fini(cpumem_diagnosis_lhp);
6112072Svn83148 #endif
612600Stsien 	cmd_cpu_fini(hdl);
613600Stsien 	cmd_mem_fini(hdl);
614600Stsien 	cmd_page_fini(hdl);
6151186Sayznaga #ifdef sun4u
6161186Sayznaga 	cmd_dp_fini(hdl);
6171186Sayznaga #endif
618600Stsien 
619600Stsien 	fmd_hdl_free(hdl, cmd.cmd_xxcu_trw,
620600Stsien 	    sizeof (cmd_xxcu_trw_t) * cmd.cmd_xxcu_ntrw);
6214934Stsien 	nvlist_free(cmd.cmd_auth);
622600Stsien }
623600Stsien 
6242072Svn83148 #ifdef	sun4v
6252072Svn83148 static void *
cpumem_diagnosis_init_alloc(size_t size)6262072Svn83148 cpumem_diagnosis_init_alloc(size_t size)
6272072Svn83148 {
6282072Svn83148 	return (fmd_hdl_alloc(init_hdl, size, FMD_SLEEP));
6292072Svn83148 }
6302072Svn83148 
6312072Svn83148 static void
cpumem_diagnosis_init_free(void * addr,size_t size)6322072Svn83148 cpumem_diagnosis_init_free(void *addr, size_t size)
6332072Svn83148 {
6342072Svn83148 	fmd_hdl_free(init_hdl, addr, size);
6352072Svn83148 }
6362072Svn83148 #endif
6372072Svn83148 
6384934Stsien /* find_auth -- find hardware platform authority within libtopo */
6394934Stsien 
6404934Stsien /* ARGSUSED */
6414934Stsien static int
find_auth(topo_hdl_t * thp,tnode_t * node,void * arg)6424934Stsien find_auth(topo_hdl_t *thp, tnode_t *node, void *arg)
6434934Stsien {
6444934Stsien 	int err;
6454934Stsien 	nvlist_t *rsrc, *auth;
6464934Stsien 
6474934Stsien 	if (cmd.cmd_auth != NULL)
6484934Stsien 		return (TOPO_WALK_TERMINATE); /* don't overwrite previous */
6494934Stsien 
6504934Stsien 	if (topo_node_resource(node, &rsrc, &err) < 0)
6514934Stsien 		return (TOPO_WALK_NEXT);	/* no resource, try next */
6524934Stsien 	if (nvlist_lookup_nvlist(rsrc, FM_FMRI_AUTHORITY, &auth) < 0) {
6534934Stsien 		nvlist_free(rsrc);
6544934Stsien 		return (TOPO_WALK_NEXT);	/* no authority, try next */
6554934Stsien 	}
6564934Stsien 	(void) nvlist_dup(auth, &cmd.cmd_auth, NV_UNIQUE_NAME);
6574934Stsien 	nvlist_free(rsrc);
6584934Stsien 	return (TOPO_WALK_TERMINATE);	/* if no space, give up */
6594934Stsien }
6604934Stsien 
6614934Stsien /* init_auth -- read hardware platform authority from libtopo */
6624934Stsien 
6634934Stsien void
init_auth(fmd_hdl_t * hdl)6644934Stsien init_auth(fmd_hdl_t *hdl)
6654934Stsien {
6664934Stsien 	topo_hdl_t *thp;
6674934Stsien 	topo_walk_t *twp;
6684934Stsien 	int err;
6694934Stsien 
6704934Stsien 	if ((thp = fmd_hdl_topo_hold(hdl, TOPO_VERSION)) == NULL)
6714934Stsien 		return;
6724934Stsien 	if ((twp = topo_walk_init(thp,
6734934Stsien 	    FM_FMRI_SCHEME_HC, find_auth, NULL, &err))
6744934Stsien 	    == NULL) {
6754934Stsien 		fmd_hdl_topo_rele(hdl, thp);
6764934Stsien 		return;
6774934Stsien 	}
6784934Stsien 	(void) topo_walk_step(twp, TOPO_WALK_CHILD);
6794934Stsien 	topo_walk_fini(twp);
6804934Stsien 	fmd_hdl_topo_rele(hdl, thp);
6814934Stsien }
6824934Stsien 
683600Stsien void
_fmd_init(fmd_hdl_t * hdl)684600Stsien _fmd_init(fmd_hdl_t *hdl)
685600Stsien {
686600Stsien 	cmd_subscriber_t *sp;
687600Stsien 	cpu_family_t cpu_family;
688600Stsien 
689600Stsien 	if (fmd_hdl_register(hdl, FMD_API_VERSION, &fmd_info) != 0)
690600Stsien 		return; /* error in configuration file or fmd_info */
691600Stsien 
692600Stsien 	cpu_family = cmd_cpu_check_support();
693600Stsien 
694600Stsien 	if (cpu_family == CMD_CPU_FAM_UNSUPPORTED) {
695600Stsien 		fmd_hdl_debug(hdl, "no supported CPUs found");
696600Stsien 		fmd_hdl_unregister(hdl);
697600Stsien 		return;
698600Stsien 	}
699600Stsien 
700600Stsien 	fmd_hdl_subscribe(hdl, "ereport.cpu.ultraSPARC-III.*");
701600Stsien 	fmd_hdl_subscribe(hdl, "ereport.cpu.ultraSPARC-IIIplus.*");
702600Stsien 	fmd_hdl_subscribe(hdl, "ereport.cpu.ultraSPARC-IIIi.*");
703600Stsien 	fmd_hdl_subscribe(hdl, "ereport.cpu.ultraSPARC-IIIiplus.*");
704600Stsien 	fmd_hdl_subscribe(hdl, "ereport.cpu.ultraSPARC-IV.*");
705600Stsien 	fmd_hdl_subscribe(hdl, "ereport.cpu.ultraSPARC-IVplus.*");
7063325Ssd77468 	fmd_hdl_subscribe(hdl, "ereport.cpu.ultraSPARC-T2.*");
7074759Ssd77468 	fmd_hdl_subscribe(hdl, "ereport.cpu.ultraSPARC-T2plus.*");
708962Stsien 	fmd_hdl_subscribe(hdl, "ereport.cpu.ultraSPARC-T1.*");
70911069STrang.Do@Sun.COM 	fmd_hdl_subscribe(hdl, "ereport.fm.ferg.invalid");
710600Stsien 
711600Stsien 	fmd_hdl_subscribe(hdl, "ereport.io.tom.ecc.drce");
712600Stsien 	fmd_hdl_subscribe(hdl, "ereport.io.tom.ecc.dwce");
713600Stsien 	fmd_hdl_subscribe(hdl, "ereport.io.tom.ecc.drue");
714600Stsien 	fmd_hdl_subscribe(hdl, "ereport.io.tom.ecc.dwue");
715600Stsien 	fmd_hdl_subscribe(hdl, "ereport.io.sch.ecc.drce");
716600Stsien 	fmd_hdl_subscribe(hdl, "ereport.io.sch.ecc.dwce");
717600Stsien 	fmd_hdl_subscribe(hdl, "ereport.io.sch.ecc.drue");
718600Stsien 	fmd_hdl_subscribe(hdl, "ereport.io.sch.ecc.dwue");
719600Stsien 	fmd_hdl_subscribe(hdl, "ereport.io.xmits.ecc.drce");
720600Stsien 	fmd_hdl_subscribe(hdl, "ereport.io.xmits.ecc.dwce");
721600Stsien 	fmd_hdl_subscribe(hdl, "ereport.io.xmits.ecc.drue");
722600Stsien 	fmd_hdl_subscribe(hdl, "ereport.io.xmits.ecc.dwue");
723600Stsien 
724600Stsien 	/*
725600Stsien 	 * Need to subscribe to secondary I/O ECC ereports, but
726600Stsien 	 * since they contain no data regarding the failure we
727600Stsien 	 * are unable to do anything with them.
728600Stsien 	 */
729600Stsien 	fmd_hdl_subscribe(hdl, "ereport.io.tom.ecc.s-drce");
730600Stsien 	fmd_hdl_subscribe(hdl, "ereport.io.tom.ecc.s-dwce");
731600Stsien 	fmd_hdl_subscribe(hdl, "ereport.io.tom.ecc.s-drue");
732600Stsien 	fmd_hdl_subscribe(hdl, "ereport.io.tom.ecc.s-dwue");
733600Stsien 	fmd_hdl_subscribe(hdl, "ereport.io.sch.ecc.s-drce");
734600Stsien 	fmd_hdl_subscribe(hdl, "ereport.io.sch.ecc.s-dwce");
735600Stsien 	fmd_hdl_subscribe(hdl, "ereport.io.sch.ecc.s-drue");
736600Stsien 	fmd_hdl_subscribe(hdl, "ereport.io.sch.ecc.s-dwue");
737600Stsien 	fmd_hdl_subscribe(hdl, "ereport.io.xmits.ecc.s-drce");
738600Stsien 	fmd_hdl_subscribe(hdl, "ereport.io.xmits.ecc.s-dwce");
739600Stsien 	fmd_hdl_subscribe(hdl, "ereport.io.xmits.ecc.s-drue");
740600Stsien 	fmd_hdl_subscribe(hdl, "ereport.io.xmits.ecc.s-dwue");
741600Stsien 
7421186Sayznaga #ifdef sun4u
7431186Sayznaga 	/*
7441186Sayznaga 	 * Subscribe to datapath events
7451186Sayznaga 	 */
7461186Sayznaga 	fmd_hdl_subscribe(hdl, "ereport.asic.*.cds.cds-dp");
7471186Sayznaga 	fmd_hdl_subscribe(hdl, "ereport.asic.*.dx.dx-dp");
7481186Sayznaga 	fmd_hdl_subscribe(hdl, "ereport.asic.*.sdi.sdi-dp");
7491186Sayznaga 	fmd_hdl_subscribe(hdl, "ereport.asic.*.cp.cp-dp");
7501186Sayznaga 	fmd_hdl_subscribe(hdl, "ereport.asic.*.rp.rp-dp");
7511772Sjl139090 
7521772Sjl139090 	/*
7531772Sjl139090 	 * OPL platform specific subscriptions.
7541772Sjl139090 	 */
7551772Sjl139090 	fmd_hdl_subscribe(hdl, "ereport.cpu.SPARC64-VI.*");
7565037Sjl139090 	fmd_hdl_subscribe(hdl, "ereport.cpu.SPARC64-VII.*");
7571772Sjl139090 	fmd_hdl_subscribe(hdl, "ereport.asic.mac.*");
7581772Sjl139090 	fmd_hdl_subscribe(hdl, "ereport.io.oberon.ubc.dmarduea-mem");
7591772Sjl139090 	fmd_hdl_subscribe(hdl, "ereport.io.oberon.ubc.dmarduea-channel");
7601772Sjl139090 	fmd_hdl_subscribe(hdl, "ereport.io.oberon.ubc.dmarduea-cpu");
7611772Sjl139090 	fmd_hdl_subscribe(hdl, "ereport.io.oberon.ubc.dmarduea-path");
7621772Sjl139090 	fmd_hdl_subscribe(hdl, "ereport.io.oberon.ubc.dmardueb-mem");
7631772Sjl139090 	fmd_hdl_subscribe(hdl, "ereport.io.oberon.ubc.dmardueb-channel");
7641772Sjl139090 	fmd_hdl_subscribe(hdl, "ereport.io.oberon.ubc.dmardueb-cpu");
7651772Sjl139090 	fmd_hdl_subscribe(hdl, "ereport.io.oberon.ubc.dmardueb-path");
7661772Sjl139090 	fmd_hdl_subscribe(hdl, "ereport.io.oberon.ubc.piowtue-mem");
7671772Sjl139090 	fmd_hdl_subscribe(hdl, "ereport.io.oberon.ubc.piowtue-channel");
7681772Sjl139090 	fmd_hdl_subscribe(hdl, "ereport.io.oberon.ubc.piowtue-cpu");
7691772Sjl139090 	fmd_hdl_subscribe(hdl, "ereport.io.oberon.ubc.piowtue-path");
7701772Sjl139090 	fmd_hdl_subscribe(hdl, "ereport.io.oberon.ubc.piowbeue-mem");
7711772Sjl139090 	fmd_hdl_subscribe(hdl, "ereport.io.oberon.ubc.piowbeue-channel");
7721772Sjl139090 	fmd_hdl_subscribe(hdl, "ereport.io.oberon.ubc.piowbeue-cpu");
7731772Sjl139090 	fmd_hdl_subscribe(hdl, "ereport.io.oberon.ubc.piowbeue-path");
7741772Sjl139090 	fmd_hdl_subscribe(hdl, "ereport.io.oberon.ubc.piorbeue-mem");
7751772Sjl139090 	fmd_hdl_subscribe(hdl, "ereport.io.oberon.ubc.piorbeue-channel");
7761772Sjl139090 	fmd_hdl_subscribe(hdl, "ereport.io.oberon.ubc.piorbeue-cpu");
7771772Sjl139090 	fmd_hdl_subscribe(hdl, "ereport.io.oberon.ubc.piorbeue-path");
7781186Sayznaga #endif
7792260Sjc25722 	fmd_hdl_subscribe(hdl, "ereport.io.fire.jbc.ce_asyn");
7802260Sjc25722 	fmd_hdl_subscribe(hdl, "ereport.io.fire.jbc.ue_asyn");
7811186Sayznaga 
782600Stsien 	bzero(&cmd, sizeof (cmd_t));
783600Stsien 
7841794Sav145390 #ifdef sun4u
7851794Sav145390 	bzero(&opl_cpu_list, sizeof (cmd_list_t));
7861794Sav145390 #endif	/* sun4u */
7871794Sav145390 
788600Stsien 	cmd.cmd_stats = (cmd_stat_t *)fmd_stat_create(hdl, FMD_STAT_NOALLOC,
789600Stsien 	    sizeof (cmd_stats) / sizeof (fmd_stat_t),
790600Stsien 	    (fmd_stat_t *)&cmd_stats);
791600Stsien 
792600Stsien 	for (sp = cmd_subscribers; sp->subr_class != NULL; sp++) {
793600Stsien 		const char *type = strrchr(sp->subr_class, '.') + 1;
794600Stsien 		int i;
795600Stsien 
796600Stsien 		for (i = 0; i < sizeof (cmd_evdisp_names) /
797600Stsien 		    sizeof (struct cmd_evdisp_name); i++) {
798600Stsien 			fmd_stat_t *stat = ((fmd_stat_t *)&sp->subr_stat) + i;
799600Stsien 
800600Stsien 			(void) snprintf(stat->fmds_name,
801600Stsien 			    sizeof (stat->fmds_name),
802600Stsien 			    cmd_evdisp_names[i].evn_name, type);
803962Stsien 
804600Stsien 			stat->fmds_type = FMD_TYPE_UINT64;
805600Stsien 			(void) snprintf(stat->fmds_desc,
806600Stsien 			    sizeof (stat->fmds_desc),
807600Stsien 			    cmd_evdisp_names[i].evn_desc, type);
808600Stsien 
809600Stsien 			(void) fmd_stat_create(hdl, FMD_STAT_NOALLOC, 1, stat);
810600Stsien 		}
811600Stsien 	}
812600Stsien 
813600Stsien 	cmd.cmd_pagesize = sysconf(_SC_PAGESIZE);
814600Stsien 	cmd.cmd_pagemask = ~((uint64_t)cmd.cmd_pagesize - 1);
815600Stsien 
816600Stsien 	cmd.cmd_iorxefrx_window = fmd_prop_get_int64(hdl, "iorxefrx_window");
817600Stsien 
818600Stsien #ifdef sun4u
8191794Sav145390 	if (cmd_cpu_ecache_support() && cmd_ecache_init() < 0) {
8201794Sav145390 		_fmd_fini(hdl);
8211794Sav145390 		fmd_hdl_abort(hdl, "failed to find device for E-cache flush");
822600Stsien 	}
8231772Sjl139090 #endif
824600Stsien 
825600Stsien 	if ((cmd.cmd_thresh_tpct_sysmem = fmd_prop_get_int64(hdl,
826600Stsien 	    "thresh_tpct_sysmem")) > 100000) {
827600Stsien 		_fmd_fini(hdl);
828600Stsien 		fmd_hdl_abort(hdl, "page retirement threshold is >100%");
829600Stsien 	}
830600Stsien 
831600Stsien 	cmd.cmd_thresh_abs_sysmem = fmd_prop_get_int64(hdl,
832600Stsien 	    "thresh_abs_sysmem");
833600Stsien 	cmd.cmd_thresh_abs_badrw = fmd_prop_get_int64(hdl,
834600Stsien 	    "thresh_abs_badrw");
835600Stsien 
836600Stsien 	cmd.cmd_xxcu_trdelay = fmd_prop_get_int64(hdl, "xxcu_trdelay");
837600Stsien 
838600Stsien 	cmd.cmd_xxcu_ntrw = fmd_prop_get_int32(hdl, "num_xxcu_waiters");
839600Stsien 	cmd.cmd_xxcu_trw = fmd_hdl_zalloc(hdl, sizeof (cmd_xxcu_trw_t) *
840600Stsien 	    cmd.cmd_xxcu_ntrw, FMD_SLEEP);
84112467STrang.Do@Sun.COM 	cmd.cmd_low_ce_thresh = fmd_prop_get_int32(hdl, "low_ce_thresh");
84212467STrang.Do@Sun.COM 	cmd.cmd_hi_ce_thresh = fmd_prop_get_int32(hdl, "hi_ce_thresh");
84312467STrang.Do@Sun.COM 	cmd.cmd_dupce = fmd_prop_get_int32(hdl, "dupce");
84412467STrang.Do@Sun.COM 	cmd.cmd_nupos = fmd_prop_get_int32(hdl, "nupos");
84512467STrang.Do@Sun.COM 
8466369Std122701 #ifdef sun4v
8476369Std122701 	cmd.cmd_delta_ena = fmd_prop_get_int64(hdl, "delta_ena");
8486369Std122701 #endif
849600Stsien 
850600Stsien 	cmd.cmd_l2data_serd.cs_name = "l2data";
851600Stsien 	cmd.cmd_l2data_serd.cs_n = fmd_prop_get_int32(hdl, "l2data_n");
852600Stsien 	cmd.cmd_l2data_serd.cs_t = fmd_prop_get_int64(hdl, "l2data_t");
853600Stsien 
854600Stsien 	cmd.cmd_l3data_serd.cs_name = "l3data";
855600Stsien 	cmd.cmd_l3data_serd.cs_n = fmd_prop_get_int32(hdl, "l3data_n");
856600Stsien 	cmd.cmd_l3data_serd.cs_t = fmd_prop_get_int64(hdl, "l3data_t");
857600Stsien 
8584735Std122701 	cmd.cmd_miscregs_serd.cs_name = "misc_regs";
8594735Std122701 	cmd.cmd_miscregs_serd.cs_n = fmd_prop_get_int32(hdl, "misc_regs_n");
8604735Std122701 	cmd.cmd_miscregs_serd.cs_t = fmd_prop_get_int64(hdl, "misc_regs_t");
8614735Std122701 
8626369Std122701 	cmd.cmd_dcache_serd.cs_name = "dcache";
8636369Std122701 	cmd.cmd_dcache_serd.cs_n = fmd_prop_get_int32(hdl, "dcache_n");
8646369Std122701 	cmd.cmd_dcache_serd.cs_t = fmd_prop_get_int64(hdl, "dcache_t");
8656369Std122701 
8666369Std122701 	cmd.cmd_icache_serd.cs_name = "icache";
8676369Std122701 	cmd.cmd_icache_serd.cs_n = fmd_prop_get_int32(hdl, "icache_n");
8686369Std122701 	cmd.cmd_icache_serd.cs_t = fmd_prop_get_int64(hdl, "icache_t");
8696369Std122701 
870600Stsien 	if (cmd_state_restore(hdl) < 0) {
871600Stsien 		_fmd_fini(hdl);
872600Stsien 		fmd_hdl_abort(hdl, "failed to restore saved state\n");
873600Stsien 	}
8742072Svn83148 
8752072Svn83148 #ifdef	sun4v
8762072Svn83148 	init_hdl = hdl;
8772072Svn83148 	cpumem_diagnosis_lhp = ldom_init(cpumem_diagnosis_init_alloc,
8782652Sav145390 	    cpumem_diagnosis_init_free);
8792072Svn83148 #endif
8804934Stsien 
8814934Stsien 	init_auth(hdl);
882600Stsien }
883