1 | /*
|
---|
2 | ** THIS SOFTWARE IS SUBJECT TO COPYRIGHT PROTECTION AND IS OFFERED ONLY
|
---|
3 | ** PURSUANT TO THE 3DFX GLIDE GENERAL PUBLIC LICENSE. THERE IS NO RIGHT
|
---|
4 | ** TO USE THE GLIDE TRADEMARK WITHOUT PRIOR WRITTEN PERMISSION OF 3DFX
|
---|
5 | ** INTERACTIVE, INC. A COPY OF THIS LICENSE MAY BE OBTAINED FROM THE
|
---|
6 | ** DISTRIBUTOR OR BY CONTACTING 3DFX INTERACTIVE INC(info@3dfx.com).
|
---|
7 | ** THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
|
---|
8 | ** EXPRESSED OR IMPLIED. SEE THE 3DFX GLIDE GENERAL PUBLIC LICENSE FOR A
|
---|
9 | ** FULL TEXT OF THE NON-WARRANTY PROVISIONS.
|
---|
10 | **
|
---|
11 | ** USE, DUPLICATION OR DISCLOSURE BY THE GOVERNMENT IS SUBJECT TO
|
---|
12 | ** RESTRICTIONS AS SET FORTH IN SUBDIVISION (C)(1)(II) OF THE RIGHTS IN
|
---|
13 | ** TECHNICAL DATA AND COMPUTER SOFTWARE CLAUSE AT DFARS 252.227-7013,
|
---|
14 | ** AND/OR IN SIMILAR OR SUCCESSOR CLAUSES IN THE FAR, DOD OR NASA FAR
|
---|
15 | ** SUPPLEMENT. UNPUBLISHED RIGHTS RESERVED UNDER THE COPYRIGHT LAWS OF
|
---|
16 | ** THE UNITED STATES.
|
---|
17 | **
|
---|
18 | ** COPYRIGHT 3DFX INTERACTIVE, INC. 1999, ALL RIGHTS RESERVED
|
---|
19 | */
|
---|
20 |
|
---|
21 | #include <stddef.h>
|
---|
22 | #include <stdio.h>
|
---|
23 | #include <stdlib.h>
|
---|
24 |
|
---|
25 | #include <windows.h>
|
---|
26 | #include <winioctl.h>
|
---|
27 |
|
---|
28 | #include <gpioctl.h>
|
---|
29 | #include <fxptl.h>
|
---|
30 |
|
---|
31 | #include <3dfx.h>
|
---|
32 | #define FX_DLL_DEFINITION
|
---|
33 | #include <fxdll.h>
|
---|
34 |
|
---|
35 | #include "fxpci.h"
|
---|
36 | #include "pcilib.h"
|
---|
37 | #include "fxw32.h"
|
---|
38 |
|
---|
39 | /* ------------------------------------------------------------- */
|
---|
40 | /* Memmap and portio through Microsoft's sample mapmem miniport */
|
---|
41 |
|
---|
42 | static HANDLE hGpdFile;
|
---|
43 |
|
---|
44 | /* Callback declarations */
|
---|
45 | static FxBool pciInitializeNT(void);
|
---|
46 | static FxBool pciShutdownNT(void);
|
---|
47 | static const char* pciIdentifierNT(void);
|
---|
48 |
|
---|
49 | static FxU8 pciPortInByteNT(FxU16 port);
|
---|
50 | static FxU16 pciPortInWordNT(FxU16 port);
|
---|
51 | static FxU32 pciPortInLongNT(FxU16 port);
|
---|
52 |
|
---|
53 | static FxBool pciPortOutByteNT(FxU16 port, FxU8 data);
|
---|
54 | static FxBool pciPortOutWordNT(FxU16 port, FxU16 data);
|
---|
55 | static FxBool pciPortOutLongNT(FxU16 port, FxU32 data);
|
---|
56 |
|
---|
57 | static FxBool pciMapLinearNT(FxU32 busNumber, FxU32 physAddr,
|
---|
58 | FxU32* linearAddr, FxU32* length);
|
---|
59 | static FxBool pciUnmapLinearNT(FxU32 linearAddr, FxU32 length);
|
---|
60 |
|
---|
61 | static FxBool pciSetPermissionNT(const FxU32 addrBase, const FxU32 addrLen,
|
---|
62 | const FxBool writePermP);
|
---|
63 |
|
---|
64 | static FxBool pciMsrGetNT(MSRInfo* in, MSRInfo* out);
|
---|
65 | static FxBool pciMsrSetNT(MSRInfo* in, MSRInfo* out);
|
---|
66 |
|
---|
67 | static FxBool pciOutputStringNT(const char* msg);
|
---|
68 | static FxBool pciSetPassThroughBaseNT(FxU32* baseAddr, FxU32 baseAddrLen);
|
---|
69 |
|
---|
70 | static char pciIdent[] = "@#% fxPCI for Windows NT";
|
---|
71 |
|
---|
72 | static const FxPlatformIOProcs __ioProcsNT = {
|
---|
73 | pciInitializeNT,
|
---|
74 | pciShutdownNT,
|
---|
75 | pciIdentifierNT,
|
---|
76 |
|
---|
77 | pciPortInByteNT,
|
---|
78 | pciPortInWordNT,
|
---|
79 | pciPortInLongNT,
|
---|
80 |
|
---|
81 | pciPortOutByteNT,
|
---|
82 | pciPortOutWordNT,
|
---|
83 | pciPortOutLongNT,
|
---|
84 |
|
---|
85 | pciMapLinearNT,
|
---|
86 | pciUnmapLinearNT,
|
---|
87 | pciSetPermissionNT,
|
---|
88 |
|
---|
89 | pciMsrGetNT,
|
---|
90 | pciMsrSetNT,
|
---|
91 |
|
---|
92 | pciOutputStringNT,
|
---|
93 | pciSetPassThroughBaseNT
|
---|
94 | };
|
---|
95 | const FxPlatformIOProcs* ioProcsNT = &__ioProcsNT;
|
---|
96 |
|
---|
97 | /* Basic platform init/shutdown stuff */
|
---|
98 | static FxBool
|
---|
99 | pciInitializeNT(void)
|
---|
100 | {
|
---|
101 | hGpdFile = INVALID_HANDLE_VALUE;
|
---|
102 | hMemmapFile = INVALID_HANDLE_VALUE;
|
---|
103 |
|
---|
104 | hGpdFile = CreateFile("\\\\.\\GpdDev",
|
---|
105 | GENERIC_READ | GENERIC_WRITE,
|
---|
106 | FILE_SHARE_READ | FILE_SHARE_WRITE,
|
---|
107 | NULL,
|
---|
108 | OPEN_EXISTING,
|
---|
109 | 0,
|
---|
110 | NULL);
|
---|
111 | if (hGpdFile == INVALID_HANDLE_VALUE) {
|
---|
112 | pciErrorCode = PCI_ERR_GENPORT;
|
---|
113 | return FXFALSE;
|
---|
114 | }
|
---|
115 |
|
---|
116 | hMemmapFile = CreateFile("\\\\.\\MAPMEM",
|
---|
117 | GENERIC_READ | GENERIC_WRITE,
|
---|
118 | 0,
|
---|
119 | NULL,
|
---|
120 | OPEN_EXISTING,
|
---|
121 | FILE_ATTRIBUTE_NORMAL,
|
---|
122 | NULL);
|
---|
123 | if (hMemmapFile == INVALID_HANDLE_VALUE) {
|
---|
124 | pciErrorCode = PCI_ERR_MAPMEMDRV;
|
---|
125 | return FXFALSE;
|
---|
126 | }
|
---|
127 |
|
---|
128 | return FXTRUE;
|
---|
129 | }
|
---|
130 |
|
---|
131 | static FxBool
|
---|
132 | pciShutdownNT(void)
|
---|
133 | {
|
---|
134 | if (hGpdFile != INVALID_HANDLE_VALUE) CloseHandle(hGpdFile);
|
---|
135 | if (hMemmapFile != INVALID_HANDLE_VALUE) CloseHandle(hMemmapFile);
|
---|
136 |
|
---|
137 | return FXTRUE;
|
---|
138 | }
|
---|
139 |
|
---|
140 | static const char*
|
---|
141 | pciIdentifierNT(void)
|
---|
142 | {
|
---|
143 | return pciIdent;
|
---|
144 | }
|
---|
145 |
|
---|
146 | /* Device address space management stuff */
|
---|
147 |
|
---|
148 | static FxBool
|
---|
149 | pciMapLinearNT(FxU32 busNumber, FxU32 physical_addr,
|
---|
150 | FxU32 *linear_addr, FxU32 *length)
|
---|
151 | {
|
---|
152 | FxU32 cbReturned;
|
---|
153 | PHYSICAL_MEMORY_INFO pmi;
|
---|
154 |
|
---|
155 | pmi.InterfaceType = PCIBus;
|
---|
156 | pmi.BusNumber = busNumber;
|
---|
157 | pmi.BusAddress.HighPart = 0x00000000;
|
---|
158 | pmi.BusAddress.LowPart = physical_addr;
|
---|
159 | pmi.AddressSpace = 0;
|
---|
160 | pmi.Length = *length;
|
---|
161 |
|
---|
162 | if(!DeviceIoControl(hMemmapFile,
|
---|
163 | (FxU32)IOCTL_MAPMEM_MAP_USER_PHYSICAL_MEMORY,
|
---|
164 | &pmi, sizeof(PHYSICAL_MEMORY_INFO),
|
---|
165 | linear_addr, sizeof(PVOID),
|
---|
166 | &cbReturned, NULL)) {
|
---|
167 | pciErrorCode = PCI_ERR_MAPMEM;
|
---|
168 | return FXFALSE;
|
---|
169 | }
|
---|
170 |
|
---|
171 | return FXTRUE;
|
---|
172 | }
|
---|
173 |
|
---|
174 | static FxBool
|
---|
175 | pciUnmapLinearNT(FxU32 linear_addr, FxU32 length)
|
---|
176 | {
|
---|
177 | FxU32 cbReturned;
|
---|
178 |
|
---|
179 | return DeviceIoControl(hMemmapFile,
|
---|
180 | (FxU32)IOCTL_MAPMEM_UNMAP_USER_PHYSICAL_MEMORY,
|
---|
181 | &linear_addr, sizeof(PVOID),
|
---|
182 | NULL, 0,
|
---|
183 | &cbReturned, NULL);
|
---|
184 | }
|
---|
185 |
|
---|
186 | /* Platform port io stuff */
|
---|
187 |
|
---|
188 | FxU8
|
---|
189 | pciPortInByteNT (unsigned short port)
|
---|
190 | {
|
---|
191 | BOOL IoctlResult;
|
---|
192 | LONG IoctlCode;
|
---|
193 | ULONG PortNumber;
|
---|
194 | UCHAR DataBuffer;
|
---|
195 | ULONG DataLength;
|
---|
196 | ULONG ReturnedLength;
|
---|
197 |
|
---|
198 | IoctlCode = IOCTL_GPD_READ_PORT_UCHAR;
|
---|
199 | PortNumber = port;
|
---|
200 | DataLength = sizeof(DataBuffer);
|
---|
201 |
|
---|
202 | IoctlResult = DeviceIoControl(hGpdFile, IoctlCode,
|
---|
203 | &PortNumber, sizeof(PortNumber),
|
---|
204 | &DataBuffer, DataLength,
|
---|
205 | &ReturnedLength, NULL);
|
---|
206 |
|
---|
207 | if (IoctlResult && ReturnedLength == DataLength)
|
---|
208 | return DataBuffer;
|
---|
209 | else
|
---|
210 | return FXFALSE;
|
---|
211 | } /* pioInByte */
|
---|
212 |
|
---|
213 | FxU16
|
---|
214 | pciPortInWordNT (unsigned short port)
|
---|
215 | {
|
---|
216 | BOOL IoctlResult;
|
---|
217 | LONG IoctlCode;
|
---|
218 | ULONG PortNumber;
|
---|
219 | USHORT DataBuffer;
|
---|
220 | ULONG DataLength;
|
---|
221 | ULONG ReturnedLength;
|
---|
222 |
|
---|
223 | IoctlCode = IOCTL_GPD_READ_PORT_USHORT;
|
---|
224 | PortNumber = port;
|
---|
225 | DataLength = sizeof(DataBuffer);
|
---|
226 |
|
---|
227 | IoctlResult = DeviceIoControl(hGpdFile, IoctlCode,
|
---|
228 | &PortNumber, sizeof(PortNumber),
|
---|
229 | &DataBuffer, DataLength,
|
---|
230 | &ReturnedLength, NULL);
|
---|
231 |
|
---|
232 | if (IoctlResult && ReturnedLength == DataLength)
|
---|
233 | return DataBuffer;
|
---|
234 | else
|
---|
235 | return FXFALSE;
|
---|
236 | } /* pioInWord */
|
---|
237 |
|
---|
238 | FxU32
|
---|
239 | pciPortInLongNT (unsigned short port)
|
---|
240 | {
|
---|
241 | BOOL IoctlResult;
|
---|
242 | LONG IoctlCode;
|
---|
243 | ULONG PortNumber;
|
---|
244 | ULONG DataBuffer;
|
---|
245 | ULONG DataLength;
|
---|
246 | ULONG ReturnedLength;
|
---|
247 |
|
---|
248 | IoctlCode = IOCTL_GPD_READ_PORT_ULONG;
|
---|
249 | PortNumber = port;
|
---|
250 | DataLength = sizeof(DataBuffer);
|
---|
251 |
|
---|
252 | IoctlResult = DeviceIoControl(hGpdFile, IoctlCode,
|
---|
253 | &PortNumber, sizeof(PortNumber),
|
---|
254 | &DataBuffer, DataLength,
|
---|
255 | &ReturnedLength, NULL);
|
---|
256 |
|
---|
257 | if (IoctlResult && ReturnedLength == DataLength)
|
---|
258 | return DataBuffer;
|
---|
259 | else
|
---|
260 | return FXFALSE;
|
---|
261 | } /* pioInLong */
|
---|
262 |
|
---|
263 | FxBool
|
---|
264 | pciPortOutByteNT (unsigned short port, FxU8 data)
|
---|
265 | {
|
---|
266 | LONG IoctlCode;
|
---|
267 | GENPORT_WRITE_INPUT InputBuffer;
|
---|
268 | ULONG DataLength;
|
---|
269 | ULONG ReturnedLength;
|
---|
270 |
|
---|
271 | IoctlCode = IOCTL_GPD_WRITE_PORT_UCHAR;
|
---|
272 | InputBuffer.PortNumber = port;
|
---|
273 | InputBuffer.CharData = (UCHAR) data;
|
---|
274 | DataLength = (offsetof(GENPORT_WRITE_INPUT, CharData) +
|
---|
275 | sizeof(InputBuffer.CharData));
|
---|
276 |
|
---|
277 | return DeviceIoControl(hGpdFile, IoctlCode,
|
---|
278 | &InputBuffer, DataLength,
|
---|
279 | NULL, 0,
|
---|
280 | &ReturnedLength, NULL);
|
---|
281 | } /* pioOutByte */
|
---|
282 |
|
---|
283 | FxBool
|
---|
284 | pciPortOutWordNT (unsigned short port, FxU16 data)
|
---|
285 | {
|
---|
286 | LONG IoctlCode;
|
---|
287 | GENPORT_WRITE_INPUT InputBuffer;
|
---|
288 | ULONG DataLength;
|
---|
289 | ULONG ReturnedLength;
|
---|
290 |
|
---|
291 | IoctlCode = IOCTL_GPD_WRITE_PORT_USHORT;
|
---|
292 | InputBuffer.PortNumber = port;
|
---|
293 | InputBuffer.ShortData = (USHORT) data;
|
---|
294 | DataLength = (offsetof(GENPORT_WRITE_INPUT, ShortData) +
|
---|
295 | sizeof(InputBuffer.ShortData));
|
---|
296 |
|
---|
297 | return DeviceIoControl(hGpdFile, IoctlCode,
|
---|
298 | &InputBuffer, DataLength,
|
---|
299 | NULL, 0,
|
---|
300 | &ReturnedLength, NULL);
|
---|
301 | } /* pioOutWord */
|
---|
302 |
|
---|
303 | FxBool
|
---|
304 | pciPortOutLongNT (unsigned short port, FxU32 data)
|
---|
305 | {
|
---|
306 | LONG IoctlCode;
|
---|
307 | GENPORT_WRITE_INPUT InputBuffer;
|
---|
308 | ULONG DataLength;
|
---|
309 | ULONG ReturnedLength;
|
---|
310 |
|
---|
311 | IoctlCode = IOCTL_GPD_WRITE_PORT_ULONG;
|
---|
312 | InputBuffer.PortNumber = port;
|
---|
313 | InputBuffer.LongData = (ULONG) data;
|
---|
314 | DataLength = (offsetof(GENPORT_WRITE_INPUT, LongData) +
|
---|
315 | sizeof(InputBuffer.LongData));
|
---|
316 |
|
---|
317 | return DeviceIoControl(hGpdFile, IoctlCode,
|
---|
318 | &InputBuffer, DataLength,
|
---|
319 | NULL, 0,
|
---|
320 | &ReturnedLength, NULL);
|
---|
321 | } /* pioOutLong */
|
---|
322 |
|
---|
323 | static FxBool
|
---|
324 | pciMsrGetNT(MSRInfo* in, MSRInfo* out)
|
---|
325 | {
|
---|
326 | ULONG retLen;
|
---|
327 |
|
---|
328 | return DeviceIoControl(hMemmapFile, (FxU32)IOCTL_MAPMEM_GET_MSR,
|
---|
329 | in, sizeof(*in),
|
---|
330 | out, sizeof(*out),
|
---|
331 | &retLen, NULL);
|
---|
332 | }
|
---|
333 |
|
---|
334 | static FxBool
|
---|
335 | pciMsrSetNT(MSRInfo* in, MSRInfo* out)
|
---|
336 | {
|
---|
337 | ULONG retLen;
|
---|
338 |
|
---|
339 | return DeviceIoControl(hMemmapFile, (FxU32)IOCTL_MAPMEM_SET_MSR,
|
---|
340 | in, sizeof(*in),
|
---|
341 | out, sizeof(*out),
|
---|
342 | &retLen, NULL);
|
---|
343 | }
|
---|
344 |
|
---|
345 | /* Platform utilities. */
|
---|
346 | static FxBool
|
---|
347 | pciOutputStringNT(const char* msg)
|
---|
348 | {
|
---|
349 | FxBool retVal = FXTRUE;
|
---|
350 |
|
---|
351 | if (pciLibraryInitialized) {
|
---|
352 | OutputDebugString(msg);
|
---|
353 | } else {
|
---|
354 | pciErrorCode = PCI_ERR_NOTOPEN;
|
---|
355 | retVal = FXFALSE;
|
---|
356 | }
|
---|
357 |
|
---|
358 | return retVal;
|
---|
359 | }
|
---|
360 |
|
---|
361 | static FxBool
|
---|
362 | pciSetPermissionNT(const FxU32 addrBase, const FxU32 addrLen,
|
---|
363 | const FxBool writePermP)
|
---|
364 | {
|
---|
365 | return FXFALSE;
|
---|
366 | }
|
---|
367 |
|
---|
368 | static FxBool
|
---|
369 | pciSetPassThroughBaseNT(FxU32* baseAddr, FxU32 baseAddrLen)
|
---|
370 | {
|
---|
371 | return FXFALSE;
|
---|
372 | }
|
---|
373 |
|
---|
374 |
|
---|
375 |
|
---|