[PATCH] Windows/Cygwin: Add support through the WinIo library

Samuel Pitoiset samuel.pitoiset at gmail.com
Sat Jan 18 08:19:14 PST 2014


V2:
- Add support for unmapping
- Add a README.cygwin

Reviewed-by: Martin Peres <martin.peres at free.fr>
---
 README.cygwin          |  25 +++++++
 configure.ac           |   5 ++
 src/Makefile.am        |   5 ++
 src/common_init.c      |   2 +-
 src/common_interface.c |   2 +-
 src/x86_pci.c          | 175 ++++++++++++++++++++++++++++++++++++++++++++++++-
 6 files changed, 210 insertions(+), 4 deletions(-)
 create mode 100755 README.cygwin

diff --git a/README.cygwin b/README.cygwin
new file mode 100755
index 0000000..8801329
--- /dev/null
+++ b/README.cygwin
@@ -0,0 +1,25 @@
+= libpciaccess support under Windows through WinIo and Cygwin =
+
+== Platforms supported ==
+
+The support should work on Windows NT/2000/XP/2003/Vista/7 and 2008 but has
+only been tested on Windows 7, 32 bits
+
+== Dependencies ==
+
+This support depends of WinIo which allows direct I/O port and physical
+memory access under Windows NT/2000/XP/2003/Vista/7 and 2008.
+
+== How to install WinIo ? ==
+
+First, you need to download WinIo from http://www.internals.com/. Then, you
+have to copy WinIo32.dll and WinIo32.sys to the same directory as the
+executables.
+
+== TODO ==
+
+Check and fix 64 bits support.
+
+== Contact ==
+
+If you have any problems, please send an email to samuel.pitoiset at gmail.com
diff --git a/configure.ac b/configure.ac
index fe3b78e..e3f7d8b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -95,6 +95,10 @@ case $host_os in
 	gnu*)
 		gnu=yes
 		;;
+	*cygwin*)
+		cygwin=yes
+		PCIACCESS_LIBS="$PCIACCESS_LIBS"
+		;;
 esac
 
 AM_CONDITIONAL(LINUX, [test "x$linux" = xyes])
@@ -103,6 +107,7 @@ AM_CONDITIONAL(NETBSD, [test "x$netbsd" = xyes])
 AM_CONDITIONAL(OPENBSD, [test "x$openbsd" = xyes])
 AM_CONDITIONAL(SOLARIS, [test "x$solaris" = xyes])
 AM_CONDITIONAL(GNU, [test "x$gnu" = xyes])
+AM_CONDITIONAL(CYGWIN, [test "x$cygwin" = xyes])
 
 AC_SYS_LARGEFILE
 
diff --git a/src/Makefile.am b/src/Makefile.am
index 0d71a80..3a46a85 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -56,6 +56,11 @@ OS_SUPPORT = x86_pci.c
 VGA_ARBITER = common_vgaarb_stub.c
 endif
 
+if CYGWIN
+OS_SUPPORT = x86_pci.c
+VGA_ARBITER = common_vgaarb_stub.c
+endif
+
 libpciaccess_la_SOURCES = common_bridge.c \
 	common_iterator.c \
 	common_init.c \
diff --git a/src/common_init.c b/src/common_init.c
index 7c9db9c..a127a8b 100644
--- a/src/common_init.c
+++ b/src/common_init.c
@@ -62,7 +62,7 @@ pci_system_init( void )
     err = pci_system_openbsd_create();
 #elif defined(__sun)
     err = pci_system_solx_devfs_create();
-#elif defined(__GNU__)
+#elif defined(__GNU__) || defined(__CYGWIN__)
     err = pci_system_x86_create();
 #endif
 
diff --git a/src/common_interface.c b/src/common_interface.c
index 3425edc..59778cf 100644
--- a/src/common_interface.c
+++ b/src/common_interface.c
@@ -36,7 +36,7 @@
 #include "pciaccess.h"
 #include "pciaccess_private.h"
 
-#if defined(__linux__) || defined(__GLIBC__)
+#if defined(__linux__) || defined(__GLIBC__) || defined(__CYGWIN__)
 #include <byteswap.h>
 
 #if __BYTE_ORDER == __BIG_ENDIAN
diff --git a/src/x86_pci.c b/src/x86_pci.c
index c75242e..b938068 100644
--- a/src/x86_pci.c
+++ b/src/x86_pci.c
@@ -72,6 +72,133 @@ x86_disable_io(void)
     return errno;
 }
 
