From f52b299f0179105c6c2ced289f97850388f085a7 Mon Sep 17 00:00:00 2001 From: hpa Date: Wed, 5 Jan 2005 23:03:38 +0000 Subject: [PATCH] Support PCI configuration space mechanism #2 if necessary. --- com32/include/sys/pci.h | 20 ++++++++++++++------ com32/lib/Makefile | 2 +- com32/lib/pci/cfgtype.c | 23 +++++++++++++++++++++++ com32/lib/pci/readb.c | 18 +++--------------- com32/lib/pci/readl.c | 18 +++--------------- com32/lib/pci/readw.c | 18 +++--------------- com32/lib/pci/readx.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ com32/lib/pci/writeb.c | 15 +++------------ com32/lib/pci/writel.c | 15 +++------------ com32/lib/pci/writew.c | 15 +++------------ com32/lib/pci/writex.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 11 files changed, 149 insertions(+), 88 deletions(-) create mode 100644 com32/lib/pci/cfgtype.c create mode 100644 com32/lib/pci/readx.c create mode 100644 com32/lib/pci/writex.c diff --git a/com32/include/sys/pci.h b/com32/include/sys/pci.h index 03d8884..bfa7e60 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 18c952e..1379264 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 0000000..5fa72be --- /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 ac0efaa..bfc544f 100644 --- a/com32/lib/pci/readb.c +++ b/com32/lib/pci/readb.c @@ -1,15 +1,3 @@ -#include -#include -#include - -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 1cd43c0..ef3fdd6 100644 --- a/com32/lib/pci/readl.c +++ b/com32/lib/pci/readl.c @@ -1,15 +1,3 @@ -#include -#include -#include - -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 b7558a6..6889229 100644 --- a/com32/lib/pci/readw.c +++ b/com32/lib/pci/readw.c @@ -1,15 +1,3 @@ -#include -#include -#include - -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 0000000..f1e542d --- /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 db399cd..a63fcf1 100644 --- a/com32/lib/pci/writeb.c +++ b/com32/lib/pci/writeb.c @@ -1,12 +1,3 @@ -#include -#include -#include - -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 cfe58d6..f608baa 100644 --- a/com32/lib/pci/writel.c +++ b/com32/lib/pci/writel.c @@ -1,12 +1,3 @@ -#include -#include -#include - -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 805ca50..4399d71 100644 --- a/com32/lib/pci/writew.c +++ b/com32/lib/pci/writew.c @@ -1,12 +1,3 @@ -#include -#include -#include - -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 0000000..c7e715e --- /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 */ + } + } +} -- 2.7.4