4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 1999 by Sun Microsystems, Inc.
24 * All rights reserved.
27 #pragma ident "%Z%%M% %I% %E% SMI"
40 #include <sys/param.h>
42 #include <sys/types.h>
43 #include <sys/utsname.h>
44 #include <sys/openpromio.h>
51 #include "pdevinfo_sun4u.h"
52 #include "display_sun4u.h"
53 #include "libprtdiag.h"
56 * This module does the reading and interpreting of sun4u system
57 * kstats. These kstats are created by the following drivers:
58 * fhc, environ, sysctrl. Each board in the tree should have
59 * kstats created for it. There are also system wide kstats that
63 read_platform_kstats(Sys_tree
*tree
, struct system_kstat_data
*sys_kstat
,
64 struct bd_kstat_data
*bdp
, struct envctrl_kstat_data
*ep
)
76 if ((kc
= kstat_open()) == NULL
) {
80 /* For each board in the system, read the kstats for it. */
81 for (bnode
= tree
->bd_list
; bnode
!= NULL
; bnode
= bnode
->next
) {
85 * Kstat instances numbers are set by fhc, ac, simmstat,
86 * and environ drivers based on their board# property.
88 board
= bnode
->board_num
;
89 bdp
= &sys_kstat
->bd_ksp_list
[board
];
91 /* Try to find an FHC instance for this board number */
92 ksp
= kstat_lookup(kc
, UNIX
, board
, FHC_KSTAT_NAME
);
94 /* Atempt to read the FHC kstat */
95 if ((ksp
!= NULL
) && (kstat_read(kc
, ksp
, NULL
) == -1)) {
99 /* Now read out the data if the kstat read OK */
102 * We set the kstats_ok flag to good here. If we
103 * fail one of the data reads, we set it to bad.
105 bdp
->fhc_kstats_ok
= 1;
108 * For each data value, If the Kstat named struct
109 * is found, then get the data out.
111 knp
= kstat_data_lookup(ksp
, CSR_KSTAT_NAMED
);
113 bdp
->fhc_csr
= knp
->value
.ul
;
115 bdp
->fhc_kstats_ok
= 0;
117 knp
= kstat_data_lookup(ksp
, BSR_KSTAT_NAMED
);
119 bdp
->fhc_bsr
= knp
->value
.ul
;
121 bdp
->fhc_kstats_ok
= 0;
125 /* Try to find an AC instance for this board number */
126 ksp
= kstat_lookup(kc
, UNIX
, board
, AC_KSTAT_NAME
);
128 /* Attempt to read the AC kstat. */
129 if ((ksp
!= NULL
) && (kstat_read(kc
, ksp
, NULL
) == -1)) {
133 /* If the AC kstat exists, try to read the data from it. */
136 * We set the kstats_ok flag to good here. If we
137 * fail one of the data reads, we set it to bad.
139 bdp
->ac_kstats_ok
= 1;
140 bdp
->ac_memstat_ok
= 1;
143 * For each data value, If the Kstat named struct
144 * is found, then get the data out.
147 knp
= kstat_data_lookup(ksp
, MEMCTL_KSTAT_NAMED
);
149 bdp
->ac_memctl
= knp
->value
.ull
;
151 bdp
->ac_kstats_ok
= 0;
154 knp
= kstat_data_lookup(ksp
, MEMDECODE0_KSTAT_NAMED
);
156 bdp
->ac_memdecode
[0] = knp
->value
.ull
;
158 bdp
->ac_kstats_ok
= 0;
161 knp
= kstat_data_lookup(ksp
, MEMDECODE1_KSTAT_NAMED
);
163 bdp
->ac_memdecode
[1] = knp
->value
.ull
;
165 bdp
->ac_kstats_ok
= 0;
168 knp
= kstat_data_lookup(ksp
, BANK_0_KSTAT_NAMED
);
170 bdp
->mem_stat
[0].status
= knp
->value
.c
[0];
171 bdp
->mem_stat
[0].condition
= knp
->value
.c
[1];
173 bdp
->ac_memstat_ok
= 0;
176 knp
= kstat_data_lookup(ksp
, BANK_1_KSTAT_NAMED
);
178 bdp
->mem_stat
[1].status
= knp
->value
.c
[0];
179 bdp
->mem_stat
[1].condition
= knp
->value
.c
[1];
181 bdp
->ac_memstat_ok
= 0;
186 /* Try to find an simmstat instance for this board number */
187 ksp
= kstat_lookup(kc
, UNIX
, board
, SIMMSTAT_KSTAT_NAME
);
190 if (kstat_read(kc
, ksp
, NULL
) == -1) {
191 bdp
->simmstat_kstats_ok
= 0;
193 bdp
->simmstat_kstats_ok
= 1;
194 (void) memcpy(&bdp
->simm_status
, ksp
->ks_data
,
195 sizeof (bdp
->simm_status
));
199 /* Try to find an overtemp kstat instance for this board */
200 ksp
= kstat_lookup(kc
, UNIX
, board
, OVERTEMP_KSTAT_NAME
);
203 if (kstat_read(kc
, ksp
, NULL
) == -1) {
204 bdp
->temp_kstat_ok
= 0;
206 bdp
->temp_kstat_ok
= 1;
207 (void) memcpy(&bdp
->tempstat
, ksp
->ks_data
,
208 sizeof (bdp
->tempstat
));
209 /* XXX - this is for 2.5.1 testing. remove */
210 if (sizeof (bdp
->tempstat
) > ksp
->ks_data_size
)
211 bdp
->tempstat
.trend
= TREND_UNKNOWN
;
216 /* Read the kstats for the system control board */
217 ksp
= kstat_lookup(kc
, UNIX
, 0, SYSCTRL_KSTAT_NAME
);
219 if ((ksp
!= NULL
) && (kstat_read(kc
, ksp
, NULL
) == -1)) {
220 sys_kstat
->sys_kstats_ok
= 0;
225 sys_kstat
->sys_kstats_ok
= 1;
227 knp
= kstat_data_lookup(ksp
, CSR_KSTAT_NAMED
);
229 sys_kstat
->sysctrl
= knp
->value
.c
[0];
231 sys_kstat
->sys_kstats_ok
= 0;
234 knp
= kstat_data_lookup(ksp
, STAT1_KSTAT_NAMED
);
236 sys_kstat
->sysstat1
= knp
->value
.c
[0];
238 sys_kstat
->sys_kstats_ok
= 0;
241 knp
= kstat_data_lookup(ksp
, STAT2_KSTAT_NAMED
);
243 sys_kstat
->sysstat2
= knp
->value
.c
[0];
245 sys_kstat
->sys_kstats_ok
= 0;
248 knp
= kstat_data_lookup(ksp
, CLK_FREQ2_KSTAT_NAMED
);
250 sys_kstat
->clk_freq2
= knp
->value
.c
[0];
252 sys_kstat
->sys_kstats_ok
= 0;
255 knp
= kstat_data_lookup(ksp
, FAN_KSTAT_NAMED
);
257 sys_kstat
->fan_status
= knp
->value
.c
[0];
259 sys_kstat
->sys_kstats_ok
= 0;
262 knp
= kstat_data_lookup(ksp
, KEY_KSTAT_NAMED
);
264 sys_kstat
->keysw_status
= knp
->value
.c
[0];
266 sys_kstat
->sys_kstats_ok
= 0;
269 knp
= kstat_data_lookup(ksp
, POWER_KSTAT_NAMED
);
271 sys_kstat
->power_state
=
272 (enum power_state
)knp
->value
.l
;
274 sys_kstat
->sys_kstats_ok
= 0;
277 knp
= kstat_data_lookup(ksp
, CLK_VER_KSTAT_NAME
);
279 sys_kstat
->clk_ver
= knp
->value
.c
[0];
282 * the clock version register only appears
283 * on new clock boards
285 sys_kstat
->clk_ver
= 0;
290 /* Read the kstats for the power supply stats */
291 ksp
= kstat_lookup(kc
, UNIX
, 0, PSSHAD_KSTAT_NAME
);
293 if ((ksp
!= NULL
) && (kstat_read(kc
, ksp
, NULL
) != -1)) {
294 sys_kstat
->psstat_kstat_ok
= 1;
295 (void) memcpy(&sys_kstat
->ps_shadow
[0], ksp
->ks_data
,
296 sizeof (sys_kstat
->ps_shadow
));
298 sys_kstat
->psstat_kstat_ok
= 0;
301 /* read the overtemp kstat for the system control board */
302 /* Try to find an overtemp kstat instance for this board */
303 ksp
= kstat_lookup(kc
, UNIX
, CLOCK_BOARD_INDEX
, OVERTEMP_KSTAT_NAME
);
306 if (kstat_read(kc
, ksp
, NULL
) == -1) {
307 sys_kstat
->temp_kstat_ok
= 0;
309 sys_kstat
->temp_kstat_ok
= 1;
310 (void) memcpy(&sys_kstat
->tempstat
, ksp
->ks_data
,
311 sizeof (sys_kstat
->tempstat
));
312 /* XXX - this is for 2.5.1 testing. remove */
313 if (sizeof (sys_kstat
->tempstat
) > ksp
->ks_data_size
)
314 sys_kstat
->tempstat
.trend
= TREND_UNKNOWN
;
318 /* Read the reset-info kstat from one of the boards. */
319 ksp
= kstat_lookup(kc
, UNIX
, 0, RESETINFO_KSTAT_NAME
);
322 sys_kstat
->reset_kstats_ok
= 0;
323 } else if (kstat_read(kc
, ksp
, NULL
) == -1) {
324 sys_kstat
->reset_kstats_ok
= 0;
326 sys_kstat
->reset_kstats_ok
= 1;
327 (void) memcpy(&sys_kstat
->reset_info
, ksp
->ks_data
,
328 sizeof (sys_kstat
->reset_info
));
331 /* read kstats for hotplugged boards */
332 for (i
= 0, hp
= &sys_kstat
->hp_info
[0]; i
< MAX_BOARDS
; i
++, hp
++) {
333 ksp
= kstat_lookup(kc
, UNIX
, i
, BDLIST_KSTAT_NAME
);
339 if (kstat_read(kc
, ksp
, NULL
) == -1) {
343 (void) memcpy(&hp
->bd_info
, ksp
->ks_data
,
344 sizeof (hp
->bd_info
));
348 /* read in the kstat for the fault list. */
349 ksp
= kstat_lookup(kc
, UNIX
, 0, FT_LIST_KSTAT_NAME
);
352 sys_kstat
->ft_kstat_ok
= 0;
354 if (kstat_read(kc
, ksp
, NULL
) == -1) {
355 perror("kstat read");
356 sys_kstat
->ft_kstat_ok
= 0;
360 sys_kstat
->nfaults
= ksp
->ks_data_size
/
361 sizeof (struct ft_list
);
363 sys_kstat
->ft_array
=
364 (struct ft_list
*)malloc(ksp
->ks_data_size
);
366 if (sys_kstat
->ft_array
== NULL
) {
370 sys_kstat
->ft_kstat_ok
= 1;
371 (void) memcpy(sys_kstat
->ft_array
, ksp
->ks_data
,
377 * This function does the reading and interpreting of sun4u system
378 * kstats. These kstats are created by the following drivers:
379 * fhc, environ, sysctrl. Each board in the tree should have
380 * kstats created for it. There are also system wide kstats that
384 read_sun4u_kstats(Sys_tree
*tree
, struct system_kstat_data
*sys_kstat
)
391 struct envctrltwo_kstat_data
*ecp
;
395 struct bd_kstat_data
*bdp
;
396 struct envctrl_kstat_data
*ep
;
398 if ((kc
= kstat_open()) == NULL
) {
405 /* Initialize the kstats structure */
406 sys_kstat
->sys_kstats_ok
= 0;
407 sys_kstat
->temp_kstat_ok
= 0;
408 sys_kstat
->reset_kstats_ok
= 0;
409 sys_kstat
->ft_kstat_ok
= 0;
410 sys_kstat
->envctrl_kstat_ok
= 0;
411 for (i
= 0; i
< MAX_BOARDS
; i
++) {
412 bdp
= &sys_kstat
->bd_ksp_list
[i
];
413 bdp
->ac_kstats_ok
= 0;
414 bdp
->fhc_kstats_ok
= 0;
415 bdp
->simmstat_kstats_ok
= 0;
416 bdp
->temp_kstat_ok
= 0;
418 sys_kstat
->hp_info
[i
].kstat_ok
= 0;
420 for (i
= 0; i
< MAX_DEVS
; i
++) {
421 ep
= &sys_kstat
->env_data
;
422 ep
->ps_kstats
[i
].instance
= I2C_NODEV
;
423 ep
->fan_kstats
[i
].instance
= I2C_NODEV
;
424 ep
->encl_kstats
[i
].instance
= I2C_NODEV
;
427 read_platform_kstats(tree
, sys_kstat
, bdp
, ep
);