diff options
author | hpa <hpa> | 2005-08-09 03:34:04 +0000 |
---|---|---|
committer | hpa <hpa> | 2005-08-09 03:34:04 +0000 |
commit | 14aef35cffa86e0a0d54b3b6556b229e61befe33 (patch) | |
tree | bc292739e3e8eeee43244b748fa71d9375a72347 | |
parent | a0764e212fd2a589f19c317393f67e1c5cdfa08d (diff) | |
download | syslinux-3.10-pre6.tar.gz |
Better tests for CM#1 and CM#2syslinux-3.10-pre6
-rw-r--r-- | com32/lib/pci/cfgtype.c | 89 |
1 files changed, 56 insertions, 33 deletions
diff --git a/com32/lib/pci/cfgtype.c b/com32/lib/pci/cfgtype.c index 0fdc81e7..0f8c623f 100644 --- a/com32/lib/pci/cfgtype.c +++ b/com32/lib/pci/cfgtype.c @@ -4,6 +4,52 @@ enum pci_config_type __pci_cfg_type; +static int type1_ok(void) +{ + uint32_t oldcf8, newcf8; + + /* Test for Configuration Method #1 */ + + /* Note: XFree86 writes ~0 and expects to read back 0x80fffffc. Linux + does this less severe test; go with Linux. */ + + cli(); + outb(1, 0xcfb); /* For old Intel chipsets */ + oldcf8 = inl(0xcf8); + outl(0x80000000, 0xcf8); + newcf8 = inl(0xcf8); + outl(oldcf8, 0xcf8); + sti(); + + return newcf8 == 0x80000000; +} + +static int type2_ok(void) +{ + uint8_t oldcf8, oldcfa; + uint8_t cf8, cfa; + + /* Test for Configuration Method #2 */ + + /* CM#2 is hard to probe for, but let's do our best... */ + + cli(); + outb(0, 0xcfb); /* For old Intel chipsets */ + oldcf8 = inb(0xcf8); + outb(0, 0xcf8); + oldcfa = inb(0xcfa); + outb(0, 0xcfa); + + cf8 = inb(0xcf8); + cfa = inb(0xcfa); + + outb(oldcf8, 0xcf8); + outb(oldcfa, 0xcfa); + sti(); + + return cf8 == 0 && cfa == 0; +} + int pci_set_config_type(enum pci_config_type type) { static const com32sys_t ireg = { @@ -22,43 +68,20 @@ int pci_set_config_type(enum pci_config_type type) if ( !(oreg.eflags.l & EFLAGS_CF) && oreg.eax.b[1] == 0 && oreg.edx.l == 0x20494250 ) { /* PCI BIOS present. Use direct access if we know how to do it. */ - if ( oreg.eax.b[0] & 1 ) + + if ( (oreg.eax.b[0] & 1) && type1_ok() ) type = PCI_CFG_TYPE1; - else if ( oreg.eax.b[0] & 2 ) + else if ( (oreg.eax.b[0] & 2) && type2_ok() ) type = PCI_CFG_TYPE2; else - type = PCI_CFG_BIOS; + type = PCI_CFG_BIOS; /* Use BIOS calls as fallback */ + + } else if ( type1_ok() ) { + type = PCI_CFG_TYPE1; + } else if ( type2_ok() ) { + type = PCI_CFG_TYPE2; } else { - /* Try to detect CM #1 */ - uint32_t oldcf8, newcf8; - - cli(); - outb(1, 0xcfb); /* Linux does this for some reason? */ - oldcf8 = inl(0xcf8); - outl(0x80000000, 0xcf8); - newcf8 = inl(0xcf8); - outl(oldcf8, 0xcf8); - sti(); - - if ( newcf8 == 0x80000000 ) - type = PCI_CFG_TYPE1; - else { - uint8_t oldcf8, oldcfa; - /* Try to detect CM#2 */ - cli(); - outb(0, 0xcfb); /* Linux does this for some reason? */ - oldcf8 = inb(0xcf8); - outb(0, 0xcf8); - oldcfa = inb(0xcfa); - outb(0, 0xcfa); - - if ( inb(0xcf8) == 0 && inb(0xcfa) == 0 ) - type = PCI_CFG_TYPE2; - - outb(oldcf8, 0xcf8); - outb(oldcfa, 0xcfa); - sti(); - } + type = PCI_CFG_NONE; /* Badness... */ } } |