2 ** Support for NE2000 PCI clones added David Monro June 1997
3 ** Generalised to other NICs by Ken Yap July 1997
5 ** Most of this is taken from:
7 ** /usr/src/linux/drivers/pci/pci.c
8 ** /usr/src/linux/include/linux/pci.h
9 ** /usr/src/linux/arch/i386/bios32.c
10 ** /usr/src/linux/include/linux/bios32.h
11 ** /usr/src/linux/drivers/net/ne.c
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation; either version 2, or (at
18 * your option) any later version.
21 #include "etherboot.h"
27 #ifdef CONFIG_PCI_DIRECT
28 #define PCIBIOS_SUCCESSFUL 0x00
31 * Functions for accessing PCI configuration space with type 1 accesses
34 #define CONFIG_CMD(bus, device_fn, where) (0x80000000 | (bus << 16) | (device_fn << 8) | (where & ~3))
36 int pcibios_read_config_byte(unsigned int bus
, unsigned int device_fn
,
37 unsigned int where
, unsigned char *value
)
39 outl(CONFIG_CMD(bus
,device_fn
,where
), 0xCF8);
40 *value
= inb(0xCFC + (where
&3));
41 return PCIBIOS_SUCCESSFUL
;
44 int pcibios_read_config_word (unsigned int bus
,
45 unsigned int device_fn
, unsigned int where
, unsigned short *value
)
47 outl(CONFIG_CMD(bus
,device_fn
,where
), 0xCF8);
48 *value
= inw(0xCFC + (where
&2));
49 return PCIBIOS_SUCCESSFUL
;
52 int pcibios_read_config_dword (unsigned int bus
, unsigned int device_fn
,
53 unsigned int where
, unsigned int *value
)
55 outl(CONFIG_CMD(bus
,device_fn
,where
), 0xCF8);
57 return PCIBIOS_SUCCESSFUL
;
60 int pcibios_write_config_byte (unsigned int bus
, unsigned int device_fn
,
61 unsigned int where
, unsigned char value
)
63 outl(CONFIG_CMD(bus
,device_fn
,where
), 0xCF8);
64 outb(value
, 0xCFC + (where
&3));
65 return PCIBIOS_SUCCESSFUL
;
68 int pcibios_write_config_word (unsigned int bus
, unsigned int device_fn
,
69 unsigned int where
, unsigned short value
)
71 outl(CONFIG_CMD(bus
,device_fn
,where
), 0xCF8);
72 outw(value
, 0xCFC + (where
&2));
73 return PCIBIOS_SUCCESSFUL
;
76 int pcibios_write_config_dword (unsigned int bus
, unsigned int device_fn
, unsigned int where
, unsigned int value
)
78 outl(CONFIG_CMD(bus
,device_fn
,where
), 0xCF8);
80 return PCIBIOS_SUCCESSFUL
;
85 #else /* CONFIG_PCI_DIRECT not defined */
88 unsigned long address
;
89 unsigned short segment
;
90 } bios32_indirect
= { 0, KERN_CODE_SEG
};
92 static long pcibios_entry
;
94 unsigned long address
;
95 unsigned short segment
;
96 } pci_indirect
= { 0, KERN_CODE_SEG
};
98 static unsigned long bios32_service(unsigned long service
)
100 unsigned char return_code
; /* %al */
101 unsigned long address
; /* %ebx */
102 unsigned long length
; /* %ecx */
103 unsigned long entry
; /* %edx */
108 #ifdef ABSOLUTE_WITHOUT_ASTERISK
113 : "=a" (return_code
),
119 "D" (&bios32_indirect
));
120 restore_flags(flags
);
122 switch (return_code
) {
124 return address
+ entry
;
125 case 0x80: /* Not present */
126 printf("bios32_service(%d) : not present\n", service
);
128 default: /* Shouldn't happen */
129 printf("bios32_service(%d) : returned %#X, mail drew@colorado.edu\n",
130 service
, return_code
);
135 int pcibios_read_config_byte(unsigned int bus
,
136 unsigned int device_fn
, unsigned int where
, unsigned char *value
)
139 unsigned long bx
= (bus
<< 8) | device_fn
;
144 #ifdef ABSOLUTE_WITHOUT_ASTERISK
154 : "1" (PCIBIOS_READ_CONFIG_BYTE
),
157 "S" (&pci_indirect
));
158 restore_flags(flags
);
159 return (int) (ret
& 0xff00) >> 8;
162 int pcibios_read_config_word(unsigned int bus
,
163 unsigned int device_fn
, unsigned int where
, unsigned short *value
)
166 unsigned long bx
= (bus
<< 8) | device_fn
;
171 #ifdef ABSOLUTE_WITHOUT_ASTERISK
181 : "1" (PCIBIOS_READ_CONFIG_WORD
),
184 "S" (&pci_indirect
));
185 restore_flags(flags
);
186 return (int) (ret
& 0xff00) >> 8;
189 int pcibios_read_config_dword(unsigned int bus
,
190 unsigned int device_fn
, unsigned int where
, unsigned int *value
)
193 unsigned long bx
= (bus
<< 8) | device_fn
;
198 #ifdef ABSOLUTE_WITHOUT_ASTERISK
208 : "1" (PCIBIOS_READ_CONFIG_DWORD
),
211 "S" (&pci_indirect
));
212 restore_flags(flags
);
213 return (int) (ret
& 0xff00) >> 8;
216 int pcibios_write_config_byte (unsigned int bus
,
217 unsigned int device_fn
, unsigned int where
, unsigned char value
)
220 unsigned long bx
= (bus
<< 8) | device_fn
;
223 save_flags(flags
); cli();
225 #ifdef ABSOLUTE_WITHOUT_ASTERISK
234 : "0" (PCIBIOS_WRITE_CONFIG_BYTE
),
238 "S" (&pci_indirect
));
239 restore_flags(flags
);
240 return (int) (ret
& 0xff00) >> 8;
243 int pcibios_write_config_word (unsigned int bus
,
244 unsigned int device_fn
, unsigned int where
, unsigned short value
)
247 unsigned long bx
= (bus
<< 8) | device_fn
;
250 save_flags(flags
); cli();
252 #ifdef ABSOLUTE_WITHOUT_ASTERISK
261 : "0" (PCIBIOS_WRITE_CONFIG_WORD
),
265 "S" (&pci_indirect
));
266 restore_flags(flags
);
267 return (int) (ret
& 0xff00) >> 8;
270 int pcibios_write_config_dword (unsigned int bus
,
271 unsigned int device_fn
, unsigned int where
, unsigned int value
)
274 unsigned long bx
= (bus
<< 8) | device_fn
;
277 save_flags(flags
); cli();
279 #ifdef ABSOLUTE_WITHOUT_ASTERISK
288 : "0" (PCIBIOS_WRITE_CONFIG_DWORD
),
292 "S" (&pci_indirect
));
293 restore_flags(flags
);
294 return (int) (ret
& 0xff00) >> 8;
297 static void check_pcibios(void)
299 unsigned long signature
;
300 unsigned char present_status
;
301 unsigned char major_revision
;
302 unsigned char minor_revision
;
306 if ((pcibios_entry
= bios32_service(PCI_SERVICE
))) {
307 pci_indirect
.address
= pcibios_entry
;
311 #ifdef ABSOLUTE_WITHOUT_ASTERISK
318 "1:\tshl $8, %%eax\n\t"
322 : "1" (PCIBIOS_PCI_BIOS_PRESENT
),
325 restore_flags(flags
);
327 present_status
= (pack
>> 16) & 0xff;
328 major_revision
= (pack
>> 8) & 0xff;
329 minor_revision
= pack
& 0xff;
330 if (present_status
|| (signature
!= PCI_SIGNATURE
)) {
331 printf("ERROR: BIOS32 says PCI BIOS, but no PCI "
337 printf ("pcibios_init : PCI BIOS revision %hhX.%hhX"
338 " entry at %#X\n", major_revision
,
339 minor_revision
, pcibios_entry
);
345 static void pcibios_init(void)
350 unsigned long bios32_entry
= 0;
353 * Follow the standard procedure for locating the BIOS32 Service
354 * directory by scanning the permissible address range from
355 * 0xe0000 through 0xfffff for a valid BIOS32 structure.
359 for (check
= (union bios32
*) 0xe0000; check
<= (union bios32
*) 0xffff0; ++check
) {
360 if (check
->fields
.signature
!= BIOS32_SIGNATURE
)
362 length
= check
->fields
.length
* 16;
366 for (i
= 0; i
< length
; ++i
)
367 sum
+= check
->chars
[i
];
370 if (check
->fields
.revision
!= 0) {
371 printf("pcibios_init : unsupported revision %d at %#X, mail drew@colorado.edu\n",
372 check
->fields
.revision
, check
);
376 printf("pcibios_init : BIOS32 Service Directory "
377 "structure at %#X\n", check
);
380 if (check
->fields
.entry
>= 0x100000) {
381 printf("pcibios_init: entry in high "
382 "memory, giving up\n");
385 bios32_entry
= check
->fields
.entry
;
387 printf("pcibios_init : BIOS32 Service Directory"
388 " entry at %#X\n", bios32_entry
);
390 bios32_indirect
.address
= bios32_entry
;
397 #endif /* CONFIG_PCI_DIRECT not defined*/
399 static void scan_bus(struct pci_device
*pcidev
)
401 unsigned int devfn
, l
, bus
, buses
;
402 unsigned char hdr_type
= 0;
403 unsigned short vendor
, device
;
404 unsigned int membase
, ioaddr
, romaddr
;
406 unsigned int pci_ioaddr
= 0;
408 /* Scan all PCI buses, until we find our card.
409 * We could be smart only scan the required busses but that
410 * is error prone, and tricky.
411 * By scanning all possible pci busses in order we should find
412 * our card eventually.
415 for (bus
= 0; bus
< buses
; ++bus
) {
416 for (devfn
= 0; devfn
< 0xff; ++devfn
) {
417 if (PCI_FUNC (devfn
) == 0)
418 pcibios_read_config_byte(bus
, devfn
, PCI_HEADER_TYPE
, &hdr_type
);
419 else if (!(hdr_type
& 0x80)) /* not a multi-function device */
421 pcibios_read_config_dword(bus
, devfn
, PCI_VENDOR_ID
, &l
);
422 /* some broken boards return 0 if a slot is empty: */
423 if (l
== 0xffffffff || l
== 0x00000000) {
428 device
= (l
>> 16) & 0xffff;
431 printf("bus %hhX, function %hhX, vendor %hX, device %hX\n",
432 bus
, devfn
, vendor
, device
);
434 for (i
= 0; pcidev
[i
].vendor
!= 0; i
++) {
435 if (vendor
!= pcidev
[i
].vendor
436 || device
!= pcidev
[i
].dev_id
)
438 pcidev
[i
].devfn
= devfn
;
440 for (reg
= PCI_BASE_ADDRESS_0
; reg
<= PCI_BASE_ADDRESS_5
; reg
+= 4) {
441 pcibios_read_config_dword(bus
, devfn
, reg
, &ioaddr
);
443 if ((ioaddr
& PCI_BASE_ADDRESS_IO_MASK
) == 0 || (ioaddr
& PCI_BASE_ADDRESS_SPACE_IO
) == 0)
445 /* Strip the I/O address out of the returned value */
446 ioaddr
&= PCI_BASE_ADDRESS_IO_MASK
;
447 /* Get the memory base address */
448 pcibios_read_config_dword(bus
, devfn
,
449 PCI_BASE_ADDRESS_1
, &membase
);
450 /* Get the ROM base address */
451 pcibios_read_config_dword(bus
, devfn
, PCI_ROM_ADDRESS
, &romaddr
);
453 printf("Found %s at %#hx, ROM address %#hx\n",
454 pcidev
[i
].name
, ioaddr
, romaddr
);
455 /* Take the first one or the one that matches in boot ROM address */
456 if (pci_ioaddr
== 0 || romaddr
== ((unsigned long) rom
.rom_segment
<< 4)) {
457 pcidev
[i
].membase
= membase
;
458 pcidev
[i
].ioaddr
= ioaddr
;
467 void eth_pci_init(struct pci_device
*pcidev
)
469 #ifndef CONFIG_PCI_DIRECT
471 if (!pcibios_entry
) {
472 printf("pci_init: no BIOS32 detected\n");
477 /* return values are in pcidev structures */
481 * Set device to be a busmaster in case BIOS neglected to do so.
482 * Also adjust PCI latency timer to a reasonable value, 32.
484 void adjust_pci_device(struct pci_device
*p
)
486 unsigned short new_command
, pci_command
;
487 unsigned char pci_latency
;
489 pcibios_read_config_word(p
->bus
, p
->devfn
, PCI_COMMAND
, &pci_command
);
490 new_command
= pci_command
| PCI_COMMAND_MASTER
|PCI_COMMAND_IO
;
491 if (pci_command
!= new_command
) {
492 printf("The PCI BIOS has not enabled this device!\nUpdating PCI command %hX->%hX. pci_bus %hhX pci_device_fn %hhX\n",
493 pci_command
, new_command
, p
->bus
, p
->devfn
);
494 pcibios_write_config_word(p
->bus
, p
->devfn
, PCI_COMMAND
, new_command
);
496 pcibios_read_config_byte(p
->bus
, p
->devfn
, PCI_LATENCY_TIMER
, &pci_latency
);
497 if (pci_latency
< 32) {
498 printf("PCI latency timer (CFLT) is unreasonably low at %d. Setting to 32 clocks.\n", pci_latency
);
499 pcibios_write_config_byte(p
->bus
, p
->devfn
, PCI_LATENCY_TIMER
, 32);