]> mj.ucw.cz Git - pciutils.git/blob - lib/i386-io-windows.h
e065620de29bf62c76d7e9d47d29f5d4407770b5
[pciutils.git] / lib / i386-io-windows.h
1 /*
2  *      The PCI Library -- Access to i386 I/O ports on Windows
3  *
4  *      Copyright (c) 2004 Alexander Stock <stock.alexander@gmx.de>
5  *      Copyright (c) 2006 Martin Mares <mj@ucw.cz>
6  *
7  *      Can be freely distributed and used under the terms of the GNU GPL.
8  */
9
10 #include <io.h>
11 #include <windows.h>
12
13 #ifdef _MSC_VER
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)
22 /*
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
27  * new UCRT library.
28  */
29 #include <intrin.h>
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__)
37 /*
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>
41  * header.
42  */
43 static inline int _outp(unsigned short port, int databyte)
44 {
45   asm volatile ("outb %b0, %w1" : : "a" (databyte), "Nd" (port));
46   return databyte;
47 }
48 static inline unsigned short _outpw(unsigned short port, unsigned short dataword)
49 {
50   asm volatile ("outw %w0, %w1" : : "a" (dataword), "Nd" (port));
51   return dataword;
52 }
53 static inline unsigned long _outpd(unsigned short port, unsigned long dataword)
54 {
55   asm volatile ("outl %0, %w1" : : "a" (dataword), "Nd" (port));
56   return dataword;
57 }
58 static inline int _inp(unsigned short port)
59 {
60   unsigned char ret;
61   asm volatile ("inb %w1, %0" : "=a" (ret) : "Nd" (port));
62   return ret;
63 }
64 static inline unsigned short _inpw(unsigned short port)
65 {
66   unsigned short ret;
67   asm volatile ("inw %w1, %0" : "=a" (ret) : "Nd" (port));
68   return ret;
69 }
70 static inline unsigned long _inpd(unsigned short port)
71 {
72   unsigned long ret;
73   asm volatile ("inl %w1, %0" : "=a" (ret) : "Nd" (port));
74   return ret;
75 }
76 #elif !defined(__GNUC__)
77 /*
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.
81  */
82 #include <conio.h>
83 #else
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);
90 #endif
91
92 #define outb(x,y) _outp(y,x)
93 #define outw(x,y) _outpw(y,x)
94 #define outl(x,y) _outpd(y,x)
95
96 #define inb(x) _inp(x)
97 #define inw(x) _inpw(x)
98 #define inl(x) _inpd(x)
99
100 static int
101 intel_setup_io(struct pci_access *a)
102 {
103   typedef int (*MYPROC)(void);
104   MYPROC InitializeWinIo;
105   HMODULE lib;
106
107 #ifndef _WIN64
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)
112     {
113       a->debug("Detected 16/32-bit non-NT system, skipping NT setup...");
114       return 1;
115     }
116 #endif
117
118   lib = LoadLibrary("WinIo.dll");
119   if (!lib)
120     {
121       a->warning("i386-io-windows: Couldn't load WinIo.dll.");
122       return 0;
123     }
124   /* XXX: Is this really needed? --mj */
125   GetProcAddress(lib, "InitializeWinIo");
126
127   InitializeWinIo = (MYPROC) GetProcAddress(lib, "InitializeWinIo");
128   if (!InitializeWinIo)
129     {
130       a->warning("i386-io-windows: Couldn't find InitializeWinIo function.");
131       return 0;
132     }
133
134   if (!InitializeWinIo())
135     {
136       a->warning("i386-io-windows: InitializeWinIo() failed.");
137       return 0;
138     }
139
140   return 1;
141 }
142
143 static inline int
144 intel_cleanup_io(struct pci_access *a UNUSED)
145 {
146   //TODO: DeInitializeWinIo!
147   return 1;
148 }
149
150 static inline void intel_io_lock(void)
151 {
152 }
153
154 static inline void intel_io_unlock(void)
155 {
156 }