1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * XFree86 int10 module
3*4882a593Smuzhiyun * execute BIOS int 10h calls in x86 real mode environment
4*4882a593Smuzhiyun * Copyright 1999 Egbert Eich
5*4882a593Smuzhiyun */
6*4882a593Smuzhiyun #ifdef HAVE_XORG_CONFIG_H
7*4882a593Smuzhiyun #include <xorg-config.h>
8*4882a593Smuzhiyun #endif
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun #include <string.h>
11*4882a593Smuzhiyun #include <unistd.h>
12*4882a593Smuzhiyun
13*4882a593Smuzhiyun #include "xf86.h"
14*4882a593Smuzhiyun #include "xf86_OSproc.h"
15*4882a593Smuzhiyun #include "compiler.h"
16*4882a593Smuzhiyun #define _INT10_PRIVATE
17*4882a593Smuzhiyun #include "xf86int10.h"
18*4882a593Smuzhiyun #include "int10Defines.h"
19*4882a593Smuzhiyun #include "Pci.h"
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun #define ALLOC_ENTRIES(x) ((V_RAM / x) - 1)
22*4882a593Smuzhiyun
23*4882a593Smuzhiyun #include <string.h> /* needed for memmove */
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun static __inline__ uint32_t
ldl_u(uint32_t * p)26*4882a593Smuzhiyun ldl_u(uint32_t * p)
27*4882a593Smuzhiyun {
28*4882a593Smuzhiyun uint32_t ret;
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun memmove(&ret, p, sizeof(*p));
31*4882a593Smuzhiyun return ret;
32*4882a593Smuzhiyun }
33*4882a593Smuzhiyun
34*4882a593Smuzhiyun static __inline__ uint16_t
ldw_u(uint16_t * p)35*4882a593Smuzhiyun ldw_u(uint16_t * p)
36*4882a593Smuzhiyun {
37*4882a593Smuzhiyun uint16_t ret;
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun memmove(&ret, p, sizeof(*p));
40*4882a593Smuzhiyun return ret;
41*4882a593Smuzhiyun }
42*4882a593Smuzhiyun
43*4882a593Smuzhiyun static __inline__ void
stl_u(uint32_t val,uint32_t * p)44*4882a593Smuzhiyun stl_u(uint32_t val, uint32_t * p)
45*4882a593Smuzhiyun {
46*4882a593Smuzhiyun uint32_t tmp = val;
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun memmove(p, &tmp, sizeof(*p));
49*4882a593Smuzhiyun }
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun static __inline__ void
stw_u(uint16_t val,uint16_t * p)52*4882a593Smuzhiyun stw_u(uint16_t val, uint16_t * p)
53*4882a593Smuzhiyun {
54*4882a593Smuzhiyun uint16_t tmp = val;
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun memmove(p, &tmp, sizeof(*p));
57*4882a593Smuzhiyun }
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun static uint8_t read_b(xf86Int10InfoPtr pInt, int addr);
60*4882a593Smuzhiyun static uint16_t read_w(xf86Int10InfoPtr pInt, int addr);
61*4882a593Smuzhiyun static uint32_t read_l(xf86Int10InfoPtr pInt, int addr);
62*4882a593Smuzhiyun static void write_b(xf86Int10InfoPtr pInt, int addr, uint8_t val);
63*4882a593Smuzhiyun static void write_w(xf86Int10InfoPtr pInt, int addr, uint16_t val);
64*4882a593Smuzhiyun static void write_l(xf86Int10InfoPtr pInt, int addr, uint32_t val);
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun /*
67*4882a593Smuzhiyun * the emulator cannot pass a pointer to the current xf86Int10InfoRec
68*4882a593Smuzhiyun * to the memory access functions therefore store it here.
69*4882a593Smuzhiyun */
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun typedef struct {
72*4882a593Smuzhiyun int shift;
73*4882a593Smuzhiyun int entries;
74*4882a593Smuzhiyun void *base;
75*4882a593Smuzhiyun void *vRam;
76*4882a593Smuzhiyun int highMemory;
77*4882a593Smuzhiyun void *sysMem;
78*4882a593Smuzhiyun char *alloc;
79*4882a593Smuzhiyun } genericInt10Priv;
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun #define INTPriv(x) ((genericInt10Priv*)x->private)
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun int10MemRec genericMem = {
84*4882a593Smuzhiyun read_b,
85*4882a593Smuzhiyun read_w,
86*4882a593Smuzhiyun read_l,
87*4882a593Smuzhiyun write_b,
88*4882a593Smuzhiyun write_w,
89*4882a593Smuzhiyun write_l
90*4882a593Smuzhiyun };
91*4882a593Smuzhiyun
92*4882a593Smuzhiyun static void MapVRam(xf86Int10InfoPtr pInt);
93*4882a593Smuzhiyun static void UnmapVRam(xf86Int10InfoPtr pInt);
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun #ifdef _PC
96*4882a593Smuzhiyun #define GET_HIGH_BASE(x) (((V_BIOS + (x) + getpagesize() - 1)/getpagesize()) \
97*4882a593Smuzhiyun * getpagesize())
98*4882a593Smuzhiyun #endif
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun static void *sysMem = NULL;
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun static Bool
readIntVec(struct pci_device * dev,unsigned char * buf,int len)103*4882a593Smuzhiyun readIntVec(struct pci_device *dev, unsigned char *buf, int len)
104*4882a593Smuzhiyun {
105*4882a593Smuzhiyun void *map;
106*4882a593Smuzhiyun
107*4882a593Smuzhiyun if (pci_device_map_legacy(dev, 0, len, 0, &map))
108*4882a593Smuzhiyun return FALSE;
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun memcpy(buf, map, len);
111*4882a593Smuzhiyun pci_device_unmap_legacy(dev, map, len);
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun return TRUE;
114*4882a593Smuzhiyun }
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun xf86Int10InfoPtr
xf86ExtendedInitInt10(int entityIndex,int Flags)117*4882a593Smuzhiyun xf86ExtendedInitInt10(int entityIndex, int Flags)
118*4882a593Smuzhiyun {
119*4882a593Smuzhiyun xf86Int10InfoPtr pInt;
120*4882a593Smuzhiyun void *base = 0;
121*4882a593Smuzhiyun void *vbiosMem = 0;
122*4882a593Smuzhiyun void *options = NULL;
123*4882a593Smuzhiyun legacyVGARec vga;
124*4882a593Smuzhiyun ScrnInfoPtr pScrn;
125*4882a593Smuzhiyun
126*4882a593Smuzhiyun pScrn = xf86FindScreenForEntity(entityIndex);
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun options = xf86HandleInt10Options(pScrn, entityIndex);
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun if (int10skip(options)) {
131*4882a593Smuzhiyun free(options);
132*4882a593Smuzhiyun return NULL;
133*4882a593Smuzhiyun }
134*4882a593Smuzhiyun
135*4882a593Smuzhiyun pInt = (xf86Int10InfoPtr) xnfcalloc(1, sizeof(xf86Int10InfoRec));
136*4882a593Smuzhiyun pInt->entityIndex = entityIndex;
137*4882a593Smuzhiyun if (!xf86Int10ExecSetup(pInt))
138*4882a593Smuzhiyun goto error0;
139*4882a593Smuzhiyun pInt->mem = &genericMem;
140*4882a593Smuzhiyun pInt->private = (void *) xnfcalloc(1, sizeof(genericInt10Priv));
141*4882a593Smuzhiyun INTPriv(pInt)->alloc = (void *) xnfcalloc(1, ALLOC_ENTRIES(getpagesize()));
142*4882a593Smuzhiyun pInt->pScrn = pScrn;
143*4882a593Smuzhiyun base = INTPriv(pInt)->base = xnfalloc(SYS_BIOS);
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun /* FIXME: Shouldn't this be a failure case? Leaving dev as NULL seems like
146*4882a593Smuzhiyun * FIXME: an error
147*4882a593Smuzhiyun */
148*4882a593Smuzhiyun pInt->dev = xf86GetPciInfoForEntity(entityIndex);
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun /*
151*4882a593Smuzhiyun * we need to map video RAM MMIO as some chipsets map mmio
152*4882a593Smuzhiyun * registers into this range.
153*4882a593Smuzhiyun */
154*4882a593Smuzhiyun MapVRam(pInt);
155*4882a593Smuzhiyun #ifdef _PC
156*4882a593Smuzhiyun if (!sysMem)
157*4882a593Smuzhiyun pci_device_map_legacy(pInt->dev, V_BIOS, BIOS_SIZE + SYS_BIOS - V_BIOS,
158*4882a593Smuzhiyun PCI_DEV_MAP_FLAG_WRITABLE, &sysMem);
159*4882a593Smuzhiyun INTPriv(pInt)->sysMem = sysMem;
160*4882a593Smuzhiyun
161*4882a593Smuzhiyun if (!readIntVec(pInt->dev, base, LOW_PAGE_SIZE)) {
162*4882a593Smuzhiyun xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Cannot read int vect\n");
163*4882a593Smuzhiyun goto error1;
164*4882a593Smuzhiyun }
165*4882a593Smuzhiyun
166*4882a593Smuzhiyun /*
167*4882a593Smuzhiyun * Retrieve everything between V_BIOS and SYS_BIOS as some system BIOSes
168*4882a593Smuzhiyun * have executable code there.
169*4882a593Smuzhiyun */
170*4882a593Smuzhiyun memset((char *) base + V_BIOS, 0, SYS_BIOS - V_BIOS);
171*4882a593Smuzhiyun INTPriv(pInt)->highMemory = V_BIOS;
172*4882a593Smuzhiyun
173*4882a593Smuzhiyun if (xf86IsEntityPrimary(entityIndex) && !(initPrimary(options))) {
174*4882a593Smuzhiyun if (!xf86int10GetBiosSegment(pInt, (unsigned char *) sysMem - V_BIOS))
175*4882a593Smuzhiyun goto error1;
176*4882a593Smuzhiyun
177*4882a593Smuzhiyun set_return_trap(pInt);
178*4882a593Smuzhiyun
179*4882a593Smuzhiyun pInt->Flags = Flags & (SET_BIOS_SCRATCH | RESTORE_BIOS_SCRATCH);
180*4882a593Smuzhiyun if (!(pInt->Flags & SET_BIOS_SCRATCH))
181*4882a593Smuzhiyun pInt->Flags &= ~RESTORE_BIOS_SCRATCH;
182*4882a593Smuzhiyun xf86Int10SaveRestoreBIOSVars(pInt, TRUE);
183*4882a593Smuzhiyun
184*4882a593Smuzhiyun }
185*4882a593Smuzhiyun else {
186*4882a593Smuzhiyun const BusType location_type = xf86int10GetBiosLocationType(pInt);
187*4882a593Smuzhiyun int bios_location = V_BIOS;
188*4882a593Smuzhiyun
189*4882a593Smuzhiyun reset_int_vect(pInt);
190*4882a593Smuzhiyun set_return_trap(pInt);
191*4882a593Smuzhiyun
192*4882a593Smuzhiyun switch (location_type) {
193*4882a593Smuzhiyun case BUS_PCI:{
194*4882a593Smuzhiyun int err;
195*4882a593Smuzhiyun struct pci_device *rom_device =
196*4882a593Smuzhiyun xf86GetPciInfoForEntity(pInt->entityIndex);
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun vbiosMem = (unsigned char *) base + bios_location;
199*4882a593Smuzhiyun err = pci_device_read_rom(rom_device, vbiosMem);
200*4882a593Smuzhiyun if (err) {
201*4882a593Smuzhiyun xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Cannot read V_BIOS (3) %s\n",
202*4882a593Smuzhiyun strerror(err));
203*4882a593Smuzhiyun goto error1;
204*4882a593Smuzhiyun }
205*4882a593Smuzhiyun INTPriv(pInt)->highMemory = GET_HIGH_BASE(rom_device->rom_size);
206*4882a593Smuzhiyun break;
207*4882a593Smuzhiyun }
208*4882a593Smuzhiyun default:
209*4882a593Smuzhiyun goto error1;
210*4882a593Smuzhiyun }
211*4882a593Smuzhiyun pInt->BIOSseg = V_BIOS >> 4;
212*4882a593Smuzhiyun pInt->num = 0xe6;
213*4882a593Smuzhiyun LockLegacyVGA(pInt, &vga);
214*4882a593Smuzhiyun xf86ExecX86int10(pInt);
215*4882a593Smuzhiyun UnlockLegacyVGA(pInt, &vga);
216*4882a593Smuzhiyun }
217*4882a593Smuzhiyun #else
218*4882a593Smuzhiyun if (!sysMem) {
219*4882a593Smuzhiyun sysMem = xnfalloc(BIOS_SIZE);
220*4882a593Smuzhiyun setup_system_bios(sysMem);
221*4882a593Smuzhiyun }
222*4882a593Smuzhiyun INTPriv(pInt)->sysMem = sysMem;
223*4882a593Smuzhiyun setup_int_vect(pInt);
224*4882a593Smuzhiyun set_return_trap(pInt);
225*4882a593Smuzhiyun
226*4882a593Smuzhiyun /* Retrieve the entire legacy video BIOS segment. This can be upto
227*4882a593Smuzhiyun * 128KiB.
228*4882a593Smuzhiyun */
229*4882a593Smuzhiyun vbiosMem = (char *) base + V_BIOS;
230*4882a593Smuzhiyun memset(vbiosMem, 0, 2 * V_BIOS_SIZE);
231*4882a593Smuzhiyun if (pci_device_read_rom(pInt->dev, vbiosMem) != 0
232*4882a593Smuzhiyun || pInt->dev->rom_size < V_BIOS_SIZE) {
233*4882a593Smuzhiyun xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
234*4882a593Smuzhiyun "Unable to retrieve all of segment 0x0C0000.\n");
235*4882a593Smuzhiyun }
236*4882a593Smuzhiyun
237*4882a593Smuzhiyun /*
238*4882a593Smuzhiyun * If this adapter is the primary, use its post-init BIOS (if we can find
239*4882a593Smuzhiyun * it).
240*4882a593Smuzhiyun */
241*4882a593Smuzhiyun {
242*4882a593Smuzhiyun int bios_location = V_BIOS;
243*4882a593Smuzhiyun Bool done = FALSE;
244*4882a593Smuzhiyun
245*4882a593Smuzhiyun vbiosMem = (unsigned char *) base + bios_location;
246*4882a593Smuzhiyun
247*4882a593Smuzhiyun if (xf86IsEntityPrimary(entityIndex)) {
248*4882a593Smuzhiyun if (int10_check_bios(pScrn->scrnIndex, bios_location >> 4, vbiosMem))
249*4882a593Smuzhiyun done = TRUE;
250*4882a593Smuzhiyun else
251*4882a593Smuzhiyun xf86DrvMsg(pScrn->scrnIndex, X_INFO,
252*4882a593Smuzhiyun "No legacy BIOS found -- trying PCI\n");
253*4882a593Smuzhiyun }
254*4882a593Smuzhiyun if (!done) {
255*4882a593Smuzhiyun int err;
256*4882a593Smuzhiyun struct pci_device *rom_device =
257*4882a593Smuzhiyun xf86GetPciInfoForEntity(pInt->entityIndex);
258*4882a593Smuzhiyun
259*4882a593Smuzhiyun err = pci_device_read_rom(rom_device, vbiosMem);
260*4882a593Smuzhiyun if (err) {
261*4882a593Smuzhiyun xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Cannot read V_BIOS (5) %s\n",
262*4882a593Smuzhiyun strerror(err));
263*4882a593Smuzhiyun goto error1;
264*4882a593Smuzhiyun }
265*4882a593Smuzhiyun }
266*4882a593Smuzhiyun }
267*4882a593Smuzhiyun
268*4882a593Smuzhiyun pInt->BIOSseg = V_BIOS >> 4;
269*4882a593Smuzhiyun pInt->num = 0xe6;
270*4882a593Smuzhiyun LockLegacyVGA(pInt, &vga);
271*4882a593Smuzhiyun xf86ExecX86int10(pInt);
272*4882a593Smuzhiyun UnlockLegacyVGA(pInt, &vga);
273*4882a593Smuzhiyun #endif
274*4882a593Smuzhiyun free(options);
275*4882a593Smuzhiyun return pInt;
276*4882a593Smuzhiyun
277*4882a593Smuzhiyun error1:
278*4882a593Smuzhiyun free(base);
279*4882a593Smuzhiyun UnmapVRam(pInt);
280*4882a593Smuzhiyun free(INTPriv(pInt)->alloc);
281*4882a593Smuzhiyun free(pInt->private);
282*4882a593Smuzhiyun error0:
283*4882a593Smuzhiyun free(pInt);
284*4882a593Smuzhiyun free(options);
285*4882a593Smuzhiyun
286*4882a593Smuzhiyun return NULL;
287*4882a593Smuzhiyun }
288*4882a593Smuzhiyun
289*4882a593Smuzhiyun static void
MapVRam(xf86Int10InfoPtr pInt)290*4882a593Smuzhiyun MapVRam(xf86Int10InfoPtr pInt)
291*4882a593Smuzhiyun {
292*4882a593Smuzhiyun int pagesize = getpagesize();
293*4882a593Smuzhiyun int size = ((VRAM_SIZE + pagesize - 1) / pagesize) * pagesize;
294*4882a593Smuzhiyun
295*4882a593Smuzhiyun pci_device_map_legacy(pInt->dev, V_RAM, size, PCI_DEV_MAP_FLAG_WRITABLE,
296*4882a593Smuzhiyun &(INTPriv(pInt)->vRam));
297*4882a593Smuzhiyun pInt->io = pci_legacy_open_io(pInt->dev, 0, 64 * 1024);
298*4882a593Smuzhiyun }
299*4882a593Smuzhiyun
300*4882a593Smuzhiyun static void
UnmapVRam(xf86Int10InfoPtr pInt)301*4882a593Smuzhiyun UnmapVRam(xf86Int10InfoPtr pInt)
302*4882a593Smuzhiyun {
303*4882a593Smuzhiyun int pagesize = getpagesize();
304*4882a593Smuzhiyun int size = ((VRAM_SIZE + pagesize - 1) / pagesize) * pagesize;
305*4882a593Smuzhiyun
306*4882a593Smuzhiyun pci_device_unmap_legacy(pInt->dev, INTPriv(pInt)->vRam, size);
307*4882a593Smuzhiyun pci_device_close_io(pInt->dev, pInt->io);
308*4882a593Smuzhiyun pInt->io = NULL;
309*4882a593Smuzhiyun }
310*4882a593Smuzhiyun
311*4882a593Smuzhiyun Bool
MapCurrentInt10(xf86Int10InfoPtr pInt)312*4882a593Smuzhiyun MapCurrentInt10(xf86Int10InfoPtr pInt)
313*4882a593Smuzhiyun {
314*4882a593Smuzhiyun /* nothing to do here */
315*4882a593Smuzhiyun return TRUE;
316*4882a593Smuzhiyun }
317*4882a593Smuzhiyun
318*4882a593Smuzhiyun void
xf86FreeInt10(xf86Int10InfoPtr pInt)319*4882a593Smuzhiyun xf86FreeInt10(xf86Int10InfoPtr pInt)
320*4882a593Smuzhiyun {
321*4882a593Smuzhiyun if (!pInt)
322*4882a593Smuzhiyun return;
323*4882a593Smuzhiyun #if defined (_PC)
324*4882a593Smuzhiyun xf86Int10SaveRestoreBIOSVars(pInt, FALSE);
325*4882a593Smuzhiyun #endif
326*4882a593Smuzhiyun if (Int10Current == pInt)
327*4882a593Smuzhiyun Int10Current = NULL;
328*4882a593Smuzhiyun free(INTPriv(pInt)->base);
329*4882a593Smuzhiyun UnmapVRam(pInt);
330*4882a593Smuzhiyun free(INTPriv(pInt)->alloc);
331*4882a593Smuzhiyun free(pInt->private);
332*4882a593Smuzhiyun free(pInt);
333*4882a593Smuzhiyun }
334*4882a593Smuzhiyun
335*4882a593Smuzhiyun void *
xf86Int10AllocPages(xf86Int10InfoPtr pInt,int num,int * off)336*4882a593Smuzhiyun xf86Int10AllocPages(xf86Int10InfoPtr pInt, int num, int *off)
337*4882a593Smuzhiyun {
338*4882a593Smuzhiyun int pagesize = getpagesize();
339*4882a593Smuzhiyun int num_pages = ALLOC_ENTRIES(pagesize);
340*4882a593Smuzhiyun int i, j;
341*4882a593Smuzhiyun
342*4882a593Smuzhiyun for (i = 0; i < (num_pages - num); i++) {
343*4882a593Smuzhiyun if (INTPriv(pInt)->alloc[i] == 0) {
344*4882a593Smuzhiyun for (j = i; j < (num + i); j++)
345*4882a593Smuzhiyun if (INTPriv(pInt)->alloc[j] != 0)
346*4882a593Smuzhiyun break;
347*4882a593Smuzhiyun if (j == (num + i))
348*4882a593Smuzhiyun break;
349*4882a593Smuzhiyun i += num;
350*4882a593Smuzhiyun }
351*4882a593Smuzhiyun }
352*4882a593Smuzhiyun if (i == (num_pages - num))
353*4882a593Smuzhiyun return NULL;
354*4882a593Smuzhiyun
355*4882a593Smuzhiyun for (j = i; j < (i + num); j++)
356*4882a593Smuzhiyun INTPriv(pInt)->alloc[j] = 1;
357*4882a593Smuzhiyun
358*4882a593Smuzhiyun *off = (i + 1) * pagesize;
359*4882a593Smuzhiyun
360*4882a593Smuzhiyun return (char *) INTPriv(pInt)->base + *off;
361*4882a593Smuzhiyun }
362*4882a593Smuzhiyun
363*4882a593Smuzhiyun void
xf86Int10FreePages(xf86Int10InfoPtr pInt,void * pbase,int num)364*4882a593Smuzhiyun xf86Int10FreePages(xf86Int10InfoPtr pInt, void *pbase, int num)
365*4882a593Smuzhiyun {
366*4882a593Smuzhiyun int pagesize = getpagesize();
367*4882a593Smuzhiyun int first =
368*4882a593Smuzhiyun (((char *) pbase - (char *) INTPriv(pInt)->base) / pagesize) - 1;
369*4882a593Smuzhiyun int i;
370*4882a593Smuzhiyun
371*4882a593Smuzhiyun for (i = first; i < (first + num); i++)
372*4882a593Smuzhiyun INTPriv(pInt)->alloc[i] = 0;
373*4882a593Smuzhiyun }
374*4882a593Smuzhiyun
375*4882a593Smuzhiyun #define OFF(addr) ((addr) & 0xffff)
376*4882a593Smuzhiyun #if defined _PC
377*4882a593Smuzhiyun #define HIGH_OFFSET (INTPriv(pInt)->highMemory)
378*4882a593Smuzhiyun #define HIGH_BASE V_BIOS
379*4882a593Smuzhiyun #else
380*4882a593Smuzhiyun #define HIGH_OFFSET SYS_BIOS
381*4882a593Smuzhiyun #define HIGH_BASE SYS_BIOS
382*4882a593Smuzhiyun #endif
383*4882a593Smuzhiyun #define SYS(addr) ((addr) >= HIGH_OFFSET)
384*4882a593Smuzhiyun #define V_ADDR(addr) \
385*4882a593Smuzhiyun (SYS(addr) ? ((char*)INTPriv(pInt)->sysMem) + (addr - HIGH_BASE) \
386*4882a593Smuzhiyun : (((char*)(INTPriv(pInt)->base) + addr)))
387*4882a593Smuzhiyun #define VRAM_ADDR(addr) (addr - V_RAM)
388*4882a593Smuzhiyun #define VRAM_BASE (INTPriv(pInt)->vRam)
389*4882a593Smuzhiyun
390*4882a593Smuzhiyun #define VRAM(addr) ((addr >= V_RAM) && (addr < (V_RAM + VRAM_SIZE)))
391*4882a593Smuzhiyun #define V_ADDR_RB(addr) \
392*4882a593Smuzhiyun (VRAM(addr)) ? MMIO_IN8((uint8_t*)VRAM_BASE,VRAM_ADDR(addr)) \
393*4882a593Smuzhiyun : *(uint8_t*) V_ADDR(addr)
394*4882a593Smuzhiyun #define V_ADDR_RW(addr) \
395*4882a593Smuzhiyun (VRAM(addr)) ? MMIO_IN16((uint16_t*)VRAM_BASE,VRAM_ADDR(addr)) \
396*4882a593Smuzhiyun : ldw_u((void *)V_ADDR(addr))
397*4882a593Smuzhiyun #define V_ADDR_RL(addr) \
398*4882a593Smuzhiyun (VRAM(addr)) ? MMIO_IN32((uint32_t*)VRAM_BASE,VRAM_ADDR(addr)) \
399*4882a593Smuzhiyun : ldl_u((void *)V_ADDR(addr))
400*4882a593Smuzhiyun
401*4882a593Smuzhiyun #define V_ADDR_WB(addr,val) \
402*4882a593Smuzhiyun if(VRAM(addr)) \
403*4882a593Smuzhiyun MMIO_OUT8((uint8_t*)VRAM_BASE,VRAM_ADDR(addr),val); \
404*4882a593Smuzhiyun else \
405*4882a593Smuzhiyun *(uint8_t*) V_ADDR(addr) = val;
406*4882a593Smuzhiyun #define V_ADDR_WW(addr,val) \
407*4882a593Smuzhiyun if(VRAM(addr)) \
408*4882a593Smuzhiyun MMIO_OUT16((uint16_t*)VRAM_BASE,VRAM_ADDR(addr),val); \
409*4882a593Smuzhiyun else \
410*4882a593Smuzhiyun stw_u((val),(void *)(V_ADDR(addr)));
411*4882a593Smuzhiyun
412*4882a593Smuzhiyun #define V_ADDR_WL(addr,val) \
413*4882a593Smuzhiyun if (VRAM(addr)) \
414*4882a593Smuzhiyun MMIO_OUT32((uint32_t*)VRAM_BASE,VRAM_ADDR(addr),val); \
415*4882a593Smuzhiyun else \
416*4882a593Smuzhiyun stl_u(val,(void *)(V_ADDR(addr)));
417*4882a593Smuzhiyun
418*4882a593Smuzhiyun static uint8_t
read_b(xf86Int10InfoPtr pInt,int addr)419*4882a593Smuzhiyun read_b(xf86Int10InfoPtr pInt, int addr)
420*4882a593Smuzhiyun {
421*4882a593Smuzhiyun return V_ADDR_RB(addr);
422*4882a593Smuzhiyun }
423*4882a593Smuzhiyun
424*4882a593Smuzhiyun static uint16_t
read_w(xf86Int10InfoPtr pInt,int addr)425*4882a593Smuzhiyun read_w(xf86Int10InfoPtr pInt, int addr)
426*4882a593Smuzhiyun {
427*4882a593Smuzhiyun #if X_BYTE_ORDER == X_LITTLE_ENDIAN
428*4882a593Smuzhiyun if (OFF(addr + 1) > 0)
429*4882a593Smuzhiyun return V_ADDR_RW(addr);
430*4882a593Smuzhiyun #endif
431*4882a593Smuzhiyun return V_ADDR_RB(addr) | (V_ADDR_RB(addr + 1) << 8);
432*4882a593Smuzhiyun }
433*4882a593Smuzhiyun
434*4882a593Smuzhiyun static uint32_t
read_l(xf86Int10InfoPtr pInt,int addr)435*4882a593Smuzhiyun read_l(xf86Int10InfoPtr pInt, int addr)
436*4882a593Smuzhiyun {
437*4882a593Smuzhiyun #if X_BYTE_ORDER == X_LITTLE_ENDIAN
438*4882a593Smuzhiyun if (OFF(addr + 3) > 2)
439*4882a593Smuzhiyun return V_ADDR_RL(addr);
440*4882a593Smuzhiyun #endif
441*4882a593Smuzhiyun return V_ADDR_RB(addr) |
442*4882a593Smuzhiyun (V_ADDR_RB(addr + 1) << 8) |
443*4882a593Smuzhiyun (V_ADDR_RB(addr + 2) << 16) | (V_ADDR_RB(addr + 3) << 24);
444*4882a593Smuzhiyun }
445*4882a593Smuzhiyun
446*4882a593Smuzhiyun static void
write_b(xf86Int10InfoPtr pInt,int addr,uint8_t val)447*4882a593Smuzhiyun write_b(xf86Int10InfoPtr pInt, int addr, uint8_t val)
448*4882a593Smuzhiyun {
449*4882a593Smuzhiyun V_ADDR_WB(addr, val);
450*4882a593Smuzhiyun }
451*4882a593Smuzhiyun
452*4882a593Smuzhiyun static void
write_w(xf86Int10InfoPtr pInt,int addr,CARD16 val)453*4882a593Smuzhiyun write_w(xf86Int10InfoPtr pInt, int addr, CARD16 val)
454*4882a593Smuzhiyun {
455*4882a593Smuzhiyun #if X_BYTE_ORDER == X_LITTLE_ENDIAN
456*4882a593Smuzhiyun if (OFF(addr + 1) > 0) {
457*4882a593Smuzhiyun V_ADDR_WW(addr, val);
458*4882a593Smuzhiyun }
459*4882a593Smuzhiyun #endif
460*4882a593Smuzhiyun V_ADDR_WB(addr, val);
461*4882a593Smuzhiyun V_ADDR_WB(addr + 1, val >> 8);
462*4882a593Smuzhiyun }
463*4882a593Smuzhiyun
464*4882a593Smuzhiyun static void
write_l(xf86Int10InfoPtr pInt,int addr,uint32_t val)465*4882a593Smuzhiyun write_l(xf86Int10InfoPtr pInt, int addr, uint32_t val)
466*4882a593Smuzhiyun {
467*4882a593Smuzhiyun #if X_BYTE_ORDER == X_LITTLE_ENDIAN
468*4882a593Smuzhiyun if (OFF(addr + 3) > 2) {
469*4882a593Smuzhiyun V_ADDR_WL(addr, val);
470*4882a593Smuzhiyun }
471*4882a593Smuzhiyun #endif
472*4882a593Smuzhiyun V_ADDR_WB(addr, val);
473*4882a593Smuzhiyun V_ADDR_WB(addr + 1, val >> 8);
474*4882a593Smuzhiyun V_ADDR_WB(addr + 2, val >> 16);
475*4882a593Smuzhiyun V_ADDR_WB(addr + 3, val >> 24);
476*4882a593Smuzhiyun }
477*4882a593Smuzhiyun
478*4882a593Smuzhiyun void *
xf86int10Addr(xf86Int10InfoPtr pInt,uint32_t addr)479*4882a593Smuzhiyun xf86int10Addr(xf86Int10InfoPtr pInt, uint32_t addr)
480*4882a593Smuzhiyun {
481*4882a593Smuzhiyun return V_ADDR(addr);
482*4882a593Smuzhiyun }
483