source: trunk/src/opengl/glide/swlibs/pcilib/fxlinux.c

Last change on this file was 2887, checked in by sandervl, 26 years ago

Created swlibs dir

File size: 8.8 KB
Line 
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 <stdlib.h>
22#include <stdio.h>
23#include <3dfx.h>
24#include <unistd.h>
25#include <sys/types.h>
26#include <sys/stat.h>
27#include <sys/mman.h>
28#include <sys/ioctl.h>
29
30/* There are a few minor differences for portio between libc5 and
31 * glibc2
32 * libc5: unistd.h (included above) has the declaration of
33 * iopl() and asm/io.h has the declarations of inb, inw, inl and such.
34 * glibc2: sys/io.h has the declaration of iopl() and includes
35 * asm/io.h for us */
36#if __GNU_LIBRARY__ <= 5
37#include <asm/io.h>
38#else
39#include <sys/io.h>
40#endif
41
42#include <fcntl.h>
43#include "fxpci.h"
44#include "pcilib.h"
45
46static const char* pciIdentifyLinux(void);
47static FxBool pciOutputStringLinux(const char *msg);
48static FxBool pciInitializeLinux(void);
49static FxBool pciShutdownLinux(void);
50static FxBool pciMapLinearLinux(FxU32, FxU32 physical_addr, FxU32 *linear_addr,
51 FxU32 *length);
52static FxBool pciUnmapLinearLinux(FxU32 linear_addr, FxU32 length);
53static FxBool pciSetPermissionLinux(const FxU32, const FxU32, const FxBool);
54static FxU8 pciPortInByteLinux(unsigned short port);
55static FxU16 pciPortInWordLinux(unsigned short port);
56static FxU32 pciPortInLongLinux(unsigned short port);
57static FxBool pciPortOutByteLinux(unsigned short port, FxU8 data);
58static FxBool pciPortOutWordLinux(unsigned short port, FxU16 data);
59static FxBool pciPortOutLongLinux(unsigned short port, FxU32 data);
60static FxBool pciMsrGetLinux(MSRInfo *, MSRInfo *);
61static FxBool pciMsrSetLinux(MSRInfo *, MSRInfo *);
62static FxBool pciSetPassThroughBaseLinux(FxU32 *, FxU32);
63
64const FxPlatformIOProcs ioProcsLinux = {
65 pciInitializeLinux,
66 pciShutdownLinux,
67 pciIdentifyLinux,
68
69 pciPortInByteLinux,
70 pciPortInWordLinux,
71 pciPortInLongLinux,
72
73 pciPortOutByteLinux,
74 pciPortOutWordLinux,
75 pciPortOutLongLinux,
76
77 pciMapLinearLinux,
78 pciUnmapLinearLinux,
79 pciSetPermissionLinux,
80
81 pciMsrGetLinux,
82 pciMsrSetLinux,
83
84 pciOutputStringLinux,
85 pciSetPassThroughBaseLinux
86};
87
88static const FxU32 PCI_VENDOR_ID_LINUX = 0x0;
89static const FxU32 PCI_DEVICE_ID_LINUX = 0x2;
90static const FxU32 PCI_COMMAND_LINUX = 0x4;
91static const FxU32 PCI_BASE_ADDRESS_0_LINUX = 0x10;
92static const FxU32 SST1_PCI_INIT_ENABLE_LINUX = 0x40;
93static const FxU32 SST1_PCI_BUS_SNOOP0_LINUX = 0x44;
94static const FxU32 SST1_PCI_BUS_SNOOP1_LINUX = 0x48;
95
96static int linuxDevFd=-1;
97
98struct pioData {
99 short port;
100 short size;
101 int device;
102 void *value;
103};
104
105FxBool
106pciPlatformInit(void)
107{
108 gCurPlatformIO = &ioProcsLinux;
109 return FXTRUE;
110}
111
112FxBool
113hasDev3DfxLinux(void)
114{
115 if (linuxDevFd==-1) return FXFALSE;
116 return FXTRUE;
117}
118
119FxU32
120pciFetchRegisterLinux( FxU32 cmd, FxU32 size, FxU32 device)
121{
122 struct pioData desc;
123 char cval;
124 short sval;
125 int ival;
126
127 if (linuxDevFd==-1) return -1;
128 desc.port=cmd;
129 desc.size=size;
130 desc.device=device;
131 switch (size) {
132 case 1:
133 desc.value=&cval;
134 break;
135 case 2:
136 desc.value=&sval;
137 break;
138 case 4:
139 desc.value=&ival;
140 break;
141 default:
142 return 0;
143 }
144 if (ioctl(linuxDevFd, _IOR('3', 3, sizeof(struct pioData)), &desc)==-1)
145 return 0;
146 switch (size) {
147 case 1:
148 return cval;
149 case 2:
150 return sval;
151 case 4:
152 return ival;
153 default:
154 return 0;
155 }
156}
157
158FxBool
159pciUpdateRegisterLinux(FxU32 cmd, FxU32 data, FxU32 size, FxU32 device)
160{
161 struct pioData desc;
162
163 if (linuxDevFd==-1) return -1;
164 desc.port=cmd;
165 desc.size=size;
166 desc.device=device;
167 desc.value=&data;
168 if (ioctl(linuxDevFd, _IOW('3', 4, sizeof(struct pioData)), &desc)==-1)
169 return FXFALSE;
170 return FXTRUE;
171}
172
173int
174getNumDevicesLinux(void)
175{
176 if (linuxDevFd==-1) return -1;
177 return ioctl(linuxDevFd, _IO('3', 2));
178}
179
180static const char*
181pciIdentifyLinux(void)
182{
183 return "fxPCI for Linux";
184}
185
186static FxBool
187pciOutputStringLinux(const char *msg)
188{
189 printf(msg);
190 return FXTRUE;
191}
192
193static FxBool
194pciInitializeLinux(void)
195{
196 if (!getenv("SST_NO_DEV3DFX")) linuxDevFd=open("/dev/3dfx", O_RDWR, 0);
197 if (linuxDevFd==-1) {
198 if (iopl(3)<0) {
199 pciErrorCode = PCI_ERR_NO_IO_PERM;
200 return FXFALSE;
201 }
202 }
203 return FXTRUE;
204}
205
206static FxBool
207pciShutdownLinux(void)
208{
209 if (linuxDevFd>=0) {
210 close(linuxDevFd);
211 } else {
212 iopl(0);
213 }
214 return FXTRUE;
215}
216
217static FxBool
218pciMapLinearLinux(FxU32 bus, FxU32 physical_addr,
219 FxU32 *linear_addr, FxU32 *length)
220{
221 int fd;
222 if (linuxDevFd!=-1) {
223 fd=linuxDevFd;
224 } else {
225 if ((fd=open("/dev/mem", O_RDWR))<0) {
226 pciErrorCode=PCI_ERR_NO_MEM_PERM;
227 return FXFALSE;
228 }
229 }
230 if (((*linear_addr)=(FxU32)mmap(0, *length, PROT_READ|PROT_WRITE,
231 MAP_SHARED, fd, physical_addr))<0) {
232 if (fd!=linuxDevFd) close(fd);
233 return FXFALSE;
234 }
235 if (fd!=linuxDevFd) close(fd);
236 return FXTRUE;
237}
238
239static FxBool
240pciUnmapLinearLinux(FxU32 linear_addr, FxU32 length)
241{
242 munmap((void*)linear_addr, length);
243 return FXTRUE;
244}
245
246static FxBool
247pciSetPermissionLinux(const FxU32 addrBase, const FxU32 addrLen,
248 const FxBool writePermP)
249{
250 return FXTRUE;
251}
252
253static FxU8
254pciPortInByteLinux(unsigned short port)
255{
256 char tmp;
257 struct pioData desc;
258
259 if (linuxDevFd==-1) {
260 tmp=inb(port);
261 /* fprintf(stderr, "Read byte at %x got %d\n", port, tmp); */
262 return tmp;
263 }
264 desc.port=port;
265 desc.size=sizeof(tmp);
266 desc.value=&tmp;
267 /* fprintf(stderr, "Read byte desc at %x tmp at %x\n", &desc, &tmp); */
268 ioctl(linuxDevFd, _IOR(0, 0, sizeof(struct pioData)), &desc);
269 /* fprintf(stderr, "Got byte %d versus %d\n", tmp, inb(port)); */
270 return tmp;
271}
272
273static FxU16
274pciPortInWordLinux(unsigned short port)
275{
276 short tmp;
277 struct pioData desc;
278
279 if (linuxDevFd==-1) {
280 tmp=inw(port);
281 /* fprintf(stderr, "Read word at %x got %x\n", port, tmp); */
282 return tmp;
283 }
284 desc.port=port;
285 desc.size=sizeof(tmp);
286 desc.value=&tmp;
287 /* fprintf(stderr, "Read word desc at %x tmp at %x\n", &desc, &tmp); */
288 ioctl(linuxDevFd, _IOR(0, 0, sizeof(struct pioData)), &desc);
289 /* fprintf(stderr, "Got word %d versus %d\n", tmp, inw(port)); */
290 return tmp;
291}
292
293static FxU32
294pciPortInLongLinux(unsigned short port)
295{
296 int tmp;
297 struct pioData desc;
298
299 if (linuxDevFd==-1) {
300 tmp=inl(port);
301 /* fprintf(stderr, "Read long at %x got %x\n", port, tmp); */
302 return tmp;
303 }
304 desc.port=port;
305 desc.size=sizeof(tmp);
306 desc.value=&tmp;
307 /* fprintf(stderr, "Read long desc at %x tmp at %x\n", &desc, &tmp); */
308 ioctl(linuxDevFd, _IOR(0, 0, sizeof(struct pioData)), &desc);
309 /* fprintf(stderr, "Got long %x versus %x\n", tmp, inl(port)); */
310 return tmp;
311}
312
313static FxBool
314pciPortOutByteLinux(unsigned short port, FxU8 data)
315{
316 struct pioData desc;
317 /* fprintf(stderr, "write byte=%d desc at %x data at %x\n", data,
318 &desc, &data); */
319 if (linuxDevFd==-1) {
320 outb(data, port);
321 return FXTRUE;
322 }
323 desc.port=port;
324 desc.size=sizeof(data);
325 desc.value=&data;
326 return ioctl(linuxDevFd, _IOW(0, 1, sizeof(struct pioData)), &desc)!=-1;
327}
328
329static FxBool
330pciPortOutWordLinux(unsigned short port, FxU16 data)
331{
332 struct pioData desc;
333 /* fprintf(stderr, "write word=%x to port=%x desc at %x data at %x\n",
334 data, port, &desc, &data); */
335 if (linuxDevFd==-1) {
336 outw(data, port);
337 return FXTRUE;
338 }
339 desc.port=port;
340 desc.size=sizeof(data);
341 desc.value=&data;
342 return ioctl(linuxDevFd, _IOW(0, 1, sizeof(struct pioData)), &desc)!=-1;
343}
344
345static FxBool
346pciPortOutLongLinux(unsigned short port, FxU32 data)
347{
348 struct pioData desc;
349 /* fprintf(stderr, "write long=%x to port=%x desc at %x data at %x\n",
350 data, port, &desc, &data); */
351 if (linuxDevFd==-1) {
352 outl(data, port);
353 return FXTRUE;
354 }
355 desc.port=port;
356 desc.size=sizeof(data);
357 desc.value=&data;
358 return ioctl(linuxDevFd, _IOW(0, 1, sizeof(struct pioData)), &desc)!=-1;
359}
360
361static FxBool
362pciMsrGetLinux(MSRInfo *in, MSRInfo *out)
363{
364 return FXTRUE;
365}
366
367static FxBool
368pciMsrSetLinux(MSRInfo *in, MSRInfo *out)
369{
370 return FXTRUE;
371}
372
373static FxBool
374pciSetPassThroughBaseLinux(FxU32 *baseAddr, FxU32 baseAddrLen)
375{
376 return FXTRUE;
377}
Note: See TracBrowser for help on using the repository browser.