1074bb90dSTom Pothier /*
2074bb90dSTom Pothier * CDDL HEADER START
3074bb90dSTom Pothier *
4074bb90dSTom Pothier * The contents of this file are subject to the terms of the
5074bb90dSTom Pothier * Common Development and Distribution License (the "License").
6074bb90dSTom Pothier * You may not use this file except in compliance with the License.
7074bb90dSTom Pothier *
8074bb90dSTom Pothier * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9074bb90dSTom Pothier * or http://www.opensolaris.org/os/licensing.
10074bb90dSTom Pothier * See the License for the specific language governing permissions
11074bb90dSTom Pothier * and limitations under the License.
12074bb90dSTom Pothier *
13074bb90dSTom Pothier * When distributing Covered Code, include this CDDL HEADER in each
14074bb90dSTom Pothier * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15074bb90dSTom Pothier * If applicable, add the following below this CDDL HEADER, with the
16074bb90dSTom Pothier * fields enclosed by brackets "[]" replaced with your own identifying
17074bb90dSTom Pothier * information: Portions Copyright [yyyy] [name of copyright owner]
18074bb90dSTom Pothier *
19074bb90dSTom Pothier * CDDL HEADER END
20074bb90dSTom Pothier */
21074bb90dSTom Pothier
22074bb90dSTom Pothier /*
235677a1bfSCheng Sean Ye * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
24074bb90dSTom Pothier */
25074bb90dSTom Pothier
26074bb90dSTom Pothier /*
27074bb90dSTom Pothier * x86 Generic FMA Topology Enumerator
28074bb90dSTom Pothier */
29074bb90dSTom Pothier
30074bb90dSTom Pothier
31074bb90dSTom Pothier #include <fcntl.h>
32074bb90dSTom Pothier #include <unistd.h>
33074bb90dSTom Pothier #include <sys/types.h>
34074bb90dSTom Pothier #include <strings.h>
35074bb90dSTom Pothier #include <sys/fcntl.h>
36074bb90dSTom Pothier #include <fm/topo_mod.h>
37074bb90dSTom Pothier #include <fm/topo_hc.h>
38074bb90dSTom Pothier #include <sys/systeminfo.h>
39074bb90dSTom Pothier #include <sys/smbios.h>
40074bb90dSTom Pothier #include <sys/smbios_impl.h>
41074bb90dSTom Pothier #include <sys/fm/protocol.h>
42074bb90dSTom Pothier #include <x86pi_impl.h>
43074bb90dSTom Pothier
44074bb90dSTom Pothier
45074bb90dSTom Pothier static int x86pi_enum_start(topo_mod_t *, x86pi_enum_t *);
46efd31e1dSTrang Do static int x86pi_enum_gentopo(topo_mod_t *, tnode_t *);
47074bb90dSTom Pothier
48074bb90dSTom Pothier /*
49074bb90dSTom Pothier * Entry point called by libtopo when enumeration is required
50074bb90dSTom Pothier */
51074bb90dSTom Pothier static topo_enum_f x86pi_enum; /* libtopo enumeration entry point */
52074bb90dSTom Pothier
53a98ca9daSTom Pothier /*
54a98ca9daSTom Pothier * Top level chassis node in a multiple chassis system; or the chassis
55a98ca9daSTom Pothier * node in a single chassis system.
56a98ca9daSTom Pothier */
57a98ca9daSTom Pothier static tnode_t *motherchassis_node = NULL;
58a98ca9daSTom Pothier
59a98ca9daSTom Pothier
60074bb90dSTom Pothier /*
61074bb90dSTom Pothier * Declare the operations vector and information structure used during
62074bb90dSTom Pothier * module registration
63074bb90dSTom Pothier */
64074bb90dSTom Pothier static topo_modops_t x86pi_ops =
65074bb90dSTom Pothier { x86pi_enum, NULL };
66074bb90dSTom Pothier
67074bb90dSTom Pothier static topo_modinfo_t x86pi_modinfo =
68074bb90dSTom Pothier { X86PI_DESC, X86PI_SCHEME, X86PI_VERSION, &x86pi_ops };
69074bb90dSTom Pothier
70074bb90dSTom Pothier /*
71074bb90dSTom Pothier * Used to pass SMBIOS' FM compatibility to the
72074bb90dSTom Pothier * chip enumerator
73074bb90dSTom Pothier */
74074bb90dSTom Pothier int x86pi_smbios = 0;
75074bb90dSTom Pothier
762a685872SToomas Soome /* indication of successful fac node creation */
772a685872SToomas Soome int fac_done;
782a685872SToomas Soome /* one for each struct */
792a685872SToomas Soome smbs_cnt_t stypes[SMB_TYPE_OEM_HI];
802a685872SToomas Soome
81074bb90dSTom Pothier /*
82074bb90dSTom Pothier * Called by libtopo when the topo module is loaded.
83074bb90dSTom Pothier */
84074bb90dSTom Pothier int
_topo_init(topo_mod_t * mod,topo_version_t version)85074bb90dSTom Pothier _topo_init(topo_mod_t *mod, topo_version_t version)
86074bb90dSTom Pothier {
87074bb90dSTom Pothier int result;
88074bb90dSTom Pothier char isa[MAXNAMELEN];
89074bb90dSTom Pothier
90074bb90dSTom Pothier if (getenv("TOPOX86PIDBG") != NULL) {
91074bb90dSTom Pothier /* Debugging is requested for this module */
92074bb90dSTom Pothier topo_mod_setdebug(mod);
93074bb90dSTom Pothier }
94074bb90dSTom Pothier topo_mod_dprintf(mod, "module initializing.\n");
95074bb90dSTom Pothier
96074bb90dSTom Pothier if (version != TOPO_VERSION) {
97d3c57c1fSTom Pothier (void) topo_mod_seterrno(mod, EMOD_VER_NEW);
98074bb90dSTom Pothier topo_mod_dprintf(mod, "incompatible topo version %d\n",
99074bb90dSTom Pothier version);
100074bb90dSTom Pothier return (-1);
101074bb90dSTom Pothier }
102074bb90dSTom Pothier
103074bb90dSTom Pothier /* Verify that this is a i86pc architecture machine */
104074bb90dSTom Pothier (void) sysinfo(SI_MACHINE, isa, MAXNAMELEN);
105074bb90dSTom Pothier if (strncmp(isa, "i86pc", MAXNAMELEN) != 0) {
106074bb90dSTom Pothier topo_mod_dprintf(mod, "not i86pc architecture: %s\n", isa);
107074bb90dSTom Pothier return (-1);
108074bb90dSTom Pothier }
109074bb90dSTom Pothier
110074bb90dSTom Pothier result = topo_mod_register(mod, &x86pi_modinfo, TOPO_VERSION);
111074bb90dSTom Pothier if (result < 0) {
112074bb90dSTom Pothier topo_mod_dprintf(mod, "registration failed: %s\n",
113074bb90dSTom Pothier topo_mod_errmsg(mod));
114074bb90dSTom Pothier /* module errno already set */
115074bb90dSTom Pothier return (-1);
116074bb90dSTom Pothier }
117074bb90dSTom Pothier topo_mod_dprintf(mod, "module ready.\n");
118074bb90dSTom Pothier return (0);
119074bb90dSTom Pothier }
120074bb90dSTom Pothier
121074bb90dSTom Pothier
122074bb90dSTom Pothier /*
123074bb90dSTom Pothier * Clean up any data used by the module before it is unloaded.
124074bb90dSTom Pothier */
125074bb90dSTom Pothier void
_topo_fini(topo_mod_t * mod)126074bb90dSTom Pothier _topo_fini(topo_mod_t *mod)
127074bb90dSTom Pothier {
128074bb90dSTom Pothier topo_mod_dprintf(mod, "module finishing.\n");
129074bb90dSTom Pothier
130074bb90dSTom Pothier /* Unregister from libtopo */
131074bb90dSTom Pothier topo_mod_unregister(mod);
132074bb90dSTom Pothier }
133074bb90dSTom Pothier
134074bb90dSTom Pothier
135074bb90dSTom Pothier /*
136074bb90dSTom Pothier * Enumeration entry point for the x86 Generic topology enumerator
137074bb90dSTom Pothier */
138074bb90dSTom Pothier /* ARGSUSED */
139074bb90dSTom Pothier static int
x86pi_enum(topo_mod_t * mod,tnode_t * t_parent,const char * name,topo_instance_t min,topo_instance_t max,void * pi_private,void * data)140074bb90dSTom Pothier x86pi_enum(topo_mod_t *mod, tnode_t *t_parent, const char *name,
141074bb90dSTom Pothier topo_instance_t min, topo_instance_t max, void *pi_private, void *data)
142074bb90dSTom Pothier {
143074bb90dSTom Pothier int result;
144074bb90dSTom Pothier hrtime_t starttime;
145074bb90dSTom Pothier x86pi_enum_t x86pi;
146074bb90dSTom Pothier
147074bb90dSTom Pothier /* Begin enumeration */
148074bb90dSTom Pothier starttime = gethrtime();
149074bb90dSTom Pothier topo_mod_dprintf(mod, "enumeration starting.\n");
150074bb90dSTom Pothier
151074bb90dSTom Pothier /*
152074bb90dSTom Pothier * Let's do some enumeration.
153074bb90dSTom Pothier */
154074bb90dSTom Pothier bzero(&x86pi, sizeof (x86pi_enum_t));
155074bb90dSTom Pothier x86pi.t_parent = t_parent;
156074bb90dSTom Pothier result = x86pi_enum_start(mod, &x86pi);
157074bb90dSTom Pothier if (result != 0) {
158074bb90dSTom Pothier topo_mod_dprintf(mod, "Enumeration failed.\n");
159074bb90dSTom Pothier return (-1);
160074bb90dSTom Pothier }
161074bb90dSTom Pothier
162074bb90dSTom Pothier /* Complete enumeration */
163074bb90dSTom Pothier topo_mod_dprintf(mod, "enumeration complete in %lld ms.\n",
164074bb90dSTom Pothier ((gethrtime() - starttime)/MICROSEC));
165074bb90dSTom Pothier
166074bb90dSTom Pothier /* All done */
167074bb90dSTom Pothier return (result);
168074bb90dSTom Pothier }
169074bb90dSTom Pothier
170074bb90dSTom Pothier static int
x86pi_enum_start(topo_mod_t * mod,x86pi_enum_t * x86pi)171074bb90dSTom Pothier x86pi_enum_start(topo_mod_t *mod, x86pi_enum_t *x86pi)
172074bb90dSTom Pothier {
173074bb90dSTom Pothier int rv;
174074bb90dSTom Pothier int complvl = 0;
175074bb90dSTom Pothier smbios_hdl_t *shp;
176074bb90dSTom Pothier char *f = "x86pi_enum_start";
177074bb90dSTom Pothier
178074bb90dSTom Pothier /*
179074bb90dSTom Pothier * Verify BIOS compliance.
180074bb90dSTom Pothier */
181074bb90dSTom Pothier shp = x86pi_smb_open(mod);
182074bb90dSTom Pothier if (shp == NULL) {
183074bb90dSTom Pothier topo_mod_dprintf(mod, "%s: failed to open SMBIOS\n", f);
184074bb90dSTom Pothier complvl = X86PI_NONE;
185074bb90dSTom Pothier } else {
186efd31e1dSTrang Do complvl = x86pi_check_comp(mod);
187074bb90dSTom Pothier }
188074bb90dSTom Pothier
189074bb90dSTom Pothier topo_mod_dprintf(mod, "%s: SMBIOS x86pi compliance: %s\n", f,
190074bb90dSTom Pothier complvl == X86PI_FULL ? "FULL" : "NONE");
191074bb90dSTom Pothier
192074bb90dSTom Pothier if (complvl == X86PI_NONE) {
193074bb90dSTom Pothier /* fall back to legacy enumeration */
194074bb90dSTom Pothier topo_mod_dprintf(mod,
195074bb90dSTom Pothier "%s: Calling legacy enumeration\n", f);
196074bb90dSTom Pothier
197074bb90dSTom Pothier return (topo_mod_enummap(mod, x86pi->t_parent,
198074bb90dSTom Pothier "i86pc-legacy", FM_FMRI_SCHEME_HC));
199074bb90dSTom Pothier }
200074bb90dSTom Pothier
201074bb90dSTom Pothier x86pi->priv = (void *)shp;
202074bb90dSTom Pothier x86pi_smbios = complvl;
203074bb90dSTom Pothier
204074bb90dSTom Pothier if (x86pi_hbr_enum_init(mod) < 0) {
205074bb90dSTom Pothier topo_mod_dprintf(mod, "%s: x86pi_hbr_enum_init() failed.\n", f);
206074bb90dSTom Pothier return (-1);
207074bb90dSTom Pothier }
208074bb90dSTom Pothier
209074bb90dSTom Pothier /*
210074bb90dSTom Pothier * Create the topology.
211074bb90dSTom Pothier */
212074bb90dSTom Pothier fac_done = 0;
213efd31e1dSTrang Do rv = x86pi_enum_gentopo(mod, x86pi->t_parent);
2145677a1bfSCheng Sean Ye
2155677a1bfSCheng Sean Ye x86pi_hbr_enum_fini(mod);
2165677a1bfSCheng Sean Ye
217074bb90dSTom Pothier if (rv != 0) {
218074bb90dSTom Pothier return (-1);
219074bb90dSTom Pothier }
220074bb90dSTom Pothier x86pi->mod = mod;
221074bb90dSTom Pothier
222074bb90dSTom Pothier if (fac_done == 0) {
223a98ca9daSTom Pothier (void) topo_mod_enummap(mod, motherchassis_node, "chassis",
224074bb90dSTom Pothier FM_FMRI_SCHEME_HC);
225a98ca9daSTom Pothier (void) topo_mod_enummap(mod, motherchassis_node, "fan",
226074bb90dSTom Pothier FM_FMRI_SCHEME_HC);
227a98ca9daSTom Pothier (void) topo_mod_enummap(mod, motherchassis_node, "psu",
228074bb90dSTom Pothier FM_FMRI_SCHEME_HC);
229074bb90dSTom Pothier }
230074bb90dSTom Pothier
231074bb90dSTom Pothier /* All done */
232074bb90dSTom Pothier topo_mod_dprintf(mod, "%s: done.\n", f);
233074bb90dSTom Pothier return (rv);
234074bb90dSTom Pothier }
235074bb90dSTom Pothier
236074bb90dSTom Pothier /*
237074bb90dSTom Pothier * Create the i86pc topology
238074bb90dSTom Pothier *
239074bb90dSTom Pothier * If either Type 2 or Type 3 structures have contained elements/handles,
240074bb90dSTom Pothier * walk them creating the topo.
241074bb90dSTom Pothier *
242074bb90dSTom Pothier * If there are no contained elements/handles, build this topo:
243074bb90dSTom Pothier *
244074bb90dSTom Pothier * Main Chassis
245074bb90dSTom Pothier * Motherboard
246074bb90dSTom Pothier * CMP Chip/Core/Strands
247074bb90dSTom Pothier * Memory Controllers/Memory Devices (DIMMs)
248074bb90dSTom Pothier * PCIE HostBrige
249074bb90dSTom Pothier * PCIE Root Complex
250074bb90dSTom Pothier *
251074bb90dSTom Pothier */
252074bb90dSTom Pothier static int
x86pi_enum_gentopo(topo_mod_t * mod,tnode_t * t_parent)253efd31e1dSTrang Do x86pi_enum_gentopo(topo_mod_t *mod, tnode_t *t_parent)
254074bb90dSTom Pothier {
255074bb90dSTom Pothier int rv;
256074bb90dSTom Pothier int nch, nbb, ncmp, i;
257074bb90dSTom Pothier int ch_smbid, bb_smbid;
258074bb90dSTom Pothier tnode_t *chassis_node = NULL;
259074bb90dSTom Pothier tnode_t *basebd_node = NULL;
260074bb90dSTom Pothier smbs_cnt_t *smbc;
261074bb90dSTom Pothier tnode_t *pnode = NULL;
262074bb90dSTom Pothier id_t psmbid;
263074bb90dSTom Pothier int notvisited;
264074bb90dSTom Pothier int bb_count, ch_count;
265074bb90dSTom Pothier int min, max;
266074bb90dSTom Pothier int ch_inst = 0;
26703f9f63dSTom Pothier int disk_inst = 0;
268074bb90dSTom Pothier topo_instance_t hbri = 0, rci = 0;
269074bb90dSTom Pothier smbios_pciexrc_t hbr;
27003f9f63dSTom Pothier smbios_port_ext_t export;
271074bb90dSTom Pothier char *f = "x86pi_enum_gentopo";
2722a685872SToomas Soome smbios_hdl_t *shp;
273efd31e1dSTrang Do
274efd31e1dSTrang Do shp = topo_mod_smbios(mod);
275efd31e1dSTrang Do if (shp == NULL) {
276efd31e1dSTrang Do topo_mod_dprintf(mod, "%s: failed to load SMBIOS\n", f);
277efd31e1dSTrang Do return (-1);
278efd31e1dSTrang Do }
279074bb90dSTom Pothier
280074bb90dSTom Pothier if (t_parent == NULL) {
281074bb90dSTom Pothier topo_mod_dprintf(mod, "%s: NULL parent\n", f);
282074bb90dSTom Pothier return (-1);
283074bb90dSTom Pothier }
284074bb90dSTom Pothier
285074bb90dSTom Pothier /*
286074bb90dSTom Pothier * "Chassis'"
287074bb90dSTom Pothier */
288074bb90dSTom Pothier /* Type 3 structs */
289074bb90dSTom Pothier stypes[SMB_TYPE_CHASSIS].type = SMB_TYPE_CHASSIS;
290efd31e1dSTrang Do x86pi_smb_strcnt(mod, &stypes[SMB_TYPE_CHASSIS]);
291074bb90dSTom Pothier
292074bb90dSTom Pothier ch_count = stypes[SMB_TYPE_CHASSIS].count;
293074bb90dSTom Pothier
294074bb90dSTom Pothier for (nch = 0; nch < ch_count; nch++) {
295074bb90dSTom Pothier topo_mod_dprintf(mod, "%s: found %d chassis\n", f,
296074bb90dSTom Pothier stypes[SMB_TYPE_CHASSIS].count);
297074bb90dSTom Pothier
298074bb90dSTom Pothier ch_smbid = stypes[SMB_TYPE_CHASSIS].ids[nch].id;
299074bb90dSTom Pothier
300074bb90dSTom Pothier /*
301074bb90dSTom Pothier * Expect SMBIOS to set the first Chassis Structure to be the
302074bb90dSTom Pothier * parent/mother of all chassis
303074bb90dSTom Pothier */
304074bb90dSTom Pothier if (nch == 0)
305074bb90dSTom Pothier motherchassis_node = chassis_node =
306efd31e1dSTrang Do x86pi_gen_chassis(mod, t_parent, ch_smbid,
307efd31e1dSTrang Do ch_inst++);
308074bb90dSTom Pothier else {
309074bb90dSTom Pothier if (motherchassis_node != NULL)
310074bb90dSTom Pothier chassis_node = x86pi_gen_chassis(mod,
311efd31e1dSTrang Do motherchassis_node, ch_smbid, ch_inst++);
312074bb90dSTom Pothier else
313074bb90dSTom Pothier chassis_node = x86pi_gen_chassis(mod,
314efd31e1dSTrang Do t_parent, ch_smbid, ch_inst++);
315074bb90dSTom Pothier }
316074bb90dSTom Pothier
317074bb90dSTom Pothier if (chassis_node == NULL) {
318074bb90dSTom Pothier topo_mod_dprintf(mod,
319074bb90dSTom Pothier "%s: Failed to create chassis %d\n", f, nch);
320074bb90dSTom Pothier continue;
321074bb90dSTom Pothier }
322074bb90dSTom Pothier stypes[SMB_TYPE_CHASSIS].ids[nch].node = chassis_node;
32303f9f63dSTom Pothier
32403f9f63dSTom Pothier /* count SMBIOS extended port connector structures */
32503f9f63dSTom Pothier smbc = &stypes[SUN_OEM_EXT_PORT];
32603f9f63dSTom Pothier smbc->type = SUN_OEM_EXT_PORT;
327efd31e1dSTrang Do x86pi_smb_strcnt(mod, smbc);
32803f9f63dSTom Pothier
32905ead181SVuong Nguyen /*
33005ead181SVuong Nguyen * enumerate direct attached SATA disks if we found a
33105ead181SVuong Nguyen * SUN_OEM_EXT_PORT record.
33205ead181SVuong Nguyen */
33305ead181SVuong Nguyen if (smbc->count > 0) {
33405ead181SVuong Nguyen rv = topo_node_range_create(mod, chassis_node, BAY, 0,
33505ead181SVuong Nguyen smbc->count + 1);
33605ead181SVuong Nguyen if (rv != 0) {
33705ead181SVuong Nguyen topo_mod_dprintf(mod,
33805ead181SVuong Nguyen "%s: Failed to create %s range: %s\n",
33905ead181SVuong Nguyen f, BAY, topo_mod_errmsg(mod));
34005ead181SVuong Nguyen continue;
34105ead181SVuong Nguyen }
34205ead181SVuong Nguyen } else {
34303f9f63dSTom Pothier topo_mod_dprintf(mod,
34405ead181SVuong Nguyen "Skipping disk bay enumeration\n");
34503f9f63dSTom Pothier }
34603f9f63dSTom Pothier
34703f9f63dSTom Pothier for (i = 0; i < smbc->count; i++) {
34803f9f63dSTom Pothier if (smbios_info_extport(shp, smbc->ids[i].id,
34903f9f63dSTom Pothier &export) != 0) {
35003f9f63dSTom Pothier topo_mod_dprintf(mod,
35103f9f63dSTom Pothier "smbios_info_export failed: id = %d\n",
35203f9f63dSTom Pothier (int)smbc->ids[i].id);
35303f9f63dSTom Pothier continue;
35403f9f63dSTom Pothier }
35503f9f63dSTom Pothier if (export.smbporte_chassis != ch_smbid)
35603f9f63dSTom Pothier continue;
35703f9f63dSTom Pothier
35803f9f63dSTom Pothier /*
35903f9f63dSTom Pothier * x86pi_gen_bay:
36003f9f63dSTom Pothier * create "bay" node
36103f9f63dSTom Pothier * call "disk" enum passing in "bay" node
36203f9f63dSTom Pothier */
363efd31e1dSTrang Do rv = x86pi_gen_bay(mod, chassis_node, &export,
364efd31e1dSTrang Do disk_inst);
36503f9f63dSTom Pothier if (rv != 0)
36603f9f63dSTom Pothier topo_mod_dprintf(mod,
36703f9f63dSTom Pothier "Failed to create disk %d\n", i);
36803f9f63dSTom Pothier disk_inst++;
36903f9f63dSTom Pothier }
370074bb90dSTom Pothier }
371074bb90dSTom Pothier
372074bb90dSTom Pothier /*
373074bb90dSTom Pothier * "Base Board"
374074bb90dSTom Pothier */
375074bb90dSTom Pothier /* Type 2 structs */
376074bb90dSTom Pothier stypes[SMB_TYPE_BASEBOARD].type = SMB_TYPE_BASEBOARD;
377efd31e1dSTrang Do x86pi_smb_strcnt(mod, &stypes[SMB_TYPE_BASEBOARD]);
378074bb90dSTom Pothier bb_count = notvisited = stypes[SMB_TYPE_BASEBOARD].count;
379074bb90dSTom Pothier
380074bb90dSTom Pothier for (nbb = 0; nbb < bb_count; nbb++) {
381074bb90dSTom Pothier stypes[SMB_TYPE_BASEBOARD].ids[nbb].visited = 0;
382074bb90dSTom Pothier stypes[SMB_TYPE_BASEBOARD].ids[nbb].con_by_id = 0;
383074bb90dSTom Pothier stypes[SMB_TYPE_BASEBOARD].ids[nbb].node = NULL;
384074bb90dSTom Pothier }
385efd31e1dSTrang Do (void) x86pi_bb_contains(mod);
386074bb90dSTom Pothier
387074bb90dSTom Pothier min = 0;
388074bb90dSTom Pothier nbb = 0;
389074bb90dSTom Pothier do {
390074bb90dSTom Pothier /*
391074bb90dSTom Pothier * We have reached end of the array due to the
392074bb90dSTom Pothier * parent-child relationship, without visiting all
393074bb90dSTom Pothier * baseboards! so re-iterate..
394074bb90dSTom Pothier * (or)
395074bb90dSTom Pothier * All baseboards are visited and their contained
396074bb90dSTom Pothier * processors are enumerated
397074bb90dSTom Pothier * (and/or)
398074bb90dSTom Pothier * More baseboards pending a visit
399074bb90dSTom Pothier */
400074bb90dSTom Pothier if (nbb > bb_count && notvisited)
401074bb90dSTom Pothier nbb = 0;
402074bb90dSTom Pothier else if (nbb > bb_count && !notvisited)
403074bb90dSTom Pothier break;
404074bb90dSTom Pothier if (stypes[SMB_TYPE_BASEBOARD].ids[nbb].visited ==
405074bb90dSTom Pothier X86PI_VISITED) {
406074bb90dSTom Pothier nbb++;
407074bb90dSTom Pothier continue;
408074bb90dSTom Pothier }
409074bb90dSTom Pothier
410074bb90dSTom Pothier /*
411074bb90dSTom Pothier * Get the Top-most Parent Baseboard, irrespective
412074bb90dSTom Pothier * of its index in the array of Type-2s
413074bb90dSTom Pothier * If this Baseboard has no Baseboard parents
414074bb90dSTom Pothier * place it under the chassis that contains it
415074bb90dSTom Pothier */
416efd31e1dSTrang Do bb_smbid = x86pi_bb_topparent(mod, nbb, &pnode, &psmbid);
417074bb90dSTom Pothier if (bb_smbid == -1 || pnode == NULL) {
418074bb90dSTom Pothier topo_mod_dprintf(mod,
419074bb90dSTom Pothier "Failed to get BaseBoard node (%d): parent\n",
420074bb90dSTom Pothier nbb);
421074bb90dSTom Pothier return (-1);
422074bb90dSTom Pothier }
423074bb90dSTom Pothier
424074bb90dSTom Pothier if (stypes[SMB_TYPE_BASEBOARD].ids[nbb].id != bb_smbid) {
425074bb90dSTom Pothier for (int i = 0; i < bb_count; i++) {
426074bb90dSTom Pothier if (bb_smbid ==
427074bb90dSTom Pothier stypes[SMB_TYPE_BASEBOARD].ids[i].id) {
428074bb90dSTom Pothier stypes[SMB_TYPE_BASEBOARD].ids[i].\
429074bb90dSTom Pothier visited = 1;
430074bb90dSTom Pothier notvisited--;
431074bb90dSTom Pothier break;
432074bb90dSTom Pothier }
433074bb90dSTom Pothier }
434074bb90dSTom Pothier } else {
435074bb90dSTom Pothier stypes[SMB_TYPE_BASEBOARD].ids[nbb].visited = 1;
436074bb90dSTom Pothier notvisited--;
437074bb90dSTom Pothier }
438074bb90dSTom Pothier
439efd31e1dSTrang Do basebd_node = x86pi_gen_bboard(mod, pnode, bb_smbid,
440efd31e1dSTrang Do nbb, psmbid);
441074bb90dSTom Pothier if (basebd_node == NULL) {
442074bb90dSTom Pothier topo_mod_dprintf(mod,
443074bb90dSTom Pothier "Failed to create BaseBoard node (%d)\n", nbb);
444074bb90dSTom Pothier nbb++;
445074bb90dSTom Pothier continue;
446074bb90dSTom Pothier }
447074bb90dSTom Pothier
448074bb90dSTom Pothier stypes[SMB_TYPE_BASEBOARD].ids[nbb].node = basebd_node;
449074bb90dSTom Pothier /*
450074bb90dSTom Pothier * Look for contained handles here and if there are
451074bb90dSTom Pothier * make sure the chip handle below is part of it.
452074bb90dSTom Pothier */
453efd31e1dSTrang Do ncmp = x86pi_bb_getchips(mod, nbb, bb_count);
454074bb90dSTom Pothier if (ncmp > 0) {
455074bb90dSTom Pothier max = min + ncmp - 1;
456074bb90dSTom Pothier /* make sure the chip enum is loaded */
457074bb90dSTom Pothier topo_mod_dprintf(mod, "%s: loading chip enum\n", f);
458074bb90dSTom Pothier
459074bb90dSTom Pothier if (topo_mod_load(mod, CHIP, TOPO_VERSION) == NULL) {
460074bb90dSTom Pothier topo_mod_dprintf(mod,
461074bb90dSTom Pothier "%s: Failed to load %s module: %s\n", f,
462074bb90dSTom Pothier CHIP, topo_strerror(topo_mod_errno(mod)));
463074bb90dSTom Pothier } else {
464074bb90dSTom Pothier /* create node range */
465074bb90dSTom Pothier topo_mod_dprintf(mod,
466074bb90dSTom Pothier "%s: chip range %d to %d\n",
467074bb90dSTom Pothier f, min, max);
468074bb90dSTom Pothier rv = topo_node_range_create(mod, basebd_node,
469074bb90dSTom Pothier CHIP, min, max);
470074bb90dSTom Pothier if (rv != 0) {
471074bb90dSTom Pothier topo_mod_dprintf(mod,
472074bb90dSTom Pothier "%s: Failed to create node range: "
473074bb90dSTom Pothier "%s\n", f,
474074bb90dSTom Pothier topo_strerror(topo_mod_errno(mod)));
475074bb90dSTom Pothier } else {
476074bb90dSTom Pothier /* call the chip enumerator */
477074bb90dSTom Pothier topo_mod_dprintf(mod, "%s: calling"
478074bb90dSTom Pothier " chip enum\n", f);
479074bb90dSTom Pothier rv =
480074bb90dSTom Pothier topo_mod_enumerate(mod, basebd_node,
481074bb90dSTom Pothier CHIP, CHIP, min, max,
482074bb90dSTom Pothier &x86pi_smbios);
483074bb90dSTom Pothier min = max + 1;
484074bb90dSTom Pothier if (rv != 0)
485074bb90dSTom Pothier topo_mod_dprintf(mod, "%s:%s"
486074bb90dSTom Pothier "enumeration failed: \n",
487074bb90dSTom Pothier f, CHIP);
488074bb90dSTom Pothier }
489074bb90dSTom Pothier }
490074bb90dSTom Pothier }
491074bb90dSTom Pothier
492074bb90dSTom Pothier /* enumerate the hostbridge node */
493074bb90dSTom Pothier rv = topo_node_range_create(mod, basebd_node, HOSTBRIDGE,
494074bb90dSTom Pothier 0, 255);
495074bb90dSTom Pothier if (rv != 0) {
496074bb90dSTom Pothier topo_mod_dprintf(mod,
497074bb90dSTom Pothier "%s: Failed to create %s range: %s\n",
498074bb90dSTom Pothier f, HOSTBRIDGE, topo_mod_errmsg(mod));
499074bb90dSTom Pothier continue;
500074bb90dSTom Pothier }
501074bb90dSTom Pothier
502074bb90dSTom Pothier smbc = &stypes[SUN_OEM_PCIEXRC];
503074bb90dSTom Pothier smbc->type = SUN_OEM_PCIEXRC;
504efd31e1dSTrang Do x86pi_smb_strcnt(mod, smbc);
505074bb90dSTom Pothier for (i = 0; i < smbc->count; i++) {
506074bb90dSTom Pothier if (smbios_info_pciexrc(shp, smbc->ids[i].id,
507074bb90dSTom Pothier &hbr) != 0) {
508074bb90dSTom Pothier topo_mod_dprintf(mod,
509074bb90dSTom Pothier "smbios_info_pciexrc failed: "
510074bb90dSTom Pothier "id = %d\n", (int)smbc->ids[i].id);
511074bb90dSTom Pothier continue;
512074bb90dSTom Pothier }
513074bb90dSTom Pothier
514074bb90dSTom Pothier if (hbr.smbpcie_bb != bb_smbid)
515074bb90dSTom Pothier continue;
516efd31e1dSTrang Do rv = x86pi_gen_hbr(mod, basebd_node,
517074bb90dSTom Pothier smbc->ids[i].id, hbri, &rci);
518*6597d6fcSRobert Mustacchi if (rv != 0) {
519*6597d6fcSRobert Mustacchi topo_mod_dprintf(mod, "couldn't create "
520*6597d6fcSRobert Mustacchi "hostbridge=%" PRIu64 "\n", hbri);
521*6597d6fcSRobert Mustacchi }
522074bb90dSTom Pothier hbri++;
523074bb90dSTom Pothier }
524074bb90dSTom Pothier nbb++;
525074bb90dSTom Pothier
526074bb90dSTom Pothier } while (notvisited);
527074bb90dSTom Pothier
528074bb90dSTom Pothier return (0);
529074bb90dSTom Pothier }
530