1*4777Smcwalter /*
2*4777Smcwalter * CDDL HEADER START
3*4777Smcwalter *
4*4777Smcwalter * The contents of this file are subject to the terms of the
5*4777Smcwalter * Common Development and Distribution License (the "License").
6*4777Smcwalter * You may not use this file except in compliance with the License.
7*4777Smcwalter *
8*4777Smcwalter * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*4777Smcwalter * or http://www.opensolaris.org/os/licensing.
10*4777Smcwalter * See the License for the specific language governing permissions
11*4777Smcwalter * and limitations under the License.
12*4777Smcwalter *
13*4777Smcwalter * When distributing Covered Code, include this CDDL HEADER in each
14*4777Smcwalter * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*4777Smcwalter * If applicable, add the following below this CDDL HEADER, with the
16*4777Smcwalter * fields enclosed by brackets "[]" replaced with your own identifying
17*4777Smcwalter * information: Portions Copyright [yyyy] [name of copyright owner]
18*4777Smcwalter *
19*4777Smcwalter * CDDL HEADER END
20*4777Smcwalter */
21*4777Smcwalter /*
22*4777Smcwalter * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23*4777Smcwalter * Use is subject to license terms.
24*4777Smcwalter */
25*4777Smcwalter
26*4777Smcwalter /*
27*4777Smcwalter * Sun4v Platform specific functions.
28*4777Smcwalter *
29*4777Smcwalter * called when :
30*4777Smcwalter * machine_type == monza
31*4777Smcwalter *
32*4777Smcwalter */
33*4777Smcwalter
34*4777Smcwalter #pragma ident "%Z%%M% %I% %E% SMI"
35*4777Smcwalter
36*4777Smcwalter #include <stdio.h>
37*4777Smcwalter #include <stdlib.h>
38*4777Smcwalter #include <unistd.h>
39*4777Smcwalter #include <kstat.h>
40*4777Smcwalter #include <fcntl.h>
41*4777Smcwalter #include <string.h>
42*4777Smcwalter #include <assert.h>
43*4777Smcwalter #include <libintl.h>
44*4777Smcwalter #include <note.h>
45*4777Smcwalter #include <sys/systeminfo.h>
46*4777Smcwalter #include <sys/openpromio.h>
47*4777Smcwalter #include <sys/sysmacros.h>
48*4777Smcwalter #include <picl.h>
49*4777Smcwalter #include "picldefs.h"
50*4777Smcwalter #include <pdevinfo.h>
51*4777Smcwalter #include <display.h>
52*4777Smcwalter #include <display_sun4v.h>
53*4777Smcwalter #include <libprtdiag.h>
54*4777Smcwalter #include "monza.h"
55*4777Smcwalter
56*4777Smcwalter #if !defined(TEXT_DOMAIN)
57*4777Smcwalter #define TEXT_DOMAIN "SYS_TEST"
58*4777Smcwalter #endif
59*4777Smcwalter
60*4777Smcwalter /*
61*4777Smcwalter * These functions will overlay the symbol table of libprtdiag
62*4777Smcwalter * at runtime
63*4777Smcwalter */
64*4777Smcwalter void sun4v_display_pci(picl_nodehdl_t plafh);
65*4777Smcwalter void sun4v_display_diaginfo(int flag, Prom_node *root, picl_nodehdl_t plafh);
66*4777Smcwalter
67*4777Smcwalter
68*4777Smcwalter /*
69*4777Smcwalter * local functions
70*4777Smcwalter */
71*4777Smcwalter static void sun4v_display_hw_revisions(Prom_node *root, picl_nodehdl_t plafh);
72*4777Smcwalter static int monza_pci_callback(picl_nodehdl_t pcih, void *args);
73*4777Smcwalter static int monza_get_first_compatible_value(picl_nodehdl_t nodeh,
74*4777Smcwalter char **outbuf);
75*4777Smcwalter static int64_t monza_get_int_propval(picl_nodehdl_t modh, char *prop_name,
76*4777Smcwalter int *ret);
77*4777Smcwalter
78*4777Smcwalter static void
monza_get_bus_type(char * path,struct io_card * card)79*4777Smcwalter monza_get_bus_type(char *path, struct io_card *card)
80*4777Smcwalter {
81*4777Smcwalter if (strcmp(path, MONZA_NIU) == 0) {
82*4777Smcwalter (void) strcpy(card->bus_type, "NIU");
83*4777Smcwalter } else {
84*4777Smcwalter (void) strcpy(card->bus_type, "PCIE");
85*4777Smcwalter }
86*4777Smcwalter }
87*4777Smcwalter
88*4777Smcwalter static void
monza_get_slot_number(char * path,struct io_card * card)89*4777Smcwalter monza_get_slot_number(char *path, struct io_card *card)
90*4777Smcwalter {
91*4777Smcwalter if (strcmp(path, MONZA_N2_XAUI0) == 0) {
92*4777Smcwalter (void) strcpy(card->slot_str, "0");
93*4777Smcwalter card->slot = 0;
94*4777Smcwalter } else if (strcmp(path, MONZA_N2_XAUI1) == 0) {
95*4777Smcwalter (void) strcpy(card->slot_str, "1");
96*4777Smcwalter card->slot = 1;
97*4777Smcwalter } else {
98*4777Smcwalter (void) strcpy(card->slot_str, MOTHERBOARD);
99*4777Smcwalter card->slot = -1;
100*4777Smcwalter }
101*4777Smcwalter }
102*4777Smcwalter
103*4777Smcwalter static int
monza_get_network_instance(char * path)104*4777Smcwalter monza_get_network_instance(char *path)
105*4777Smcwalter {
106*4777Smcwalter
107*4777Smcwalter if (strncmp(path, MONZA_NETWORK_0, strlen(MONZA_NETWORK_0)) == 0) {
108*4777Smcwalter return (0);
109*4777Smcwalter } else if (strncmp(path, MONZA_NETWORK_1, strlen(MONZA_NETWORK_1))
110*4777Smcwalter == 0) {
111*4777Smcwalter return (1);
112*4777Smcwalter } else if (strncmp(path, MONZA_NETWORK_2, strlen(MONZA_NETWORK_2))
113*4777Smcwalter == 0) {
114*4777Smcwalter return (2);
115*4777Smcwalter } else if (strncmp(path, MONZA_ENET_2, strlen(MONZA_ENET_2))
116*4777Smcwalter == 0) {
117*4777Smcwalter return (2);
118*4777Smcwalter } else if (strncmp(path, MONZA_NETWORK_3, strlen(MONZA_NETWORK_3))
119*4777Smcwalter == 0) {
120*4777Smcwalter return (3);
121*4777Smcwalter } else if (strncmp(path, MONZA_ENET_3, strlen(MONZA_ENET_3))
122*4777Smcwalter == 0) {
123*4777Smcwalter return (3);
124*4777Smcwalter } else if (strncmp(path, MONZA_NETWORK_4, strlen(MONZA_NETWORK_4))
125*4777Smcwalter == 0) {
126*4777Smcwalter return (4);
127*4777Smcwalter } else if (strncmp(path, MONZA_NETWORK_5, strlen(MONZA_NETWORK_5))
128*4777Smcwalter == 0) {
129*4777Smcwalter return (5);
130*4777Smcwalter } else if (strncmp(path, MONZA_N2_XAUI0, strlen(MONZA_N2_XAUI0))
131*4777Smcwalter == 0) {
132*4777Smcwalter return (0);
133*4777Smcwalter } else if (strncmp(path, MONZA_N2_XAUI1, strlen(MONZA_N2_XAUI1))
134*4777Smcwalter == 0) {
135*4777Smcwalter return (1);
136*4777Smcwalter } else {
137*4777Smcwalter return (-1);
138*4777Smcwalter }
139*4777Smcwalter }
140*4777Smcwalter
141*4777Smcwalter /*
142*4777Smcwalter * add all io devices under pci in io list
143*4777Smcwalter */
144*4777Smcwalter /* ARGSUSED */
145*4777Smcwalter static int
monza_pci_callback(picl_nodehdl_t pcih,void * args)146*4777Smcwalter monza_pci_callback(picl_nodehdl_t pcih, void *args)
147*4777Smcwalter {
148*4777Smcwalter int err = PICL_SUCCESS;
149*4777Smcwalter picl_nodehdl_t nodeh;
150*4777Smcwalter char path[MAXSTRLEN];
151*4777Smcwalter char parent_path[MAXSTRLEN];
152*4777Smcwalter char piclclass[PICL_CLASSNAMELEN_MAX];
153*4777Smcwalter char name[MAXSTRLEN];
154*4777Smcwalter char model[MAXSTRLEN];
155*4777Smcwalter char *compatible;
156*4777Smcwalter char binding_name[MAXSTRLEN];
157*4777Smcwalter struct io_card pci_card;
158*4777Smcwalter int32_t instance;
159*4777Smcwalter
160*4777Smcwalter err = picl_get_propval_by_name(pcih, PICL_PROP_DEVFS_PATH, parent_path,
161*4777Smcwalter sizeof (parent_path));
162*4777Smcwalter if (err != PICL_SUCCESS) {
163*4777Smcwalter return (err);
164*4777Smcwalter }
165*4777Smcwalter
166*4777Smcwalter /*
167*4777Smcwalter * Walk through the children
168*4777Smcwalter */
169*4777Smcwalter err = picl_get_propval_by_name(pcih, PICL_PROP_CHILD, &nodeh,
170*4777Smcwalter sizeof (picl_nodehdl_t));
171*4777Smcwalter
172*4777Smcwalter while (err == PICL_SUCCESS) {
173*4777Smcwalter err = picl_get_propval_by_name(nodeh, PICL_PROP_CLASSNAME,
174*4777Smcwalter piclclass, sizeof (piclclass));
175*4777Smcwalter if (err != PICL_SUCCESS)
176*4777Smcwalter return (err);
177*4777Smcwalter
178*4777Smcwalter /*
179*4777Smcwalter * Skip PCI and PCIEX devices because they will be processed
180*4777Smcwalter * later in the picl tree walk.
181*4777Smcwalter */
182*4777Smcwalter if ((strcmp(piclclass, PCIEX) == 0) ||
183*4777Smcwalter (strcmp(piclclass, PCI) == 0)) {
184*4777Smcwalter err = picl_get_propval_by_name(nodeh, PICL_PROP_PEER,
185*4777Smcwalter &nodeh, sizeof (picl_nodehdl_t));
186*4777Smcwalter continue;
187*4777Smcwalter }
188*4777Smcwalter
189*4777Smcwalter err = picl_get_propval_by_name(nodeh, PICL_PROP_DEVFS_PATH,
190*4777Smcwalter path, sizeof (path));
191*4777Smcwalter if (err != PICL_SUCCESS) {
192*4777Smcwalter return (err);
193*4777Smcwalter }
194*4777Smcwalter
195*4777Smcwalter (void) strlcpy(pci_card.notes, path, sizeof (pci_card.notes));
196*4777Smcwalter
197*4777Smcwalter monza_get_bus_type(parent_path, &pci_card);
198*4777Smcwalter
199*4777Smcwalter err = picl_get_propval_by_name(nodeh, PICL_PROP_NAME, &name,
200*4777Smcwalter sizeof (name));
201*4777Smcwalter if (err == PICL_PROPNOTFOUND)
202*4777Smcwalter (void) strcpy(name, "");
203*4777Smcwalter else if (err != PICL_SUCCESS)
204*4777Smcwalter return (err);
205*4777Smcwalter
206*4777Smcwalter if (strcmp(parent_path, MONZA_NIU) == 0)
207*4777Smcwalter monza_get_slot_number(path, &pci_card);
208*4777Smcwalter else
209*4777Smcwalter monza_get_slot_number(parent_path, &pci_card);
210*4777Smcwalter
211*4777Smcwalter err = picl_get_propval_by_name(nodeh, PICL_PROP_NAME, &name,
212*4777Smcwalter sizeof (name));
213*4777Smcwalter if (err == PICL_PROPNOTFOUND)
214*4777Smcwalter (void) strcpy(name, "");
215*4777Smcwalter else if (err != PICL_SUCCESS)
216*4777Smcwalter return (err);
217*4777Smcwalter
218*4777Smcwalter /* Figure NAC name */
219*4777Smcwalter if ((strcmp(name, NETWORK) == 0 ||
220*4777Smcwalter strcmp(name, ETHERNET) == 0) &&
221*4777Smcwalter (strcmp(pci_card.slot_str, MOTHERBOARD) == 0)) {
222*4777Smcwalter instance = monza_get_network_instance(path);
223*4777Smcwalter
224*4777Smcwalter (void) snprintf(pci_card.status,
225*4777Smcwalter sizeof (pci_card.status), "%s/%s%d", MOTHERBOARD,
226*4777Smcwalter "NET", instance);
227*4777Smcwalter } else {
228*4777Smcwalter if (pci_card.slot != -1) {
229*4777Smcwalter (void) snprintf(pci_card.status,
230*4777Smcwalter sizeof (pci_card.status), "%s/%s%d",
231*4777Smcwalter IOBOARD, pci_card.bus_type, pci_card.slot);
232*4777Smcwalter } else {
233*4777Smcwalter (void) snprintf(pci_card.status,
234*4777Smcwalter sizeof (pci_card.status),
235*4777Smcwalter "%s/%s", MOTHERBOARD, pci_card.bus_type);
236*4777Smcwalter }
237*4777Smcwalter }
238*4777Smcwalter
239*4777Smcwalter /*
240*4777Smcwalter * Get the name of this card. If binding_name is found,
241*4777Smcwalter * name will be <nodename>-<binding_name>
242*4777Smcwalter */
243*4777Smcwalter
244*4777Smcwalter err = picl_get_propval_by_name(nodeh, PICL_PROP_BINDING_NAME,
245*4777Smcwalter &binding_name, sizeof (binding_name));
246*4777Smcwalter if (err == PICL_PROPNOTFOUND) {
247*4777Smcwalter /*
248*4777Smcwalter * if compatible prop is found, name will be
249*4777Smcwalter * <nodename>-<compatible>
250*4777Smcwalter */
251*4777Smcwalter err = monza_get_first_compatible_value(nodeh,
252*4777Smcwalter &compatible);
253*4777Smcwalter if (err == PICL_SUCCESS) {
254*4777Smcwalter (void) strlcat(name, "-", MAXSTRLEN);
255*4777Smcwalter (void) strlcat(name, compatible, MAXSTRLEN);
256*4777Smcwalter free(compatible);
257*4777Smcwalter } else if (err != PICL_PROPNOTFOUND) {
258*4777Smcwalter return (err);
259*4777Smcwalter }
260*4777Smcwalter } else if (err != PICL_SUCCESS) {
261*4777Smcwalter return (err);
262*4777Smcwalter } else if (strcmp(name, binding_name) != 0) {
263*4777Smcwalter (void) strlcat(name, "-", MAXSTRLEN);
264*4777Smcwalter (void) strlcat(name, binding_name, MAXSTRLEN);
265*4777Smcwalter }
266*4777Smcwalter
267*4777Smcwalter (void) strlcpy(pci_card.name, name, sizeof (pci_card.name));
268*4777Smcwalter
269*4777Smcwalter /* Get the model of this card */
270*4777Smcwalter
271*4777Smcwalter err = picl_get_propval_by_name(nodeh, OBP_PROP_MODEL,
272*4777Smcwalter &model, sizeof (model));
273*4777Smcwalter if (err == PICL_PROPNOTFOUND)
274*4777Smcwalter (void) strcpy(model, "");
275*4777Smcwalter else if (err != PICL_SUCCESS)
276*4777Smcwalter return (err);
277*4777Smcwalter (void) strlcpy(pci_card.model, model, sizeof (pci_card.model));
278*4777Smcwalter
279*4777Smcwalter /* Print NAC name */
280*4777Smcwalter log_printf("%-11s", pci_card.status);
281*4777Smcwalter /* Print IO Type */
282*4777Smcwalter log_printf("%6s", pci_card.bus_type);
283*4777Smcwalter /* Print Slot # */
284*4777Smcwalter log_printf("%5s", pci_card.slot_str);
285*4777Smcwalter /* Print Parent Path */
286*4777Smcwalter log_printf("%46.45s", pci_card.notes);
287*4777Smcwalter /* Printf Card Name */
288*4777Smcwalter if (strlen(pci_card.name) > 24)
289*4777Smcwalter log_printf("%25.24s+", pci_card.name);
290*4777Smcwalter else
291*4777Smcwalter log_printf("%26s", pci_card.name);
292*4777Smcwalter /* Print Card Model */
293*4777Smcwalter if (strlen(pci_card.model) > 10)
294*4777Smcwalter log_printf("%10.9s+", pci_card.model);
295*4777Smcwalter else
296*4777Smcwalter log_printf("%10s", pci_card.model);
297*4777Smcwalter log_printf("\n");
298*4777Smcwalter
299*4777Smcwalter err = picl_get_propval_by_name(nodeh, PICL_PROP_PEER, &nodeh,
300*4777Smcwalter sizeof (picl_nodehdl_t));
301*4777Smcwalter
302*4777Smcwalter }
303*4777Smcwalter
304*4777Smcwalter return (PICL_WALK_CONTINUE);
305*4777Smcwalter }
306*4777Smcwalter
307*4777Smcwalter /*
308*4777Smcwalter * display_pci
309*4777Smcwalter * Display all the PCI IO cards on this board.
310*4777Smcwalter */
311*4777Smcwalter void
sun4v_display_pci(picl_nodehdl_t plafh)312*4777Smcwalter sun4v_display_pci(picl_nodehdl_t plafh)
313*4777Smcwalter {
314*4777Smcwalter char platbuf[MAXSTRLEN];
315*4777Smcwalter char *fmt = "%-11s %-7s %-4s %-46s %-25s %-8s";
316*4777Smcwalter static int banner = FALSE; /* Have we printed the column headings? */
317*4777Smcwalter
318*4777Smcwalter if (banner == FALSE) {
319*4777Smcwalter log_printf("\n", 0);
320*4777Smcwalter log_printf("=========================", 0);
321*4777Smcwalter log_printf(dgettext(TEXT_DOMAIN, " IO Configuration "), 0);
322*4777Smcwalter log_printf("=========================", 0);
323*4777Smcwalter log_printf("\n", 0);
324*4777Smcwalter log_printf("\n", 0);
325*4777Smcwalter log_printf(fmt, "", "IO", "", "", "", "", 0);
326*4777Smcwalter log_printf("\n", 0);
327*4777Smcwalter log_printf(fmt, "Location", "Type", "Slot", "Path",
328*4777Smcwalter "Name", "Model", 0);
329*4777Smcwalter log_printf("\n");
330*4777Smcwalter log_printf(fmt, "-----------", "-----", "----",
331*4777Smcwalter "---------------------------------------------",
332*4777Smcwalter "-------------------------", "---------", 0);
333*4777Smcwalter log_printf("\n");
334*4777Smcwalter banner = TRUE;
335*4777Smcwalter }
336*4777Smcwalter
337*4777Smcwalter /* Get platform name, if that fails, use monza name by default */
338*4777Smcwalter if (sysinfo(SI_PLATFORM, platbuf, sizeof (platbuf)) == -1) {
339*4777Smcwalter (void) strcpy(platbuf, MONZA_PLATFORM);
340*4777Smcwalter }
341*4777Smcwalter
342*4777Smcwalter (void) picl_walk_tree_by_class(plafh, PCIEX, PCIEX, monza_pci_callback);
343*4777Smcwalter (void) picl_walk_tree_by_class(plafh, PCI, PCI, monza_pci_callback);
344*4777Smcwalter }
345*4777Smcwalter
346*4777Smcwalter /* ARGSUSED */
347*4777Smcwalter void
sun4v_display_diaginfo(int flag,Prom_node * root,picl_nodehdl_t plafh)348*4777Smcwalter sun4v_display_diaginfo(int flag, Prom_node *root, picl_nodehdl_t plafh)
349*4777Smcwalter {
350*4777Smcwalter /* NOTE(ARGUNUSED(kstats)) */
351*4777Smcwalter /*
352*4777Smcwalter * Now display the last powerfail time and the fatal hardware
353*4777Smcwalter * reset information. We do this under a couple of conditions.
354*4777Smcwalter * First if the user asks for it. The second is if the user
355*4777Smcwalter * told us to do logging, and we found a system failure.
356*4777Smcwalter */
357*4777Smcwalter if (flag) {
358*4777Smcwalter /*
359*4777Smcwalter * display time of latest powerfail. Not all systems
360*4777Smcwalter * have this capability. For those that do not, this
361*4777Smcwalter * is just a no-op.
362*4777Smcwalter */
363*4777Smcwalter disp_powerfail(root);
364*4777Smcwalter
365*4777Smcwalter /* platform_disp_prom_version(tree); */
366*4777Smcwalter sun4v_display_hw_revisions(root, plafh);
367*4777Smcwalter }
368*4777Smcwalter }
369*4777Smcwalter
370*4777Smcwalter /*
371*4777Smcwalter * local functions
372*4777Smcwalter */
373*4777Smcwalter /*
374*4777Smcwalter * add all io devices under pci in io list
375*4777Smcwalter */
376*4777Smcwalter /* ARGSUSED */
377*4777Smcwalter static int
monza_hw_rev_callback(picl_nodehdl_t pcih,void * args)378*4777Smcwalter monza_hw_rev_callback(picl_nodehdl_t pcih, void *args)
379*4777Smcwalter {
380*4777Smcwalter int err = PICL_SUCCESS;
381*4777Smcwalter char path[MAXSTRLEN] = "";
382*4777Smcwalter char device_path[MAXSTRLEN];
383*4777Smcwalter char NAC[MAXSTRLEN];
384*4777Smcwalter char *compatible;
385*4777Smcwalter int32_t revision;
386*4777Smcwalter int device_found;
387*4777Smcwalter
388*4777Smcwalter device_found = 0;
389*4777Smcwalter
390*4777Smcwalter err = picl_get_propval_by_name(pcih, PICL_PROP_DEVFS_PATH, path,
391*4777Smcwalter sizeof (path));
392*4777Smcwalter if (err != PICL_SUCCESS) {
393*4777Smcwalter return (err);
394*4777Smcwalter }
395*4777Smcwalter
396*4777Smcwalter
397*4777Smcwalter if ((strncmp(path, MONZA_NETWORK_0, strlen(MONZA_NETWORK_0)) == 0) ||
398*4777Smcwalter (strncmp(path, MONZA_NETWORK_1, strlen(MONZA_NETWORK_1)) == 0)) {
399*4777Smcwalter device_found = 1;
400*4777Smcwalter (void) snprintf(NAC, sizeof (NAC), "%s/%s%d",
401*4777Smcwalter MOTHERBOARD, OPHIR, 0);
402*4777Smcwalter revision = monza_get_int_propval(pcih, OBP_PROP_REVISION_ID,
403*4777Smcwalter &err);
404*4777Smcwalter }
405*4777Smcwalter
406*4777Smcwalter if ((strncmp(path, MONZA_NETWORK_2, strlen(MONZA_NETWORK_2)) == 0) ||
407*4777Smcwalter (strncmp(path, MONZA_NETWORK_3, strlen(MONZA_NETWORK_3)) == 0)) {
408*4777Smcwalter device_found = 1;
409*4777Smcwalter (void) snprintf(NAC, sizeof (NAC), "%s/%s%d",
410*4777Smcwalter MOTHERBOARD, OPHIR, 1);
411*4777Smcwalter revision = monza_get_int_propval(pcih, OBP_PROP_REVISION_ID,
412*4777Smcwalter &err);
413*4777Smcwalter }
414*4777Smcwalter
415*4777Smcwalter if ((strncmp(path, MONZA_ENET_2, strlen(MONZA_ENET_2)) == 0) ||
416*4777Smcwalter (strncmp(path, MONZA_ENET_3, strlen(MONZA_ENET_3)) == 0)) {
417*4777Smcwalter device_found = 1;
418*4777Smcwalter (void) snprintf(NAC, sizeof (NAC), "%s/%s%d",
419*4777Smcwalter MOTHERBOARD, OPHIR, 1);
420*4777Smcwalter revision = monza_get_int_propval(pcih, OBP_PROP_REVISION_ID,
421*4777Smcwalter &err);
422*4777Smcwalter }
423*4777Smcwalter
424*4777Smcwalter if ((strncmp(path, MONZA_NETWORK_4, strlen(MONZA_NETWORK_4)) == 0) ||
425*4777Smcwalter (strncmp(path, MONZA_NETWORK_5, strlen(MONZA_NETWORK_5)) == 0)) {
426*4777Smcwalter device_found = 1;
427*4777Smcwalter (void) snprintf(NAC, sizeof (NAC), "%s/%s%d",
428*4777Smcwalter MOTHERBOARD, OPHIR, 2);
429*4777Smcwalter revision = monza_get_int_propval(pcih, OBP_PROP_REVISION_ID,
430*4777Smcwalter &err);
431*4777Smcwalter }
432*4777Smcwalter
433*4777Smcwalter if (strcmp(path, MONZA_PCIE_SWITCH_PATH) == 0) {
434*4777Smcwalter device_found = 1;
435*4777Smcwalter (void) snprintf(NAC, sizeof (NAC), "%s/%s",
436*4777Smcwalter MOTHERBOARD, PCIE_SWITCH);
437*4777Smcwalter revision = monza_get_int_propval(pcih,
438*4777Smcwalter OBP_PROP_REVISION_ID, &err);
439*4777Smcwalter }
440*4777Smcwalter
441*4777Smcwalter if (strcmp(path, MONZA_RTM_PATH) == 0) {
442*4777Smcwalter device_found = 1;
443*4777Smcwalter (void) snprintf(NAC, sizeof (NAC), "%s/%s", RTM, AMC);
444*4777Smcwalter revision = monza_get_int_propval(pcih, OBP_PROP_REVISION_ID,
445*4777Smcwalter &err);
446*4777Smcwalter }
447*4777Smcwalter
448*4777Smcwalter if (strcmp(path, MONZA_CF_PATH) == 0) {
449*4777Smcwalter device_found = 1;
450*4777Smcwalter (void) snprintf(NAC, sizeof (NAC), "%s/%s", MOTHERBOARD,
451*4777Smcwalter MONZA_CF_DEVICE);
452*4777Smcwalter revision = monza_get_int_propval(pcih, OBP_PROP_REVISION_ID,
453*4777Smcwalter &err);
454*4777Smcwalter }
455*4777Smcwalter
456*4777Smcwalter if (device_found == 1) {
457*4777Smcwalter (void) strcpy(device_path, path);
458*4777Smcwalter err = monza_get_first_compatible_value(pcih, &compatible);
459*4777Smcwalter
460*4777Smcwalter /* Print NAC name */
461*4777Smcwalter log_printf("%-20s", NAC);
462*4777Smcwalter /* Print Device Path */
463*4777Smcwalter if (strlen(device_path) > 38)
464*4777Smcwalter log_printf("%38.37s+", device_path);
465*4777Smcwalter else
466*4777Smcwalter log_printf("%39s", device_path);
467*4777Smcwalter
468*4777Smcwalter /* Print Compatible # */
469*4777Smcwalter if (err == PICL_SUCCESS) {
470*4777Smcwalter log_printf("%31s", compatible);
471*4777Smcwalter free(compatible);
472*4777Smcwalter } else
473*4777Smcwalter log_printf("%31s", " ");
474*4777Smcwalter
475*4777Smcwalter /* Print Revision */
476*4777Smcwalter log_printf("%6d", revision);
477*4777Smcwalter log_printf("\n");
478*4777Smcwalter }
479*4777Smcwalter
480*4777Smcwalter return (PICL_WALK_CONTINUE);
481*4777Smcwalter }
482*4777Smcwalter
483*4777Smcwalter /*ARGSUSED*/
484*4777Smcwalter static void
sun4v_display_hw_revisions(Prom_node * root,picl_nodehdl_t plafh)485*4777Smcwalter sun4v_display_hw_revisions(Prom_node *root, picl_nodehdl_t plafh)
486*4777Smcwalter {
487*4777Smcwalter Prom_node *pnode;
488*4777Smcwalter char *value;
489*4777Smcwalter char platbuf[MAXSTRLEN];
490*4777Smcwalter char *fmt = "%-20s %-40s %-30s %-9s";
491*4777Smcwalter
492*4777Smcwalter log_printf(dgettext(TEXT_DOMAIN, "\n"
493*4777Smcwalter "========================= HW Revisions "
494*4777Smcwalter "=======================================\n\n"));
495*4777Smcwalter
496*4777Smcwalter log_printf(dgettext(TEXT_DOMAIN,
497*4777Smcwalter "System PROM revisions:\n"
498*4777Smcwalter "----------------------\n"));
499*4777Smcwalter
500*4777Smcwalter pnode = dev_find_node(root, "openprom");
501*4777Smcwalter if (pnode != NULL) {
502*4777Smcwalter value = (char *)get_prop_val(find_prop(pnode, "version"));
503*4777Smcwalter log_printf(value);
504*4777Smcwalter }
505*4777Smcwalter
506*4777Smcwalter log_printf(dgettext(TEXT_DOMAIN, "\n\n"
507*4777Smcwalter "IO ASIC revisions:\n"
508*4777Smcwalter "------------------\n"));
509*4777Smcwalter log_printf(fmt, "Location", "Path", "Device", "Revision\n", 0);
510*4777Smcwalter log_printf(fmt, "--------------------",
511*4777Smcwalter "----------------------------------------",
512*4777Smcwalter "------------------------------",
513*4777Smcwalter "---------\n", 0);
514*4777Smcwalter
515*4777Smcwalter /* Get platform name, if that fails, use monza name by default */
516*4777Smcwalter if (sysinfo(SI_PLATFORM, platbuf, sizeof (platbuf)) == -1) {
517*4777Smcwalter (void) strcpy(platbuf, MONZA_PLATFORM);
518*4777Smcwalter }
519*4777Smcwalter
520*4777Smcwalter (void) picl_walk_tree_by_class(plafh, PCIEX,
521*4777Smcwalter PCIEX, monza_hw_rev_callback);
522*4777Smcwalter (void) picl_walk_tree_by_class(plafh, PCI,
523*4777Smcwalter PCI, monza_hw_rev_callback);
524*4777Smcwalter (void) picl_walk_tree_by_class(plafh, NETWORK,
525*4777Smcwalter NETWORK, monza_hw_rev_callback);
526*4777Smcwalter }
527*4777Smcwalter
528*4777Smcwalter /*
529*4777Smcwalter * return the first compatible value
530*4777Smcwalter */
531*4777Smcwalter static int
monza_get_first_compatible_value(picl_nodehdl_t nodeh,char ** outbuf)532*4777Smcwalter monza_get_first_compatible_value(picl_nodehdl_t nodeh, char **outbuf)
533*4777Smcwalter {
534*4777Smcwalter int err;
535*4777Smcwalter picl_prophdl_t proph;
536*4777Smcwalter picl_propinfo_t pinfo;
537*4777Smcwalter picl_prophdl_t tblh;
538*4777Smcwalter picl_prophdl_t rowproph;
539*4777Smcwalter char *pval;
540*4777Smcwalter
541*4777Smcwalter err = picl_get_propinfo_by_name(nodeh, OBP_PROP_COMPATIBLE,
542*4777Smcwalter &pinfo, &proph);
543*4777Smcwalter if (err != PICL_SUCCESS)
544*4777Smcwalter return (err);
545*4777Smcwalter
546*4777Smcwalter if (pinfo.type == PICL_PTYPE_CHARSTRING) {
547*4777Smcwalter pval = malloc(pinfo.size);
548*4777Smcwalter if (pval == NULL)
549*4777Smcwalter return (PICL_FAILURE);
550*4777Smcwalter err = picl_get_propval(proph, pval, pinfo.size);
551*4777Smcwalter if (err != PICL_SUCCESS) {
552*4777Smcwalter free(pval);
553*4777Smcwalter return (err);
554*4777Smcwalter }
555*4777Smcwalter *outbuf = pval;
556*4777Smcwalter return (PICL_SUCCESS);
557*4777Smcwalter }
558*4777Smcwalter
559*4777Smcwalter if (pinfo.type != PICL_PTYPE_TABLE)
560*4777Smcwalter return (PICL_FAILURE);
561*4777Smcwalter
562*4777Smcwalter /* get first string from table */
563*4777Smcwalter err = picl_get_propval(proph, &tblh, pinfo.size);
564*4777Smcwalter if (err != PICL_SUCCESS)
565*4777Smcwalter return (err);
566*4777Smcwalter
567*4777Smcwalter err = picl_get_next_by_row(tblh, &rowproph);
568*4777Smcwalter if (err != PICL_SUCCESS)
569*4777Smcwalter return (err);
570*4777Smcwalter
571*4777Smcwalter err = picl_get_propinfo(rowproph, &pinfo);
572*4777Smcwalter if (err != PICL_SUCCESS)
573*4777Smcwalter return (err);
574*4777Smcwalter
575*4777Smcwalter pval = malloc(pinfo.size);
576*4777Smcwalter if (pval == NULL)
577*4777Smcwalter return (PICL_FAILURE);
578*4777Smcwalter
579*4777Smcwalter err = picl_get_propval(rowproph, pval, pinfo.size);
580*4777Smcwalter if (err != PICL_SUCCESS) {
581*4777Smcwalter free(pval);
582*4777Smcwalter return (err);
583*4777Smcwalter }
584*4777Smcwalter
585*4777Smcwalter *outbuf = pval;
586*4777Smcwalter return (PICL_SUCCESS);
587*4777Smcwalter }
588*4777Smcwalter
589*4777Smcwalter static int64_t
monza_get_int_propval(picl_nodehdl_t modh,char * prop_name,int * ret)590*4777Smcwalter monza_get_int_propval(picl_nodehdl_t modh, char *prop_name, int *ret)
591*4777Smcwalter {
592*4777Smcwalter int err;
593*4777Smcwalter picl_prophdl_t proph;
594*4777Smcwalter picl_propinfo_t pinfo;
595*4777Smcwalter int8_t int8v;
596*4777Smcwalter int16_t int16v;
597*4777Smcwalter int32_t int32v;
598*4777Smcwalter int64_t int64v;
599*4777Smcwalter
600*4777Smcwalter err = picl_get_propinfo_by_name(modh, prop_name, &pinfo, &proph);
601*4777Smcwalter if (err != PICL_SUCCESS) {
602*4777Smcwalter *ret = err;
603*4777Smcwalter return (0);
604*4777Smcwalter }
605*4777Smcwalter
606*4777Smcwalter /*
607*4777Smcwalter * If it is not an int, uint or byte array prop, return failure
608*4777Smcwalter */
609*4777Smcwalter if ((pinfo.type != PICL_PTYPE_INT) &&
610*4777Smcwalter (pinfo.type != PICL_PTYPE_UNSIGNED_INT) &&
611*4777Smcwalter (pinfo.type != PICL_PTYPE_BYTEARRAY)) {
612*4777Smcwalter *ret = PICL_FAILURE;
613*4777Smcwalter return (0);
614*4777Smcwalter }
615*4777Smcwalter
616*4777Smcwalter switch (pinfo.size) {
617*4777Smcwalter case sizeof (int8_t):
618*4777Smcwalter err = picl_get_propval(proph, &int8v, sizeof (int8v));
619*4777Smcwalter *ret = err;
620*4777Smcwalter return (int8v);
621*4777Smcwalter case sizeof (int16_t):
622*4777Smcwalter err = picl_get_propval(proph, &int16v, sizeof (int16v));
623*4777Smcwalter *ret = err;
624*4777Smcwalter return (int16v);
625*4777Smcwalter case sizeof (int32_t):
626*4777Smcwalter err = picl_get_propval(proph, &int32v, sizeof (int32v));
627*4777Smcwalter *ret = err;
628*4777Smcwalter return (int32v);
629*4777Smcwalter case sizeof (int64_t):
630*4777Smcwalter err = picl_get_propval(proph, &int64v, sizeof (int64v));
631*4777Smcwalter *ret = err;
632*4777Smcwalter return (int64v);
633*4777Smcwalter default: /* not supported size */
634*4777Smcwalter *ret = PICL_FAILURE;
635*4777Smcwalter return (0);
636*4777Smcwalter }
637*4777Smcwalter }
638