+#elif defined(__CYGWIN__)
+
+#include <windows.h>
+
+/* WinIo declarations */
+typedef BYTE bool;
+typedef struct tagPhysStruct {
+    DWORD64 dwPhysMemSizeInBytes;
+    DWORD64 pvPhysAddress;
+    DWORD64 PhysicalMemoryHandle;
+    DWORD64 pvPhysMemLin;
+    DWORD64 pvPhysSection;
+} tagPhysStruct;
+
+typedef bool  (_stdcall* INITIALIZEWINIO)(void);
+typedef void  (_stdcall* SHUTDOWNWINIO)(void);
+typedef bool  (_stdcall* GETPORTVAL)(WORD,PDWORD,BYTE);
+typedef bool  (_stdcall* SETPORTVAL)(WORD,DWORD,BYTE);
+typedef PBYTE (_stdcall* MAPPHYSTOLIN)(tagPhysStruct*);
+typedef bool  (_stdcall* UNMAPPHYSMEM)(tagPhysStruct*);
+
+SHUTDOWNWINIO ShutdownWinIo;
+GETPORTVAL GetPortVal;
+SETPORTVAL SetPortVal;
+INITIALIZEWINIO InitializeWinIo;
+MAPPHYSTOLIN MapPhysToLin;
+UNMAPPHYSMEM UnmapPhysicalMemory;
+
+static int
+x86_enable_io(void)
+{
+    HMODULE lib = NULL;
+
+    if ((GetVersion() & 0x80000000) == 0) {
+      /* running on NT, try WinIo version 3 (32 or 64 bits) */
+#ifdef WIN64
+      lib = LoadLibrary("WinIo64.dll");
+#else
+      lib = LoadLibrary("WinIo32.dll");
+#endif
+    }
+
+    if (!lib) {
+      fprintf(stderr, "Failed to load WinIo library.\n");
+      return 1;
+    }
+
+#define GETPROC(n, d) 						\
+    n = (d) GetProcAddress(lib, #n); 				\
+    if (!n) { 							\
+      fprintf(stderr, "Failed to load " #n " function.\n");	\
+      return 1; 						\
+    }
+
+    GETPROC(InitializeWinIo, INITIALIZEWINIO);
+    GETPROC(ShutdownWinIo, SHUTDOWNWINIO);
+    GETPROC(GetPortVal, GETPORTVAL);
+    GETPROC(SetPortVal, SETPORTVAL);
+    GETPROC(MapPhysToLin, MAPPHYSTOLIN);
+    GETPROC(UnmapPhysicalMemory, UNMAPPHYSMEM);
+
+#undef GETPROC
+
+    if (!InitializeWinIo()) {
+      fprintf(stderr, "Failed to initialize WinIo.\n"
+		      "NOTE: WinIo.dll and WinIo.sys must be in the same directory as the executable!\n");
+      return 0;
+    }
+
+    return 0;
+}
+
+static int
+x86_disable_io(void)
+{
+    ShutdownWinIo();
+    return 1;
+}
+
+static inline uint8_t
+inb(uint16_t port)
+{
+    DWORD pv;
+
+    if (GetPortVal(port, &pv, 1))
+      return (uint8_t)pv;
+    return 0;
+}
+
+static inline uint16_t
+inw(uint16_t port)
+{
+    DWORD pv;
+
+    if (GetPortVal(port, &pv, 2))
+      return (uint16_t)pv;
+    return 0;
+}
+
+static inline uint32_t
+inl(uint16_t port)
+{
+    DWORD pv;
+
+    if (GetPortVal(port, &pv, 4))
+        return (uint32_t)pv;
+    return 0;
+}
+
+static inline void
+outb(uint8_t value, uint16_t port)
+{
+    SetPortVal(port, value, 1);
+}
+
+static inline void
+outw(uint16_t value, uint16_t port)
+{
+    SetPortVal(port, value, 2);
+}
+
+static inline void
+outl(uint32_t value, uint16_t port)
+{
+    SetPortVal(port, value, 4);
+}
+
 #else
 
 #error How to enable IO ports on this system?
@@ -471,6 +598,41 @@ pci_device_x86_probe(struct pci_device *dev)
     return 0;
 }
 
+#if defined(__CYGWIN__)
+
+static int
+pci_device_x86_map_range(struct pci_device *dev,
+    struct pci_device_mapping *map)
+{
+    tagPhysStruct phys;
+
+    phys.pvPhysAddress        = (DWORD64)(DWORD32)map->base;
+    phys.dwPhysMemSizeInBytes = map->size;
+
+    map->memory = (PDWORD)MapPhysToLin(&phys);
+    if (map->memory == NULL)
+        return EFAULT;
+
+    return 0;
+}
+
+static int
+pci_device_x86_unmap_range(struct pci_device *dev,
+    struct pci_device_mapping *map)
+{
+    tagPhysStruct phys;
+
+    phys.pvPhysAddress        = (DWORD64)(DWORD32)map->base;
+    phys.dwPhysMemSizeInBytes = map->size;
+
+    if (!UnmapPhysicalMemory(&phys))
+        return EFAULT;
+
+    return 0;
+}
+
+#else
+
 static int
 pci_device_x86_map_range(struct pci_device *dev,
     struct pci_device_mapping *map)
@@ -493,6 +655,15 @@ pci_device_x86_map_range(struct pci_device *dev,
 }
 
 static int
+pci_device_x86_unmap_range(struct pci_device *dev,
+    struct pci_device_mapping *map)
+{
+    return pci_device_generic_unamp_range(dev, map);
+}
+
+#endif
+
+static int
 pci_device_x86_read(struct pci_device *dev, void *data,
     pciaddr_t offset, pciaddr_t size, pciaddr_t *bytes_read)
 {
@@ -635,7 +806,7 @@ pci_device_x86_unmap_legacy(struct pci_device *dev, void *addr,
     map.flags = 0;
     map.memory = addr;
 
-    return pci_device_generic_unmap_range(dev, &map);
+    return pci_device_x86_unmap_range(dev, &map);
 }
 
 static const struct pci_system_methods x86_pci_methods = {
@@ -643,7 +814,7 @@ static const struct pci_system_methods x86_pci_methods = {
     .read_rom = pci_device_x86_read_rom,
     .probe = pci_device_x86_probe,
     .map_range = pci_device_x86_map_range,
-    .unmap_range = pci_device_generic_unmap_range,
+    .unmap_range = pci_device_x86_unmap_range,
     .read = pci_device_x86_read,
     .write = pci_device_x86_write,
     .fill_capabilities = pci_fill_capabilities_generic,
-- 
1.8.5.2



More information about the xorg-devel mailing list