summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthieu Herrb <matthieu@herrb.eu>2014-03-15 22:05:56 +0100
committerMatthieu Herrb <matthieu@herrb.eu>2014-03-15 22:05:56 +0100
commit8b923797ed5b250c993822bec08aa01dd37d875d (patch)
treecab85539f1d3bf22d1f3a2dda0911a9009ecf0f2
parent851eb6766ac3f477554ae214191d097972b30bda (diff)
parentb9c068896914b4132a24839c9ef7f9fcd6282d88 (diff)
Merge remote-tracking branch 'origin/master' into obsd
-rwxr-xr-xREADME.cygwin25
-rw-r--r--configure.ac5
-rw-r--r--src/Makefile.am5
-rw-r--r--src/common_init.c2
-rw-r--r--src/common_interface.c2
-rw-r--r--src/freebsd_pci.c2
-rw-r--r--src/linux_sysfs.c62
-rw-r--r--src/netbsd_pci.c2
-rw-r--r--src/openbsd_pci.c3
-rw-r--r--src/pciaccess_private.h1
-rw-r--r--src/solx_devfs.c1
-rw-r--r--src/x86_pci.c176
12 files changed, 264 insertions, 22 deletions
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/freebsd_pci.c b/src/freebsd_pci.c
index 14ec3bc..7f5f56b 100644
--- a/src/freebsd_pci.c
+++ b/src/freebsd_pci.c
@@ -579,6 +579,7 @@ pci_device_freebsd_open_legacy_io(struct pci_io_handle *ret,
ret->base = base;
ret->size = size;
+ ret->is_legacy = 1;
return ret;
#elif defined(PCI_MAGIC_IO_RANGE)
ret->memory = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED,
@@ -588,6 +589,7 @@ pci_device_freebsd_open_legacy_io(struct pci_io_handle *ret,
ret->base = base;
ret->size = size;
+ ret->is_legacy = 1;
return ret;
#else
return NULL;
diff --git a/src/linux_sysfs.c b/src/linux_sysfs.c
index 97fcf36..8fca65e 100644
--- a/src/linux_sysfs.c
+++ b/src/linux_sysfs.c
@@ -759,6 +759,7 @@ pci_device_linux_sysfs_open_device_io(struct pci_io_handle *ret,
ret->base = base;
ret->size = size;
+ ret->is_legacy = 0;
return ret;
}
@@ -796,6 +797,7 @@ pci_device_linux_sysfs_open_legacy_io(struct pci_io_handle *ret,
ret->base = base;
ret->size = size;
+ ret->is_legacy = 1;
return ret;
}
@@ -813,10 +815,14 @@ pci_device_linux_sysfs_read32(struct pci_io_handle *handle, uint32_t port)
{
uint32_t ret;
- if (handle->fd > -1)
- pread(handle->fd, &ret, 4, port + handle->base);
- else
+ if (handle->fd > -1) {
+ if (handle->is_legacy)
+ pread(handle->fd, &ret, 4, port + handle->base);
+ else
+ pread(handle->fd, &ret, 4, port);
+ } else {
ret = inl(port + handle->base);
+ }
return ret;
}
@@ -826,10 +832,14 @@ pci_device_linux_sysfs_read16(struct pci_io_handle *handle, uint32_t port)
{
uint16_t ret;
- if (handle->fd > -1)
- pread(handle->fd, &ret, 2, port + handle->base);
- else
+ if (handle->fd > -1) {
+ if (handle->is_legacy)
+ pread(handle->fd, &ret, 2, port + handle->base);
+ else
+ pread(handle->fd, &ret, 2, port);
+ } else {
ret = inw(port + handle->base);
+ }
return ret;
}
@@ -839,10 +849,14 @@ pci_device_linux_sysfs_read8(struct pci_io_handle *handle, uint32_t port)
{
uint8_t ret;
- if (handle->fd > -1)
- pread(handle->fd, &ret, 1, port + handle->base);
- else
+ if (handle->fd > -1) {
+ if (handle->is_legacy)
+ pread(handle->fd, &ret, 1, port + handle->base);
+ else
+ pread(handle->fd, &ret, 1, port);
+ } else {
ret = inb(port + handle->base);
+ }
return ret;
}
@@ -851,30 +865,42 @@ static void
pci_device_linux_sysfs_write32(struct pci_io_handle *handle, uint32_t port,
uint32_t data)
{
- if (handle->fd > -1)
- pwrite(handle->fd, &data, 4, port + handle->base);
- else
+ if (handle->fd > -1) {
+ if (handle->is_legacy)
+ pwrite(handle->fd, &data, 4, port + handle->base);
+ else
+ pwrite(handle->fd, &data, 4, port);
+ } else {
outl(data, port + handle->base);
+ }
}
static void
pci_device_linux_sysfs_write16(struct pci_io_handle *handle, uint32_t port,
uint16_t data)
{
- if (handle->fd > -1)
- pwrite(handle->fd, &data, 2, port + handle->base);
- else
+ if (handle->fd > -1) {
+ if (handle->is_legacy)
+ pwrite(handle->fd, &data, 2, port + handle->base);
+ else
+ pwrite(handle->fd, &data, 2, port);
+ } else {
outw(data, port + handle->base);
+ }
}
static void
pci_device_linux_sysfs_write8(struct pci_io_handle *handle, uint32_t port,
uint8_t data)
{
- if (handle->fd > -1)
- pwrite(handle->fd, &data, 1, port + handle->base);
- else
+ if (handle->fd > -1) {
+ if (handle->is_legacy)
+ pwrite(handle->fd, &data, 1, port + handle->base);
+ else
+ pwrite(handle->fd, &data, 1, port);
+ } else {
outb(data, port + handle->base);
+ }
}
static int
diff --git a/src/netbsd_pci.c b/src/netbsd_pci.c
index b3f7f2d..e6dae4c 100644
--- a/src/netbsd_pci.c
+++ b/src/netbsd_pci.c
@@ -733,6 +733,7 @@ pci_device_netbsd_open_legacy_io(struct pci_io_handle *ret,
ret->base = base;
ret->size = size;
+ ret->is_legacy = 1;
return ret;
#elif defined(__amd64__)
struct x86_64_iopl_args ia;
@@ -743,6 +744,7 @@ pci_device_netbsd_open_legacy_io(struct pci_io_handle *ret,
ret->base = base;
ret->size = size;
+ ret->is_legacy = 1;
return ret;
#else
return NULL;
diff --git a/src/openbsd_pci.c b/src/openbsd_pci.c
index 37f5cea..5b24a22 100644
--- a/src/openbsd_pci.c
+++ b/src/openbsd_pci.c
@@ -413,6 +413,7 @@ pci_device_openbsd_open_legacy_io(struct pci_io_handle *ret,
ret->base = base;
ret->size = size;
+ ret->is_legacy = 1;
return ret;
#elif defined(__amd64__)
struct amd64_iopl_args ia;
@@ -423,6 +424,7 @@ pci_device_openbsd_open_legacy_io(struct pci_io_handle *ret,
ret->base = base;
ret->size = size;
+ ret->is_legacy = 1;
return ret;
#elif defined(PCI_MAGIC_IO_RANGE)
ret->memory = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED,
@@ -432,6 +434,7 @@ pci_device_openbsd_open_legacy_io(struct pci_io_handle *ret,
ret->base = base;
ret->size = size;
+ ret->is_legacy = 1;
return ret;
#else
return NULL;
diff --git a/src/pciaccess_private.h b/src/pciaccess_private.h
index 339ec0f..9f4e8f9 100644
--- a/src/pciaccess_private.h
+++ b/src/pciaccess_private.h
@@ -109,6 +109,7 @@ struct pci_io_handle {
pciaddr_t size;
void *memory;
int fd;
+ int is_legacy;
};
struct pci_device_private {
diff --git a/src/solx_devfs.c b/src/solx_devfs.c
index 41f5c19..8e7ea9b 100644
--- a/src/solx_devfs.c
+++ b/src/solx_devfs.c
@@ -911,6 +911,7 @@ pci_device_solx_devfs_open_legacy_io(struct pci_io_handle *ret,
if (sysi86(SI86V86, V86SC_IOPL, PS_IOPL) == 0) {
ret->base = base;
ret->size = size;
+ ret->is_legacy = 1;
return ret;
}
#endif
diff --git a/src/x86_pci.c b/src/x86_pci.c
index c75242e..49c1cab 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_unmap_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)
{
@@ -558,6 +729,7 @@ pci_device_x86_open_legacy_io(struct pci_io_handle *ret,
ret->base = base;
ret->size = size;
+ ret->is_legacy = 1;
return ret;
}
@@ -635,7 +807,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 +815,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,