aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhpa <hpa>2005-01-05 23:03:38 +0000
committerhpa <hpa>2005-01-05 23:03:38 +0000
commitf52b299f0179105c6c2ced289f97850388f085a7 (patch)
tree1839d11847012c85f1ad98bb9431d07433447593
parent7c2df92d9aaed17bee41f2ce4d469297d927f61c (diff)
downloadsyslinux-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.h20
-rw-r--r--com32/lib/Makefile2
-rw-r--r--com32/lib/pci/cfgtype.c23
-rw-r--r--com32/lib/pci/readb.c18
-rw-r--r--com32/lib/pci/readl.c18
-rw-r--r--com32/lib/pci/readw.c18
-rw-r--r--com32/lib/pci/readx.c48
-rw-r--r--com32/lib/pci/writeb.c15
-rw-r--r--com32/lib/pci/writel.c15
-rw-r--r--com32/lib/pci/writew.c15
-rw-r--r--com32/lib/pci/writex.c45
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 */
+ }
+ }
+}