2 * The PCI Library -- Access to i386 I/O ports on Windows
4 * Copyright (c) 2004 Alexander Stock <stock.alexander@gmx.de>
5 * Copyright (c) 2006 Martin Mares <mj@ucw.cz>
7 * Can be freely distributed and used under the terms of the GNU GPL.
14 /* MSVC compiler provides I/O port intrinsics for both 32 and 64-bit modes. */
15 #pragma intrinsic(_outp)
16 #pragma intrinsic(_outpw)
17 #pragma intrinsic(_outpd)
18 #pragma intrinsic(_inp)
19 #pragma intrinsic(_inpw)
20 #pragma intrinsic(_inpd)
21 #elif defined(_WIN64) || defined(_UCRT)
23 * For other compilers I/O port intrinsics are available in <intrin.h> header
24 * file either as inline/external functions or macros. Beware that <intrin.h>
25 * names are different than MSVC intrinsics names and glibc function names.
26 * Usage of <intrin.h> is also the prefered way for 64-bit mode or when using
30 #define _outp(x,y) __outbyte(x,y)
31 #define _outpw(x,y) __outword(x,y)
32 #define _outpd(x,y) __outdword(x,y)
33 #define _inp(x) __inbyte(x)
34 #define _inpw(x) __inword(x)
35 #define _inpd(x) __indword(x)
36 #elif defined(__CRTDLL__)
38 * Old CRTDLL library does not provide I/O port functions. Even it is the oldest
39 * CRT library it exists also in 64-bit variant. Implement I/O port functions
40 * via inline assembly just for 32-bit mode as 64-bit mode uses above <intrin.h>
43 static inline int _outp(unsigned short port, int databyte)
45 asm volatile ("outb %b0, %w1" : : "a" (databyte), "Nd" (port));
48 static inline unsigned short _outpw(unsigned short port, unsigned short dataword)
50 asm volatile ("outw %w0, %w1" : : "a" (dataword), "Nd" (port));
53 static inline unsigned long _outpd(unsigned short port, unsigned long dataword)
55 asm volatile ("outl %0, %w1" : : "a" (dataword), "Nd" (port));
58 static inline int _inp(unsigned short port)
61 asm volatile ("inb %w1, %0" : "=a" (ret) : "Nd" (port));
64 static inline unsigned short _inpw(unsigned short port)
67 asm volatile ("inw %w1, %0" : "=a" (ret) : "Nd" (port));
70 static inline unsigned long _inpd(unsigned short port)
73 asm volatile ("inl %w1, %0" : "=a" (ret) : "Nd" (port));
76 #elif !defined(__GNUC__)
78 * Old 32-bit MSVCRT (non-UCRT) library provides I/O port functions. Function
79 * prototypes are defined in <conio.h> header file but they are missing in
80 * some MinGW toolchains. So for GCC compiler define them manually.
84 int _outp(unsigned short port, int databyte);
85 unsigned short _outpw(unsigned short port, unsigned short dataword);
86 unsigned long _outpd(unsigned short port, unsigned long dataword);
87 int _inp(unsigned short port);
88 unsigned short _inpw(unsigned short port);
89 unsigned long _inpd(unsigned short port);
92 #define outb(x,y) _outp(y,x)
93 #define outw(x,y) _outpw(y,x)
94 #define outl(x,y) _outpd(y,x)
96 #define inb(x) _inp(x)
97 #define inw(x) _inpw(x)
98 #define inl(x) _inpd(x)
101 intel_setup_io(struct pci_access *a)
103 typedef int (*MYPROC)(void);
104 MYPROC InitializeWinIo;
108 /* 16/32-bit non-NT systems allow applications to access PCI I/O ports without any special setup. */
109 OSVERSIONINFOA version;
110 version.dwOSVersionInfoSize = sizeof(version);
111 if (GetVersionExA(&version) && version.dwPlatformId < VER_PLATFORM_WIN32_NT)
113 a->debug("Detected 16/32-bit non-NT system, skipping NT setup...");
118 lib = LoadLibrary("WinIo.dll");
121 a->warning("i386-io-windows: Couldn't load WinIo.dll.");
124 /* XXX: Is this really needed? --mj */
125 GetProcAddress(lib, "InitializeWinIo");
127 InitializeWinIo = (MYPROC) GetProcAddress(lib, "InitializeWinIo");
128 if (!InitializeWinIo)
130 a->warning("i386-io-windows: Couldn't find InitializeWinIo function.");
134 if (!InitializeWinIo())
136 a->warning("i386-io-windows: InitializeWinIo() failed.");
144 intel_cleanup_io(struct pci_access *a UNUSED)
146 //TODO: DeInitializeWinIo!
150 static inline void intel_io_lock(void)
154 static inline void intel_io_unlock(void)