Deleted Added
full compact
pci_bus.c (102934) pci_bus.c (103016)
1/*
2 * Copyright (c) 1997, Stefan Esser <se@freebsd.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice unmodified, this list of conditions, and the following
10 * disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
1/*
2 * Copyright (c) 1997, Stefan Esser <se@freebsd.org>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice unmodified, this list of conditions, and the following
10 * disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
26 * $FreeBSD: head/sys/i386/pci/pci_bus.c 102934 2002-09-04 19:43:22Z phk $
26 * $FreeBSD: head/sys/i386/pci/pci_bus.c 103016 2002-09-06 16:09:07Z jhb $
27 *
28 */
29
30#include <sys/param.h>
31#include <sys/systm.h>
32#include <sys/bus.h>
33#include <sys/kernel.h>
34#include <sys/module.h>
35#include <sys/malloc.h>
36
37#include <pci/pcivar.h>
38#include <pci/pcireg.h>
39#include <isa/isavar.h>
40#include <machine/nexusvar.h>
41#include <machine/pci_cfgreg.h>
42#include <machine/segments.h>
43#include <machine/cputypes.h>
44#include <machine/pc/bios.h>
45#include <machine/md_var.h>
46
47#include "opt_cpu.h"
48
49#include "pcib_if.h"
50
51static int
52nexus_pcib_maxslots(device_t dev)
53{
54 return 31;
55}
56
57/* read configuration space register */
58
59static u_int32_t
60nexus_pcib_read_config(device_t dev, int bus, int slot, int func,
61 int reg, int bytes)
62{
63 return(pci_cfgregread(bus, slot, func, reg, bytes));
64}
65
66/* write configuration space register */
67
68static void
69nexus_pcib_write_config(device_t dev, int bus, int slot, int func,
70 int reg, u_int32_t data, int bytes)
71{
72 pci_cfgregwrite(bus, slot, func, reg, data, bytes);
73}
74
75/* route interrupt */
76
77static int
78nexus_pcib_route_interrupt(device_t pcib, device_t dev, int pin)
79{
80 return(pci_cfgintr(pci_get_bus(dev), pci_get_slot(dev), pin));
81}
82
83static devclass_t pcib_devclass;
84
85static const char *
86nexus_pcib_is_host_bridge(int bus, int slot, int func,
87 u_int32_t id, u_int8_t class, u_int8_t subclass,
88 u_int8_t *busnum)
89{
90 const char *s = NULL;
91 static u_int8_t pxb[4]; /* hack for 450nx */
92
93 *busnum = 0;
94
95 switch (id) {
96 case 0x12258086:
97 s = "Intel 824?? host to PCI bridge";
98 /* XXX This is a guess */
99 /* *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x41, 1); */
100 *busnum = bus;
101 break;
102 case 0x71208086:
103 s = "Intel 82810 (i810 GMCH) Host To Hub bridge";
104 break;
105 case 0x71228086:
106 s = "Intel 82810-DC100 (i810-DC100 GMCH) Host To Hub bridge";
107 break;
108 case 0x71248086:
109 s = "Intel 82810E (i810E GMCH) Host To Hub bridge";
110 break;
111 case 0x11308086:
112 s = "Intel 82815 (i815 GMCH) Host To Hub bridge";
113 break;
114 case 0x71808086:
115 s = "Intel 82443LX (440 LX) host to PCI bridge";
116 break;
117 case 0x71908086:
118 s = "Intel 82443BX (440 BX) host to PCI bridge";
119 break;
120 case 0x71928086:
121 s = "Intel 82443BX host to PCI bridge (AGP disabled)";
122 break;
123 case 0x71948086:
124 s = "Intel 82443MX host to PCI bridge";
125 break;
126 case 0x71a08086:
127 s = "Intel 82443GX host to PCI bridge";
128 break;
129 case 0x71a18086:
130 s = "Intel 82443GX host to AGP bridge";
131 break;
132 case 0x71a28086:
133 s = "Intel 82443GX host to PCI bridge (AGP disabled)";
134 break;
135 case 0x84c48086:
136 s = "Intel 82454KX/GX (Orion) host to PCI bridge";
137 *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x4a, 1);
138 break;
139 case 0x84ca8086:
140 /*
141 * For the 450nx chipset, there is a whole bundle of
142 * things pretending to be host bridges. The MIOC will
143 * be seen first and isn't really a pci bridge (the
144 * actual busses are attached to the PXB's). We need to
145 * read the registers of the MIOC to figure out the
146 * bus numbers for the PXB channels.
147 *
148 * Since the MIOC doesn't have a pci bus attached, we
149 * pretend it wasn't there.
150 */
151 pxb[0] = nexus_pcib_read_config(0, bus, slot, func,
152 0xd0, 1); /* BUSNO[0] */
153 pxb[1] = nexus_pcib_read_config(0, bus, slot, func,
154 0xd1, 1) + 1; /* SUBA[0]+1 */
155 pxb[2] = nexus_pcib_read_config(0, bus, slot, func,
156 0xd3, 1); /* BUSNO[1] */
157 pxb[3] = nexus_pcib_read_config(0, bus, slot, func,
158 0xd4, 1) + 1; /* SUBA[1]+1 */
159 return NULL;
160 case 0x84cb8086:
161 switch (slot) {
162 case 0x12:
163 s = "Intel 82454NX PXB#0, Bus#A";
164 *busnum = pxb[0];
165 break;
166 case 0x13:
167 s = "Intel 82454NX PXB#0, Bus#B";
168 *busnum = pxb[1];
169 break;
170 case 0x14:
171 s = "Intel 82454NX PXB#1, Bus#A";
172 *busnum = pxb[2];
173 break;
174 case 0x15:
175 s = "Intel 82454NX PXB#1, Bus#B";
176 *busnum = pxb[3];
177 break;
178 }
179 break;
180
181 /* AMD -- vendor 0x1022 */
182 case 0x30001022:
183 s = "AMD Elan SC520 host to PCI bridge";
184#ifdef CPU_ELAN
185 init_AMD_Elan_sc520();
186#else
187 printf("*** WARNING: kernel option CPU_ELAN missing");
188 printf("-- timekeeping may be wrong\n");
189#endif
190 break;
191 case 0x70061022:
192 s = "AMD-751 host to PCI bridge";
193 break;
194 case 0x700e1022:
195 s = "AMD-761 host to PCI bridge";
196 break;
197
198 /* SiS -- vendor 0x1039 */
199 case 0x04961039:
200 s = "SiS 85c496";
201 break;
202 case 0x04061039:
203 s = "SiS 85c501";
204 break;
205 case 0x06011039:
206 s = "SiS 85c601";
207 break;
208 case 0x55911039:
209 s = "SiS 5591 host to PCI bridge";
210 break;
211 case 0x00011039:
212 s = "SiS 5591 host to AGP bridge";
213 break;
214
215 /* VLSI -- vendor 0x1004 */
216 case 0x00051004:
217 s = "VLSI 82C592 Host to PCI bridge";
218 break;
219
220 /* XXX Here is MVP3, I got the datasheet but NO M/B to test it */
221 /* totally. Please let me know if anything wrong. -F */
222 /* XXX need info on the MVP3 -- any takers? */
223 case 0x05981106:
224 s = "VIA 82C598MVP (Apollo MVP3) host bridge";
225 break;
226
227 /* AcerLabs -- vendor 0x10b9 */
228 /* Funny : The datasheet told me vendor id is "10b8",sub-vendor */
229 /* id is '10b9" but the register always shows "10b9". -Foxfair */
230 case 0x154110b9:
231 s = "AcerLabs M1541 (Aladdin-V) PCI host bridge";
232 break;
233
234 /* OPTi -- vendor 0x1045 */
235 case 0xc7011045:
236 s = "OPTi 82C700 host to PCI bridge";
237 break;
238 case 0xc8221045:
239 s = "OPTi 82C822 host to PCI Bridge";
240 break;
241
242 /* ServerWorks -- vendor 0x1166 */
243 case 0x00051166:
244 s = "ServerWorks NB6536 2.0HE host to PCI bridge";
245 *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x44, 1);
246 break;
247
248 case 0x00061166:
249 /* FALLTHROUGH */
250 case 0x00081166:
251 /* FALLTHROUGH */
252 case 0x02011166:
253 /* FALLTHROUGH */
254 case 0x010f1014: /* IBM re-badged ServerWorks chipset */
255 s = "ServerWorks host to PCI bridge";
256 *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x44, 1);
257 break;
258
259 case 0x00091166:
260 s = "ServerWorks NB6635 3.0LE host to PCI bridge";
261 *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x44, 1);
262 break;
263
264 case 0x00111166:
265 /* FALLTHROUGH */
266 case 0x03021014: /* IBM re-badged ServerWorks chipset */
267 s = "ServerWorks CMIC-HE host to PCI-X bridge";
268 *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x44, 1);
269 break;
270
271 /* Integrated Micro Solutions -- vendor 0x10e0 */
272 case 0x884910e0:
273 s = "Integrated Micro Solutions VL Bridge";
274 break;
275
276 default:
277 if (class == PCIC_BRIDGE && subclass == PCIS_BRIDGE_HOST)
278 s = "Host to PCI bridge";
279 break;
280 }
281
282 return s;
283}
284
285/*
286 * Scan the first pci bus for host-pci bridges and add pcib instances
287 * to the nexus for each bridge.
288 */
289static void
290nexus_pcib_identify(driver_t *driver, device_t parent)
291{
292 int bus, slot, func;
293 u_int8_t hdrtype;
294 int found = 0;
295 int pcifunchigh;
296 int found824xx = 0;
297 int found_orion = 0;
298 int found_pcibios_flaming_death = 0;
299 device_t child;
300 devclass_t pci_devclass;
301
302 if (pci_cfgregopen() == 0)
303 return;
304 /*
305 * Check to see if we haven't already had a PCI bus added
306 * via some other means. If we have, bail since otherwise
307 * we're going to end up duplicating it.
308 */
309 if ((pci_devclass = devclass_find("pci")) &&
310 devclass_get_device(pci_devclass, 0))
311 return;
312
313
314 bus = 0;
315 retry:
316 for (slot = 0; slot <= PCI_SLOTMAX; slot++) {
317 func = 0;
318 hdrtype = nexus_pcib_read_config(0, bus, slot, func,
319 PCIR_HEADERTYPE, 1);
320 if ((hdrtype & PCIM_MFDEV) &&
321 (!found_orion || hdrtype != 0xff))
322 pcifunchigh = 7;
323 else
324 pcifunchigh = 0;
325 for (func = 0; func <= pcifunchigh; func++) {
326 /*
327 * Read the IDs and class from the device.
328 */
329 u_int32_t id;
330 u_int8_t class, subclass, busnum;
331 const char *s;
332 device_t *devs;
333 int ndevs, i;
334
335 id = nexus_pcib_read_config(0, bus, slot, func,
336 PCIR_DEVVENDOR, 4);
337 if (id == -1)
338 continue;
339 class = nexus_pcib_read_config(0, bus, slot, func,
340 PCIR_CLASS, 1);
341 subclass = nexus_pcib_read_config(0, bus, slot, func,
342 PCIR_SUBCLASS, 1);
343
344 s = nexus_pcib_is_host_bridge(bus, slot, func,
345 id, class, subclass,
346 &busnum);
347 if (s == NULL)
348 continue;
349
350 /*
351 * Check to see if the physical bus has already
352 * been seen. Eg: hybrid 32 and 64 bit host
353 * bridges to the same logical bus.
354 */
355 if (device_get_children(parent, &devs, &ndevs) == 0) {
356 for (i = 0; s != NULL && i < ndevs; i++) {
357 if (strcmp(device_get_name(devs[i]),
358 "pcib") != 0)
359 continue;
360 if (nexus_get_pcibus(devs[i]) == busnum)
361 s = NULL;
362 }
363 free(devs, M_TEMP);
364 }
365
366 if (s == NULL)
367 continue;
368 /*
369 * Add at priority 100 to make sure we
370 * go after any motherboard resources
371 */
372 child = BUS_ADD_CHILD(parent, 100,
373 "pcib", busnum);
374 device_set_desc(child, s);
375 nexus_set_pcibus(child, busnum);
376
377 found = 1;
378 if (id == 0x12258086)
379 found824xx = 1;
380 if (id == 0x84c48086)
381 found_orion = 1;
382 }
383 }
384 if (found824xx && bus == 0) {
385 bus++;
386 goto retry;
387 }
388
389 /*
390 * This is just freaking brilliant! Some BIOS writers have
391 * decided that we must be forcibly prevented from using
392 * PCIBIOS to query the host->pci bridges. If you try and
393 * access configuration registers, it pretends there is
394 * no pci device at that bus:device:function address.
395 */
396 if (!found && pci_pcibios_active() && !found_pcibios_flaming_death) {
397 /* retry with the old mechanism, or fail */
398 if (pci_kill_pcibios() == 0)
399 return;
400 printf("nexus_pcib_identify: found broken PCIBIOS - disabling it and retrying.\n");
401 printf("nexus_pcib_identify: it is bogusly censoring host->pci bridges.\n");
402 found_pcibios_flaming_death = 1;
403 goto retry;
404 }
405
406 /*
407 * Make sure we add at least one bridge since some old
408 * hardware doesn't actually have a host-pci bridge device.
409 * Note that pci_cfgregopen() thinks we have PCI devices..
410 */
411 if (!found) {
412 if (bootverbose)
413 printf(
414 "nexus_pcib_identify: no bridge found, adding pcib0 anyway\n");
415 child = BUS_ADD_CHILD(parent, 100, "pcib", 0);
416 nexus_set_pcibus(child, 0);
417 }
418}
419
420static int
421nexus_pcib_probe(device_t dev)
422{
423 devclass_t pci_devclass;
424
425 if (pci_cfgregopen() == 0)
426 return ENXIO;
427 /*
428 * Check to see if we haven't already had a PCI bus added
429 * via some other means. If we have, bail since otherwise
430 * we're going to end up duplicating it.
431 */
432 if ((pci_devclass = devclass_find("pci")) &&
433 devclass_get_device(pci_devclass, device_get_unit(dev)))
434 return ENXIO;
435
436 return 0;
437}
438
439static int
440nexus_pcib_attach(device_t dev)
441{
442 device_t child;
443
27 *
28 */
29
30#include <sys/param.h>
31#include <sys/systm.h>
32#include <sys/bus.h>
33#include <sys/kernel.h>
34#include <sys/module.h>
35#include <sys/malloc.h>
36
37#include <pci/pcivar.h>
38#include <pci/pcireg.h>
39#include <isa/isavar.h>
40#include <machine/nexusvar.h>
41#include <machine/pci_cfgreg.h>
42#include <machine/segments.h>
43#include <machine/cputypes.h>
44#include <machine/pc/bios.h>
45#include <machine/md_var.h>
46
47#include "opt_cpu.h"
48
49#include "pcib_if.h"
50
51static int
52nexus_pcib_maxslots(device_t dev)
53{
54 return 31;
55}
56
57/* read configuration space register */
58
59static u_int32_t
60nexus_pcib_read_config(device_t dev, int bus, int slot, int func,
61 int reg, int bytes)
62{
63 return(pci_cfgregread(bus, slot, func, reg, bytes));
64}
65
66/* write configuration space register */
67
68static void
69nexus_pcib_write_config(device_t dev, int bus, int slot, int func,
70 int reg, u_int32_t data, int bytes)
71{
72 pci_cfgregwrite(bus, slot, func, reg, data, bytes);
73}
74
75/* route interrupt */
76
77static int
78nexus_pcib_route_interrupt(device_t pcib, device_t dev, int pin)
79{
80 return(pci_cfgintr(pci_get_bus(dev), pci_get_slot(dev), pin));
81}
82
83static devclass_t pcib_devclass;
84
85static const char *
86nexus_pcib_is_host_bridge(int bus, int slot, int func,
87 u_int32_t id, u_int8_t class, u_int8_t subclass,
88 u_int8_t *busnum)
89{
90 const char *s = NULL;
91 static u_int8_t pxb[4]; /* hack for 450nx */
92
93 *busnum = 0;
94
95 switch (id) {
96 case 0x12258086:
97 s = "Intel 824?? host to PCI bridge";
98 /* XXX This is a guess */
99 /* *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x41, 1); */
100 *busnum = bus;
101 break;
102 case 0x71208086:
103 s = "Intel 82810 (i810 GMCH) Host To Hub bridge";
104 break;
105 case 0x71228086:
106 s = "Intel 82810-DC100 (i810-DC100 GMCH) Host To Hub bridge";
107 break;
108 case 0x71248086:
109 s = "Intel 82810E (i810E GMCH) Host To Hub bridge";
110 break;
111 case 0x11308086:
112 s = "Intel 82815 (i815 GMCH) Host To Hub bridge";
113 break;
114 case 0x71808086:
115 s = "Intel 82443LX (440 LX) host to PCI bridge";
116 break;
117 case 0x71908086:
118 s = "Intel 82443BX (440 BX) host to PCI bridge";
119 break;
120 case 0x71928086:
121 s = "Intel 82443BX host to PCI bridge (AGP disabled)";
122 break;
123 case 0x71948086:
124 s = "Intel 82443MX host to PCI bridge";
125 break;
126 case 0x71a08086:
127 s = "Intel 82443GX host to PCI bridge";
128 break;
129 case 0x71a18086:
130 s = "Intel 82443GX host to AGP bridge";
131 break;
132 case 0x71a28086:
133 s = "Intel 82443GX host to PCI bridge (AGP disabled)";
134 break;
135 case 0x84c48086:
136 s = "Intel 82454KX/GX (Orion) host to PCI bridge";
137 *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x4a, 1);
138 break;
139 case 0x84ca8086:
140 /*
141 * For the 450nx chipset, there is a whole bundle of
142 * things pretending to be host bridges. The MIOC will
143 * be seen first and isn't really a pci bridge (the
144 * actual busses are attached to the PXB's). We need to
145 * read the registers of the MIOC to figure out the
146 * bus numbers for the PXB channels.
147 *
148 * Since the MIOC doesn't have a pci bus attached, we
149 * pretend it wasn't there.
150 */
151 pxb[0] = nexus_pcib_read_config(0, bus, slot, func,
152 0xd0, 1); /* BUSNO[0] */
153 pxb[1] = nexus_pcib_read_config(0, bus, slot, func,
154 0xd1, 1) + 1; /* SUBA[0]+1 */
155 pxb[2] = nexus_pcib_read_config(0, bus, slot, func,
156 0xd3, 1); /* BUSNO[1] */
157 pxb[3] = nexus_pcib_read_config(0, bus, slot, func,
158 0xd4, 1) + 1; /* SUBA[1]+1 */
159 return NULL;
160 case 0x84cb8086:
161 switch (slot) {
162 case 0x12:
163 s = "Intel 82454NX PXB#0, Bus#A";
164 *busnum = pxb[0];
165 break;
166 case 0x13:
167 s = "Intel 82454NX PXB#0, Bus#B";
168 *busnum = pxb[1];
169 break;
170 case 0x14:
171 s = "Intel 82454NX PXB#1, Bus#A";
172 *busnum = pxb[2];
173 break;
174 case 0x15:
175 s = "Intel 82454NX PXB#1, Bus#B";
176 *busnum = pxb[3];
177 break;
178 }
179 break;
180
181 /* AMD -- vendor 0x1022 */
182 case 0x30001022:
183 s = "AMD Elan SC520 host to PCI bridge";
184#ifdef CPU_ELAN
185 init_AMD_Elan_sc520();
186#else
187 printf("*** WARNING: kernel option CPU_ELAN missing");
188 printf("-- timekeeping may be wrong\n");
189#endif
190 break;
191 case 0x70061022:
192 s = "AMD-751 host to PCI bridge";
193 break;
194 case 0x700e1022:
195 s = "AMD-761 host to PCI bridge";
196 break;
197
198 /* SiS -- vendor 0x1039 */
199 case 0x04961039:
200 s = "SiS 85c496";
201 break;
202 case 0x04061039:
203 s = "SiS 85c501";
204 break;
205 case 0x06011039:
206 s = "SiS 85c601";
207 break;
208 case 0x55911039:
209 s = "SiS 5591 host to PCI bridge";
210 break;
211 case 0x00011039:
212 s = "SiS 5591 host to AGP bridge";
213 break;
214
215 /* VLSI -- vendor 0x1004 */
216 case 0x00051004:
217 s = "VLSI 82C592 Host to PCI bridge";
218 break;
219
220 /* XXX Here is MVP3, I got the datasheet but NO M/B to test it */
221 /* totally. Please let me know if anything wrong. -F */
222 /* XXX need info on the MVP3 -- any takers? */
223 case 0x05981106:
224 s = "VIA 82C598MVP (Apollo MVP3) host bridge";
225 break;
226
227 /* AcerLabs -- vendor 0x10b9 */
228 /* Funny : The datasheet told me vendor id is "10b8",sub-vendor */
229 /* id is '10b9" but the register always shows "10b9". -Foxfair */
230 case 0x154110b9:
231 s = "AcerLabs M1541 (Aladdin-V) PCI host bridge";
232 break;
233
234 /* OPTi -- vendor 0x1045 */
235 case 0xc7011045:
236 s = "OPTi 82C700 host to PCI bridge";
237 break;
238 case 0xc8221045:
239 s = "OPTi 82C822 host to PCI Bridge";
240 break;
241
242 /* ServerWorks -- vendor 0x1166 */
243 case 0x00051166:
244 s = "ServerWorks NB6536 2.0HE host to PCI bridge";
245 *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x44, 1);
246 break;
247
248 case 0x00061166:
249 /* FALLTHROUGH */
250 case 0x00081166:
251 /* FALLTHROUGH */
252 case 0x02011166:
253 /* FALLTHROUGH */
254 case 0x010f1014: /* IBM re-badged ServerWorks chipset */
255 s = "ServerWorks host to PCI bridge";
256 *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x44, 1);
257 break;
258
259 case 0x00091166:
260 s = "ServerWorks NB6635 3.0LE host to PCI bridge";
261 *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x44, 1);
262 break;
263
264 case 0x00111166:
265 /* FALLTHROUGH */
266 case 0x03021014: /* IBM re-badged ServerWorks chipset */
267 s = "ServerWorks CMIC-HE host to PCI-X bridge";
268 *busnum = nexus_pcib_read_config(0, bus, slot, func, 0x44, 1);
269 break;
270
271 /* Integrated Micro Solutions -- vendor 0x10e0 */
272 case 0x884910e0:
273 s = "Integrated Micro Solutions VL Bridge";
274 break;
275
276 default:
277 if (class == PCIC_BRIDGE && subclass == PCIS_BRIDGE_HOST)
278 s = "Host to PCI bridge";
279 break;
280 }
281
282 return s;
283}
284
285/*
286 * Scan the first pci bus for host-pci bridges and add pcib instances
287 * to the nexus for each bridge.
288 */
289static void
290nexus_pcib_identify(driver_t *driver, device_t parent)
291{
292 int bus, slot, func;
293 u_int8_t hdrtype;
294 int found = 0;
295 int pcifunchigh;
296 int found824xx = 0;
297 int found_orion = 0;
298 int found_pcibios_flaming_death = 0;
299 device_t child;
300 devclass_t pci_devclass;
301
302 if (pci_cfgregopen() == 0)
303 return;
304 /*
305 * Check to see if we haven't already had a PCI bus added
306 * via some other means. If we have, bail since otherwise
307 * we're going to end up duplicating it.
308 */
309 if ((pci_devclass = devclass_find("pci")) &&
310 devclass_get_device(pci_devclass, 0))
311 return;
312
313
314 bus = 0;
315 retry:
316 for (slot = 0; slot <= PCI_SLOTMAX; slot++) {
317 func = 0;
318 hdrtype = nexus_pcib_read_config(0, bus, slot, func,
319 PCIR_HEADERTYPE, 1);
320 if ((hdrtype & PCIM_MFDEV) &&
321 (!found_orion || hdrtype != 0xff))
322 pcifunchigh = 7;
323 else
324 pcifunchigh = 0;
325 for (func = 0; func <= pcifunchigh; func++) {
326 /*
327 * Read the IDs and class from the device.
328 */
329 u_int32_t id;
330 u_int8_t class, subclass, busnum;
331 const char *s;
332 device_t *devs;
333 int ndevs, i;
334
335 id = nexus_pcib_read_config(0, bus, slot, func,
336 PCIR_DEVVENDOR, 4);
337 if (id == -1)
338 continue;
339 class = nexus_pcib_read_config(0, bus, slot, func,
340 PCIR_CLASS, 1);
341 subclass = nexus_pcib_read_config(0, bus, slot, func,
342 PCIR_SUBCLASS, 1);
343
344 s = nexus_pcib_is_host_bridge(bus, slot, func,
345 id, class, subclass,
346 &busnum);
347 if (s == NULL)
348 continue;
349
350 /*
351 * Check to see if the physical bus has already
352 * been seen. Eg: hybrid 32 and 64 bit host
353 * bridges to the same logical bus.
354 */
355 if (device_get_children(parent, &devs, &ndevs) == 0) {
356 for (i = 0; s != NULL && i < ndevs; i++) {
357 if (strcmp(device_get_name(devs[i]),
358 "pcib") != 0)
359 continue;
360 if (nexus_get_pcibus(devs[i]) == busnum)
361 s = NULL;
362 }
363 free(devs, M_TEMP);
364 }
365
366 if (s == NULL)
367 continue;
368 /*
369 * Add at priority 100 to make sure we
370 * go after any motherboard resources
371 */
372 child = BUS_ADD_CHILD(parent, 100,
373 "pcib", busnum);
374 device_set_desc(child, s);
375 nexus_set_pcibus(child, busnum);
376
377 found = 1;
378 if (id == 0x12258086)
379 found824xx = 1;
380 if (id == 0x84c48086)
381 found_orion = 1;
382 }
383 }
384 if (found824xx && bus == 0) {
385 bus++;
386 goto retry;
387 }
388
389 /*
390 * This is just freaking brilliant! Some BIOS writers have
391 * decided that we must be forcibly prevented from using
392 * PCIBIOS to query the host->pci bridges. If you try and
393 * access configuration registers, it pretends there is
394 * no pci device at that bus:device:function address.
395 */
396 if (!found && pci_pcibios_active() && !found_pcibios_flaming_death) {
397 /* retry with the old mechanism, or fail */
398 if (pci_kill_pcibios() == 0)
399 return;
400 printf("nexus_pcib_identify: found broken PCIBIOS - disabling it and retrying.\n");
401 printf("nexus_pcib_identify: it is bogusly censoring host->pci bridges.\n");
402 found_pcibios_flaming_death = 1;
403 goto retry;
404 }
405
406 /*
407 * Make sure we add at least one bridge since some old
408 * hardware doesn't actually have a host-pci bridge device.
409 * Note that pci_cfgregopen() thinks we have PCI devices..
410 */
411 if (!found) {
412 if (bootverbose)
413 printf(
414 "nexus_pcib_identify: no bridge found, adding pcib0 anyway\n");
415 child = BUS_ADD_CHILD(parent, 100, "pcib", 0);
416 nexus_set_pcibus(child, 0);
417 }
418}
419
420static int
421nexus_pcib_probe(device_t dev)
422{
423 devclass_t pci_devclass;
424
425 if (pci_cfgregopen() == 0)
426 return ENXIO;
427 /*
428 * Check to see if we haven't already had a PCI bus added
429 * via some other means. If we have, bail since otherwise
430 * we're going to end up duplicating it.
431 */
432 if ((pci_devclass = devclass_find("pci")) &&
433 devclass_get_device(pci_devclass, device_get_unit(dev)))
434 return ENXIO;
435
436 return 0;
437}
438
439static int
440nexus_pcib_attach(device_t dev)
441{
442 device_t child;
443
444 child = device_add_child(dev, "pci", device_get_unit(dev));
444 child = device_add_child(dev, "pci", pcib_get_bus(dev));
445
446 return bus_generic_attach(dev);
447}
448
449static int
450nexus_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
451{
452
453 switch (which) {
454 case PCIB_IVAR_BUS:
455 *result = nexus_get_pcibus(dev);
456 return 0;
457 }
458 return ENOENT;
459}
460
461static int
462nexus_pcib_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
463{
464
465 switch (which) {
466 case PCIB_IVAR_BUS:
467 nexus_set_pcibus(dev, value);
468 return 0;
469 }
470 return ENOENT;
471}
472
473
474static device_method_t nexus_pcib_methods[] = {
475 /* Device interface */
476 DEVMETHOD(device_identify, nexus_pcib_identify),
477 DEVMETHOD(device_probe, nexus_pcib_probe),
478 DEVMETHOD(device_attach, nexus_pcib_attach),
479 DEVMETHOD(device_shutdown, bus_generic_shutdown),
480 DEVMETHOD(device_suspend, bus_generic_suspend),
481 DEVMETHOD(device_resume, bus_generic_resume),
482
483 /* Bus interface */
484 DEVMETHOD(bus_print_child, bus_generic_print_child),
485 DEVMETHOD(bus_read_ivar, nexus_pcib_read_ivar),
486 DEVMETHOD(bus_write_ivar, nexus_pcib_write_ivar),
487 DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
488 DEVMETHOD(bus_release_resource, bus_generic_release_resource),
489 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
490 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
491 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
492 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
493
494 /* pcib interface */
495 DEVMETHOD(pcib_maxslots, nexus_pcib_maxslots),
496 DEVMETHOD(pcib_read_config, nexus_pcib_read_config),
497 DEVMETHOD(pcib_write_config, nexus_pcib_write_config),
498 DEVMETHOD(pcib_route_interrupt, nexus_pcib_route_interrupt),
499
500 { 0, 0 }
501};
502
503static driver_t nexus_pcib_driver = {
504 "pcib",
505 nexus_pcib_methods,
506 1,
507};
508
509DRIVER_MODULE(pcib, nexus, nexus_pcib_driver, pcib_devclass, 0, 0);
510
511
512/*
513 * Provide a device to "eat" the host->pci bridges that we dug up above
514 * and stop them showing up twice on the probes. This also stops them
515 * showing up as 'none' in pciconf -l.
516 */
517static int
518pci_hostb_probe(device_t dev)
519{
520 u_int32_t id;
521
522 id = pci_get_devid(dev);
523
524 switch (id) {
525
526 /* VIA VT82C596 Power Managment Function */
527 case 0x30501106:
528 return ENXIO;
529
530 default:
531 break;
532 }
533
534 if (pci_get_class(dev) == PCIC_BRIDGE &&
535 pci_get_subclass(dev) == PCIS_BRIDGE_HOST) {
536 device_set_desc(dev, "Host to PCI bridge");
537 device_quiet(dev);
538 return -10000;
539 }
540 return ENXIO;
541}
542
543static int
544pci_hostb_attach(device_t dev)
545{
546
547 return 0;
548}
549
550static device_method_t pci_hostb_methods[] = {
551 /* Device interface */
552 DEVMETHOD(device_probe, pci_hostb_probe),
553 DEVMETHOD(device_attach, pci_hostb_attach),
554 DEVMETHOD(device_shutdown, bus_generic_shutdown),
555 DEVMETHOD(device_suspend, bus_generic_suspend),
556 DEVMETHOD(device_resume, bus_generic_resume),
557
558 { 0, 0 }
559};
560static driver_t pci_hostb_driver = {
561 "hostb",
562 pci_hostb_methods,
563 1,
564};
565static devclass_t pci_hostb_devclass;
566
567DRIVER_MODULE(hostb, pci, pci_hostb_driver, pci_hostb_devclass, 0, 0);
568
569
570/*
571 * Install placeholder to claim the resources owned by the
572 * PCI bus interface. This could be used to extract the
573 * config space registers in the extreme case where the PnP
574 * ID is available and the PCI BIOS isn't, but for now we just
575 * eat the PnP ID and do nothing else.
576 *
577 * XXX we should silence this probe, as it will generally confuse
578 * people.
579 */
580static struct isa_pnp_id pcibus_pnp_ids[] = {
581 { 0x030ad041 /* PNP0A03 */, "PCI Bus" },
582 { 0 }
583};
584
585static int
586pcibus_pnp_probe(device_t dev)
587{
588 int result;
589
590 if ((result = ISA_PNP_PROBE(device_get_parent(dev), dev, pcibus_pnp_ids)) <= 0)
591 device_quiet(dev);
592 return(result);
593}
594
595static int
596pcibus_pnp_attach(device_t dev)
597{
598 return(0);
599}
600
601static device_method_t pcibus_pnp_methods[] = {
602 /* Device interface */
603 DEVMETHOD(device_probe, pcibus_pnp_probe),
604 DEVMETHOD(device_attach, pcibus_pnp_attach),
605 DEVMETHOD(device_detach, bus_generic_detach),
606 DEVMETHOD(device_shutdown, bus_generic_shutdown),
607 DEVMETHOD(device_suspend, bus_generic_suspend),
608 DEVMETHOD(device_resume, bus_generic_resume),
609 { 0, 0 }
610};
611
612static driver_t pcibus_pnp_driver = {
613 "pcibus_pnp",
614 pcibus_pnp_methods,
615 1, /* no softc */
616};
617
618static devclass_t pcibus_pnp_devclass;
619
620DRIVER_MODULE(pcibus_pnp, isa, pcibus_pnp_driver, pcibus_pnp_devclass, 0, 0);
445
446 return bus_generic_attach(dev);
447}
448
449static int
450nexus_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
451{
452
453 switch (which) {
454 case PCIB_IVAR_BUS:
455 *result = nexus_get_pcibus(dev);
456 return 0;
457 }
458 return ENOENT;
459}
460
461static int
462nexus_pcib_write_ivar(device_t dev, device_t child, int which, uintptr_t value)
463{
464
465 switch (which) {
466 case PCIB_IVAR_BUS:
467 nexus_set_pcibus(dev, value);
468 return 0;
469 }
470 return ENOENT;
471}
472
473
474static device_method_t nexus_pcib_methods[] = {
475 /* Device interface */
476 DEVMETHOD(device_identify, nexus_pcib_identify),
477 DEVMETHOD(device_probe, nexus_pcib_probe),
478 DEVMETHOD(device_attach, nexus_pcib_attach),
479 DEVMETHOD(device_shutdown, bus_generic_shutdown),
480 DEVMETHOD(device_suspend, bus_generic_suspend),
481 DEVMETHOD(device_resume, bus_generic_resume),
482
483 /* Bus interface */
484 DEVMETHOD(bus_print_child, bus_generic_print_child),
485 DEVMETHOD(bus_read_ivar, nexus_pcib_read_ivar),
486 DEVMETHOD(bus_write_ivar, nexus_pcib_write_ivar),
487 DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
488 DEVMETHOD(bus_release_resource, bus_generic_release_resource),
489 DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
490 DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
491 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
492 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
493
494 /* pcib interface */
495 DEVMETHOD(pcib_maxslots, nexus_pcib_maxslots),
496 DEVMETHOD(pcib_read_config, nexus_pcib_read_config),
497 DEVMETHOD(pcib_write_config, nexus_pcib_write_config),
498 DEVMETHOD(pcib_route_interrupt, nexus_pcib_route_interrupt),
499
500 { 0, 0 }
501};
502
503static driver_t nexus_pcib_driver = {
504 "pcib",
505 nexus_pcib_methods,
506 1,
507};
508
509DRIVER_MODULE(pcib, nexus, nexus_pcib_driver, pcib_devclass, 0, 0);
510
511
512/*
513 * Provide a device to "eat" the host->pci bridges that we dug up above
514 * and stop them showing up twice on the probes. This also stops them
515 * showing up as 'none' in pciconf -l.
516 */
517static int
518pci_hostb_probe(device_t dev)
519{
520 u_int32_t id;
521
522 id = pci_get_devid(dev);
523
524 switch (id) {
525
526 /* VIA VT82C596 Power Managment Function */
527 case 0x30501106:
528 return ENXIO;
529
530 default:
531 break;
532 }
533
534 if (pci_get_class(dev) == PCIC_BRIDGE &&
535 pci_get_subclass(dev) == PCIS_BRIDGE_HOST) {
536 device_set_desc(dev, "Host to PCI bridge");
537 device_quiet(dev);
538 return -10000;
539 }
540 return ENXIO;
541}
542
543static int
544pci_hostb_attach(device_t dev)
545{
546
547 return 0;
548}
549
550static device_method_t pci_hostb_methods[] = {
551 /* Device interface */
552 DEVMETHOD(device_probe, pci_hostb_probe),
553 DEVMETHOD(device_attach, pci_hostb_attach),
554 DEVMETHOD(device_shutdown, bus_generic_shutdown),
555 DEVMETHOD(device_suspend, bus_generic_suspend),
556 DEVMETHOD(device_resume, bus_generic_resume),
557
558 { 0, 0 }
559};
560static driver_t pci_hostb_driver = {
561 "hostb",
562 pci_hostb_methods,
563 1,
564};
565static devclass_t pci_hostb_devclass;
566
567DRIVER_MODULE(hostb, pci, pci_hostb_driver, pci_hostb_devclass, 0, 0);
568
569
570/*
571 * Install placeholder to claim the resources owned by the
572 * PCI bus interface. This could be used to extract the
573 * config space registers in the extreme case where the PnP
574 * ID is available and the PCI BIOS isn't, but for now we just
575 * eat the PnP ID and do nothing else.
576 *
577 * XXX we should silence this probe, as it will generally confuse
578 * people.
579 */
580static struct isa_pnp_id pcibus_pnp_ids[] = {
581 { 0x030ad041 /* PNP0A03 */, "PCI Bus" },
582 { 0 }
583};
584
585static int
586pcibus_pnp_probe(device_t dev)
587{
588 int result;
589
590 if ((result = ISA_PNP_PROBE(device_get_parent(dev), dev, pcibus_pnp_ids)) <= 0)
591 device_quiet(dev);
592 return(result);
593}
594
595static int
596pcibus_pnp_attach(device_t dev)
597{
598 return(0);
599}
600
601static device_method_t pcibus_pnp_methods[] = {
602 /* Device interface */
603 DEVMETHOD(device_probe, pcibus_pnp_probe),
604 DEVMETHOD(device_attach, pcibus_pnp_attach),
605 DEVMETHOD(device_detach, bus_generic_detach),
606 DEVMETHOD(device_shutdown, bus_generic_shutdown),
607 DEVMETHOD(device_suspend, bus_generic_suspend),
608 DEVMETHOD(device_resume, bus_generic_resume),
609 { 0, 0 }
610};
611
612static driver_t pcibus_pnp_driver = {
613 "pcibus_pnp",
614 pcibus_pnp_methods,
615 1, /* no softc */
616};
617
618static devclass_t pcibus_pnp_devclass;
619
620DRIVER_MODULE(pcibus_pnp, isa, pcibus_pnp_driver, pcibus_pnp_devclass, 0, 0);