105b261ecSmrg/*
205b261ecSmrg *                   XFree86 int10 module
305b261ecSmrg *   execute BIOS int 10h calls in x86 real mode environment
405b261ecSmrg *                 Copyright 1999 Egbert Eich
505b261ecSmrg */
605b261ecSmrg#ifdef HAVE_XORG_CONFIG_H
705b261ecSmrg#include <xorg-config.h>
805b261ecSmrg#endif
905b261ecSmrg
1005b261ecSmrg#include <string.h>
1105b261ecSmrg#include <unistd.h>
1205b261ecSmrg
1305b261ecSmrg#include "xf86.h"
1405b261ecSmrg#include "xf86_OSproc.h"
1505b261ecSmrg#include "compiler.h"
1605b261ecSmrg#define _INT10_PRIVATE
1705b261ecSmrg#include "xf86int10.h"
1805b261ecSmrg#include "int10Defines.h"
194642e01fSmrg#include "Pci.h"
2005b261ecSmrg
2105b261ecSmrg#define ALLOC_ENTRIES(x) ((V_RAM / x) - 1)
2205b261ecSmrg
23f7df2e56Smrg#include <string.h>             /* needed for memmove */
24f7df2e56Smrg
25f7df2e56Smrgstatic __inline__ uint32_t
26f7df2e56Smrgldl_u(uint32_t * p)
27f7df2e56Smrg{
28f7df2e56Smrg    uint32_t ret;
29f7df2e56Smrg
30f7df2e56Smrg    memmove(&ret, p, sizeof(*p));
31f7df2e56Smrg    return ret;
32f7df2e56Smrg}
33f7df2e56Smrg
34f7df2e56Smrgstatic __inline__ uint16_t
35f7df2e56Smrgldw_u(uint16_t * p)
36f7df2e56Smrg{
37f7df2e56Smrg    uint16_t ret;
38f7df2e56Smrg
39f7df2e56Smrg    memmove(&ret, p, sizeof(*p));
40f7df2e56Smrg    return ret;
41f7df2e56Smrg}
42f7df2e56Smrg
43f7df2e56Smrgstatic __inline__ void
44f7df2e56Smrgstl_u(uint32_t val, uint32_t * p)
45f7df2e56Smrg{
46f7df2e56Smrg    uint32_t tmp = val;
47f7df2e56Smrg
48f7df2e56Smrg    memmove(p, &tmp, sizeof(*p));
49f7df2e56Smrg}
50f7df2e56Smrg
51f7df2e56Smrgstatic __inline__ void
52f7df2e56Smrgstw_u(uint16_t val, uint16_t * p)
53f7df2e56Smrg{
54f7df2e56Smrg    uint16_t tmp = val;
55f7df2e56Smrg
56f7df2e56Smrg    memmove(p, &tmp, sizeof(*p));
57f7df2e56Smrg}
58f7df2e56Smrg
59f7df2e56Smrgstatic uint8_t read_b(xf86Int10InfoPtr pInt, int addr);
60f7df2e56Smrgstatic uint16_t read_w(xf86Int10InfoPtr pInt, int addr);
61f7df2e56Smrgstatic uint32_t read_l(xf86Int10InfoPtr pInt, int addr);
62f7df2e56Smrgstatic void write_b(xf86Int10InfoPtr pInt, int addr, uint8_t val);
63f7df2e56Smrgstatic void write_w(xf86Int10InfoPtr pInt, int addr, uint16_t val);
64f7df2e56Smrgstatic void write_l(xf86Int10InfoPtr pInt, int addr, uint32_t val);
6505b261ecSmrg
6605b261ecSmrg/*
6705b261ecSmrg * the emulator cannot pass a pointer to the current xf86Int10InfoRec
6805b261ecSmrg * to the memory access functions therefore store it here.
6905b261ecSmrg */
7005b261ecSmrg
7105b261ecSmrgtypedef struct {
7205b261ecSmrg    int shift;
7305b261ecSmrg    int entries;
74f7df2e56Smrg    void *base;
75f7df2e56Smrg    void *vRam;
7605b261ecSmrg    int highMemory;
77f7df2e56Smrg    void *sysMem;
78f7df2e56Smrg    char *alloc;
7905b261ecSmrg} genericInt10Priv;
8005b261ecSmrg
8105b261ecSmrg#define INTPriv(x) ((genericInt10Priv*)x->private)
8205b261ecSmrg
8305b261ecSmrgint10MemRec genericMem = {
8405b261ecSmrg    read_b,
8505b261ecSmrg    read_w,
8605b261ecSmrg    read_l,
8705b261ecSmrg    write_b,
8805b261ecSmrg    write_w,
8905b261ecSmrg    write_l
9005b261ecSmrg};
9105b261ecSmrg
9205b261ecSmrgstatic void MapVRam(xf86Int10InfoPtr pInt);
9305b261ecSmrgstatic void UnmapVRam(xf86Int10InfoPtr pInt);
94f7df2e56Smrg
9505b261ecSmrg#ifdef _PC
964642e01fSmrg#define GET_HIGH_BASE(x) (((V_BIOS + (x) + getpagesize() - 1)/getpagesize()) \
974642e01fSmrg                              * getpagesize())
9805b261ecSmrg#endif
9905b261ecSmrg
10005b261ecSmrgstatic void *sysMem = NULL;
10105b261ecSmrg
102f7df2e56Smrgstatic Bool
103f7df2e56SmrgreadIntVec(struct pci_device *dev, unsigned char *buf, int len)
1044642e01fSmrg{
105f7df2e56Smrg    void *map;
1064642e01fSmrg
107f7df2e56Smrg    if (pci_device_map_legacy(dev, 0, len, 0, &map))
108f7df2e56Smrg        return FALSE;
1094642e01fSmrg
110f7df2e56Smrg    memcpy(buf, map, len);
111f7df2e56Smrg    pci_device_unmap_legacy(dev, map, len);
1124642e01fSmrg
113f7df2e56Smrg    return TRUE;
1144642e01fSmrg}
1154642e01fSmrg
11605b261ecSmrgxf86Int10InfoPtr
11705b261ecSmrgxf86ExtendedInitInt10(int entityIndex, int Flags)
11805b261ecSmrg{
11905b261ecSmrg    xf86Int10InfoPtr pInt;
120f7df2e56Smrg    void *base = 0;
121f7df2e56Smrg    void *vbiosMem = 0;
122f7df2e56Smrg    void *options = NULL;
12305b261ecSmrg    legacyVGARec vga;
124f7df2e56Smrg    ScrnInfoPtr pScrn;
125f7df2e56Smrg
126f7df2e56Smrg    pScrn = xf86FindScreenForEntity(entityIndex);
12705b261ecSmrg
128f7df2e56Smrg    options = xf86HandleInt10Options(pScrn, entityIndex);
12905b261ecSmrg
13005b261ecSmrg    if (int10skip(options)) {
131f7df2e56Smrg        free(options);
132f7df2e56Smrg        return NULL;
13305b261ecSmrg    }
134f7df2e56Smrg
135f7df2e56Smrg    pInt = (xf86Int10InfoPtr) xnfcalloc(1, sizeof(xf86Int10InfoRec));
13605b261ecSmrg    pInt->entityIndex = entityIndex;
13705b261ecSmrg    if (!xf86Int10ExecSetup(pInt))
138f7df2e56Smrg        goto error0;
13905b261ecSmrg    pInt->mem = &genericMem;
140f7df2e56Smrg    pInt->private = (void *) xnfcalloc(1, sizeof(genericInt10Priv));
141f7df2e56Smrg    INTPriv(pInt)->alloc = (void *) xnfcalloc(1, ALLOC_ENTRIES(getpagesize()));
142f7df2e56Smrg    pInt->pScrn = pScrn;
14305b261ecSmrg    base = INTPriv(pInt)->base = xnfalloc(SYS_BIOS);
14405b261ecSmrg
1454642e01fSmrg    /* FIXME: Shouldn't this be a failure case?  Leaving dev as NULL seems like
1464642e01fSmrg     * FIXME: an error
1474642e01fSmrg     */
1486dfbdd3dSsnj    pInt->dev = xf86GetPciInfoForEntity(entityIndex);
14905b261ecSmrg
15005b261ecSmrg    /*
15105b261ecSmrg     * we need to map video RAM MMIO as some chipsets map mmio
15205b261ecSmrg     * registers into this range.
15305b261ecSmrg     */
15405b261ecSmrg    MapVRam(pInt);
15505b261ecSmrg#ifdef _PC
15605b261ecSmrg    if (!sysMem)
157f7df2e56Smrg        pci_device_map_legacy(pInt->dev, V_BIOS, BIOS_SIZE + SYS_BIOS - V_BIOS,
158f7df2e56Smrg                              PCI_DEV_MAP_FLAG_WRITABLE, &sysMem);
15905b261ecSmrg    INTPriv(pInt)->sysMem = sysMem;
16005b261ecSmrg
161f7df2e56Smrg    if (!readIntVec(pInt->dev, base, LOW_PAGE_SIZE)) {
162f7df2e56Smrg        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Cannot read int vect\n");
163f7df2e56Smrg        goto error1;
16405b261ecSmrg    }
16505b261ecSmrg
16605b261ecSmrg    /*
16705b261ecSmrg     * Retrieve everything between V_BIOS and SYS_BIOS as some system BIOSes
168f7df2e56Smrg     * have executable code there.
16905b261ecSmrg     */
170f7df2e56Smrg    memset((char *) base + V_BIOS, 0, SYS_BIOS - V_BIOS);
17105b261ecSmrg    INTPriv(pInt)->highMemory = V_BIOS;
172f7df2e56Smrg
17305b261ecSmrg    if (xf86IsEntityPrimary(entityIndex) && !(initPrimary(options))) {
174f7df2e56Smrg        if (!xf86int10GetBiosSegment(pInt, (unsigned char *) sysMem - V_BIOS))
175f7df2e56Smrg            goto error1;
17605b261ecSmrg
177f7df2e56Smrg        set_return_trap(pInt);
17805b261ecSmrg
179f7df2e56Smrg        pInt->Flags = Flags & (SET_BIOS_SCRATCH | RESTORE_BIOS_SCRATCH);
180f7df2e56Smrg        if (!(pInt->Flags & SET_BIOS_SCRATCH))
181f7df2e56Smrg            pInt->Flags &= ~RESTORE_BIOS_SCRATCH;
182f7df2e56Smrg        xf86Int10SaveRestoreBIOSVars(pInt, TRUE);
183f7df2e56Smrg
184f7df2e56Smrg    }
185f7df2e56Smrg    else {
186f7df2e56Smrg        const BusType location_type = xf86int10GetBiosLocationType(pInt);
187f7df2e56Smrg        int bios_location = V_BIOS;
18805b261ecSmrg
18905b261ecSmrg        reset_int_vect(pInt);
190f7df2e56Smrg        set_return_trap(pInt);
191f7df2e56Smrg
192f7df2e56Smrg        switch (location_type) {
193f7df2e56Smrg        case BUS_PCI:{
194f7df2e56Smrg            int err;
195f7df2e56Smrg            struct pci_device *rom_device =
196f7df2e56Smrg                xf86GetPciInfoForEntity(pInt->entityIndex);
197f7df2e56Smrg
198f7df2e56Smrg            vbiosMem = (unsigned char *) base + bios_location;
199f7df2e56Smrg            err = pci_device_read_rom(rom_device, vbiosMem);
200f7df2e56Smrg            if (err) {
201f7df2e56Smrg                xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Cannot read V_BIOS (3) %s\n",
202f7df2e56Smrg                           strerror(err));
203f7df2e56Smrg                goto error1;
204f7df2e56Smrg            }
205f7df2e56Smrg            INTPriv(pInt)->highMemory = GET_HIGH_BASE(rom_device->rom_size);
206f7df2e56Smrg            break;
207f7df2e56Smrg        }
208f7df2e56Smrg        default:
209f7df2e56Smrg            goto error1;
210f7df2e56Smrg        }
211f7df2e56Smrg        pInt->BIOSseg = V_BIOS >> 4;
212f7df2e56Smrg        pInt->num = 0xe6;
213f7df2e56Smrg        LockLegacyVGA(pInt, &vga);
214f7df2e56Smrg        xf86ExecX86int10(pInt);
215f7df2e56Smrg        UnlockLegacyVGA(pInt, &vga);
21605b261ecSmrg    }
21705b261ecSmrg#else
21805b261ecSmrg    if (!sysMem) {
219f7df2e56Smrg        sysMem = xnfalloc(BIOS_SIZE);
220f7df2e56Smrg        setup_system_bios(sysMem);
22105b261ecSmrg    }
22205b261ecSmrg    INTPriv(pInt)->sysMem = sysMem;
22305b261ecSmrg    setup_int_vect(pInt);
22405b261ecSmrg    set_return_trap(pInt);
22505b261ecSmrg
2265a112b11Smrg    /* Retrieve the entire legacy video BIOS segment.  This can be up to
2274642e01fSmrg     * 128KiB.
22805b261ecSmrg     */
229f7df2e56Smrg    vbiosMem = (char *) base + V_BIOS;
2304642e01fSmrg    memset(vbiosMem, 0, 2 * V_BIOS_SIZE);
231f7df2e56Smrg    if (pci_device_read_rom(pInt->dev, vbiosMem) != 0
232f7df2e56Smrg        || pInt->dev->rom_size < V_BIOS_SIZE) {
233f7df2e56Smrg        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
234f7df2e56Smrg                   "Unable to retrieve all of segment 0x0C0000.\n");
2354642e01fSmrg    }
23605b261ecSmrg
23705b261ecSmrg    /*
23805b261ecSmrg     * If this adapter is the primary, use its post-init BIOS (if we can find
23905b261ecSmrg     * it).
24005b261ecSmrg     */
24105b261ecSmrg    {
242f7df2e56Smrg        int bios_location = V_BIOS;
243f7df2e56Smrg        Bool done = FALSE;
244f7df2e56Smrg
245f7df2e56Smrg        vbiosMem = (unsigned char *) base + bios_location;
246f7df2e56Smrg
247f7df2e56Smrg        if (xf86IsEntityPrimary(entityIndex)) {
248f7df2e56Smrg            if (int10_check_bios(pScrn->scrnIndex, bios_location >> 4, vbiosMem))
249f7df2e56Smrg                done = TRUE;
250f7df2e56Smrg            else
251f7df2e56Smrg                xf86DrvMsg(pScrn->scrnIndex, X_INFO,
252f7df2e56Smrg                           "No legacy BIOS found -- trying PCI\n");
253f7df2e56Smrg        }
254f7df2e56Smrg        if (!done) {
255f7df2e56Smrg            int err;
256f7df2e56Smrg            struct pci_device *rom_device =
257f7df2e56Smrg                xf86GetPciInfoForEntity(pInt->entityIndex);
258f7df2e56Smrg
259f7df2e56Smrg            err = pci_device_read_rom(rom_device, vbiosMem);
260f7df2e56Smrg            if (err) {
261f7df2e56Smrg                xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Cannot read V_BIOS (5) %s\n",
262f7df2e56Smrg                           strerror(err));
263f7df2e56Smrg                goto error1;
264f7df2e56Smrg            }
265f7df2e56Smrg        }
26605b261ecSmrg    }
26705b261ecSmrg
26805b261ecSmrg    pInt->BIOSseg = V_BIOS >> 4;
26905b261ecSmrg    pInt->num = 0xe6;
27005b261ecSmrg    LockLegacyVGA(pInt, &vga);
27105b261ecSmrg    xf86ExecX86int10(pInt);
27205b261ecSmrg    UnlockLegacyVGA(pInt, &vga);
27305b261ecSmrg#endif
2746747b715Smrg    free(options);
27505b261ecSmrg    return pInt;
27605b261ecSmrg
27705b261ecSmrg error1:
2786747b715Smrg    free(base);
27905b261ecSmrg    UnmapVRam(pInt);
2806747b715Smrg    free(INTPriv(pInt)->alloc);
2816747b715Smrg    free(pInt->private);
28205b261ecSmrg error0:
2836747b715Smrg    free(pInt);
2846747b715Smrg    free(options);
285f7df2e56Smrg
28605b261ecSmrg    return NULL;
28705b261ecSmrg}
28805b261ecSmrg
28905b261ecSmrgstatic void
29005b261ecSmrgMapVRam(xf86Int10InfoPtr pInt)
29105b261ecSmrg{
29205b261ecSmrg    int pagesize = getpagesize();
29305b261ecSmrg    int size = ((VRAM_SIZE + pagesize - 1) / pagesize) * pagesize;
29405b261ecSmrg
295f7df2e56Smrg    pci_device_map_legacy(pInt->dev, V_RAM, size, PCI_DEV_MAP_FLAG_WRITABLE,
296f7df2e56Smrg                          &(INTPriv(pInt)->vRam));
297f7df2e56Smrg    pInt->io = pci_legacy_open_io(pInt->dev, 0, 64 * 1024);
29805b261ecSmrg}
29905b261ecSmrg
30005b261ecSmrgstatic void
30105b261ecSmrgUnmapVRam(xf86Int10InfoPtr pInt)
30205b261ecSmrg{
30305b261ecSmrg    int pagesize = getpagesize();
304f7df2e56Smrg    int size = ((VRAM_SIZE + pagesize - 1) / pagesize) * pagesize;
30505b261ecSmrg
306f7df2e56Smrg    pci_device_unmap_legacy(pInt->dev, INTPriv(pInt)->vRam, size);
307f7df2e56Smrg    pci_device_close_io(pInt->dev, pInt->io);
308f7df2e56Smrg    pInt->io = NULL;
30905b261ecSmrg}
31005b261ecSmrg
31105b261ecSmrgBool
31205b261ecSmrgMapCurrentInt10(xf86Int10InfoPtr pInt)
31305b261ecSmrg{
31405b261ecSmrg    /* nothing to do here */
31505b261ecSmrg    return TRUE;
31605b261ecSmrg}
31705b261ecSmrg
31805b261ecSmrgvoid
31905b261ecSmrgxf86FreeInt10(xf86Int10InfoPtr pInt)
32005b261ecSmrg{
32105b261ecSmrg    if (!pInt)
322f7df2e56Smrg        return;
32305b261ecSmrg#if defined (_PC)
32405b261ecSmrg    xf86Int10SaveRestoreBIOSVars(pInt, FALSE);
32505b261ecSmrg#endif
32605b261ecSmrg    if (Int10Current == pInt)
327f7df2e56Smrg        Int10Current = NULL;
3286747b715Smrg    free(INTPriv(pInt)->base);
32905b261ecSmrg    UnmapVRam(pInt);
3306747b715Smrg    free(INTPriv(pInt)->alloc);
3316747b715Smrg    free(pInt->private);
3326747b715Smrg    free(pInt);
33305b261ecSmrg}
33405b261ecSmrg
33505b261ecSmrgvoid *
33605b261ecSmrgxf86Int10AllocPages(xf86Int10InfoPtr pInt, int num, int *off)
33705b261ecSmrg{
33805b261ecSmrg    int pagesize = getpagesize();
33905b261ecSmrg    int num_pages = ALLOC_ENTRIES(pagesize);
340f7df2e56Smrg    int i, j;
34105b261ecSmrg
34205b261ecSmrg    for (i = 0; i < (num_pages - num); i++) {
343f7df2e56Smrg        if (INTPriv(pInt)->alloc[i] == 0) {
344f7df2e56Smrg            for (j = i; j < (num + i); j++)
345f7df2e56Smrg                if (INTPriv(pInt)->alloc[j] != 0)
346f7df2e56Smrg                    break;
347f7df2e56Smrg            if (j == (num + i))
348f7df2e56Smrg                break;
349f7df2e56Smrg            i += num;
350f7df2e56Smrg        }
35105b261ecSmrg    }
35205b261ecSmrg    if (i == (num_pages - num))
353f7df2e56Smrg        return NULL;
35405b261ecSmrg
35505b261ecSmrg    for (j = i; j < (i + num); j++)
356f7df2e56Smrg        INTPriv(pInt)->alloc[j] = 1;
35705b261ecSmrg
35805b261ecSmrg    *off = (i + 1) * pagesize;
35905b261ecSmrg
360f7df2e56Smrg    return (char *) INTPriv(pInt)->base + *off;
36105b261ecSmrg}
36205b261ecSmrg
36305b261ecSmrgvoid
36405b261ecSmrgxf86Int10FreePages(xf86Int10InfoPtr pInt, void *pbase, int num)
36505b261ecSmrg{
36605b261ecSmrg    int pagesize = getpagesize();
367f7df2e56Smrg    int first =
368f7df2e56Smrg        (((char *) pbase - (char *) INTPriv(pInt)->base) / pagesize) - 1;
36905b261ecSmrg    int i;
37005b261ecSmrg
37105b261ecSmrg    for (i = first; i < (first + num); i++)
372f7df2e56Smrg        INTPriv(pInt)->alloc[i] = 0;
37305b261ecSmrg}
37405b261ecSmrg
37505b261ecSmrg#define OFF(addr) ((addr) & 0xffff)
37605b261ecSmrg#if defined _PC
377f7df2e56Smrg#define HIGH_OFFSET (INTPriv(pInt)->highMemory)
378f7df2e56Smrg#define HIGH_BASE   V_BIOS
37905b261ecSmrg#else
380f7df2e56Smrg#define HIGH_OFFSET SYS_BIOS
381f7df2e56Smrg#define HIGH_BASE   SYS_BIOS
38205b261ecSmrg#endif
383f7df2e56Smrg#define SYS(addr) ((addr) >= HIGH_OFFSET)
38405b261ecSmrg#define V_ADDR(addr) \
38505b261ecSmrg	  (SYS(addr) ? ((char*)INTPriv(pInt)->sysMem) + (addr - HIGH_BASE) \
38605b261ecSmrg	   : (((char*)(INTPriv(pInt)->base) + addr)))
38705b261ecSmrg#define VRAM_ADDR(addr) (addr - V_RAM)
38805b261ecSmrg#define VRAM_BASE (INTPriv(pInt)->vRam)
38905b261ecSmrg
39005b261ecSmrg#define VRAM(addr) ((addr >= V_RAM) && (addr < (V_RAM + VRAM_SIZE)))
39105b261ecSmrg#define V_ADDR_RB(addr) \
3925a112b11Smrg	((VRAM(addr)) ? MMIO_IN8((uint8_t*)VRAM_BASE,VRAM_ADDR(addr)) \
3935a112b11Smrg	   : *(uint8_t*) V_ADDR(addr))
39405b261ecSmrg#define V_ADDR_RW(addr) \
3955a112b11Smrg	((VRAM(addr)) ? MMIO_IN16((uint16_t*)VRAM_BASE,VRAM_ADDR(addr)) \
3965a112b11Smrg	   : ldw_u((void *)V_ADDR(addr)))
39705b261ecSmrg#define V_ADDR_RL(addr) \
3985a112b11Smrg	((VRAM(addr)) ? MMIO_IN32((uint32_t*)VRAM_BASE,VRAM_ADDR(addr)) \
3995a112b11Smrg	   : ldl_u((void *)V_ADDR(addr)))
40005b261ecSmrg
40105b261ecSmrg#define V_ADDR_WB(addr,val) \
40205b261ecSmrg	if(VRAM(addr)) \
403f7df2e56Smrg	    MMIO_OUT8((uint8_t*)VRAM_BASE,VRAM_ADDR(addr),val); \
40405b261ecSmrg	else \
405f7df2e56Smrg	    *(uint8_t*) V_ADDR(addr) = val;
40605b261ecSmrg#define V_ADDR_WW(addr,val) \
40705b261ecSmrg	if(VRAM(addr)) \
408f7df2e56Smrg	    MMIO_OUT16((uint16_t*)VRAM_BASE,VRAM_ADDR(addr),val); \
40905b261ecSmrg	else \
410f7df2e56Smrg	    stw_u((val),(void *)(V_ADDR(addr)));
41105b261ecSmrg
41205b261ecSmrg#define V_ADDR_WL(addr,val) \
41305b261ecSmrg	if (VRAM(addr)) \
414f7df2e56Smrg	    MMIO_OUT32((uint32_t*)VRAM_BASE,VRAM_ADDR(addr),val); \
41505b261ecSmrg	else \
416f7df2e56Smrg	    stl_u(val,(void *)(V_ADDR(addr)));
41705b261ecSmrg
418f7df2e56Smrgstatic uint8_t
41905b261ecSmrgread_b(xf86Int10InfoPtr pInt, int addr)
42005b261ecSmrg{
42105b261ecSmrg    return V_ADDR_RB(addr);
42205b261ecSmrg}
42305b261ecSmrg
424f7df2e56Smrgstatic uint16_t
42505b261ecSmrgread_w(xf86Int10InfoPtr pInt, int addr)
42605b261ecSmrg{
42705b261ecSmrg#if X_BYTE_ORDER == X_LITTLE_ENDIAN
42805b261ecSmrg    if (OFF(addr + 1) > 0)
429f7df2e56Smrg        return V_ADDR_RW(addr);
43005b261ecSmrg#endif
43105b261ecSmrg    return V_ADDR_RB(addr) | (V_ADDR_RB(addr + 1) << 8);
43205b261ecSmrg}
43305b261ecSmrg
434f7df2e56Smrgstatic uint32_t
43505b261ecSmrgread_l(xf86Int10InfoPtr pInt, int addr)
43605b261ecSmrg{
43705b261ecSmrg#if X_BYTE_ORDER == X_LITTLE_ENDIAN
43805b261ecSmrg    if (OFF(addr + 3) > 2)
439f7df2e56Smrg        return V_ADDR_RL(addr);
44005b261ecSmrg#endif
44105b261ecSmrg    return V_ADDR_RB(addr) |
442f7df2e56Smrg        (V_ADDR_RB(addr + 1) << 8) |
443f7df2e56Smrg        (V_ADDR_RB(addr + 2) << 16) | (V_ADDR_RB(addr + 3) << 24);
44405b261ecSmrg}
44505b261ecSmrg
44605b261ecSmrgstatic void
447f7df2e56Smrgwrite_b(xf86Int10InfoPtr pInt, int addr, uint8_t val)
44805b261ecSmrg{
449f7df2e56Smrg    V_ADDR_WB(addr, val);
45005b261ecSmrg}
45105b261ecSmrg
45205b261ecSmrgstatic void
45305b261ecSmrgwrite_w(xf86Int10InfoPtr pInt, int addr, CARD16 val)
45405b261ecSmrg{
45505b261ecSmrg#if X_BYTE_ORDER == X_LITTLE_ENDIAN
456f7df2e56Smrg    if (OFF(addr + 1) > 0) {
457f7df2e56Smrg        V_ADDR_WW(addr, val);
458f7df2e56Smrg    }
45905b261ecSmrg#endif
46005b261ecSmrg    V_ADDR_WB(addr, val);
46105b261ecSmrg    V_ADDR_WB(addr + 1, val >> 8);
46205b261ecSmrg}
46305b261ecSmrg
46405b261ecSmrgstatic void
465f7df2e56Smrgwrite_l(xf86Int10InfoPtr pInt, int addr, uint32_t val)
46605b261ecSmrg{
46705b261ecSmrg#if X_BYTE_ORDER == X_LITTLE_ENDIAN
468f7df2e56Smrg    if (OFF(addr + 3) > 2) {
469f7df2e56Smrg        V_ADDR_WL(addr, val);
470f7df2e56Smrg    }
47105b261ecSmrg#endif
47205b261ecSmrg    V_ADDR_WB(addr, val);
47305b261ecSmrg    V_ADDR_WB(addr + 1, val >> 8);
47405b261ecSmrg    V_ADDR_WB(addr + 2, val >> 16);
47505b261ecSmrg    V_ADDR_WB(addr + 3, val >> 24);
47605b261ecSmrg}
47705b261ecSmrg
478f7df2e56Smrgvoid *
479f7df2e56Smrgxf86int10Addr(xf86Int10InfoPtr pInt, uint32_t addr)
48005b261ecSmrg{
48105b261ecSmrg    return V_ADDR(addr);
48205b261ecSmrg}
483