1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
23 */
24
25 /*
26 * CPU/Memory error diagnosis engine for the UltraSPARC III, IV, T1,
27 * SPARC64 VI and SPARC64 VII families of processors.
28 */
29
30 #include <cmd_state.h>
31 #include <cmd_cpu.h>
32
33 #ifdef sun4u
34 #include <cmd_ecache.h>
35 #include <cmd_Lxcache.h>
36 #endif /* sun4u */
37
38 #include <cmd_mem.h>
39 #include <cmd_page.h>
40 #include <cmd_dimm.h>
41 #ifdef sun4u
42 #include <cmd_dp.h>
43 #include <cmd_opl.h>
44 #endif
45 #include <cmd_bank.h>
46 #include <cmd.h>
47
48 #include <errno.h>
49 #include <string.h>
50 #include <unistd.h>
51 #include <strings.h>
52 #include <fm/fmd_api.h>
53 #include <fm/libtopo.h>
54 #include <sys/fm/protocol.h>
55 #include <sys/async.h>
56
57 #ifdef sun4v
58 #include <sys/fm/ldom.h>
59 static fmd_hdl_t *init_hdl;
60 ldom_hdl_t *cpumem_diagnosis_lhp;
61 #endif
62
63 cmd_t cmd;
64
65 #ifdef sun4u
66 cmd_list_t opl_cpu_list;
67 #endif /* sun4u */
68
69 typedef struct cmd_subscriber {
70 const char *subr_class;
71 cmd_evdisp_t (*subr_func)(fmd_hdl_t *, fmd_event_t *, nvlist_t *,
72 const char *, cmd_errcl_t);
73 cmd_errcl_t subr_arg;
74 cmd_evdisp_stat_t subr_stat;
75 } cmd_subscriber_t;
76
77 /*ARGSUSED*/
78 cmd_evdisp_t
cmd_nop(fmd_hdl_t * hdl,fmd_event_t * ep,nvlist_t * nvl,const char * class,cmd_errcl_t clcode)79 cmd_nop(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class,
80 cmd_errcl_t clcode)
81 {
82 return (CMD_EVD_UNUSED);
83 }
84
85 #ifdef sun4u
86 /*
87 * It used to be that cmd_opluecpu_detio() was called directly, with a
88 * 'class' argument of ereport.io.oberon.xxx. But the code underlying
89 * cmd_opluecpu_detio() assumed that the class would always be of the form
90 * ereport.cpu.<cputype>.<subclass>.
91 *
92 * Rather than generalizing the underlying code, the following adjusts the
93 * input to cmd_opluecpu_detio() so that it conforms to the above expectation.
94 */
95
96 /*ARGSUSED*/
97 cmd_evdisp_t
opl_opluecpu_detio(fmd_hdl_t * hdl,fmd_event_t * ep,nvlist_t * nvl,const char * class,cmd_errcl_t clcode)98 opl_opluecpu_detio(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl,
99 const char *class, cmd_errcl_t clcode)
100 {
101 return (cmd_opluecpu_detio(hdl, ep, nvl,
102 "ereport.cpu.SPARC64-VI.", clcode));
103 }
104 #endif /* sun4u */
105
106 static cmd_subscriber_t cmd_subscribers[] = {
107 #ifdef sun4u
108 { "ereport.cpu.*.ucc", cmd_xxc, CMD_ERRCL_UCC |
109 CMD_CPU_LEVEL_CORE },
110 { "ereport.cpu.*.ucu", cmd_xxu, CMD_ERRCL_UCU |
111 CMD_CPU_LEVEL_CORE },
112 { "ereport.cpu.*.cpc", cmd_xxc, CMD_ERRCL_CPC |
113 CMD_CPU_LEVEL_CORE },
114 { "ereport.cpu.*.cpu", cmd_xxu, CMD_ERRCL_CPU |
115 CMD_CPU_LEVEL_CORE },
116 { "ereport.cpu.*.wdc", cmd_xxc, CMD_ERRCL_WDC |
117 CMD_CPU_LEVEL_CORE },
118 { "ereport.cpu.*.wdu", cmd_xxu, CMD_ERRCL_WDU |
119 CMD_CPU_LEVEL_CORE },
120 { "ereport.cpu.*.edc", cmd_xxc, CMD_ERRCL_EDC |
121 CMD_CPU_LEVEL_CORE },
122 { "ereport.cpu.*.edu-st", cmd_xxu, CMD_ERRCL_EDU_ST |
123 CMD_CPU_LEVEL_CORE },
124 { "ereport.cpu.*.edu-bl", cmd_xxu, CMD_ERRCL_EDU_BL |
125 CMD_CPU_LEVEL_CORE },
126 { "ereport.cpu.*.l3-ucc", cmd_xxc, CMD_ERRCL_L3_UCC |
127 CMD_CPU_LEVEL_CORE },
128 { "ereport.cpu.*.l3-ucu", cmd_xxu, CMD_ERRCL_L3_UCU |
129 CMD_CPU_LEVEL_CORE },
130 { "ereport.cpu.*.l3-cpc", cmd_xxc, CMD_ERRCL_L3_CPC |
131 CMD_CPU_LEVEL_CORE },
132 { "ereport.cpu.*.l3-cpu", cmd_xxu, CMD_ERRCL_L3_CPU |
133 CMD_CPU_LEVEL_CORE },
134 { "ereport.cpu.*.l3-wdc", cmd_xxc, CMD_ERRCL_L3_WDC |
135 CMD_CPU_LEVEL_CORE },
136 { "ereport.cpu.*.l3-wdu", cmd_xxu, CMD_ERRCL_L3_WDU |
137 CMD_CPU_LEVEL_CORE },
138 { "ereport.cpu.*.l3-edc", cmd_xxc, CMD_ERRCL_L3_EDC |
139 CMD_CPU_LEVEL_CORE },
140 { "ereport.cpu.*.l3-edu-st", cmd_xxu, CMD_ERRCL_L3_EDU_ST |
141 CMD_CPU_LEVEL_CORE },
142 { "ereport.cpu.*.l3-edu-bl", cmd_xxu, CMD_ERRCL_L3_EDU_BL |
143 CMD_CPU_LEVEL_CORE },
144 { "ereport.cpu.*.l3-mecc", cmd_xxu, CMD_ERRCL_L3_MECC |
145 CMD_CPU_LEVEL_CORE },
146 { "ereport.cpu.*.ipe", cmd_icache },
147 { "ereport.cpu.*.idspe", cmd_icache },
148 { "ereport.cpu.*.itspe", cmd_icache },
149 { "ereport.cpu.*.dpe", cmd_dcache },
150 { "ereport.cpu.*.ddspe", cmd_dcache },
151 { "ereport.cpu.*.dtspe", cmd_dcache },
152 { "ereport.cpu.*.pdspe", cmd_pcache },
153 { "ereport.cpu.*.itlbpe", cmd_itlb },
154 { "ereport.cpu.*.dtlbpe", cmd_dtlb },
155 { "ereport.cpu.*.thce", cmd_txce, CMD_CPU_LEVEL_CORE },
156 { "ereport.cpu.*.tsce", cmd_txce },
157 { "ereport.cpu.*.l3-thce", cmd_l3_thce, CMD_CPU_LEVEL_CORE },
158 { "ereport.cpu.*.ce", cmd_ce },
159 { "ereport.cpu.*.emc", cmd_ce },
160 { "ereport.cpu.*.ue", cmd_ue },
161 { "ereport.cpu.*.due", cmd_ue },
162 { "ereport.cpu.*.emu", cmd_ue },
163 { "ereport.cpu.*.frc", cmd_frx, CMD_ERRCL_FRC },
164 { "ereport.cpu.*.rce", cmd_rxe, CMD_ERRCL_RCE },
165 { "ereport.cpu.*.fru", cmd_frx, CMD_ERRCL_FRU },
166 { "ereport.cpu.*.rue", cmd_rxe, CMD_ERRCL_RUE },
167 { "ereport.cpu.*.eti", cmd_txce },
168 { "ereport.cpu.*.etc", cmd_txce },
169 { "ereport.io.*.ecc.drce", cmd_ioxe, CMD_ERRCL_IOCE },
170 { "ereport.io.*.ecc.dwce", cmd_ioxe, CMD_ERRCL_IOCE },
171 { "ereport.io.*.ecc.drue", cmd_ioxe, CMD_ERRCL_IOUE },
172 { "ereport.io.*.ecc.dwue", cmd_ioxe, CMD_ERRCL_IOUE },
173 { "ereport.io.*.ecc.s-drce", cmd_ioxe_sec },
174 { "ereport.io.*.ecc.s-dwce", cmd_ioxe_sec },
175 { "ereport.io.*.ecc.s-drue", cmd_ioxe_sec },
176 { "ereport.io.*.ecc.s-dwue", cmd_ioxe_sec },
177 { "ereport.io.fire.jbc.ce_asyn", cmd_ioxe, CMD_ERRCL_IOCE },
178 { "ereport.io.fire.jbc.ue_asyn", cmd_ioxe, CMD_ERRCL_IOUE },
179 { "ereport.asic.*.cds.cds-dp", cmd_dp_cds },
180 { "ereport.asic.*.dx.dx-dp", cmd_dp_dx },
181 { "ereport.asic.*.sdi.sdi-dp", cmd_dp_ex },
182 { "ereport.asic.*.cp.cp-dp", cmd_dp_cp },
183 { "ereport.asic.*.rp.rp-dp", cmd_dp_cp },
184 { "ereport.asic.mac.mi-ue", cmd_opl_mac_common },
185 { "ereport.asic.mac.ptrl-ue", cmd_opl_mac_common },
186 { "ereport.asic.mac.mi-ce", cmd_opl_mac_common },
187 { "ereport.asic.mac.ptrl-ce", cmd_opl_mac_common },
188 { "ereport.asic.mac.ptrl-ice", cmd_opl_mac_common },
189 { "ereport.asic.mac.mi-cmpe", cmd_opl_mac_common },
190 { "ereport.asic.mac.ptrl-cmpe", cmd_opl_mac_common },
191 { "ereport.asic.mac.mi-sue", cmd_opl_mac_common },
192 { "ereport.asic.mac.ptrl-sue", cmd_opl_mac_common },
193 { "ereport.asic.mac.mi-mue", cmd_opl_mac_common },
194 { "ereport.asic.mac.ptrl-mue", cmd_opl_mac_common },
195 { "ereport.cpu.*.ue-mem", cmd_opl_cpu_mem },
196 { "ereport.cpu.*.ue-channel", cmd_nop },
197 { "ereport.cpu.*.ue-cpu", cmd_opluecpu_detcpu },
198 { "ereport.cpu.*.ue-path", cmd_nop },
199 { "ereport.cpu.*.inv-sfsr", cmd_oplinv_sfsr },
200 { "ereport.cpu.*.berr", cmd_nop },
201 { "ereport.cpu.*.bto", cmd_nop },
202 { "ereport.cpu.*.mtlb", cmd_oplmtlb },
203 { "ereport.cpu.*.tlbp", cmd_opltlbp },
204 { "ereport.cpu.*.inv-uge", cmd_oplinv_urg },
205 { "ereport.cpu.*.cre", cmd_oplcre },
206 { "ereport.cpu.*.tsb-ctx", cmd_opltsb_ctx },
207 { "ereport.cpu.*.tsbp", cmd_opltsbp },
208 { "ereport.cpu.*.pstate", cmd_oplpstate },
209 { "ereport.cpu.*.tstate", cmd_opltstate },
210 { "ereport.cpu.*.iug-f", cmd_opliug_f },
211 { "ereport.cpu.*.iug-r", cmd_opliug_r },
212 { "ereport.cpu.*.sdc", cmd_oplsdc },
213 { "ereport.cpu.*.wdt", cmd_oplwdt },
214 { "ereport.cpu.*.dtlb", cmd_opldtlb },
215 { "ereport.cpu.*.itlb", cmd_oplitlb },
216 { "ereport.cpu.*.core-err", cmd_oplcore_err },
217 { "ereport.cpu.*.dae", cmd_opldae },
218 { "ereport.cpu.*.iae", cmd_opliae },
219 { "ereport.cpu.*.uge", cmd_opluge },
220 { "ereport.io.oberon.ubc.dmarduea-mem", cmd_opl_io_mem },
221 { "ereport.io.oberon.ubc.dmarduea-channel", cmd_nop },
222 { "ereport.io.oberon.ubc.dmarduea-cpu", opl_opluecpu_detio },
223 { "ereport.io.oberon.ubc.dmarduea-path", cmd_nop },
224 { "ereport.io.oberon.ubc.dmardueb-mem", cmd_opl_io_mem },
225 { "ereport.io.oberon.ubc.dmardueb-channel", cmd_nop },
226 { "ereport.io.oberon.ubc.dmardueb-cpu", opl_opluecpu_detio },
227 { "ereport.io.oberon.ubc.dmardueb-path", cmd_nop },
228 { "ereport.io.oberon.ubc.piowtue-mem", cmd_opl_io_mem },
229 { "ereport.io.oberon.ubc.piowtue-channel", cmd_nop },
230 { "ereport.io.oberon.ubc.piowtue-cpu", opl_opluecpu_detio },
231 { "ereport.io.oberon.ubc.piowtue-path", cmd_nop },
232 { "ereport.io.oberon.ubc.piowbeue-mem", cmd_opl_io_mem },
233 { "ereport.io.oberon.ubc.piowbeue-channel", cmd_nop },
234 { "ereport.io.oberon.ubc.piowbeue-cpu", opl_opluecpu_detio },
235 { "ereport.io.oberon.ubc.piowbeue-path", cmd_nop },
236 { "ereport.io.oberon.ubc.piorbeue-mem", cmd_opl_io_mem },
237 { "ereport.io.oberon.ubc.piorbeue-channel", cmd_nop },
238 { "ereport.io.oberon.ubc.piorbeue-cpu", opl_opluecpu_detio },
239 { "ereport.io.oberon.ubc.piorbeue-path", cmd_nop },
240 { "ereport.cpu.*.fpu.fpscrub", cmd_fps },
241 #else /* i.e. sun4v */
242 { "ereport.cpu.*.irc", cmd_irc },
243 { "ereport.cpu.*.iru", cmd_iru },
244 { "ereport.cpu.*.frc", cmd_frc },
245 { "ereport.cpu.*.fru", cmd_fru },
246 { "ereport.cpu.*.mau", cmd_mau },
247 { "ereport.cpu.*.imdu", cmd_itlb, CMD_CPU_LEVEL_CORE },
248 { "ereport.cpu.*.dmdu", cmd_dtlb, CMD_CPU_LEVEL_CORE },
249 { "ereport.cpu.*.dmsu", cmd_dtlb, CMD_CPU_LEVEL_CORE },
250 { "ereport.cpu.*.imtu", cmd_itlb, CMD_CPU_LEVEL_CORE },
251 { "ereport.cpu.*.dmtu", cmd_dtlb, CMD_CPU_LEVEL_CORE },
252 { "ereport.cpu.*.itc", cmd_icache, CMD_CPU_LEVEL_CORE },
253 { "ereport.cpu.*.idc", cmd_icache, CMD_CPU_LEVEL_CORE },
254 { "ereport.cpu.*.dtc", cmd_dcache, CMD_CPU_LEVEL_CORE },
255 { "ereport.cpu.*.ddc", cmd_dcache, CMD_CPU_LEVEL_CORE },
256 { "ereport.cpu.*.irfc", cmd_irc },
257 { "ereport.cpu.*.irfu", cmd_iru },
258 { "ereport.cpu.*.frfc", cmd_frc },
259 { "ereport.cpu.*.frfu", cmd_fru },
260
261
262
263
264
265 { "ereport.cpu.*.mamu", cmd_mau, CMD_CPU_LEVEL_CORE },
266 { "ereport.cpu.*.ittm", cmd_itlb, CMD_CPU_LEVEL_CORE },
267 { "ereport.cpu.*.ittp", cmd_itlb, CMD_CPU_LEVEL_CORE },
268 { "ereport.cpu.*.itdp", cmd_itlb, CMD_CPU_LEVEL_CORE },
269 { "ereport.cpu.*.itmu", cmd_itlb, CMD_CPU_LEVEL_CORE },
270 { "ereport.cpu.*.dttm", cmd_dtlb, CMD_CPU_LEVEL_CORE },
271 { "ereport.cpu.*.dttp", cmd_dtlb, CMD_CPU_LEVEL_CORE },
272 { "ereport.cpu.*.dtdp", cmd_dtlb, CMD_CPU_LEVEL_CORE },
273 { "ereport.cpu.*.dtmu", cmd_dtlb, CMD_CPU_LEVEL_CORE },
274 { "ereport.cpu.*.icvp", cmd_icache, CMD_CPU_LEVEL_CORE },
275 { "ereport.cpu.*.ictp", cmd_icache, CMD_CPU_LEVEL_CORE },
276 { "ereport.cpu.*.ictm", cmd_icache, CMD_CPU_LEVEL_CORE },
277 { "ereport.cpu.*.icdp", cmd_xxc,
278 CMD_ERRCL_ICDP | CMD_CPU_LEVEL_CORE },
279 { "ereport.cpu.*.dcvp", cmd_dcache, CMD_CPU_LEVEL_CORE },
280 { "ereport.cpu.*.dctp", cmd_dcache, CMD_CPU_LEVEL_CORE },
281 { "ereport.cpu.*.dctm", cmd_dcache, CMD_CPU_LEVEL_CORE },
282 { "ereport.cpu.*.dcdp", cmd_xxc,
283 CMD_ERRCL_DCDP | CMD_CPU_LEVEL_CORE },
284 { "ereport.cpu.*.itl2c", cmd_xxc, CMD_ERRCL_LDAC |
285 CMD_CPU_LEVEL_CHIP },
286 { "ereport.cpu.*.dtl2c", cmd_xxc, CMD_ERRCL_LDAC |
287 CMD_CPU_LEVEL_CHIP },
288 { "ereport.cpu.*.icl2c", cmd_xxc, CMD_ERRCL_LDAC |
289 CMD_CPU_LEVEL_CHIP },
290 { "ereport.cpu.*.dcl2c", cmd_xxc, CMD_ERRCL_LDAC |
291 CMD_CPU_LEVEL_CHIP },
292 { "ereport.cpu.*.mal2c", cmd_xxc, CMD_ERRCL_LDAC |
293 CMD_CPU_LEVEL_CHIP },
294 { "ereport.cpu.*.cwql2c", cmd_xxc, CMD_ERRCL_LDAC |
295 CMD_CPU_LEVEL_CHIP },
296 { "ereport.cpu.*.lvc", cmd_txce, CMD_CPU_LEVEL_CHIP },
297 { "ereport.cpu.*.itl2u", cmd_xxu, CMD_ERRCL_IL2U |
298 CMD_CPU_LEVEL_CHIP },
299 { "ereport.cpu.*.dtl2u", cmd_xxu, CMD_ERRCL_DL2U |
300 CMD_CPU_LEVEL_CHIP },
301 { "ereport.cpu.*.icl2u", cmd_xxu, CMD_ERRCL_IL2U |
302 CMD_CPU_LEVEL_CHIP },
303 { "ereport.cpu.*.dcl2u", cmd_xxu, CMD_ERRCL_DL2U |
304 CMD_CPU_LEVEL_CHIP },
305 { "ereport.cpu.*.mal2u", cmd_xxu, CMD_ERRCL_LDAU |
306 CMD_CPU_LEVEL_CHIP },
307 { "ereport.cpu.*.cwql2u", cmd_xxu, CMD_ERRCL_LDAU |
308 CMD_CPU_LEVEL_CHIP },
309 { "ereport.cpu.*.lvf", cmd_l2ctl, CMD_CPU_LEVEL_CHIP },
310 { "ereport.cpu.*.lrf", cmd_l2ctl, CMD_CPU_LEVEL_CHIP },
311 { "ereport.cpu.*.ltu", cmd_l2ctl, CMD_CPU_LEVEL_CHIP },
312 { "ereport.cpu.*.itl2nd", cmd_nop_train, CMD_ERRCL_IL2ND },
313 { "ereport.cpu.*.dtl2nd", cmd_nop_train, CMD_ERRCL_DL2ND },
314 { "ereport.cpu.*.icl2nd", cmd_nop_train, CMD_ERRCL_IL2ND },
315 { "ereport.cpu.*.dcl2nd", cmd_nop_train, CMD_ERRCL_DL2ND },
316 { "ereport.cpu.*.l2nd", cmd_nop_train, CMD_ERRCL_L2ND },
317 { "ereport.cpu.*.mal2nd", cmd_nop_train, CMD_ERRCL_L2ND },
318 { "ereport.cpu.*.cwql2nd", cmd_nop_train, CMD_ERRCL_L2ND },
319 { "ereport.cpu.*.ldac", cmd_xxc, CMD_ERRCL_LDAC |
320 CMD_CPU_LEVEL_CHIP },
321 { "ereport.cpu.*.ldwc", cmd_xxc, CMD_ERRCL_LDWC |
322 CMD_CPU_LEVEL_CHIP },
323 { "ereport.cpu.*.ldrc", cmd_xxc, CMD_ERRCL_LDRC |
324 CMD_CPU_LEVEL_CHIP },
325 { "ereport.cpu.*.ldsc", cmd_xxc, CMD_ERRCL_LDSC |
326 CMD_CPU_LEVEL_CHIP },
327 { "ereport.cpu.*.ltc", cmd_txce, CMD_CPU_LEVEL_CHIP },
328 { "ereport.cpu.*.ldau", cmd_xxu, CMD_ERRCL_LDAU |
329 CMD_CPU_LEVEL_CHIP },
330 { "ereport.cpu.*.ldwu", cmd_xxu, CMD_ERRCL_LDWU |
331 CMD_CPU_LEVEL_CHIP },
332 { "ereport.cpu.*.ldru", cmd_xxu, CMD_ERRCL_LDRU |
333 CMD_CPU_LEVEL_CHIP },
334 { "ereport.cpu.*.ldsu", cmd_xxu, CMD_ERRCL_LDSU |
335 CMD_CPU_LEVEL_CHIP },
336 { "ereport.cpu.*.lvu", cmd_l2ctl, CMD_CPU_LEVEL_CHIP },
337 { "ereport.cpu.*.lru", cmd_l2ctl, CMD_CPU_LEVEL_CHIP },
338 { "ereport.cpu.*.fbr", cmd_fb },
339 { "ereport.cpu.*.fbu", cmd_fb_train, CMD_ERRCL_FBU },
340 { "ereport.cpu.*.dac", cmd_ce, CMD_ERRCL_DAC },
341 { "ereport.cpu.*.dsc", cmd_ce, CMD_ERRCL_DSC },
342 { "ereport.cpu.*.dau", cmd_ue_train, CMD_ERRCL_DAU },
343 { "ereport.cpu.*.dbu", cmd_fw_defect, CMD_ERRCL_DBU },
344 { "ereport.cpu.*.dsu", cmd_ue, CMD_ERRCL_DSU },
345 { "ereport.cpu.*.sbdpc", cmd_miscregs_train,
346 CMD_ERRCL_SBDPC | CMD_CPU_LEVEL_THREAD },
347 { "ereport.cpu.*.sbdlc", cmd_miscregs_train,
348 CMD_ERRCL_SBDLC | CMD_CPU_LEVEL_THREAD },
349 { "ereport.cpu.*.sbdpu", cmd_miscregs_ue,
350 CMD_CPU_LEVEL_THREAD },
351 { "ereport.cpu.*.sbdlu", cmd_miscregs_ue,
352 CMD_CPU_LEVEL_THREAD },
353 { "ereport.cpu.*.sbdio", cmd_miscregs_ue,
354 CMD_CPU_LEVEL_THREAD },
355 { "ereport.cpu.*.sbapp", cmd_miscregs_ue,
356 CMD_CPU_LEVEL_THREAD },
357 { "ereport.cpu.*.mrau", cmd_miscregs_ue,
358 CMD_CPU_LEVEL_THREAD },
359 { "ereport.cpu.*.scac", cmd_miscregs_train,
360 CMD_ERRCL_SBDPC | CMD_CPU_LEVEL_THREAD },
361 { "ereport.cpu.*.scau", cmd_miscregs_ue,
362 CMD_CPU_LEVEL_THREAD },
363 { "ereport.cpu.*.tccp", cmd_miscregs_train,
364 CMD_ERRCL_TCCP | CMD_CPU_LEVEL_THREAD },
365 { "ereport.cpu.*.tccd", cmd_miscregs_train,
366 CMD_ERRCL_TCCD | CMD_CPU_LEVEL_THREAD },
367 { "ereport.cpu.*.tcup", cmd_miscregs_ue,
368 CMD_CPU_LEVEL_THREAD },
369 { "ereport.cpu.*.tcud", cmd_miscregs_ue,
370 CMD_CPU_LEVEL_THREAD },
371 { "ereport.cpu.*.tsac", cmd_miscregs_train,
372 CMD_ERRCL_SBDPC | CMD_CPU_LEVEL_THREAD },
373 { "ereport.cpu.*.tsau", cmd_miscregs_ue,
374 CMD_CPU_LEVEL_THREAD },
375 { "ereport.cpu.*.cbce", cmd_xxc, CMD_ERRCL_CBCE |
376 CMD_CPU_LEVEL_CHIP },
377 { "ereport.cpu.*.dce", cmd_nop },
378 { "ereport.cpu.*.wbue", cmd_xxu, CMD_ERRCL_WBUE |
379 CMD_CPU_LEVEL_CHIP },
380 { "ereport.cpu.*.lfu-slf", cmd_lfu_ce, CMD_CPU_LEVEL_CHIP },
381 { "ereport.cpu.*.lfu-rtf", cmd_lfu_ue, CMD_CPU_LEVEL_CHIP },
382 { "ereport.cpu.*.lfu-tto", cmd_lfu_ue, CMD_CPU_LEVEL_CHIP },
383 { "ereport.cpu.*.lfu-cto", cmd_lfu_ue, CMD_CPU_LEVEL_CHIP },
384 { "ereport.cpu.*.lfu-mlf", cmd_lfu_ue, CMD_CPU_LEVEL_CHIP },
385 { "ereport.cpu.*.frack", cmd_lfu_pe, CMD_CPU_LEVEL_CHIP },
386 { "ereport.cpu.*.fsr", cmd_lfu_pe, CMD_CPU_LEVEL_CHIP },
387 { "ereport.cpu.*.fdr", cmd_lfu_pe, CMD_CPU_LEVEL_CHIP },
388 { "ereport.cpu.*.to", cmd_lfu_pe, CMD_CPU_LEVEL_CHIP },
389 { "ereport.cpu.*.snptyp", cmd_lfu_pe, CMD_CPU_LEVEL_CHIP },
390 { "ereport.fm.ferg.invalid", cmd_fw_defect },
391 #endif /* sun4u */
392 { "ereport.cpu.*.fpu.hwcopy", cmd_fpu },
393 { NULL, NULL }
394 };
395
396 static void
cmd_recv(fmd_hdl_t * hdl,fmd_event_t * ep,nvlist_t * nvl,const char * class)397 cmd_recv(fmd_hdl_t *hdl, fmd_event_t *ep, nvlist_t *nvl, const char *class)
398 {
399 cmd_subscriber_t *sp;
400 int disp;
401
402 fmd_hdl_debug(hdl, "cmd_recv: begin: %s\n", strrchr(class, '.') + 1);
403
404 for (sp = cmd_subscribers; sp->subr_class != NULL; sp++) {
405 if (fmd_nvl_class_match(hdl, nvl, sp->subr_class)) {
406 disp = sp->subr_func(hdl, ep, nvl, class, sp->subr_arg);
407 ((fmd_stat_t *)&sp->subr_stat)[disp].fmds_value.ui64++;
408 fmd_hdl_debug(hdl, "cmd_recv: done: %s (disp %d)\n",
409 strrchr(class, '.') + 1, disp);
410 return;
411 }
412 }
413
414 fmd_hdl_debug(hdl, "cmd_recv: dropping %s - unable to handle\n", class);
415 }
416
417 static void
cmd_timeout(fmd_hdl_t * hdl,id_t id,void * arg)418 cmd_timeout(fmd_hdl_t *hdl, id_t id, void *arg)
419 {
420 uintptr_t timertype = (uintptr_t)arg;
421
422 switch (timertype) {
423 case CMD_TIMERTYPE_MEM:
424 cmd_mem_timeout(hdl, id);
425 break;
426
427 #ifdef sun4u
428 case CMD_TIMERTYPE_DP:
429
430 cmd_dp_timeout(hdl, id);
431 break;
432 case CMD_TIMERTYPE_ANONYMOUS_TAG_ERROR:
433
434 cmd_Lxcache_anonymous_tag_error_timeout(hdl, id);
435 break;
436 #endif
437
438 case CMD_TIMERTYPE_CPU_UEC_FLUSH:
439 case CMD_TIMERTYPE_CPU_XR_WAITER:
440 cmd_cpu_timeout(hdl, id, (void *)timertype);
441 break;
442
443 default:
444 break;
445 }
446 }
447
448 static void
cmd_close(fmd_hdl_t * hdl,fmd_case_t * cp)449 cmd_close(fmd_hdl_t *hdl, fmd_case_t *cp)
450 {
451 cmd_case_closer_t *cl = fmd_case_getspecific(hdl, cp);
452 const char *uuid = fmd_case_uuid(hdl, cp);
453
454 /*
455 * Our active cases all have closers registered in case-specific data.
456 * Cases in the process of closing (for which we've freed all associated
457 * data, but which haven't had an fmd-initiated fmdo_close callback)
458 * have had their case-specific data nulled out.
459 */
460 fmd_hdl_debug(hdl, "close case %s%s\n", uuid,
461 (cl == NULL ? " (no cl)" : ""));
462
463 if (cl != NULL)
464 cl->cl_func(hdl, cl->cl_arg);
465 }
466
467 static void
cmd_gc(fmd_hdl_t * hdl)468 cmd_gc(fmd_hdl_t *hdl)
469 {
470 cmd_cpu_gc(hdl);
471 cmd_mem_gc(hdl);
472 #ifdef sun4u
473 cmd_Lxcache_gc(hdl);
474 #endif
475 }
476
477 static cmd_stat_t cmd_stats = {
478 { "bad_det", FMD_TYPE_UINT64, "detector missing or malformed" },
479 { "bad_cpu_asru", FMD_TYPE_UINT64, "CPU ASRU missing or malformed" },
480 { "bad_mem_asru", FMD_TYPE_UINT64, "memory ASRU missing or malformed" },
481 { "bad_close", FMD_TYPE_UINT64, "case close for nonexistent case" },
482 { "old_erpt", FMD_TYPE_UINT64, "ereport out of date wrt hardware" },
483 { "cpu_creat", FMD_TYPE_UINT64, "created new cpu structure" },
484 { "dimm_creat", FMD_TYPE_UINT64, "created new mem module structure" },
485 { "bank_creat", FMD_TYPE_UINT64, "created new mem bank structure" },
486 { "page_creat", FMD_TYPE_UINT64, "created new page structure" },
487 { "cache_creat", FMD_TYPE_UINT64, "created new cache structure" },
488 { "ce_unknown", FMD_TYPE_UINT64, "unknown CEs" },
489 { "ce_interm", FMD_TYPE_UINT64, "intermittent CEs" },
490 { "ce_ppersis", FMD_TYPE_UINT64, "possibly persistent CEs" },
491 { "ce_persis", FMD_TYPE_UINT64, "persistent CEs" },
492 { "ce_leaky", FMD_TYPE_UINT64, "leaky CEs" },
493 { "ce_psticky_noptnr", FMD_TYPE_UINT64,
494 "possibly sticky CEs, no partner test" },
495 { "ce_psticky_ptnrnoerr", FMD_TYPE_UINT64,
496 "possibly sticky CEs, partner sees no CE" },
497 { "ce_psticky_ptnrclrd", FMD_TYPE_UINT64,
498 "possibly sticky CEs, partner can clear CE" },
499 { "ce_sticky", FMD_TYPE_UINT64, "sticky CEs" },
500 { "xxu_ue_match", FMD_TYPE_UINT64, "xxUs obviated by UEs" },
501 { "xxu_retr_flt", FMD_TYPE_UINT64, "xxUs obviated by faults" },
502 { "cpu_migrat", FMD_TYPE_UINT64, "CPUs migrated to new version" },
503 { "dimm_migrat", FMD_TYPE_UINT64, "DIMMs migrated to new version" },
504 { "bank_migrat", FMD_TYPE_UINT64, "banks migrated to new version" },
505 #ifdef sun4u
506 { "dp_ignored_ce", FMD_TYPE_UINT64,
507 "memory CEs ignored due to DP error or fault" },
508 { "dp_ignored_ue", FMD_TYPE_UINT64,
509 "memory UEs ignored due to DP fault" },
510 { "dp_deferred_ue", FMD_TYPE_UINT64,
511 "memory UEs deferred due to DP error" },
512 #endif
513 #ifdef sun4v
514 { "branch_creat", FMD_TYPE_UINT64, "created new mem branch structure" },
515 #endif
516 };
517
518 static const fmd_prop_t fmd_props[] = {
519 { "icache_n", FMD_TYPE_UINT32, "8" },
520 { "icache_t", FMD_TYPE_TIME, "168h" },
521 { "dcache_n", FMD_TYPE_UINT32, "8" },
522 { "dcache_t", FMD_TYPE_TIME, "168h" },
523 { "pcache_n", FMD_TYPE_UINT32, "2" },
524 { "pcache_t", FMD_TYPE_TIME, "168h" },
525 #ifdef sun4u
526 { "itlb_n", FMD_TYPE_UINT32, "2" },
527 { "itlb_t", FMD_TYPE_TIME, "168h" },
528 { "dtlb_n", FMD_TYPE_UINT32, "2" },
529 { "dtlb_t", FMD_TYPE_TIME, "168h" },
530 { "l2tag_n", FMD_TYPE_UINT32, "4" },
531 { "l2tag_t", FMD_TYPE_TIME, "1h" },
532 { "l2data_n", FMD_TYPE_UINT32, "12" },
533 { "l2data_t", FMD_TYPE_TIME, "1h" },
534 #else
535 { "itlb_n", FMD_TYPE_UINT32, "8" },
536 { "itlb_t", FMD_TYPE_TIME, "168h" },
537 { "dtlb_n", FMD_TYPE_UINT32, "8" },
538 { "dtlb_t", FMD_TYPE_TIME, "168h" },
539 { "l2tag_n", FMD_TYPE_UINT32, "8" },
540 { "l2tag_t", FMD_TYPE_TIME, "20h" },
541 { "l2data_n", FMD_TYPE_UINT32, "8" },
542 { "l2data_t", FMD_TYPE_TIME, "2h" },
543 #endif
544 { "l3tag_n", FMD_TYPE_UINT32, "4" },
545 { "l3tag_t", FMD_TYPE_TIME, "1h" },
546 { "l3data_n", FMD_TYPE_UINT32, "12" },
547 { "l3data_t", FMD_TYPE_TIME, "1h" },
548 { "ce_n", FMD_TYPE_UINT32, "2" },
549 { "ce_t", FMD_TYPE_TIME, "72h" },
550 { "ireg_n", FMD_TYPE_UINT32, "8" },
551 { "ireg_t", FMD_TYPE_TIME, "168h" },
552 { "freg_n", FMD_TYPE_UINT32, "8" },
553 { "freg_t", FMD_TYPE_TIME, "168h" },
554 { "mau_n", FMD_TYPE_UINT32, "0" },
555 { "mau_t", FMD_TYPE_TIME, "168h" },
556 { "misc_regs_n", FMD_TYPE_UINT32, "8"},
557 { "misc_regs_t", FMD_TYPE_TIME, "168h" },
558 { "iorxefrx_window", FMD_TYPE_TIME, "3s" },
559 #ifdef sun4u
560 { "xxcu_trdelay", FMD_TYPE_TIME, "200ms" },
561 #else
562 { "xxcu_trdelay", FMD_TYPE_TIME, "15s"},
563 #endif /* sun4u */
564 { "xxcu_restart_delay", FMD_TYPE_TIME, "1s" },
565 { "num_xxcu_waiters", FMD_TYPE_UINT32, "128" },
566 { "thresh_tpct_sysmem", FMD_TYPE_UINT64, "100" },
567 { "thresh_abs_sysmem", FMD_TYPE_UINT64, "0" },
568 { "thresh_abs_badrw", FMD_TYPE_UINT64, "128" },
569 { "max_perm_ce_dimm", FMD_TYPE_UINT32, "128" },
570 { "low_ce_thresh", FMD_TYPE_UINT32, "128" },
571 { "hi_ce_thresh", FMD_TYPE_UINT32, "512" },
572 { "dupce", FMD_TYPE_UINT32, "120"},
573 { "nupos", FMD_TYPE_UINT32, "4"},
574 #ifdef sun4v
575 { "fbr_n", FMD_TYPE_UINT32, "14" },
576 { "fbr_t", FMD_TYPE_TIME, "30min"},
577 /* delta_ena value = 0x500000000nsec ~= 22sec */
578 { "delta_ena", FMD_TYPE_UINT64, "0x50000000000000"},
579 #endif
580 { NULL, 0, NULL }
581 };
582
583 static const fmd_hdl_ops_t fmd_ops = {
584 cmd_recv, /* fmdo_recv */
585 cmd_timeout, /* fmdo_timeout */
586 cmd_close, /* fmdo_close */
587 NULL, /* fmdo_stats */
588 cmd_gc /* fmdo_gc */
589 };
590
591 static const fmd_hdl_info_t fmd_info = {
592 "CPU/Memory Diagnosis", CMD_VERSION, &fmd_ops, fmd_props
593 };
594
595 static const struct cmd_evdisp_name {
596 const char *evn_name;
597 const char *evn_desc;
598 } cmd_evdisp_names[] = {
599 { "%s", "ok %s ereports" }, /* CMD_EVD_OK */
600 { "bad_%s", "bad %s ereports" }, /* CMD_EVD_BAD */
601 { "unused_%s", "unused %s ereports" }, /* CMD_EVD_UNUSED */
602 { "redun_%s", "redundant %s ereports" }, /* CMD_EVD_REDUN */
603 };
604
605 void
_fmd_fini(fmd_hdl_t * hdl)606 _fmd_fini(fmd_hdl_t *hdl)
607 {
608
609 #ifdef sun4v
610 ldom_fini(cpumem_diagnosis_lhp);
611 #endif
612 cmd_cpu_fini(hdl);
613 cmd_mem_fini(hdl);
614 cmd_page_fini(hdl);
615 #ifdef sun4u
616 cmd_dp_fini(hdl);
617 #endif
618
619 fmd_hdl_free(hdl, cmd.cmd_xxcu_trw,
620 sizeof (cmd_xxcu_trw_t) * cmd.cmd_xxcu_ntrw);
621 nvlist_free(cmd.cmd_auth);
622 }
623
624 #ifdef sun4v
625 static void *
cpumem_diagnosis_init_alloc(size_t size)626 cpumem_diagnosis_init_alloc(size_t size)
627 {
628 return (fmd_hdl_alloc(init_hdl, size, FMD_SLEEP));
629 }
630
631 static void
cpumem_diagnosis_init_free(void * addr,size_t size)632 cpumem_diagnosis_init_free(void *addr, size_t size)
633 {
634 fmd_hdl_free(init_hdl, addr, size);
635 }
636 #endif
637
638 /* find_auth -- find hardware platform authority within libtopo */
639
640 /* ARGSUSED */
641 static int
find_auth(topo_hdl_t * thp,tnode_t * node,void * arg)642 find_auth(topo_hdl_t *thp, tnode_t *node, void *arg)
643 {
644 int err;
645 nvlist_t *rsrc, *auth;
646
647 if (cmd.cmd_auth != NULL)
648 return (TOPO_WALK_TERMINATE); /* don't overwrite previous */
649
650 if (topo_node_resource(node, &rsrc, &err) < 0)
651 return (TOPO_WALK_NEXT); /* no resource, try next */
652 if (nvlist_lookup_nvlist(rsrc, FM_FMRI_AUTHORITY, &auth) < 0) {
653 nvlist_free(rsrc);
654 return (TOPO_WALK_NEXT); /* no authority, try next */
655 }
656 (void) nvlist_dup(auth, &cmd.cmd_auth, NV_UNIQUE_NAME);
657 nvlist_free(rsrc);
658 return (TOPO_WALK_TERMINATE); /* if no space, give up */
659 }
660
661 /* init_auth -- read hardware platform authority from libtopo */
662
663 void
init_auth(fmd_hdl_t * hdl)664 init_auth(fmd_hdl_t *hdl)
665 {
666 topo_hdl_t *thp;
667 topo_walk_t *twp;
668 int err;
669
670 if ((thp = fmd_hdl_topo_hold(hdl, TOPO_VERSION)) == NULL)
671 return;
672 if ((twp = topo_walk_init(thp,
673 FM_FMRI_SCHEME_HC, find_auth, NULL, &err))
674 == NULL) {
675 fmd_hdl_topo_rele(hdl, thp);
676 return;
677 }
678 (void) topo_walk_step(twp, TOPO_WALK_CHILD);
679 topo_walk_fini(twp);
680 fmd_hdl_topo_rele(hdl, thp);
681 }
682
683 void
_fmd_init(fmd_hdl_t * hdl)684 _fmd_init(fmd_hdl_t *hdl)
685 {
686 cmd_subscriber_t *sp;
687 cpu_family_t cpu_family;
688
689 if (fmd_hdl_register(hdl, FMD_API_VERSION, &fmd_info) != 0)
690 return; /* error in configuration file or fmd_info */
691
692 cpu_family = cmd_cpu_check_support();
693
694 if (cpu_family == CMD_CPU_FAM_UNSUPPORTED) {
695 fmd_hdl_debug(hdl, "no supported CPUs found");
696 fmd_hdl_unregister(hdl);
697 return;
698 }
699
700 fmd_hdl_subscribe(hdl, "ereport.cpu.ultraSPARC-III.*");
701 fmd_hdl_subscribe(hdl, "ereport.cpu.ultraSPARC-IIIplus.*");
702 fmd_hdl_subscribe(hdl, "ereport.cpu.ultraSPARC-IIIi.*");
703 fmd_hdl_subscribe(hdl, "ereport.cpu.ultraSPARC-IIIiplus.*");
704 fmd_hdl_subscribe(hdl, "ereport.cpu.ultraSPARC-IV.*");
705 fmd_hdl_subscribe(hdl, "ereport.cpu.ultraSPARC-IVplus.*");
706 fmd_hdl_subscribe(hdl, "ereport.cpu.ultraSPARC-T2.*");
707 fmd_hdl_subscribe(hdl, "ereport.cpu.ultraSPARC-T2plus.*");
708 fmd_hdl_subscribe(hdl, "ereport.cpu.ultraSPARC-T1.*");
709 fmd_hdl_subscribe(hdl, "ereport.fm.ferg.invalid");
710
711 fmd_hdl_subscribe(hdl, "ereport.io.tom.ecc.drce");
712 fmd_hdl_subscribe(hdl, "ereport.io.tom.ecc.dwce");
713 fmd_hdl_subscribe(hdl, "ereport.io.tom.ecc.drue");
714 fmd_hdl_subscribe(hdl, "ereport.io.tom.ecc.dwue");
715 fmd_hdl_subscribe(hdl, "ereport.io.sch.ecc.drce");
716 fmd_hdl_subscribe(hdl, "ereport.io.sch.ecc.dwce");
717 fmd_hdl_subscribe(hdl, "ereport.io.sch.ecc.drue");
718 fmd_hdl_subscribe(hdl, "ereport.io.sch.ecc.dwue");
719 fmd_hdl_subscribe(hdl, "ereport.io.xmits.ecc.drce");
720 fmd_hdl_subscribe(hdl, "ereport.io.xmits.ecc.dwce");
721 fmd_hdl_subscribe(hdl, "ereport.io.xmits.ecc.drue");
722 fmd_hdl_subscribe(hdl, "ereport.io.xmits.ecc.dwue");
723
724 /*
725 * Need to subscribe to secondary I/O ECC ereports, but
726 * since they contain no data regarding the failure we
727 * are unable to do anything with them.
728 */
729 fmd_hdl_subscribe(hdl, "ereport.io.tom.ecc.s-drce");
730 fmd_hdl_subscribe(hdl, "ereport.io.tom.ecc.s-dwce");
731 fmd_hdl_subscribe(hdl, "ereport.io.tom.ecc.s-drue");
732 fmd_hdl_subscribe(hdl, "ereport.io.tom.ecc.s-dwue");
733 fmd_hdl_subscribe(hdl, "ereport.io.sch.ecc.s-drce");
734 fmd_hdl_subscribe(hdl, "ereport.io.sch.ecc.s-dwce");
735 fmd_hdl_subscribe(hdl, "ereport.io.sch.ecc.s-drue");
736 fmd_hdl_subscribe(hdl, "ereport.io.sch.ecc.s-dwue");
737 fmd_hdl_subscribe(hdl, "ereport.io.xmits.ecc.s-drce");
738 fmd_hdl_subscribe(hdl, "ereport.io.xmits.ecc.s-dwce");
739 fmd_hdl_subscribe(hdl, "ereport.io.xmits.ecc.s-drue");
740 fmd_hdl_subscribe(hdl, "ereport.io.xmits.ecc.s-dwue");
741
742 #ifdef sun4u
743 /*
744 * Subscribe to datapath events
745 */
746 fmd_hdl_subscribe(hdl, "ereport.asic.*.cds.cds-dp");
747 fmd_hdl_subscribe(hdl, "ereport.asic.*.dx.dx-dp");
748 fmd_hdl_subscribe(hdl, "ereport.asic.*.sdi.sdi-dp");
749 fmd_hdl_subscribe(hdl, "ereport.asic.*.cp.cp-dp");
750 fmd_hdl_subscribe(hdl, "ereport.asic.*.rp.rp-dp");
751
752 /*
753 * OPL platform specific subscriptions.
754 */
755 fmd_hdl_subscribe(hdl, "ereport.cpu.SPARC64-VI.*");
756 fmd_hdl_subscribe(hdl, "ereport.cpu.SPARC64-VII.*");
757 fmd_hdl_subscribe(hdl, "ereport.asic.mac.*");
758 fmd_hdl_subscribe(hdl, "ereport.io.oberon.ubc.dmarduea-mem");
759 fmd_hdl_subscribe(hdl, "ereport.io.oberon.ubc.dmarduea-channel");
760 fmd_hdl_subscribe(hdl, "ereport.io.oberon.ubc.dmarduea-cpu");
761 fmd_hdl_subscribe(hdl, "ereport.io.oberon.ubc.dmarduea-path");
762 fmd_hdl_subscribe(hdl, "ereport.io.oberon.ubc.dmardueb-mem");
763 fmd_hdl_subscribe(hdl, "ereport.io.oberon.ubc.dmardueb-channel");
764 fmd_hdl_subscribe(hdl, "ereport.io.oberon.ubc.dmardueb-cpu");
765 fmd_hdl_subscribe(hdl, "ereport.io.oberon.ubc.dmardueb-path");
766 fmd_hdl_subscribe(hdl, "ereport.io.oberon.ubc.piowtue-mem");
767 fmd_hdl_subscribe(hdl, "ereport.io.oberon.ubc.piowtue-channel");
768 fmd_hdl_subscribe(hdl, "ereport.io.oberon.ubc.piowtue-cpu");
769 fmd_hdl_subscribe(hdl, "ereport.io.oberon.ubc.piowtue-path");
770 fmd_hdl_subscribe(hdl, "ereport.io.oberon.ubc.piowbeue-mem");
771 fmd_hdl_subscribe(hdl, "ereport.io.oberon.ubc.piowbeue-channel");
772 fmd_hdl_subscribe(hdl, "ereport.io.oberon.ubc.piowbeue-cpu");
773 fmd_hdl_subscribe(hdl, "ereport.io.oberon.ubc.piowbeue-path");
774 fmd_hdl_subscribe(hdl, "ereport.io.oberon.ubc.piorbeue-mem");
775 fmd_hdl_subscribe(hdl, "ereport.io.oberon.ubc.piorbeue-channel");
776 fmd_hdl_subscribe(hdl, "ereport.io.oberon.ubc.piorbeue-cpu");
777 fmd_hdl_subscribe(hdl, "ereport.io.oberon.ubc.piorbeue-path");
778 #endif
779 fmd_hdl_subscribe(hdl, "ereport.io.fire.jbc.ce_asyn");
780 fmd_hdl_subscribe(hdl, "ereport.io.fire.jbc.ue_asyn");
781
782 bzero(&cmd, sizeof (cmd_t));
783
784 #ifdef sun4u
785 bzero(&opl_cpu_list, sizeof (cmd_list_t));
786 #endif /* sun4u */
787
788 cmd.cmd_stats = (cmd_stat_t *)fmd_stat_create(hdl, FMD_STAT_NOALLOC,
789 sizeof (cmd_stats) / sizeof (fmd_stat_t),
790 (fmd_stat_t *)&cmd_stats);
791
792 for (sp = cmd_subscribers; sp->subr_class != NULL; sp++) {
793 const char *type = strrchr(sp->subr_class, '.') + 1;
794 int i;
795
796 for (i = 0; i < sizeof (cmd_evdisp_names) /
797 sizeof (struct cmd_evdisp_name); i++) {
798 fmd_stat_t *stat = ((fmd_stat_t *)&sp->subr_stat) + i;
799
800 (void) snprintf(stat->fmds_name,
801 sizeof (stat->fmds_name),
802 cmd_evdisp_names[i].evn_name, type);
803
804 stat->fmds_type = FMD_TYPE_UINT64;
805 (void) snprintf(stat->fmds_desc,
806 sizeof (stat->fmds_desc),
807 cmd_evdisp_names[i].evn_desc, type);
808
809 (void) fmd_stat_create(hdl, FMD_STAT_NOALLOC, 1, stat);
810 }
811 }
812
813 cmd.cmd_pagesize = sysconf(_SC_PAGESIZE);
814 cmd.cmd_pagemask = ~((uint64_t)cmd.cmd_pagesize - 1);
815
816 cmd.cmd_iorxefrx_window = fmd_prop_get_int64(hdl, "iorxefrx_window");
817
818 #ifdef sun4u
819 if (cmd_cpu_ecache_support() && cmd_ecache_init() < 0) {
820 _fmd_fini(hdl);
821 fmd_hdl_abort(hdl, "failed to find device for E-cache flush");
822 }
823 #endif
824
825 if ((cmd.cmd_thresh_tpct_sysmem = fmd_prop_get_int64(hdl,
826 "thresh_tpct_sysmem")) > 100000) {
827 _fmd_fini(hdl);
828 fmd_hdl_abort(hdl, "page retirement threshold is >100%");
829 }
830
831 cmd.cmd_thresh_abs_sysmem = fmd_prop_get_int64(hdl,
832 "thresh_abs_sysmem");
833 cmd.cmd_thresh_abs_badrw = fmd_prop_get_int64(hdl,
834 "thresh_abs_badrw");
835
836 cmd.cmd_xxcu_trdelay = fmd_prop_get_int64(hdl, "xxcu_trdelay");
837
838 cmd.cmd_xxcu_ntrw = fmd_prop_get_int32(hdl, "num_xxcu_waiters");
839 cmd.cmd_xxcu_trw = fmd_hdl_zalloc(hdl, sizeof (cmd_xxcu_trw_t) *
840 cmd.cmd_xxcu_ntrw, FMD_SLEEP);
841 cmd.cmd_low_ce_thresh = fmd_prop_get_int32(hdl, "low_ce_thresh");
842 cmd.cmd_hi_ce_thresh = fmd_prop_get_int32(hdl, "hi_ce_thresh");
843 cmd.cmd_dupce = fmd_prop_get_int32(hdl, "dupce");
844 cmd.cmd_nupos = fmd_prop_get_int32(hdl, "nupos");
845
846 #ifdef sun4v
847 cmd.cmd_delta_ena = fmd_prop_get_int64(hdl, "delta_ena");
848 #endif
849
850 cmd.cmd_l2data_serd.cs_name = "l2data";
851 cmd.cmd_l2data_serd.cs_n = fmd_prop_get_int32(hdl, "l2data_n");
852 cmd.cmd_l2data_serd.cs_t = fmd_prop_get_int64(hdl, "l2data_t");
853
854 cmd.cmd_l3data_serd.cs_name = "l3data";
855 cmd.cmd_l3data_serd.cs_n = fmd_prop_get_int32(hdl, "l3data_n");
856 cmd.cmd_l3data_serd.cs_t = fmd_prop_get_int64(hdl, "l3data_t");
857
858 cmd.cmd_miscregs_serd.cs_name = "misc_regs";
859 cmd.cmd_miscregs_serd.cs_n = fmd_prop_get_int32(hdl, "misc_regs_n");
860 cmd.cmd_miscregs_serd.cs_t = fmd_prop_get_int64(hdl, "misc_regs_t");
861
862 cmd.cmd_dcache_serd.cs_name = "dcache";
863 cmd.cmd_dcache_serd.cs_n = fmd_prop_get_int32(hdl, "dcache_n");
864 cmd.cmd_dcache_serd.cs_t = fmd_prop_get_int64(hdl, "dcache_t");
865
866 cmd.cmd_icache_serd.cs_name = "icache";
867 cmd.cmd_icache_serd.cs_n = fmd_prop_get_int32(hdl, "icache_n");
868 cmd.cmd_icache_serd.cs_t = fmd_prop_get_int64(hdl, "icache_t");
869
870 if (cmd_state_restore(hdl) < 0) {
871 _fmd_fini(hdl);
872 fmd_hdl_abort(hdl, "failed to restore saved state\n");
873 }
874
875 #ifdef sun4v
876 init_hdl = hdl;
877 cpumem_diagnosis_lhp = ldom_init(cpumem_diagnosis_init_alloc,
878 cpumem_diagnosis_init_free);
879 #endif
880
881 init_auth(hdl);
882 }
883