1706f2543Smrg/*
2706f2543Smrg *                   XFree86 int10 module
3706f2543Smrg *   execute BIOS int 10h calls in x86 real mode environment
4706f2543Smrg *                 Copyright 1999 Egbert Eich
5706f2543Smrg */
6706f2543Smrg#ifdef HAVE_XORG_CONFIG_H
7706f2543Smrg#include <xorg-config.h>
8706f2543Smrg#endif
9706f2543Smrg
10706f2543Smrg#include <string.h>
11706f2543Smrg#include <unistd.h>
12706f2543Smrg
13706f2543Smrg#include "xf86.h"
14706f2543Smrg#include "xf86_OSproc.h"
15706f2543Smrg#include "compiler.h"
16706f2543Smrg#define _INT10_PRIVATE
17706f2543Smrg#include "xf86int10.h"
18706f2543Smrg#include "int10Defines.h"
19706f2543Smrg#include "Pci.h"
20706f2543Smrg
21706f2543Smrg#define ALLOC_ENTRIES(x) ((V_RAM / x) - 1)
22706f2543Smrg
23706f2543Smrgstatic CARD8 read_b(xf86Int10InfoPtr pInt,int addr);
24706f2543Smrgstatic CARD16 read_w(xf86Int10InfoPtr pInt,int addr);
25706f2543Smrgstatic CARD32 read_l(xf86Int10InfoPtr pInt,int addr);
26706f2543Smrgstatic void write_b(xf86Int10InfoPtr pInt,int addr, CARD8 val);
27706f2543Smrgstatic void write_w(xf86Int10InfoPtr pInt,int addr, CARD16 val);
28706f2543Smrgstatic void write_l(xf86Int10InfoPtr pInt,int addr, CARD32 val);
29706f2543Smrg
30706f2543Smrg/*
31706f2543Smrg * the emulator cannot pass a pointer to the current xf86Int10InfoRec
32706f2543Smrg * to the memory access functions therefore store it here.
33706f2543Smrg */
34706f2543Smrg
35706f2543Smrgtypedef struct {
36706f2543Smrg    int shift;
37706f2543Smrg    int entries;
38706f2543Smrg    void* base;
39706f2543Smrg    void* vRam;
40706f2543Smrg    int highMemory;
41706f2543Smrg    void* sysMem;
42706f2543Smrg    char* alloc;
43706f2543Smrg} genericInt10Priv;
44706f2543Smrg
45706f2543Smrg#define INTPriv(x) ((genericInt10Priv*)x->private)
46706f2543Smrg
47706f2543Smrgint10MemRec genericMem = {
48706f2543Smrg    read_b,
49706f2543Smrg    read_w,
50706f2543Smrg    read_l,
51706f2543Smrg    write_b,
52706f2543Smrg    write_w,
53706f2543Smrg    write_l
54706f2543Smrg};
55706f2543Smrg
56706f2543Smrgstatic void MapVRam(xf86Int10InfoPtr pInt);
57706f2543Smrgstatic void UnmapVRam(xf86Int10InfoPtr pInt);
58706f2543Smrg#ifdef _PC
59706f2543Smrg#define GET_HIGH_BASE(x) (((V_BIOS + (x) + getpagesize() - 1)/getpagesize()) \
60706f2543Smrg                              * getpagesize())
61706f2543Smrg#endif
62706f2543Smrg
63706f2543Smrgstatic void *sysMem = NULL;
64706f2543Smrg
65706f2543Smrg/**
66706f2543Smrg * Read legacy VGA video BIOS associated with specified domain.
67706f2543Smrg *
68706f2543Smrg * Attempts to read up to 128KiB of legacy VGA video BIOS.
69706f2543Smrg *
70706f2543Smrg * \return
71706f2543Smrg * The number of bytes read on success or -1 on failure.
72706f2543Smrg *
73706f2543Smrg * \bug
74706f2543Smrg * PCI ROMs can contain multiple BIOS images (e.g., OpenFirmware, x86 VGA,
75706f2543Smrg * etc.).  How do we know that \c pci_device_read_rom will return the
76706f2543Smrg * legacy VGA BIOS image?
77706f2543Smrg */
78706f2543Smrg#ifndef _PC
79706f2543Smrgstatic int
80706f2543Smrgread_legacy_video_BIOS(struct pci_device *dev, unsigned char *Buf)
81706f2543Smrg{
82706f2543Smrg    const ADDRESS Base = 0xC0000;
83706f2543Smrg    const int Len = 0x10000 * 2;
84706f2543Smrg    const int pagemask = getpagesize() - 1;
85706f2543Smrg    const ADDRESS offset = Base & ~pagemask;
86706f2543Smrg    const unsigned long size = ((Base + Len + pagemask) & ~pagemask) - offset;
87706f2543Smrg    unsigned char *ptr, *src;
88706f2543Smrg    int len;
89706f2543Smrg
90706f2543Smrg
91706f2543Smrg    /* Try to use the civilized PCI interface first.
92706f2543Smrg     */
93706f2543Smrg    if (pci_device_read_rom(dev, Buf) == 0) {
94706f2543Smrg	return (unsigned long)dev->rom_size;
95706f2543Smrg    }
96706f2543Smrg
97706f2543Smrg    ptr = xf86MapDomainMemory(-1, VIDMEM_READONLY, dev, offset, size);
98706f2543Smrg
99706f2543Smrg    if (!ptr)
100706f2543Smrg	return -1;
101706f2543Smrg
102706f2543Smrg    /* Using memcpy() here can hang the system */
103706f2543Smrg    src = ptr + (Base - offset);
104706f2543Smrg    for (len = 0; len < (Len / 2); len++) {
105706f2543Smrg	Buf[len] = src[len];
106706f2543Smrg    }
107706f2543Smrg
108706f2543Smrg    if ((Buf[0] == 0x55) && (Buf[1] == 0xAA) && (Buf[2] > 0x80)) {
109706f2543Smrg	for ( /* empty */ ; len < Len; len++) {
110706f2543Smrg	    Buf[len] = src[len];
111706f2543Smrg	}
112706f2543Smrg    }
113706f2543Smrg
114706f2543Smrg    xf86UnMapVidMem(-1, ptr, size);
115706f2543Smrg
116706f2543Smrg    return Len;
117706f2543Smrg}
118706f2543Smrg#endif /* _PC */
119706f2543Smrg
120706f2543Smrg
121706f2543Smrgxf86Int10InfoPtr
122706f2543Smrgxf86ExtendedInitInt10(int entityIndex, int Flags)
123706f2543Smrg{
124706f2543Smrg    xf86Int10InfoPtr pInt;
125706f2543Smrg    void* base = 0;
126706f2543Smrg    void* vbiosMem = 0;
127706f2543Smrg    void* options = NULL;
128706f2543Smrg    int screen;
129706f2543Smrg    legacyVGARec vga;
130706f2543Smrg
131706f2543Smrg#if 0
132706f2543Smrg    CARD32 cs;
133706f2543Smrg#endif
134706f2543Smrg
135706f2543Smrg    screen = (xf86FindScreenForEntity(entityIndex))->scrnIndex;
136706f2543Smrg
137706f2543Smrg    options = xf86HandleInt10Options(xf86Screens[screen],entityIndex);
138706f2543Smrg
139706f2543Smrg    if (int10skip(options)) {
140706f2543Smrg	free(options);
141706f2543Smrg	return NULL;
142706f2543Smrg    }
143706f2543Smrg
144706f2543Smrg    pInt = (xf86Int10InfoPtr)xnfcalloc(1, sizeof(xf86Int10InfoRec));
145706f2543Smrg    pInt->entityIndex = entityIndex;
146706f2543Smrg    if (!xf86Int10ExecSetup(pInt))
147706f2543Smrg	goto error0;
148706f2543Smrg
149706f2543Smrg    pInt->mem = &genericMem;
150706f2543Smrg    pInt->private = (pointer)xnfcalloc(1, sizeof(genericInt10Priv));
151706f2543Smrg    INTPriv(pInt)->alloc = (pointer)xnfcalloc(1, ALLOC_ENTRIES(getpagesize()));
152706f2543Smrg    pInt->scrnIndex = screen;
153706f2543Smrg    base = INTPriv(pInt)->base = xnfalloc(SYS_BIOS);
154706f2543Smrg
155706f2543Smrg    /* FIXME: Shouldn't this be a failure case?  Leaving dev as NULL seems like
156706f2543Smrg     * FIXME: an error
157706f2543Smrg     */
158706f2543Smrg
159706f2543Smrg   pInt->dev = xf86GetPciInfoForEntity(entityIndex);
160706f2543Smrg
161706f2543Smrg    /*
162706f2543Smrg     * we need to map video RAM MMIO as some chipsets map mmio
163706f2543Smrg     * registers into this range.
164706f2543Smrg     */
165706f2543Smrg    MapVRam(pInt);
166706f2543Smrg#ifdef _PC
167706f2543Smrg    if (!sysMem)
168706f2543Smrg	sysMem = xf86MapVidMem(screen, VIDMEM_MMIO, V_BIOS,
169706f2543Smrg			       BIOS_SIZE + SYS_BIOS - V_BIOS);
170706f2543Smrg    INTPriv(pInt)->sysMem = sysMem;
171706f2543Smrg
172706f2543Smrg    if (xf86ReadBIOS(0, 0, base, LOW_PAGE_SIZE) < 0) {
173706f2543Smrg	xf86DrvMsg(screen, X_ERROR, "Cannot read int vect\n");
174706f2543Smrg	goto error1;
175706f2543Smrg    }
176706f2543Smrg
177706f2543Smrg    /*
178706f2543Smrg     * Retrieve everything between V_BIOS and SYS_BIOS as some system BIOSes
179706f2543Smrg     * have executable code there.  Note that xf86ReadBIOS() can only read in
180706f2543Smrg     * 64kB at a time.
181706f2543Smrg     */
182706f2543Smrg    memset((char *)base + V_BIOS, 0, SYS_BIOS - V_BIOS);
183706f2543Smrg#if 0
184706f2543Smrg    for (cs = V_BIOS;  cs < SYS_BIOS;  cs += V_BIOS_SIZE)
185706f2543Smrg	if (xf86ReadBIOS(cs, 0, (unsigned char *)base + cs, V_BIOS_SIZE) <
186706f2543Smrg		V_BIOS_SIZE)
187706f2543Smrg	    xf86DrvMsg(screen, X_WARNING,
188706f2543Smrg		       "Unable to retrieve all of segment 0x%06X.\n", cs);
189706f2543Smrg#endif
190706f2543Smrg    INTPriv(pInt)->highMemory = V_BIOS;
191706f2543Smrg
192706f2543Smrg    if (xf86IsEntityPrimary(entityIndex) && !(initPrimary(options))) {
193706f2543Smrg	if (!xf86int10GetBiosSegment(pInt, (unsigned char *)sysMem - V_BIOS))
194706f2543Smrg	    goto error1;
195706f2543Smrg
196706f2543Smrg	set_return_trap(pInt);
197706f2543Smrg
198706f2543Smrg	pInt->Flags = Flags & (SET_BIOS_SCRATCH | RESTORE_BIOS_SCRATCH);
199706f2543Smrg	if (! (pInt->Flags & SET_BIOS_SCRATCH))
200706f2543Smrg	    pInt->Flags &= ~RESTORE_BIOS_SCRATCH;
201706f2543Smrg	xf86Int10SaveRestoreBIOSVars(pInt, TRUE);
202706f2543Smrg
203706f2543Smrg    } else {
204706f2543Smrg	const BusType location_type = xf86int10GetBiosLocationType(pInt);
205706f2543Smrg	int bios_location = V_BIOS;
206706f2543Smrg
207706f2543Smrg        reset_int_vect(pInt);
208706f2543Smrg	set_return_trap(pInt);
209706f2543Smrg
210706f2543Smrg	switch (location_type) {
211706f2543Smrg	case BUS_PCI: {
212706f2543Smrg	    int err;
213706f2543Smrg	    struct pci_device *rom_device =
214706f2543Smrg		xf86GetPciInfoForEntity(pInt->entityIndex);
215706f2543Smrg
216706f2543Smrg	    vbiosMem = (unsigned char *)base + bios_location;
217706f2543Smrg	    err = pci_device_read_rom(rom_device, vbiosMem);
218706f2543Smrg	    if (err) {
219706f2543Smrg		xf86DrvMsg(screen,X_ERROR,"Cannot read V_BIOS (3) %s\n",
220706f2543Smrg			   strerror(err));
221706f2543Smrg		goto error1;
222706f2543Smrg	    }
223706f2543Smrg	    INTPriv(pInt)->highMemory = GET_HIGH_BASE(rom_device->rom_size);
224706f2543Smrg	    break;
225706f2543Smrg	}
226706f2543Smrg	default:
227706f2543Smrg	    goto error1;
228706f2543Smrg	}
229706f2543Smrg	pInt->BIOSseg = V_BIOS >> 4;
230706f2543Smrg	pInt->num = 0xe6;
231706f2543Smrg	LockLegacyVGA(pInt, &vga);
232706f2543Smrg	xf86ExecX86int10(pInt);
233706f2543Smrg	UnlockLegacyVGA(pInt, &vga);
234706f2543Smrg    }
235706f2543Smrg#else
236706f2543Smrg    if (!sysMem) {
237706f2543Smrg	sysMem = xnfalloc(BIOS_SIZE);
238706f2543Smrg	setup_system_bios(sysMem);
239706f2543Smrg    }
240706f2543Smrg    INTPriv(pInt)->sysMem = sysMem;
241706f2543Smrg    setup_int_vect(pInt);
242706f2543Smrg    set_return_trap(pInt);
243706f2543Smrg
244706f2543Smrg    /* Retrieve the entire legacy video BIOS segment.  This can be upto
245706f2543Smrg     * 128KiB.
246706f2543Smrg     */
247706f2543Smrg    vbiosMem = (char *)base + V_BIOS;
248706f2543Smrg    memset(vbiosMem, 0, 2 * V_BIOS_SIZE);
249706f2543Smrg    if (read_legacy_video_BIOS(pInt->dev, vbiosMem) < V_BIOS_SIZE) {
250706f2543Smrg	xf86DrvMsg(screen, X_WARNING,
251706f2543Smrg		   "Unable to retrieve all of segment 0x0C0000.\n");
252706f2543Smrg    }
253706f2543Smrg
254706f2543Smrg    /*
255706f2543Smrg     * If this adapter is the primary, use its post-init BIOS (if we can find
256706f2543Smrg     * it).
257706f2543Smrg     */
258706f2543Smrg    {
259706f2543Smrg	int bios_location = V_BIOS;
260706f2543Smrg	Bool done = FALSE;
261706f2543Smrg	vbiosMem = (unsigned char *)base + bios_location;
262706f2543Smrg
263706f2543Smrg	if (xf86IsEntityPrimary(entityIndex)) {
264706f2543Smrg	    if (int10_check_bios(screen, bios_location >> 4, vbiosMem))
265706f2543Smrg		done = TRUE;
266706f2543Smrg	    else
267706f2543Smrg		xf86DrvMsg(screen,X_INFO,
268706f2543Smrg			"No legacy BIOS found -- trying PCI\n");
269706f2543Smrg	}
270706f2543Smrg
271706f2543Smrg	if (!done) {
272706f2543Smrg	    int err;
273706f2543Smrg	    struct pci_device *rom_device =
274706f2543Smrg		xf86GetPciInfoForEntity(pInt->entityIndex);
275706f2543Smrg
276706f2543Smrg	    err = pci_device_read_rom(rom_device, vbiosMem);
277706f2543Smrg
278706f2543Smrg	    if (err) {
279706f2543Smrg		xf86DrvMsg(screen,X_ERROR,"Cannot read V_BIOS (5) %s\n",
280706f2543Smrg			   strerror(err));
281706f2543Smrg		goto error1;
282706f2543Smrg	    }
283706f2543Smrg	    if (!int10_check_bios(screen, bios_location >> 4, vbiosMem)) {
284706f2543Smrg	        xf86Msg(X_INFO, "No BIOS found\n");
285706f2543Smrg		goto error1;
286706f2543Smrg	    }
287706f2543Smrg	}
288706f2543Smrg    }
289706f2543Smrg
290706f2543Smrg    pInt->BIOSseg = V_BIOS >> 4;
291706f2543Smrg    pInt->num = 0xe6;
292706f2543Smrg    LockLegacyVGA(pInt, &vga);
293706f2543Smrg    xf86ExecX86int10(pInt);
294706f2543Smrg    UnlockLegacyVGA(pInt, &vga);
295706f2543Smrg#endif
296706f2543Smrg    free(options);
297706f2543Smrg    return pInt;
298706f2543Smrg
299706f2543Smrg error1:
300706f2543Smrg    free(base);
301706f2543Smrg    UnmapVRam(pInt);
302706f2543Smrg    free(INTPriv(pInt)->alloc);
303706f2543Smrg    free(pInt->private);
304706f2543Smrg error0:
305706f2543Smrg    free(pInt);
306706f2543Smrg    free(options);
307706f2543Smrg
308706f2543Smrg    return NULL;
309706f2543Smrg}
310706f2543Smrg
311706f2543Smrgstatic void
312706f2543SmrgMapVRam(xf86Int10InfoPtr pInt)
313706f2543Smrg{
314706f2543Smrg    int pagesize = getpagesize();
315706f2543Smrg    int size = ((VRAM_SIZE + pagesize - 1) / pagesize) * pagesize;
316706f2543Smrg
317706f2543Smrg    INTPriv(pInt)->vRam = xf86MapDomainMemory(pInt->scrnIndex, VIDMEM_MMIO,
318706f2543Smrg					      pInt->dev, V_RAM, size);
319706f2543Smrg
320706f2543Smrg    pInt->ioBase = xf86Screens[pInt->scrnIndex]->domainIOBase;
321706f2543Smrg}
322706f2543Smrg
323706f2543Smrgstatic void
324706f2543SmrgUnmapVRam(xf86Int10InfoPtr pInt)
325706f2543Smrg{
326706f2543Smrg    int screen = pInt->scrnIndex;
327706f2543Smrg    int pagesize = getpagesize();
328706f2543Smrg    int size = ((VRAM_SIZE + pagesize - 1)/pagesize) * pagesize;
329706f2543Smrg
330706f2543Smrg    xf86UnMapVidMem(screen, INTPriv(pInt)->vRam, size);
331706f2543Smrg}
332706f2543Smrg
333706f2543SmrgBool
334706f2543SmrgMapCurrentInt10(xf86Int10InfoPtr pInt)
335706f2543Smrg{
336706f2543Smrg    /* nothing to do here */
337706f2543Smrg    return TRUE;
338706f2543Smrg}
339706f2543Smrg
340706f2543Smrgvoid
341706f2543Smrgxf86FreeInt10(xf86Int10InfoPtr pInt)
342706f2543Smrg{
343706f2543Smrg    if (!pInt)
344706f2543Smrg      return;
345706f2543Smrg#if defined (_PC)
346706f2543Smrg    xf86Int10SaveRestoreBIOSVars(pInt, FALSE);
347706f2543Smrg#endif
348706f2543Smrg    if (Int10Current == pInt)
349706f2543Smrg	Int10Current = NULL;
350706f2543Smrg    free(INTPriv(pInt)->base);
351706f2543Smrg    UnmapVRam(pInt);
352706f2543Smrg    free(INTPriv(pInt)->alloc);
353706f2543Smrg    free(pInt->private);
354706f2543Smrg    free(pInt);
355706f2543Smrg}
356706f2543Smrg
357706f2543Smrgvoid *
358706f2543Smrgxf86Int10AllocPages(xf86Int10InfoPtr pInt, int num, int *off)
359706f2543Smrg{
360706f2543Smrg    int pagesize = getpagesize();
361706f2543Smrg    int num_pages = ALLOC_ENTRIES(pagesize);
362706f2543Smrg    int i,j;
363706f2543Smrg
364706f2543Smrg    for (i = 0; i < (num_pages - num); i++) {
365706f2543Smrg	if (INTPriv(pInt)->alloc[i] == 0) {
366706f2543Smrg	    for (j = i; j < (num + i); j++)
367706f2543Smrg		if (INTPriv(pInt)->alloc[j] != 0)
368706f2543Smrg		    break;
369706f2543Smrg	    if (j == (num + i))
370706f2543Smrg		break;
371706f2543Smrg	    i += num;
372706f2543Smrg	}
373706f2543Smrg    }
374706f2543Smrg    if (i == (num_pages - num))
375706f2543Smrg	return NULL;
376706f2543Smrg
377706f2543Smrg    for (j = i; j < (i + num); j++)
378706f2543Smrg	INTPriv(pInt)->alloc[j] = 1;
379706f2543Smrg
380706f2543Smrg    *off = (i + 1) * pagesize;
381706f2543Smrg
382706f2543Smrg    return (char *)INTPriv(pInt)->base + *off;
383706f2543Smrg}
384706f2543Smrg
385706f2543Smrgvoid
386706f2543Smrgxf86Int10FreePages(xf86Int10InfoPtr pInt, void *pbase, int num)
387706f2543Smrg{
388706f2543Smrg    int pagesize = getpagesize();
389706f2543Smrg    int first = (((char *)pbase - (char *)INTPriv(pInt)->base) / pagesize) - 1;
390706f2543Smrg    int i;
391706f2543Smrg
392706f2543Smrg    for (i = first; i < (first + num); i++)
393706f2543Smrg	INTPriv(pInt)->alloc[i] = 0;
394706f2543Smrg}
395706f2543Smrg
396706f2543Smrg#define OFF(addr) ((addr) & 0xffff)
397706f2543Smrg#if defined _PC
398706f2543Smrg# define HIGH_OFFSET (INTPriv(pInt)->highMemory)
399706f2543Smrg# define HIGH_BASE   V_BIOS
400706f2543Smrg#else
401706f2543Smrg# define HIGH_OFFSET SYS_BIOS
402706f2543Smrg# define HIGH_BASE   SYS_BIOS
403706f2543Smrg#endif
404706f2543Smrg# define SYS(addr) ((addr) >= HIGH_OFFSET)
405706f2543Smrg#define V_ADDR(addr) \
406706f2543Smrg	  (SYS(addr) ? ((char*)INTPriv(pInt)->sysMem) + (addr - HIGH_BASE) \
407706f2543Smrg	   : (((char*)(INTPriv(pInt)->base) + addr)))
408706f2543Smrg#define VRAM_ADDR(addr) (addr - V_RAM)
409706f2543Smrg#define VRAM_BASE (INTPriv(pInt)->vRam)
410706f2543Smrg
411706f2543Smrg#define VRAM(addr) ((addr >= V_RAM) && (addr < (V_RAM + VRAM_SIZE)))
412706f2543Smrg#define V_ADDR_RB(addr) \
413706f2543Smrg	(VRAM(addr)) ? MMIO_IN8((CARD8*)VRAM_BASE,VRAM_ADDR(addr)) \
414706f2543Smrg	   : *(CARD8*) V_ADDR(addr)
415706f2543Smrg#define V_ADDR_RW(addr) \
416706f2543Smrg	(VRAM(addr)) ? MMIO_IN16((CARD16*)VRAM_BASE,VRAM_ADDR(addr)) \
417706f2543Smrg	   : ldw_u((pointer)V_ADDR(addr))
418706f2543Smrg#define V_ADDR_RL(addr) \
419706f2543Smrg	(VRAM(addr)) ? MMIO_IN32((CARD32*)VRAM_BASE,VRAM_ADDR(addr)) \
420706f2543Smrg	   : ldl_u((pointer)V_ADDR(addr))
421706f2543Smrg
422706f2543Smrg#define V_ADDR_WB(addr,val) \
423706f2543Smrg	if(VRAM(addr)) \
424706f2543Smrg	    MMIO_OUT8((CARD8*)VRAM_BASE,VRAM_ADDR(addr),val); \
425706f2543Smrg	else \
426706f2543Smrg	    *(CARD8*) V_ADDR(addr) = val;
427706f2543Smrg#define V_ADDR_WW(addr,val) \
428706f2543Smrg	if(VRAM(addr)) \
429706f2543Smrg	    MMIO_OUT16((CARD16*)VRAM_BASE,VRAM_ADDR(addr),val); \
430706f2543Smrg	else \
431706f2543Smrg	    stw_u((val),(pointer)(V_ADDR(addr)));
432706f2543Smrg
433706f2543Smrg#define V_ADDR_WL(addr,val) \
434706f2543Smrg	if (VRAM(addr)) \
435706f2543Smrg	    MMIO_OUT32((CARD32*)VRAM_BASE,VRAM_ADDR(addr),val); \
436706f2543Smrg	else \
437706f2543Smrg	    stl_u(val,(pointer)(V_ADDR(addr)));
438706f2543Smrg
439706f2543Smrgstatic CARD8
440706f2543Smrgread_b(xf86Int10InfoPtr pInt, int addr)
441706f2543Smrg{
442706f2543Smrg    return V_ADDR_RB(addr);
443706f2543Smrg}
444706f2543Smrg
445706f2543Smrgstatic CARD16
446706f2543Smrgread_w(xf86Int10InfoPtr pInt, int addr)
447706f2543Smrg{
448706f2543Smrg#if X_BYTE_ORDER == X_LITTLE_ENDIAN
449706f2543Smrg    if (OFF(addr + 1) > 0)
450706f2543Smrg	return V_ADDR_RW(addr);
451706f2543Smrg#endif
452706f2543Smrg    return V_ADDR_RB(addr) | (V_ADDR_RB(addr + 1) << 8);
453706f2543Smrg}
454706f2543Smrg
455706f2543Smrgstatic CARD32
456706f2543Smrgread_l(xf86Int10InfoPtr pInt, int addr)
457706f2543Smrg{
458706f2543Smrg#if X_BYTE_ORDER == X_LITTLE_ENDIAN
459706f2543Smrg    if (OFF(addr + 3) > 2)
460706f2543Smrg	return V_ADDR_RL(addr);
461706f2543Smrg#endif
462706f2543Smrg    return V_ADDR_RB(addr) |
463706f2543Smrg	   (V_ADDR_RB(addr + 1) << 8) |
464706f2543Smrg	   (V_ADDR_RB(addr + 2) << 16) |
465706f2543Smrg	   (V_ADDR_RB(addr + 3) << 24);
466706f2543Smrg}
467706f2543Smrg
468706f2543Smrgstatic void
469706f2543Smrgwrite_b(xf86Int10InfoPtr pInt, int addr, CARD8 val)
470706f2543Smrg{
471706f2543Smrg    V_ADDR_WB(addr,val);
472706f2543Smrg}
473706f2543Smrg
474706f2543Smrgstatic void
475706f2543Smrgwrite_w(xf86Int10InfoPtr pInt, int addr, CARD16 val)
476706f2543Smrg{
477706f2543Smrg#if X_BYTE_ORDER == X_LITTLE_ENDIAN
478706f2543Smrg    if (OFF(addr + 1) > 0)
479706f2543Smrg      { V_ADDR_WW(addr, val); }
480706f2543Smrg#endif
481706f2543Smrg    V_ADDR_WB(addr, val);
482706f2543Smrg    V_ADDR_WB(addr + 1, val >> 8);
483706f2543Smrg}
484706f2543Smrg
485706f2543Smrgstatic void
486706f2543Smrgwrite_l(xf86Int10InfoPtr pInt, int addr, CARD32 val)
487706f2543Smrg{
488706f2543Smrg#if X_BYTE_ORDER == X_LITTLE_ENDIAN
489706f2543Smrg    if (OFF(addr + 3) > 2)
490706f2543Smrg      { V_ADDR_WL(addr, val); }
491706f2543Smrg#endif
492706f2543Smrg    V_ADDR_WB(addr, val);
493706f2543Smrg    V_ADDR_WB(addr + 1, val >> 8);
494706f2543Smrg    V_ADDR_WB(addr + 2, val >> 16);
495706f2543Smrg    V_ADDR_WB(addr + 3, val >> 24);
496706f2543Smrg}
497706f2543Smrg
498706f2543Smrgpointer
499706f2543Smrgxf86int10Addr(xf86Int10InfoPtr pInt, CARD32 addr)
500706f2543Smrg{
501706f2543Smrg    return V_ADDR(addr);
502706f2543Smrg}
503