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
)
73 if ((kc
= kstat_open()) == NULL
) {
77 /* For each board in the system, read the kstats for it. */
78 for (bnode
= tree
->bd_list
; bnode
!= NULL
; bnode
= bnode
->next
) {
82 * Kstat instances numbers are set by fhc, ac, simmstat,
83 * and environ drivers based on their board# property.
85 board
= bnode
->board_num
;
86 bdp
= &sys_kstat
->bd_ksp_list
[board
];
88 /* Try to find an FHC instance for this board number */
89 ksp
= kstat_lookup(kc
, UNIX
, board
, FHC_KSTAT_NAME
);
91 /* Atempt to read the FHC kstat */
92 if ((ksp
!= NULL
) && (kstat_read(kc
, ksp
, NULL
) == -1)) {
96 /* Now read out the data if the kstat read OK */
99 * We set the kstats_ok flag to good here. If we
100 * fail one of the data reads, we set it to bad.
102 bdp
->fhc_kstats_ok
= 1;
105 * For each data value, If the Kstat named struct
106 * is found, then get the data out.
108 knp
= kstat_data_lookup(ksp
, CSR_KSTAT_NAMED
);
110 bdp
->fhc_csr
= knp
->value
.ul
;
112 bdp
->fhc_kstats_ok
= 0;
114 knp
= kstat_data_lookup(ksp
, BSR_KSTAT_NAMED
);
116 bdp
->fhc_bsr
= knp
->value
.ul
;
118 bdp
->fhc_kstats_ok
= 0;
122 /* Try to find an AC instance for this board number */
123 ksp
= kstat_lookup(kc
, UNIX
, board
, AC_KSTAT_NAME
);
125 /* Attempt to read the AC kstat. */
126 if ((ksp
!= NULL
) && (kstat_read(kc
, ksp
, NULL
) == -1)) {
130 /* If the AC kstat exists, try to read the data from it. */
133 * We set the kstats_ok flag to good here. If we
134 * fail one of the data reads, we set it to bad.
136 bdp
->ac_kstats_ok
= 1;
137 bdp
->ac_memstat_ok
= 1;
140 * For each data value, If the Kstat named struct
141 * is found, then get the data out.
144 knp
= kstat_data_lookup(ksp
, MEMCTL_KSTAT_NAMED
);
146 bdp
->ac_memctl
= knp
->value
.ull
;
148 bdp
->ac_kstats_ok
= 0;
151 knp
= kstat_data_lookup(ksp
, MEMDECODE0_KSTAT_NAMED
);
153 bdp
->ac_memdecode
[0] = knp
->value
.ull
;
155 bdp
->ac_kstats_ok
= 0;
158 knp
= kstat_data_lookup(ksp
, MEMDECODE1_KSTAT_NAMED
);
160 bdp
->ac_memdecode
[1] = knp
->value
.ull
;
162 bdp
->ac_kstats_ok
= 0;
165 knp
= kstat_data_lookup(ksp
, BANK_0_KSTAT_NAMED
);
167 bdp
->mem_stat
[0].status
= knp
->value
.c
[0];
168 bdp
->mem_stat
[0].condition
= knp
->value
.c
[1];
170 bdp
->ac_memstat_ok
= 0;
173 knp
= kstat_data_lookup(ksp
, BANK_1_KSTAT_NAMED
);
175 bdp
->mem_stat
[1].status
= knp
->value
.c
[0];
176 bdp
->mem_stat
[1].condition
= knp
->value
.c
[1];
178 bdp
->ac_memstat_ok
= 0;
183 /* Try to find an simmstat instance for this board number */
184 ksp
= kstat_lookup(kc
, UNIX
, board
, SIMMSTAT_KSTAT_NAME
);
187 if (kstat_read(kc
, ksp
, NULL
) == -1) {
188 bdp
->simmstat_kstats_ok
= 0;
190 bdp
->simmstat_kstats_ok
= 1;
191 (void) memcpy(&bdp
->simm_status
, ksp
->ks_data
,
192 sizeof (bdp
->simm_status
));
196 /* Try to find an overtemp kstat instance for this board */
197 ksp
= kstat_lookup(kc
, UNIX
, board
, OVERTEMP_KSTAT_NAME
);
200 if (kstat_read(kc
, ksp
, NULL
) == -1) {
201 bdp
->temp_kstat_ok
= 0;
203 bdp
->temp_kstat_ok
= 1;
204 (void) memcpy(&bdp
->tempstat
, ksp
->ks_data
,
205 sizeof (bdp
->tempstat
));
206 /* XXX - this is for 2.5.1 testing. remove */
207 if (sizeof (bdp
->tempstat
) > ksp
->ks_data_size
)
208 bdp
->tempstat
.trend
= TREND_UNKNOWN
;
213 /* Read the kstats for the system control board */
214 ksp
= kstat_lookup(kc
, UNIX
, 0, SYSCTRL_KSTAT_NAME
);
216 if ((ksp
!= NULL
) && (kstat_read(kc
, ksp
, NULL
) == -1)) {
217 sys_kstat
->sys_kstats_ok
= 0;
222 sys_kstat
->sys_kstats_ok
= 1;
224 knp
= kstat_data_lookup(ksp
, CSR_KSTAT_NAMED
);
226 sys_kstat
->sysctrl
= knp
->value
.c
[0];
228 sys_kstat
->sys_kstats_ok
= 0;
231 knp
= kstat_data_lookup(ksp
, STAT1_KSTAT_NAMED
);
233 sys_kstat
->sysstat1
= knp
->value
.c
[0];
235 sys_kstat
->sys_kstats_ok
= 0;
238 knp
= kstat_data_lookup(ksp
, STAT2_KSTAT_NAMED
);
240 sys_kstat
->sysstat2
= knp
->value
.c
[0];
242 sys_kstat
->sys_kstats_ok
= 0;
245 knp
= kstat_data_lookup(ksp
, CLK_FREQ2_KSTAT_NAMED
);
247 sys_kstat
->clk_freq2
= knp
->value
.c
[0];
249 sys_kstat
->sys_kstats_ok
= 0;
252 knp
= kstat_data_lookup(ksp
, FAN_KSTAT_NAMED
);
254 sys_kstat
->fan_status
= knp
->value
.c
[0];
256 sys_kstat
->sys_kstats_ok
= 0;
259 knp
= kstat_data_lookup(ksp
, KEY_KSTAT_NAMED
);
261 sys_kstat
->keysw_status
= knp
->value
.c
[0];
263 sys_kstat
->sys_kstats_ok
= 0;
266 knp
= kstat_data_lookup(ksp
, POWER_KSTAT_NAMED
);
268 sys_kstat
->power_state
=
269 (enum power_state
)knp
->value
.l
;
271 sys_kstat
->sys_kstats_ok
= 0;
274 knp
= kstat_data_lookup(ksp
, CLK_VER_KSTAT_NAME
);
276 sys_kstat
->clk_ver
= knp
->value
.c
[0];
279 * the clock version register only appears
280 * on new clock boards
282 sys_kstat
->clk_ver
= 0;
287 /* Read the kstats for the power supply stats */
288 ksp
= kstat_lookup(kc
, UNIX
, 0, PSSHAD_KSTAT_NAME
);
290 if ((ksp
!= NULL
) && (kstat_read(kc
, ksp
, NULL
) != -1)) {
291 sys_kstat
->psstat_kstat_ok
= 1;
292 (void) memcpy(&sys_kstat
->ps_shadow
[0], ksp
->ks_data
,
293 sizeof (sys_kstat
->ps_shadow
));
295 sys_kstat
->psstat_kstat_ok
= 0;
298 /* read the overtemp kstat for the system control board */
299 /* Try to find an overtemp kstat instance for this board */
300 ksp
= kstat_lookup(kc
, UNIX
, CLOCK_BOARD_INDEX
, OVERTEMP_KSTAT_NAME
);
303 if (kstat_read(kc
, ksp
, NULL
) == -1) {
304 sys_kstat
->temp_kstat_ok
= 0;
306 sys_kstat
->temp_kstat_ok
= 1;
307 (void) memcpy(&sys_kstat
->tempstat
, ksp
->ks_data
,
308 sizeof (sys_kstat
->tempstat
));
309 /* XXX - this is for 2.5.1 testing. remove */
310 if (sizeof (sys_kstat
->tempstat
) > ksp
->ks_data_size
)
311 sys_kstat
->tempstat
.trend
= TREND_UNKNOWN
;
315 /* Read the reset-info kstat from one of the boards. */
316 ksp
= kstat_lookup(kc
, UNIX
, 0, RESETINFO_KSTAT_NAME
);
319 sys_kstat
->reset_kstats_ok
= 0;
320 } else if (kstat_read(kc
, ksp
, NULL
) == -1) {
321 sys_kstat
->reset_kstats_ok
= 0;
323 sys_kstat
->reset_kstats_ok
= 1;
324 (void) memcpy(&sys_kstat
->reset_info
, ksp
->ks_data
,
325 sizeof (sys_kstat
->reset_info
));
328 /* read kstats for hotplugged boards */
329 for (i
= 0, hp
= &sys_kstat
->hp_info
[0]; i
< MAX_BOARDS
; i
++, hp
++) {
330 ksp
= kstat_lookup(kc
, UNIX
, i
, BDLIST_KSTAT_NAME
);
336 if (kstat_read(kc
, ksp
, NULL
) == -1) {
340 (void) memcpy(&hp
->bd_info
, ksp
->ks_data
,
341 sizeof (hp
->bd_info
));
345 /* read in the kstat for the fault list. */
346 ksp
= kstat_lookup(kc
, UNIX
, 0, FT_LIST_KSTAT_NAME
);
349 sys_kstat
->ft_kstat_ok
= 0;
351 if (kstat_read(kc
, ksp
, NULL
) == -1) {
352 perror("kstat read");
353 sys_kstat
->ft_kstat_ok
= 0;
357 sys_kstat
->nfaults
= ksp
->ks_data_size
/
358 sizeof (struct ft_list
);
360 sys_kstat
->ft_array
=
361 (struct ft_list
*)malloc(ksp
->ks_data_size
);
363 if (sys_kstat
->ft_array
== NULL
) {
367 sys_kstat
->ft_kstat_ok
= 1;
368 (void) memcpy(sys_kstat
->ft_array
, ksp
->ks_data
,
374 * This function does the reading and interpreting of sun4u system
375 * kstats. These kstats are created by the following drivers:
376 * fhc, environ, sysctrl. Each board in the tree should have
377 * kstats created for it. There are also system wide kstats that
381 read_sun4u_kstats(Sys_tree
*tree
, struct system_kstat_data
*sys_kstat
)
388 struct envctrltwo_kstat_data
*ecp
;
392 struct bd_kstat_data
*bdp
;
393 struct envctrl_kstat_data
*ep
;
395 if ((kc
= kstat_open()) == NULL
) {
399 /* Initialize the kstats structure */
400 sys_kstat
->sys_kstats_ok
= 0;
401 sys_kstat
->temp_kstat_ok
= 0;
402 sys_kstat
->reset_kstats_ok
= 0;
403 sys_kstat
->ft_kstat_ok
= 0;
404 sys_kstat
->envctrl_kstat_ok
= 0;
405 for (i
= 0; i
< MAX_BOARDS
; i
++) {
406 bdp
= &sys_kstat
->bd_ksp_list
[i
];
407 bdp
->ac_kstats_ok
= 0;
408 bdp
->fhc_kstats_ok
= 0;
409 bdp
->simmstat_kstats_ok
= 0;
410 bdp
->temp_kstat_ok
= 0;
412 sys_kstat
->hp_info
[i
].kstat_ok
= 0;
414 for (i
= 0; i
< MAX_DEVS
; i
++) {
415 ep
= &sys_kstat
->env_data
;
416 ep
->ps_kstats
[i
].instance
= I2C_NODEV
;
417 ep
->fan_kstats
[i
].instance
= I2C_NODEV
;
418 ep
->encl_kstats
[i
].instance
= I2C_NODEV
;
421 read_platform_kstats(tree
, sys_kstat
, bdp
, ep
);