diff options
Diffstat (limited to 'src')
-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/freebsd_pci.c | 2 | ||||
-rw-r--r-- | src/linux_sysfs.c | 62 | ||||
-rw-r--r-- | src/netbsd_pci.c | 2 | ||||
-rw-r--r-- | src/openbsd_pci.c | 3 | ||||
-rw-r--r-- | src/pciaccess_private.h | 1 | ||||
-rw-r--r-- | src/solx_devfs.c | 1 | ||||
-rw-r--r-- | src/x86_pci.c | 176 |
10 files changed, 234 insertions, 22 deletions
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, |