7 #include <linux/slab.h>
8 #include <linux/module.h>
12 #include <asm/cacheflush.h>
15 #define BIOS32_SIGNATURE (('_' << 0) + ('3' << 8) + ('2' << 16) + ('_' << 24))
18 #define PCI_SIGNATURE (('P' << 0) + ('C' << 8) + ('I' << 16) + (' ' << 24))
21 #define PCI_SERVICE (('$' << 0) + ('P' << 8) + ('C' << 16) + ('I' << 24))
24 #define PCIBIOS_HW_TYPE1 0x01
25 #define PCIBIOS_HW_TYPE2 0x02
26 #define PCIBIOS_HW_TYPE1_SPEC 0x10
27 #define PCIBIOS_HW_TYPE2_SPEC 0x20
42 static inline void set_bios_x(
void)
47 printk(
KERN_INFO "PCI : PCI BIOS area is rw and x. Use pci=nobios if you want it NX.\n");
88 static unsigned long bios32_service(
unsigned long service)
104 "D" (&bios32_indirect));
107 switch (return_code) {
109 return address +
entry;
115 service, return_code);
125 static int pci_bios_present;
130 u8 status, major_ver, minor_ver, hw_mech;
131 unsigned long flags, pcibios_entry;
133 if ((pcibios_entry = bios32_service(
PCI_SERVICE))) {
134 pci_indirect.address = pcibios_entry +
PAGE_OFFSET;
138 "lcall *(%%edi); cld\n\t"
151 status = (eax >> 8) & 0xff;
152 hw_mech = eax & 0xff;
153 major_ver = (ebx >> 8) & 0xff;
154 minor_ver = ebx & 0xff;
157 DBG(
"PCI: BIOS probe returned s=%02x hw=%02x ver=%02x.%02x l=%02x\n",
164 printk(
KERN_INFO "PCI: PCI BIOS revision %x.%02x entry at 0x%lx, last bus=%d\n",
166 #ifdef CONFIG_PCI_DIRECT
177 static int pci_bios_read(
unsigned int seg,
unsigned int bus,
182 unsigned long bx = (bus << 8) | devfn;
185 if (!value || (bus > 255) || (devfn > 255) || (reg > 255))
192 __asm__(
"lcall *(%%esi); cld\n\t"
201 "S" (&pci_indirect));
209 __asm__(
"lcall *(%%esi); cld\n\t"
218 "S" (&pci_indirect));
226 __asm__(
"lcall *(%%esi); cld\n\t"
235 "S" (&pci_indirect));
241 return (
int)((result & 0xff00) >> 8);
244 static int pci_bios_write(
unsigned int seg,
unsigned int bus,
245 unsigned int devfn,
int reg,
int len,
u32 value)
247 unsigned long result = 0;
249 unsigned long bx = (bus << 8) | devfn;
252 if ((bus > 255) || (devfn > 255) || (reg > 255))
259 __asm__(
"lcall *(%%esi); cld\n\t"
268 "S" (&pci_indirect));
271 __asm__(
"lcall *(%%esi); cld\n\t"
280 "S" (&pci_indirect));
283 __asm__(
"lcall *(%%esi); cld\n\t"
292 "S" (&pci_indirect));
298 return (
int)((result & 0xff00) >> 8);
306 static const struct pci_raw_ops pci_bios_access = {
307 .read = pci_bios_read,
308 .write = pci_bios_write
336 length = check->
fields.length * 16;
341 sum += check->
chars[i];
344 if (check->
fields.revision != 0) {
345 printk(
"PCI: unsupported BIOS32 revision %d at 0x%p\n",
346 check->
fields.revision, check);
349 DBG(
"PCI: BIOS32 Service Directory structure at 0x%p\n", check);
350 if (check->
fields.entry >= 0x100000) {
351 printk(
"PCI: BIOS32 entry (0x%p) in high memory, "
352 "cannot use.\n", check);
355 unsigned long bios32_entry = check->
fields.entry;
356 DBG(
"PCI: BIOS32 Service Directory entry at 0x%lx\n",
358 bios32_indirect.address = bios32_entry +
PAGE_OFFSET;
361 return &pci_bios_access;
386 if (!pci_bios_present)
395 DBG(
"PCI: Fetching IRQ routing table... ");
399 "lcall *(%%esi); cld\n\t"
413 DBG(
"OK ret=%d, size=%d, map=%x\n", ret, opt.size, map);
415 printk(
KERN_ERR "PCI: Error %02x when fetching IRQ routing table.\n", (ret >> 8) & 0xff);
435 __asm__(
"lcall *(%%esi); cld\n\t"
441 "b" ((dev->
bus->number << 8) | dev->
devfn),
442 "c" ((irq << 8) | (pin + 10)),
443 "S" (&pci_indirect));
444 return !(ret & 0xff00);
452 pci_bios_present = 1;