diff options
author | Samuel Pitoiset <samuel.pitoiset@gmail.com> | 2014-01-18 17:19:14 +0100 |
---|---|---|
committer | Jon TURNEY <jon.turney@dronecode.org.uk> | 2014-01-27 23:39:48 +0000 |
commit | 6bfccc7ec4f0705595385f6684b6849663f781b4 (patch) | |
tree | 8fc059d191c7cde1d633f5e221c8f508127fa31c | |
parent | 06f562584a885eff7366dca82caf746e62b5a21f (diff) |
Windows/Cygwin: Add support through the WinIo library
V2:
- Add support for unmapping
- Add a README.cygwin
Reviewed-by: Martin Peres <martin.peres@free.fr>
Reviewed-by: Jon TURNEY <jon.turney@dronecode.org.uk>
-rwxr-xr-x | README.cygwin | 25 | ||||
-rw-r--r-- | configure.ac | 5 | ||||
-rw-r--r-- | src/Makefile.am | 5 | ||||
-rw-r--r-- | src/common_init.c | 2 | ||||
-rw-r--r-- | src/common_interface.c | 2 | ||||
-rw-r--r-- | src/x86_pci.c | 175 |
6 files changed, 210 insertions, 4 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/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, |