xref: /illumos-gate/usr/src/grub/grub-0.97/netboot/pci.c (revision 89b2a9fbeabf42fa54594df0e5927bcc50a07cc9)
1 
2 /*
3  * This program is free software; you can redistribute it and/or
4  * modify it under the terms of the GNU General Public License as
5  * published by the Free Software Foundation; either version 2, or (at
6  * your option) any later version.
7  */
8 
9 #include "grub.h"
10 #include "pci.h"
11 
12 unsigned long virt_offset = 0;
13 unsigned long virt_to_phys(volatile const void *virt_addr)
14 {
15 	return ((unsigned long)virt_addr) + virt_offset;
16 }
17 
18 void *phys_to_virt(unsigned long phys_addr)
19 {
20 	return (void *)(phys_addr - virt_offset);
21 }
22 
23 #ifdef INCLUDE_3C595
24 extern struct pci_driver t595_driver;
25 #endif /* INCLUDE_3C595 */
26 
27 #ifdef INCLUDE_3C90X
28 extern struct pci_driver a3c90x_driver;
29 #endif /* INCLUDE_3C90X */
30 
31 #ifdef INCLUDE_DAVICOM
32 extern struct pci_driver davicom_driver;
33 #endif /* INCLUDE_DAVICOM */
34 
35 #ifdef INCLUDE_E1000
36 extern struct pci_driver e1000_driver;
37 #endif /* INCLUDE_E1000 */
38 
39 #ifdef INCLUDE_EEPRO100
40 extern struct pci_driver eepro100_driver;
41 #endif /* INCLUDE_EEPRO100 */
42 
43 #ifdef INCLUDE_EPIC100
44 extern struct pci_driver epic100_driver;
45 #endif /* INCLUDE_EPIC100 */
46 
47 #ifdef INCLUDE_FORCEDETH
48 extern struct pci_driver forcedeth_driver;
49 #endif /* INCLUDE_FORCEDETH */
50 
51 #ifdef INCLUDE_NATSEMI
52 extern struct pci_driver natsemi_driver;
53 #endif /* INCLUDE_NATSEMI */
54 
55 #ifdef INCLUDE_NS83820
56 extern struct pci_driver ns83820_driver;
57 #endif /* INCLUDE_NS83820 */
58 
59 #ifdef INCLUDE_NS8390
60 extern struct pci_driver nepci_driver;
61 #endif /* INCLUDE_NS8390 */
62 
63 #ifdef INCLUDE_PCNET32
64 extern struct pci_driver pcnet32_driver;
65 #endif /* INCLUDE_PCNET32 */
66 
67 #ifdef INCLUDE_PNIC
68 extern struct pci_driver pnic_driver;
69 #endif /* INCLUDE_PNIC */
70 
71 #ifdef INCLUDE_RTL8139
72 extern struct pci_driver rtl8139_driver;
73 #endif /* INCLUDE_RTL8139 */
74 
75 #ifdef INCLUDE_SIS900
76 extern struct pci_driver sis900_driver;
77 extern struct pci_driver sis_bridge_driver;
78 #endif /* INCLUDE_SIS900 */
79 
80 #ifdef INCLUDE_SUNDANCE
81 extern struct pci_driver sundance_driver;
82 #endif	/* INCLUDE_SUNDANCE */
83 
84 #ifdef INCLUDE_TG3
85 extern struct pci_driver  tg3_driver;
86 #endif /* INCLUDE_TG3 */
87 
88 #ifdef INCLUDE_TLAN
89 extern struct pci_driver tlan_driver;
90 #endif /* INCLUDE_TLAN */
91 
92 #ifdef INCLUDE_TULIP
93 extern struct pci_driver tulip_driver;
94 #endif /* INCLUDE_TULIP */
95 
96 #ifdef INCLUDE_UNDI
97 extern struct pci_driver undi_driver;
98 #endif /* INCLUDE_UNDI */
99 
100 #ifdef INCLUDE_VIA_RHINE
101 extern struct pci_driver rhine_driver;
102 #endif/* INCLUDE_VIA_RHINE */
103 
104 #ifdef INCLUDE_W89C840
105 extern struct pci_driver w89c840_driver;
106 #endif /* INCLUDE_W89C840 */
107 
108 #ifdef INCLUDE_R8169
109 extern struct pci_driver r8169_driver;
110 #endif /* INCLUDE_R8169 */
111 
112 static const struct pci_driver *pci_drivers[] = {
113 
114 #ifdef INCLUDE_3C595
115 	&t595_driver,
116 #endif /* INCLUDE_3C595 */
117 
118 #ifdef INCLUDE_3C90X
119 	&a3c90x_driver,
120 #endif /* INCLUDE_3C90X */
121 
122 #ifdef INCLUDE_DAVICOM
123 	&davicom_driver,
124 #endif /* INCLUDE_DAVICOM */
125 
126 #ifdef INCLUDE_E1000
127 	&e1000_driver,
128 #endif /* INCLUDE_E1000 */
129 
130 #ifdef INCLUDE_EEPRO100
131 	&eepro100_driver,
132 #endif /* INCLUDE_EEPRO100 */
133 
134 #ifdef INCLUDE_EPIC100
135 	&epic100_driver,
136 #endif /* INCLUDE_EPIC100 */
137 
138 #ifdef INCLUDE_FORCEDETH
139 	&forcedeth_driver,
140 #endif /* INCLUDE_FORCEDETH */
141 
142 #ifdef INCLUDE_NATSEMI
143 	&natsemi_driver,
144 #endif /* INCLUDE_NATSEMI */
145 
146 #ifdef INCLUDE_NS83820
147 	&ns83820_driver,
148 #endif /* INCLUDE_NS83820 */
149 
150 #ifdef INCLUDE_NS8390
151 	&nepci_driver,
152 #endif /* INCLUDE_NS8390 */
153 
154 #ifdef INCLUDE_PCNET32
155 	&pcnet32_driver,
156 #endif /* INCLUDE_PCNET32 */
157 
158 #ifdef INCLUDE_PNIC
159 	&pnic_driver,
160 #endif /* INCLUDE_PNIC */
161 
162 #ifdef INCLUDE_RTL8139
163 	&rtl8139_driver,
164 #endif /* INCLUDE_RTL8139 */
165 
166 #ifdef INCLUDE_SIS900
167 	&sis900_driver,
168 	&sis_bridge_driver,
169 #endif /* INCLUDE_SIS900 */
170 
171 #ifdef INCLUDE_SUNDANCE
172 	&sundance_driver,
173 #endif /* INCLUDE_SUNDANCE */
174 
175 #ifdef INCLUDE_TG3
176 	& tg3_driver,
177 #endif /* INCLUDE_TG3 */
178 
179 #ifdef INCLUDE_TLAN
180 	&tlan_driver,
181 #endif /* INCLUDE_TLAN */
182 
183 #ifdef INCLUDE_TULIP
184 	& tulip_driver,
185 #endif /* INCLUDE_TULIP */
186 
187 #ifdef INCLUDE_VIA_RHINE
188 	&rhine_driver,
189 #endif/* INCLUDE_VIA_RHINE */
190 
191 #ifdef INCLUDE_W89C840
192 	&w89c840_driver,
193 #endif /* INCLUDE_W89C840 */
194 
195 #ifdef INCLUDE_R8169
196 	&r8169_driver,
197 #endif /* INCLUDE_R8169 */
198 
199 /* We must be the last one */
200 #ifdef INCLUDE_UNDI
201 	&undi_driver,
202 #endif /* INCLUDE_UNDI */
203 
204 	0
205 };
206 
207 static void scan_drivers(
208 	int type,
209 	uint32_t class, uint16_t vendor, uint16_t device,
210 	const struct pci_driver *last_driver, struct pci_device *dev)
211 {
212 	const struct pci_driver *skip_driver = last_driver;
213 	/* Assume there is only one match of the correct type */
214 	const struct pci_driver *driver;
215 	int i, j;
216 
217 	for(j = 0; pci_drivers[j] != 0; j++){
218 		driver = pci_drivers[j];
219 		if (driver->type != type)
220 			continue;
221 		if (skip_driver) {
222 			if (skip_driver == driver)
223 				skip_driver = 0;
224 			continue;
225 		}
226 		for(i = 0; i < driver->id_count; i++) {
227 			if ((vendor == driver->ids[i].vendor) &&
228 			    (device == driver->ids[i].dev_id)) {
229 
230 				dev->driver = driver;
231 				dev->name   = driver->ids[i].name;
232 
233 				goto out;
234 			}
235 		}
236 	}
237 	if (!class) {
238 		goto out;
239 	}
240 	for(j = 0; pci_drivers[j] != 0; j++){
241 		driver = pci_drivers[j];
242 		if (driver->type != type)
243 			continue;
244 		if (skip_driver) {
245 			if (skip_driver == driver)
246 				skip_driver = 0;
247 			continue;
248 		}
249 		if (last_driver == driver)
250 			continue;
251 		if ((class >> 8) == driver->class) {
252 			dev->driver = driver;
253 			dev->name   = driver->name;
254 			goto out;
255 		}
256 	}
257  out:
258 	return;
259 }
260 
261 void scan_pci_bus(int type, struct pci_device *dev)
262 {
263 	unsigned int first_bus, first_devfn;
264 	const struct pci_driver *first_driver;
265 	unsigned int devfn, bus, buses;
266 	unsigned char hdr_type = 0;
267 	uint32_t class;
268 	uint16_t vendor, device;
269 	uint32_t l, membase, ioaddr, romaddr;
270 	int reg;
271 
272 	EnterFunction("scan_pci_bus");
273 	first_bus    = 0;
274 	first_devfn  = 0;
275 	first_driver = 0;
276 	if (dev->driver) {
277 		first_driver = dev->driver;
278 		first_bus    = dev->bus;
279 		first_devfn  = dev->devfn;
280 		/* Re read the header type on a restart */
281 		pcibios_read_config_byte(first_bus, first_devfn & ~0x7,
282 			PCI_HEADER_TYPE, &hdr_type);
283 		dev->driver  = 0;
284 		dev->bus     = 0;
285 		dev->devfn   = 0;
286 	}
287 
288 	/* Scan all PCI buses, until we find our card.
289 	 * We could be smart only scan the required buses but that
290 	 * is error prone, and tricky.
291 	 * By scanning all possible pci buses in order we should find
292 	 * our card eventually.
293 	 */
294 	buses=256;
295 	for (bus = first_bus; bus < buses; ++bus) {
296 		for (devfn = first_devfn; devfn < 0xff; ++devfn, first_driver = 0) {
297 			if (PCI_FUNC (devfn) == 0)
298 				pcibios_read_config_byte(bus, devfn, PCI_HEADER_TYPE, &hdr_type);
299 			else if (!(hdr_type & 0x80))	/* not a multi-function device */
300 				continue;
301 			pcibios_read_config_dword(bus, devfn, PCI_VENDOR_ID, &l);
302 			/* some broken boards return 0 if a slot is empty: */
303 			if (l == 0xffffffff || l == 0x00000000) {
304 				continue;
305 			}
306 			vendor = l & 0xffff;
307 			device = (l >> 16) & 0xffff;
308 
309 			pcibios_read_config_dword(bus, devfn, PCI_REVISION, &l);
310 			class = (l >> 8) & 0xffffff;
311 #if	DEBUG
312 		{
313 			int i;
314 			printf("%hhx:%hhx.%hhx [%hX/%hX] ---- ",
315 				bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
316 				vendor, device);
317 #if	DEBUG > 1
318 			for(i = 0; i < 256; i++) {
319 				unsigned char byte;
320 				if ((i & 0xf) == 0) {
321 					printf("%hhx: ", i);
322 				}
323 				pcibios_read_config_byte(bus, devfn, i, &byte);
324 				printf("%hhx ", byte);
325 				if ((i & 0xf) == 0xf) {
326 					printf("\n");
327 				}
328 			}
329 #endif
330 
331 		}
332 #endif
333 			scan_drivers(type, class, vendor, device, first_driver, dev);
334 			if (!dev->driver){
335 #if DEBUG
336 				printf("No driver fit.\n");
337 #endif
338 				continue;
339 			}
340 #if DEBUG
341 			printf("Get Driver:\n");
342 #endif
343 			dev->devfn = devfn;
344 			dev->bus = bus;
345 			dev->class = class;
346 			dev->vendor = vendor;
347 			dev->dev_id = device;
348 
349 
350 			/* Get the ROM base address */
351 			pcibios_read_config_dword(bus, devfn,
352 				PCI_ROM_ADDRESS, &romaddr);
353 			romaddr >>= 10;
354 			dev->romaddr = romaddr;
355 
356 			/* Get the ``membase'' */
357 			pcibios_read_config_dword(bus, devfn,
358 				PCI_BASE_ADDRESS_1, &membase);
359 			dev->membase = membase;
360 
361 			/* Get the ``ioaddr'' */
362 			for (reg = PCI_BASE_ADDRESS_0; reg <= PCI_BASE_ADDRESS_5; reg += 4) {
363 				pcibios_read_config_dword(bus, devfn, reg, &ioaddr);
364 				if ((ioaddr & PCI_BASE_ADDRESS_IO_MASK) == 0 || (ioaddr & PCI_BASE_ADDRESS_SPACE_IO) == 0)
365 					continue;
366 
367 
368 				/* Strip the I/O address out of the returned value */
369 				ioaddr &= PCI_BASE_ADDRESS_IO_MASK;
370 
371 				/* Take the first one or the one that matches in boot ROM address */
372 				dev->ioaddr = ioaddr;
373 			}
374 #if DEBUG > 2
375 			printf("Found %s ROM address %#hx\n",
376 				dev->name, romaddr);
377 #endif
378 			LeaveFunction("scan_pci_bus");
379 			return;
380 		}
381 		first_devfn = 0;
382 	}
383 	first_bus = 0;
384 	LeaveFunction("scan_pci_bus");
385 }
386 
387 
388 
389 /*
390  *	Set device to be a busmaster in case BIOS neglected to do so.
391  *	Also adjust PCI latency timer to a reasonable value, 32.
392  */
393 void adjust_pci_device(struct pci_device *p)
394 {
395 	unsigned short	new_command, pci_command;
396 	unsigned char	pci_latency;
397 
398 	pcibios_read_config_word(p->bus, p->devfn, PCI_COMMAND, &pci_command);
399 	new_command = pci_command | PCI_COMMAND_MASTER|PCI_COMMAND_IO;
400 	if (pci_command != new_command) {
401 #if DEBUG > 0
402 		printf(
403 			"The PCI BIOS has not enabled this device!\n"
404 			"Updating PCI command %hX->%hX. pci_bus %hhX pci_device_fn %hhX\n",
405 			   pci_command, new_command, p->bus, p->devfn);
406 #endif
407 		pcibios_write_config_word(p->bus, p->devfn, PCI_COMMAND, new_command);
408 	}
409 	pcibios_read_config_byte(p->bus, p->devfn, PCI_LATENCY_TIMER, &pci_latency);
410 	if (pci_latency < 32) {
411 #if DEBUG > 0
412 		printf("PCI latency timer (CFLT) is unreasonably low at %d. Setting to 32 clocks.\n",
413 			pci_latency);
414 #endif
415 		pcibios_write_config_byte(p->bus, p->devfn, PCI_LATENCY_TIMER, 32);
416 	}
417 }
418 
419 /*
420  * Find the start of a pci resource.
421  */
422 unsigned long pci_bar_start(struct pci_device *dev, unsigned int index)
423 {
424 	uint32_t lo, hi;
425 	unsigned long bar;
426 	pci_read_config_dword(dev, index, &lo);
427 	if (lo & PCI_BASE_ADDRESS_SPACE_IO) {
428 		bar = lo & PCI_BASE_ADDRESS_IO_MASK;
429 	} else {
430 		bar = 0;
431 		if ((lo & PCI_BASE_ADDRESS_MEM_TYPE_MASK) == PCI_BASE_ADDRESS_MEM_TYPE_64) {
432 			pci_read_config_dword(dev, index + 4, &hi);
433 			if (hi) {
434 				if (sizeof(unsigned long) > sizeof(uint32_t)) {
435 					/* It's REALLY interesting:-) */
436 					bar = (uint64_t)hi << 32;
437 				}
438 				else {
439 					printf("Unhandled 64bit BAR\n");
440 					return -1UL;
441 				}
442 			}
443 		}
444 		bar |= lo & PCI_BASE_ADDRESS_MEM_MASK;
445 	}
446 	return bar + pcibios_bus_base(dev->bus);
447 }
448 
449 /*
450  * Find the size of a pci resource.
451  */
452 unsigned long pci_bar_size(struct pci_device *dev, unsigned int bar)
453 {
454 	uint32_t start, size;
455 	/* Save the original bar */
456 	pci_read_config_dword(dev, bar, &start);
457 	/* Compute which bits can be set */
458 	pci_write_config_dword(dev, bar, ~0);
459 	pci_read_config_dword(dev, bar, &size);
460 	/* Restore the original size */
461 	pci_write_config_dword(dev, bar, start);
462 	/* Find the significant bits */
463 	if (start & PCI_BASE_ADDRESS_SPACE_IO) {
464 		size &= PCI_BASE_ADDRESS_IO_MASK;
465 	} else {
466 		size &= PCI_BASE_ADDRESS_MEM_MASK;
467 	}
468 	/* Find the lowest bit set */
469 	size = size & ~(size - 1);
470 	return size;
471 }
472 
473 /**
474  * pci_find_capability - query for devices' capabilities
475  * @dev: PCI device to query
476  * @cap: capability code
477  *
478  * Tell if a device supports a given PCI capability.
479  * Returns the address of the requested capability structure within the
480  * device's PCI configuration space or 0 in case the device does not
481  * support it.  Possible values for @cap:
482  *
483  *  %PCI_CAP_ID_PM           Power Management
484  *
485  *  %PCI_CAP_ID_AGP          Accelerated Graphics Port
486  *
487  *  %PCI_CAP_ID_VPD          Vital Product Data
488  *
489  *  %PCI_CAP_ID_SLOTID       Slot Identification
490  *
491  *  %PCI_CAP_ID_MSI          Message Signalled Interrupts
492  *
493  *  %PCI_CAP_ID_CHSWP        CompactPCI HotSwap
494  */
495 int pci_find_capability(struct pci_device *dev, int cap)
496 {
497 	uint16_t status;
498 	uint8_t pos, id;
499 	uint8_t hdr_type;
500 	int ttl = 48;
501 
502 	pci_read_config_word(dev, PCI_STATUS, &status);
503 	if (!(status & PCI_STATUS_CAP_LIST))
504 		return 0;
505 	pci_read_config_byte(dev, PCI_HEADER_TYPE, &hdr_type);
506 	switch (hdr_type & 0x7F) {
507 	case PCI_HEADER_TYPE_NORMAL:
508 	case PCI_HEADER_TYPE_BRIDGE:
509 	default:
510 		pci_read_config_byte(dev, PCI_CAPABILITY_LIST, &pos);
511 		break;
512 	case PCI_HEADER_TYPE_CARDBUS:
513 		pci_read_config_byte(dev, PCI_CB_CAPABILITY_LIST, &pos);
514 		break;
515 	}
516 	while (ttl-- && pos >= 0x40) {
517 		pos &= ~3;
518 		pci_read_config_byte(dev, pos + PCI_CAP_LIST_ID, &id);
519 #if	DEBUG > 0
520 		printf("Capability: %d\n", id);
521 #endif
522 		if (id == 0xff)
523 			break;
524 		if (id == cap)
525 			return pos;
526 		pci_read_config_byte(dev, pos + PCI_CAP_LIST_NEXT, &pos);
527 	}
528 	return 0;
529 }
530 
531