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 | |
parent | 7c2df92d9aaed17bee41f2ce4d469297d927f61c (diff) | |
download | syslinux-elf-f52b299f0179105c6c2ced289f97850388f085a7.tar.gz syslinux-elf-f52b299f0179105c6c2ced289f97850388f085a7.tar.xz syslinux-elf-f52b299f0179105c6c2ced289f97850388f085a7.zip |
Support PCI configuration space mechanism #2 if necessary.
-rw-r--r-- | com32/include/sys/pci.h | 20 | ||||
-rw-r--r-- | com32/lib/Makefile | 2 | ||||
-rw-r--r-- | com32/lib/pci/cfgtype.c | 23 | ||||
-rw-r--r-- | com32/lib/pci/readb.c | 18 | ||||
-rw-r--r-- | com32/lib/pci/readl.c | 18 | ||||
-rw-r--r-- | com32/lib/pci/readw.c | 18 | ||||
-rw-r--r-- | com32/lib/pci/readx.c | 48 | ||||
-rw-r--r-- | com32/lib/pci/writeb.c | 15 | ||||
-rw-r--r-- | com32/lib/pci/writel.c | 15 | ||||
-rw-r--r-- | com32/lib/pci/writew.c | 15 | ||||
-rw-r--r-- | com32/lib/pci/writex.c | 45 |
11 files changed, 149 insertions, 88 deletions
diff --git a/com32/include/sys/pci.h b/com32/include/sys/pci.h index 03d8884f..bfa7e601 100644 --- a/com32/include/sys/pci.h +++ b/com32/include/sys/pci.h @@ -13,11 +13,19 @@ static inline pciaddr_t pci_mkaddr(uint32_t bus, uint32_t dev, ((func & 0x07) << 8) | (reg & 0xff); } -uint8_t pci_readb(pciaddr_t a); -uint16_t pci_readw(pciaddr_t a); -uint32_t pci_readl(pciaddr_t a); -void pci_writeb(uint8_t v, pciaddr_t a); -void pci_writew(uint16_t v, pciaddr_t a); -void pci_writel(uint32_t v, pciaddr_t a); +enum pci_config_type { + PCI_CFG_AUTO = 0, /* autodetect */ + PCI_CFG_TYPE1 = 1, + PCI_CFG_TYPE2 = 2, +}; + +void pci_set_config_type(enum pci_config_type); + +uint8_t pci_readb(pciaddr_t); +uint16_t pci_readw(pciaddr_t); +uint32_t pci_readl(pciaddr_t); +void pci_writeb(uint8_t, pciaddr_t); +void pci_writew(uint16_t, pciaddr_t); +void pci_writel(uint32_t, pciaddr_t); #endif /* _SYS_PCI_H */ diff --git a/com32/lib/Makefile b/com32/lib/Makefile index 18c952e1..1379264c 100644 --- a/com32/lib/Makefile +++ b/com32/lib/Makefile @@ -26,7 +26,7 @@ LIBOBJS = abort.o atexit.o atoi.o atol.o atoll.o calloc.o creat.o \ sys/rawcon_write.o sys/err_read.o sys/err_write.o \ sys/null_read.o sys/null_write.o sys/serial_write.o \ sys/ansicon_write.o sys/ansiserial_write.o \ - pci/readb.o pci/readw.o pci/readl.o \ + pci/cfgtype.o pci/readb.o pci/readw.o pci/readl.o \ pci/writeb.o pci/writew.o pci/writel.o BINDIR = /usr/bin diff --git a/com32/lib/pci/cfgtype.c b/com32/lib/pci/cfgtype.c new file mode 100644 index 00000000..5fa72beb --- /dev/null +++ b/com32/lib/pci/cfgtype.c @@ -0,0 +1,23 @@ +#include "pci/pci.h" + +enum pci_config_type __pci_cfg_type; + +void pci_set_config_type(enum pci_config_type type) +{ + uint32_t oldcf8; + + if ( type == PCI_CFG_AUTO ) { + /* Try to detect CM #1 */ + cli(); + oldcf8 = inl(0xcf8); + outl(~0, 0xcf8); + if ( inl(0xcf8) == pci_mkaddr(255,31,7,252) ) + type = PCI_CFG_TYPE1; + else + type = PCI_CFG_TYPE2; /* ... it better be ... */ + outl(oldcf8, 0xcf8); + sti(); + } + + __pci_cfg_type = type; +} diff --git a/com32/lib/pci/readb.c b/com32/lib/pci/readb.c index ac0efaa4..bfc544f4 100644 --- a/com32/lib/pci/readb.c +++ b/com32/lib/pci/readb.c @@ -1,15 +1,3 @@ -#include <inttypes.h> -#include <sys/io.h> -#include <sys/pci.h> - -uint8_t pci_readb(pciaddr_t a) -{ - uint32_t oldcf8 = inl(0xcf8); - uint8_t r; - - outl(a, 0xcf8); - r = inb(0xcfc + (a & 3)); - outl(oldcf8, 0xcf8); - - return r; -} +#define TYPE uint8_t +#define BWL(x) x ## b +#include "pci/readx.c" diff --git a/com32/lib/pci/readl.c b/com32/lib/pci/readl.c index 1cd43c03..ef3fdd69 100644 --- a/com32/lib/pci/readl.c +++ b/com32/lib/pci/readl.c @@ -1,15 +1,3 @@ -#include <inttypes.h> -#include <sys/io.h> -#include <sys/pci.h> - -uint32_t pci_readl(pciaddr_t a) -{ - uint32_t oldcf8 = inl(0xcf8); - uint32_t r; - - outl(a, 0xcf8); - r = inl(0xcfc + (a & 3)); - outl(oldcf8, 0xcf8); - - return r; -} +#define TYPE uint32_t +#define BWL(x) x ## l +#include "pci/readx.c" diff --git a/com32/lib/pci/readw.c b/com32/lib/pci/readw.c index b7558a6c..68892298 100644 --- a/com32/lib/pci/readw.c +++ b/com32/lib/pci/readw.c @@ -1,15 +1,3 @@ -#include <inttypes.h> -#include <sys/io.h> -#include <sys/pci.h> - -uint16_t pci_readw(pciaddr_t a) -{ - uint32_t oldcf8 = inl(0xcf8); - uint16_t r; - - outl(a, 0xcf8); - r = inw(0xcfc + (a & 3)); - outl(oldcf8, 0xcf8); - - return r; -} +#define TYPE uint16_t +#define BWL(x) x ## w +#include "pci/readx.c" 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; + } + } +} diff --git a/com32/lib/pci/writeb.c b/com32/lib/pci/writeb.c index db399cd5..a63fcf1f 100644 --- a/com32/lib/pci/writeb.c +++ b/com32/lib/pci/writeb.c @@ -1,12 +1,3 @@ -#include <inttypes.h> -#include <sys/io.h> -#include <sys/pci.h> - -void pci_writeb(uint8_t v, pciaddr_t a) -{ - uint32_t oldcf8 = inl(0xcf8); - - outl(a, 0xcf8); - outb(v, 0xcfc + (a & 3)); - outl(oldcf8, 0xcf8); -} +#define TYPE uint8_t +#define BWL(x) x ## b +#include "pci/writex.c" diff --git a/com32/lib/pci/writel.c b/com32/lib/pci/writel.c index cfe58d68..f608baa0 100644 --- a/com32/lib/pci/writel.c +++ b/com32/lib/pci/writel.c @@ -1,12 +1,3 @@ -#include <inttypes.h> -#include <sys/io.h> -#include <sys/pci.h> - -void pci_writel(uint32_t v, pciaddr_t a) -{ - uint32_t oldcf8 = inl(0xcf8); - - outl(a, 0xcf8); - outl(v, 0xcfc + (a & 3)); - outl(oldcf8, 0xcf8); -} +#define TYPE uint32_t +#define BWL(x) x ## l +#include "pci/writex.c" diff --git a/com32/lib/pci/writew.c b/com32/lib/pci/writew.c index 805ca50a..4399d716 100644 --- a/com32/lib/pci/writew.c +++ b/com32/lib/pci/writew.c @@ -1,12 +1,3 @@ -#include <inttypes.h> -#include <sys/io.h> -#include <sys/pci.h> - -void pci_writew(uint16_t v, pciaddr_t a) -{ - uint32_t oldcf8 = inl(0xcf8); - - outl(a, 0xcf8); - outw(v, 0xcfc + (a & 3)); - outl(oldcf8, 0xcf8); -} +#define TYPE uint16_t +#define BWL(x) x ## w +#include "pci/writex.c" diff --git a/com32/lib/pci/writex.c b/com32/lib/pci/writex.c new file mode 100644 index 00000000..c7e715e7 --- /dev/null +++ b/com32/lib/pci/writex.c @@ -0,0 +1,45 @@ +#include "pci/pci.h" + +void BWL(pci_write) (TYPE v, pciaddr_t a) +{ + 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); + BWL(out) (v, 0xcfc + (a & 3)); + outl(oldcf8, 0xcf8); + sti(); + } + return; + + case PCI_CFG_TYPE2: + { + uint8_t oldcf8, oldcfa; + + if ( a & (0x10 << 11) ) + return; + + cli(); + oldcf8 = inb(0xcf8); + oldcfa = inb(0xcfa); + outb(0xf0 + ((a >> (8-1)) & 0x0e), 0xcf8); + outb(a >> 16, 0xcfa); + BWL(out) (v, 0xc000 + ((a >> (11-8)) & 0xf00) + (a & 0xff)); + outb(oldcf8, 0xcf8); + outb(oldcfa, 0xcfa); + sti(); + } + + default: + return; /* Do nothing */ + } + } +} |