diff options
author | hpa <hpa> | 2005-01-05 23:03:38 +0000 |
---|---|---|
committer | hpa <hpa> | 2005-01-05 23:03:38 +0000 |
commit | f52b299f0179105c6c2ced289f97850388f085a7 (patch) | |
tree | 1839d11847012c85f1ad98bb9431d07433447593 /com32/lib/pci/readx.c | |
parent | 7c2df92d9aaed17bee41f2ce4d469297d927f61c (diff) | |
download | syslinux.git-f52b299f0179105c6c2ced289f97850388f085a7.tar.gz syslinux.git-f52b299f0179105c6c2ced289f97850388f085a7.tar.xz syslinux.git-f52b299f0179105c6c2ced289f97850388f085a7.zip |
Support PCI configuration space mechanism #2 if necessary.
Diffstat (limited to 'com32/lib/pci/readx.c')
-rw-r--r-- | com32/lib/pci/readx.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/com32/lib/pci/readx.c b/com32/lib/pci/readx.c new file mode 100644 index 00000000..f1e542d7 --- /dev/null +++ b/com32/lib/pci/readx.c @@ -0,0 +1,48 @@ +#include "pci/pci.h" + +TYPE BWL(pci_read) (pciaddr_t a) +{ + TYPE r; + + for (;;) { + switch ( __pci_cfg_type ) { + case PCI_CFG_AUTO: + pci_set_config_type(PCI_CFG_AUTO); + break; /* Try again */ + + case PCI_CFG_TYPE1: + { + uint32_t oldcf8; + cli(); + oldcf8 = inl(0xcf8); + outl(a, 0xcf8); + r = BWL(in) (0xcfc + (a & 3)); + outl(oldcf8, 0xcf8); + sti(); + } + return r; + + case PCI_CFG_TYPE2: + { + uint8_t oldcf8, oldcfa; + + if ( a & (0x10 << 11) ) + return (TYPE)~0; + + cli(); + oldcf8 = inb(0xcf8); + oldcfa = inb(0xcfa); + outb(0xf0 + ((a >> (8-1)) & 0x0e), 0xcf8); + outb(a >> 16, 0xcfa); + r = BWL(in) (0xc000 + ((a >> (11-8)) & 0xf00) + (a & 0xff)); + outb(oldcf8, 0xcf8); + outb(oldcfa, 0xcfa); + sti(); + } + return r; + + default: + return (TYPE)~0; + } + } +} |