563 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			563 lines
		
	
	
		
			14 KiB
		
	
	
	
		
			C
		
	
	
	
/*
 | 
						|
 * linux specific part of the int10 module
 | 
						|
 * Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2008 Egbert Eich
 | 
						|
 */
 | 
						|
#ifdef HAVE_XORG_CONFIG_H
 | 
						|
#include <xorg-config.h>
 | 
						|
#endif
 | 
						|
 | 
						|
#include "xf86.h"
 | 
						|
#include "xf86_OSproc.h"
 | 
						|
#include "xf86Pci.h"
 | 
						|
#include "compiler.h"
 | 
						|
#define _INT10_PRIVATE
 | 
						|
#include "xf86int10.h"
 | 
						|
#ifdef __sparc__
 | 
						|
#define DEV_MEM "/dev/fb"
 | 
						|
#else
 | 
						|
#define DEV_MEM "/dev/mem"
 | 
						|
#endif
 | 
						|
#define ALLOC_ENTRIES(x) ((V_RAM / x) - 1)
 | 
						|
#define SHMERRORPTR (pointer)(-1)
 | 
						|
 | 
						|
#include <fcntl.h>
 | 
						|
#include <errno.h>
 | 
						|
#include <sys/mman.h>
 | 
						|
#include <sys/ipc.h>
 | 
						|
#include <sys/shm.h>
 | 
						|
#include <unistd.h>
 | 
						|
#include <string.h>
 | 
						|
 | 
						|
static int counter = 0;
 | 
						|
static unsigned long int10Generation = 0;
 | 
						|
 | 
						|
static CARD8 read_b(xf86Int10InfoPtr pInt, int addr);
 | 
						|
static CARD16 read_w(xf86Int10InfoPtr pInt, int addr);
 | 
						|
static CARD32 read_l(xf86Int10InfoPtr pInt, int addr);
 | 
						|
static void write_b(xf86Int10InfoPtr pInt, int addr, CARD8 val);
 | 
						|
static void write_w(xf86Int10InfoPtr pInt, int addr, CARD16 val);
 | 
						|
static void write_l(xf86Int10InfoPtr pInt, int addr, CARD32 val);
 | 
						|
 | 
						|
int10MemRec linuxMem = {
 | 
						|
    read_b,
 | 
						|
    read_w,
 | 
						|
    read_l,
 | 
						|
    write_b,
 | 
						|
    write_w,
 | 
						|
    write_l
 | 
						|
};
 | 
						|
 | 
						|
typedef struct {
 | 
						|
    int lowMem;
 | 
						|
    int highMem;
 | 
						|
    char* base;
 | 
						|
    char* base_high;
 | 
						|
    int screen;
 | 
						|
    char* alloc;
 | 
						|
} linuxInt10Priv;
 | 
						|
 | 
						|
#if defined DoSubModules
 | 
						|
 | 
						|
typedef enum {
 | 
						|
    INT10_NOT_LOADED,
 | 
						|
    INT10_LOADED_VM86,
 | 
						|
    INT10_LOADED_X86EMU,
 | 
						|
    INT10_LOAD_FAILED
 | 
						|
} Int10LinuxSubModuleState;
 | 
						|
 | 
						|
static Int10LinuxSubModuleState loadedSubModule = INT10_NOT_LOADED;
 | 
						|
 | 
						|
static Int10LinuxSubModuleState int10LinuxLoadSubModule(ScrnInfoPtr pScrn);
 | 
						|
 | 
						|
#endif /* DoSubModules */
 | 
						|
 | 
						|
xf86Int10InfoPtr
 | 
						|
xf86ExtendedInitInt10(int entityIndex, int Flags)
 | 
						|
{
 | 
						|
    xf86Int10InfoPtr pInt = NULL;
 | 
						|
    int screen;
 | 
						|
    int fd;
 | 
						|
    static void* vidMem = NULL;
 | 
						|
    static void* sysMem = NULL;
 | 
						|
    void* vMem = NULL;
 | 
						|
    void *options = NULL;
 | 
						|
    int low_mem;
 | 
						|
    int high_mem = -1;
 | 
						|
    char *base = SHMERRORPTR;
 | 
						|
    char *base_high = SHMERRORPTR;
 | 
						|
    int pagesize; 
 | 
						|
    memType cs;
 | 
						|
    legacyVGARec vga;
 | 
						|
    Bool videoBiosMapped = FALSE;
 | 
						|
    
 | 
						|
    if (int10Generation != serverGeneration) {
 | 
						|
	counter = 0;
 | 
						|
	int10Generation = serverGeneration;
 | 
						|
    }
 | 
						|
 | 
						|
    screen = (xf86FindScreenForEntity(entityIndex))->scrnIndex;
 | 
						|
 | 
						|
    options = xf86HandleInt10Options(xf86Screens[screen],entityIndex);
 | 
						|
 | 
						|
    if (int10skip(options)) {
 | 
						|
	xfree(options);
 | 
						|
	return NULL;
 | 
						|
    }
 | 
						|
 | 
						|
#if defined DoSubModules
 | 
						|
    if (loadedSubModule == INT10_NOT_LOADED) 
 | 
						|
	loadedSubModule = int10LinuxLoadSubModule(xf86Screens[screen]);
 | 
						|
 | 
						|
    if (loadedSubModule == INT10_LOAD_FAILED)
 | 
						|
	return NULL;
 | 
						|
#endif
 | 
						|
 | 
						|
    if ((!vidMem) || (!sysMem)) {
 | 
						|
	if ((fd = open(DEV_MEM, O_RDWR, 0)) >= 0) {
 | 
						|
	    if (!sysMem) {
 | 
						|
#ifdef DEBUG
 | 
						|
		ErrorF("Mapping sys bios area\n");
 | 
						|
#endif
 | 
						|
		if ((sysMem = mmap((void *)(SYS_BIOS), BIOS_SIZE,
 | 
						|
				   PROT_READ | PROT_EXEC,
 | 
						|
				   MAP_SHARED | MAP_FIXED, fd, SYS_BIOS))
 | 
						|
		    == MAP_FAILED) {
 | 
						|
		    xf86DrvMsg(screen, X_ERROR, "Cannot map SYS BIOS\n");
 | 
						|
		    close(fd);
 | 
						|
		    goto error0;
 | 
						|
		}
 | 
						|
	    }
 | 
						|
	    if (!vidMem) {
 | 
						|
#ifdef DEBUG
 | 
						|
		ErrorF("Mapping VRAM area\n");
 | 
						|
#endif
 | 
						|
		if ((vidMem = mmap((void *)(V_RAM), VRAM_SIZE,
 | 
						|
				   PROT_READ | PROT_WRITE | PROT_EXEC,
 | 
						|
				   MAP_SHARED | MAP_FIXED, fd, V_RAM))
 | 
						|
		    == MAP_FAILED) {
 | 
						|
		    xf86DrvMsg(screen, X_ERROR, "Cannot map V_RAM\n");
 | 
						|
		    close(fd);
 | 
						|
		    goto error0;
 | 
						|
		}
 | 
						|
	    }
 | 
						|
	    close(fd);
 | 
						|
	} else {
 | 
						|
	    xf86DrvMsg(screen, X_ERROR, "Cannot open %s\n", DEV_MEM);
 | 
						|
	    goto error0;
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
    pInt = (xf86Int10InfoPtr)xnfcalloc(1, sizeof(xf86Int10InfoRec));
 | 
						|
    pInt->scrnIndex = screen;
 | 
						|
    pInt->entityIndex = entityIndex;
 | 
						|
    pInt->dev = xf86GetPciInfoForEntity(entityIndex);
 | 
						|
 | 
						|
    if (!xf86Int10ExecSetup(pInt))
 | 
						|
	goto error0;
 | 
						|
    pInt->mem = &linuxMem;
 | 
						|
    pagesize = getpagesize();
 | 
						|
    pInt->private = (pointer)xnfcalloc(1, sizeof(linuxInt10Priv));
 | 
						|
    ((linuxInt10Priv*)pInt->private)->screen = screen;
 | 
						|
    ((linuxInt10Priv*)pInt->private)->alloc =
 | 
						|
	(pointer)xnfcalloc(1, ALLOC_ENTRIES(pagesize));
 | 
						|
 | 
						|
    if (!xf86IsEntityPrimary(entityIndex)) {
 | 
						|
#ifdef DEBUG
 | 
						|
	ErrorF("Mapping high memory area\n");
 | 
						|
#endif
 | 
						|
	if ((high_mem = shmget(counter++, HIGH_MEM_SIZE,
 | 
						|
			       IPC_CREAT | SHM_R | SHM_W)) == -1) {
 | 
						|
	    if (errno == ENOSYS)
 | 
						|
		xf86DrvMsg(screen, X_ERROR, "shmget error\n Please reconfigure"
 | 
						|
			   " your kernel to include System V IPC support\n");
 | 
						|
	    else
 | 
						|
		xf86DrvMsg(screen, X_ERROR,
 | 
						|
			   "shmget(highmem) error: %s\n",strerror(errno));
 | 
						|
	    goto error1;
 | 
						|
	}
 | 
						|
    } else {
 | 
						|
#ifdef DEBUG
 | 
						|
	ErrorF("Mapping Video BIOS\n");
 | 
						|
#endif
 | 
						|
	videoBiosMapped = TRUE;
 | 
						|
	if ((fd = open(DEV_MEM, O_RDWR, 0)) >= 0) {
 | 
						|
	    if ((vMem = mmap((void *)(V_BIOS), SYS_BIOS - V_BIOS,
 | 
						|
			     PROT_READ | PROT_WRITE | PROT_EXEC,
 | 
						|
			     MAP_SHARED | MAP_FIXED, fd, V_BIOS))
 | 
						|
		== MAP_FAILED) {
 | 
						|
		xf86DrvMsg(screen, X_ERROR, "Cannot map V_BIOS\n");
 | 
						|
		close(fd);
 | 
						|
		goto error1;
 | 
						|
	    }
 | 
						|
	    close (fd);
 | 
						|
	} else
 | 
						|
	    goto error1;
 | 
						|
    }
 | 
						|
    ((linuxInt10Priv*)pInt->private)->highMem = high_mem;
 | 
						|
    
 | 
						|
#ifdef DEBUG
 | 
						|
    ErrorF("Mapping 640kB area\n");
 | 
						|
#endif
 | 
						|
    if ((low_mem = shmget(counter++, V_RAM,
 | 
						|
			  IPC_CREAT | SHM_R | SHM_W)) == -1) {
 | 
						|
	xf86DrvMsg(screen, X_ERROR,
 | 
						|
		   "shmget(lowmem) error: %s\n",strerror(errno));
 | 
						|
	goto error2;
 | 
						|
    }
 | 
						|
 | 
						|
    ((linuxInt10Priv*)pInt->private)->lowMem = low_mem;
 | 
						|
    base = shmat(low_mem, 0, 0);
 | 
						|
    if (base == SHMERRORPTR) {
 | 
						|
	xf86DrvMsg(screen, X_ERROR,
 | 
						|
		   "shmat(low_mem) error: %s\n",strerror(errno));
 | 
						|
	goto error3;
 | 
						|
    }
 | 
						|
    ((linuxInt10Priv *)pInt->private)->base = base;
 | 
						|
    if (high_mem > -1) {
 | 
						|
	base_high = shmat(high_mem, 0, 0);
 | 
						|
	if (base_high == SHMERRORPTR) {
 | 
						|
	    xf86DrvMsg(screen, X_ERROR,
 | 
						|
		       "shmat(high_mem) error: %s\n",strerror(errno));
 | 
						|
	    goto error3;
 | 
						|
	}
 | 
						|
	((linuxInt10Priv*)pInt->private)->base_high = base_high;
 | 
						|
    } else
 | 
						|
	((linuxInt10Priv*)pInt->private)->base_high = NULL;
 | 
						|
 | 
						|
    if (!MapCurrentInt10(pInt))
 | 
						|
	goto error3;
 | 
						|
    
 | 
						|
    Int10Current = pInt;
 | 
						|
 | 
						|
#ifdef DEBUG
 | 
						|
    ErrorF("Mapping int area\n");
 | 
						|
#endif
 | 
						|
    if (xf86ReadBIOS(0, 0, (unsigned char *)0, LOW_PAGE_SIZE) < 0) {
 | 
						|
	xf86DrvMsg(screen, X_ERROR, "Cannot read int vect\n");
 | 
						|
	goto error3;
 | 
						|
    }
 | 
						|
#ifdef DEBUG
 | 
						|
    ErrorF("done\n");
 | 
						|
#endif
 | 
						|
    /*
 | 
						|
     * Read in everything between V_BIOS and SYS_BIOS as some system BIOSes
 | 
						|
     * have executable code there.  Note that xf86ReadBIOS() can only bring in
 | 
						|
     * 64K bytes at a time.
 | 
						|
     */
 | 
						|
    if (!videoBiosMapped) {
 | 
						|
	memset((pointer)V_BIOS, 0, SYS_BIOS - V_BIOS);
 | 
						|
#ifdef DEBUG
 | 
						|
	ErrorF("Reading BIOS\n");
 | 
						|
#endif
 | 
						|
	for (cs = V_BIOS;  cs < SYS_BIOS;  cs += V_BIOS_SIZE)
 | 
						|
	    if (xf86ReadBIOS(cs, 0, (pointer)cs, V_BIOS_SIZE) < V_BIOS_SIZE)
 | 
						|
		xf86DrvMsg(screen, X_WARNING,
 | 
						|
			   "Unable to retrieve all of segment 0x%06lX.\n",
 | 
						|
			   (long)cs);
 | 
						|
#ifdef DEBUG
 | 
						|
	ErrorF("done\n");
 | 
						|
#endif
 | 
						|
    }
 | 
						|
 | 
						|
    if (xf86IsEntityPrimary(entityIndex) && !(initPrimary(options))) {
 | 
						|
	if (!xf86int10GetBiosSegment(pInt, NULL))
 | 
						|
	    goto error3;
 | 
						|
 | 
						|
	set_return_trap(pInt);
 | 
						|
#ifdef _PC	
 | 
						|
	pInt->Flags = Flags & (SET_BIOS_SCRATCH | RESTORE_BIOS_SCRATCH);
 | 
						|
	if (! (pInt->Flags & SET_BIOS_SCRATCH))
 | 
						|
	    pInt->Flags &= ~RESTORE_BIOS_SCRATCH;
 | 
						|
  	xf86Int10SaveRestoreBIOSVars(pInt, TRUE);
 | 
						|
#endif
 | 
						|
    } else {
 | 
						|
	const BusType location_type = xf86int10GetBiosLocationType(pInt);
 | 
						|
 | 
						|
	switch (location_type) {
 | 
						|
	case BUS_PCI: {
 | 
						|
	    int err;
 | 
						|
	    struct pci_device *rom_device =
 | 
						|
		xf86GetPciInfoForEntity(pInt->entityIndex);
 | 
						|
 | 
						|
#if HAVE_PCI_DEVICE_ENABLE
 | 
						|
	    pci_device_enable(rom_device);
 | 
						|
#endif
 | 
						|
 | 
						|
	    err = pci_device_read_rom(rom_device, (unsigned char *)(V_BIOS));
 | 
						|
	    if (err) {
 | 
						|
		xf86DrvMsg(screen,X_ERROR,"Cannot read V_BIOS (%s)\n",
 | 
						|
			   strerror(err));
 | 
						|
		goto error3;
 | 
						|
	    }
 | 
						|
 | 
						|
	    pInt->BIOSseg = V_BIOS >> 4;
 | 
						|
	    break;
 | 
						|
	}
 | 
						|
	default:
 | 
						|
	    goto error3;
 | 
						|
	}
 | 
						|
 | 
						|
	pInt->num = 0xe6;
 | 
						|
	reset_int_vect(pInt);
 | 
						|
	set_return_trap(pInt);
 | 
						|
	LockLegacyVGA(pInt, &vga);
 | 
						|
	xf86ExecX86int10(pInt);
 | 
						|
	UnlockLegacyVGA(pInt, &vga);
 | 
						|
    }
 | 
						|
#ifdef DEBUG
 | 
						|
    dprint(0xc0000, 0x20);
 | 
						|
#endif
 | 
						|
 | 
						|
    xfree(options);
 | 
						|
    return pInt;
 | 
						|
 | 
						|
error3:
 | 
						|
    if (base_high)
 | 
						|
	shmdt(base_high);
 | 
						|
    shmdt(base);
 | 
						|
    shmdt(0);
 | 
						|
    if (base_high)
 | 
						|
	shmdt((char*)HIGH_MEM);
 | 
						|
    shmctl(low_mem, IPC_RMID, NULL);
 | 
						|
    Int10Current = NULL;
 | 
						|
error2:
 | 
						|
    if (high_mem > -1)
 | 
						|
	shmctl(high_mem, IPC_RMID,NULL);
 | 
						|
error1:
 | 
						|
    if (vMem)
 | 
						|
	munmap(vMem, SYS_BIOS - V_BIOS);
 | 
						|
    xfree(((linuxInt10Priv*)pInt->private)->alloc);
 | 
						|
    xfree(pInt->private);
 | 
						|
error0:
 | 
						|
    xfree(options);
 | 
						|
    xfree(pInt);
 | 
						|
    return NULL;
 | 
						|
}
 | 
						|
 | 
						|
Bool
 | 
						|
MapCurrentInt10(xf86Int10InfoPtr pInt)
 | 
						|
{
 | 
						|
    pointer addr;
 | 
						|
    int fd = -1;
 | 
						|
    
 | 
						|
    if (Int10Current) {
 | 
						|
	shmdt(0);
 | 
						|
	if (((linuxInt10Priv*)Int10Current->private)->highMem >= 0)
 | 
						|
	    shmdt((char*)HIGH_MEM);
 | 
						|
	else
 | 
						|
	    munmap((pointer)V_BIOS, (SYS_BIOS - V_BIOS));
 | 
						|
    }
 | 
						|
    addr = shmat(((linuxInt10Priv*)pInt->private)->lowMem, (char*)1, SHM_RND);
 | 
						|
    if (addr == SHMERRORPTR) {
 | 
						|
	xf86DrvMsg(pInt->scrnIndex, X_ERROR, "Cannot shmat() low memory\n");
 | 
						|
	xf86DrvMsg(pInt->scrnIndex, X_ERROR,
 | 
						|
		   "shmat(low_mem) error: %s\n",strerror(errno));
 | 
						|
	return FALSE;
 | 
						|
    }
 | 
						|
    if (mprotect((void*)0, V_RAM, PROT_READ|PROT_WRITE|PROT_EXEC) != 0)
 | 
						|
        xf86DrvMsg(pInt->scrnIndex, X_ERROR,
 | 
						|
		   "Cannot set EXEC bit on low memory: %s\n", strerror(errno));
 | 
						|
 | 
						|
    if (((linuxInt10Priv*)pInt->private)->highMem >= 0) {
 | 
						|
	addr = shmat(((linuxInt10Priv*)pInt->private)->highMem,
 | 
						|
		     (char*)HIGH_MEM, 0);
 | 
						|
	if (addr == SHMERRORPTR) {
 | 
						|
	    xf86DrvMsg(pInt->scrnIndex, X_ERROR,
 | 
						|
		       "Cannot shmat() high memory\n");
 | 
						|
	    xf86DrvMsg(pInt->scrnIndex, X_ERROR,
 | 
						|
		       "shmget error: %s\n",strerror(errno));
 | 
						|
	    return FALSE;
 | 
						|
	}
 | 
						|
	if (mprotect((void*)HIGH_MEM, HIGH_MEM_SIZE,
 | 
						|
		     PROT_READ|PROT_WRITE|PROT_EXEC) != 0)
 | 
						|
	    xf86DrvMsg(pInt->scrnIndex, X_ERROR,
 | 
						|
		       "Cannot set EXEC bit on high memory: %s\n",
 | 
						|
		       strerror(errno));
 | 
						|
    } else {
 | 
						|
	if ((fd = open(DEV_MEM, O_RDWR, 0)) >= 0) {
 | 
						|
	    if (mmap((void *)(V_BIOS), SYS_BIOS - V_BIOS,
 | 
						|
			     PROT_READ | PROT_WRITE | PROT_EXEC,
 | 
						|
			     MAP_SHARED | MAP_FIXED, fd, V_BIOS)
 | 
						|
		== MAP_FAILED) {
 | 
						|
		xf86DrvMsg(pInt->scrnIndex, X_ERROR, "Cannot map V_BIOS\n");
 | 
						|
		close (fd);
 | 
						|
		return FALSE;
 | 
						|
	    }
 | 
						|
	} else {
 | 
						|
	    xf86DrvMsg(pInt->scrnIndex, X_ERROR, "Cannot open %s\n",DEV_MEM);
 | 
						|
	    return FALSE;
 | 
						|
	}
 | 
						|
	close (fd);
 | 
						|
    }
 | 
						|
    
 | 
						|
    return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
xf86FreeInt10(xf86Int10InfoPtr pInt)
 | 
						|
{
 | 
						|
    if (!pInt)
 | 
						|
	return;
 | 
						|
 | 
						|
#ifdef _PC
 | 
						|
    xf86Int10SaveRestoreBIOSVars(pInt, FALSE); 
 | 
						|
#endif
 | 
						|
    if (Int10Current == pInt) {
 | 
						|
	shmdt(0);
 | 
						|
	if (((linuxInt10Priv*)pInt->private)->highMem >= 0)
 | 
						|
	    shmdt((char*)HIGH_MEM);
 | 
						|
	else
 | 
						|
	    munmap((pointer)V_BIOS, (SYS_BIOS - V_BIOS));
 | 
						|
	Int10Current = NULL;
 | 
						|
    }
 | 
						|
    
 | 
						|
    if (((linuxInt10Priv*)pInt->private)->base_high)
 | 
						|
	shmdt(((linuxInt10Priv*)pInt->private)->base_high);
 | 
						|
    shmdt(((linuxInt10Priv*)pInt->private)->base);
 | 
						|
    shmctl(((linuxInt10Priv*)pInt->private)->lowMem, IPC_RMID, NULL);
 | 
						|
    if (((linuxInt10Priv*)pInt->private)->highMem >= 0)
 | 
						|
	shmctl(((linuxInt10Priv*)pInt->private)->highMem, IPC_RMID, NULL);
 | 
						|
    xfree(((linuxInt10Priv*)pInt->private)->alloc);
 | 
						|
    xfree(pInt->private);
 | 
						|
    xfree(pInt);
 | 
						|
}
 | 
						|
 | 
						|
void *
 | 
						|
xf86Int10AllocPages(xf86Int10InfoPtr pInt, int num, int *off)
 | 
						|
{
 | 
						|
    int pagesize = getpagesize();
 | 
						|
    int num_pages = ALLOC_ENTRIES(pagesize);
 | 
						|
    int i, j;
 | 
						|
 | 
						|
    for (i = 0; i < (num_pages - num); i++) {
 | 
						|
	if (((linuxInt10Priv*)pInt->private)->alloc[i] == 0) {
 | 
						|
	    for (j = i; j < (num + i); j++)
 | 
						|
		if ((((linuxInt10Priv*)pInt->private)->alloc[j] != 0))
 | 
						|
		    break;
 | 
						|
	    if (j == (num + i))
 | 
						|
		break;
 | 
						|
	    else
 | 
						|
		i = i + num;
 | 
						|
	}
 | 
						|
    }
 | 
						|
    if (i == (num_pages - num))
 | 
						|
	return NULL;
 | 
						|
 | 
						|
    for (j = i; j < (i + num); j++)
 | 
						|
	((linuxInt10Priv*)pInt->private)->alloc[j] = 1;
 | 
						|
 | 
						|
    *off = (i + 1) * pagesize;
 | 
						|
 | 
						|
    return ((linuxInt10Priv*)pInt->private)->base + ((i + 1) * pagesize);
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
xf86Int10FreePages(xf86Int10InfoPtr pInt, void *pbase, int num)
 | 
						|
{
 | 
						|
    int pagesize = getpagesize();
 | 
						|
    int first = (((unsigned long)pbase
 | 
						|
		 - (unsigned long)((linuxInt10Priv*)pInt->private)->base)
 | 
						|
	/ pagesize) - 1;
 | 
						|
    int i;
 | 
						|
 | 
						|
    for (i = first; i < (first + num); i++)
 | 
						|
	((linuxInt10Priv*)pInt->private)->alloc[i] = 0;
 | 
						|
}
 | 
						|
 | 
						|
static CARD8
 | 
						|
read_b(xf86Int10InfoPtr pInt, int addr)
 | 
						|
{
 | 
						|
    return *((CARD8 *)(memType)addr);
 | 
						|
}
 | 
						|
 | 
						|
static CARD16
 | 
						|
read_w(xf86Int10InfoPtr pInt, int addr)
 | 
						|
{
 | 
						|
    return *((CARD16 *)(memType)addr);
 | 
						|
}
 | 
						|
 | 
						|
static CARD32
 | 
						|
read_l(xf86Int10InfoPtr pInt, int addr)
 | 
						|
{
 | 
						|
    return *((CARD32 *)(memType)addr);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
write_b(xf86Int10InfoPtr pInt, int addr, CARD8 val)
 | 
						|
{
 | 
						|
    *((CARD8 *)(memType)addr) = val;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
write_w(xf86Int10InfoPtr pInt, int addr, CARD16 val)
 | 
						|
{
 | 
						|
    *((CARD16 *)(memType)addr) = val;
 | 
						|
}
 | 
						|
 | 
						|
static
 | 
						|
void write_l(xf86Int10InfoPtr pInt, int addr, CARD32 val)
 | 
						|
{
 | 
						|
    *((CARD32 *)(memType) addr) = val;
 | 
						|
}
 | 
						|
 | 
						|
pointer
 | 
						|
xf86int10Addr(xf86Int10InfoPtr pInt, CARD32 addr)
 | 
						|
{
 | 
						|
    if (addr < V_RAM)
 | 
						|
	return ((linuxInt10Priv*)pInt->private)->base + addr;
 | 
						|
    else if (addr < V_BIOS)
 | 
						|
	return (pointer)(memType)addr;
 | 
						|
    else if (addr < SYS_BIOS) {
 | 
						|
	if (((linuxInt10Priv*)pInt->private)->base_high)
 | 
						|
	    return (pointer)(((linuxInt10Priv*)pInt->private)->base_high
 | 
						|
			     - V_BIOS + addr);
 | 
						|
	else
 | 
						|
	    return (pointer) (memType)addr;
 | 
						|
    } else
 | 
						|
	return (pointer) (memType)addr;
 | 
						|
}
 | 
						|
 | 
						|
#if defined DoSubModules
 | 
						|
 | 
						|
static Bool
 | 
						|
vm86_tst(void)
 | 
						|
{
 | 
						|
    int __res;
 | 
						|
 | 
						|
#ifdef __PIC__
 | 
						|
    /* When compiling with -fPIC, we can't use asm constraint "b" because
 | 
						|
       %ebx is already taken by gcc. */
 | 
						|
    __asm__ __volatile__("pushl %%ebx\n\t"
 | 
						|
			 "movl %2,%%ebx\n\t"
 | 
						|
			 "movl %1,%%eax\n\t"
 | 
						|
			 "int $0x80\n\t"
 | 
						|
			 "popl %%ebx"
 | 
						|
			 :"=a" (__res)
 | 
						|
			 :"n" ((int)113), "r" (NULL));
 | 
						|
#else
 | 
						|
    __asm__ __volatile__("int $0x80\n\t"
 | 
						|
			 :"=a" (__res):"a" ((int)113),
 | 
						|
			 "b" ((struct vm86_struct *)NULL));
 | 
						|
#endif
 | 
						|
 | 
						|
    if (__res < 0 && __res == -ENOSYS) 
 | 
						|
	return FALSE;
 | 
						|
 | 
						|
    return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
static Int10LinuxSubModuleState
 | 
						|
int10LinuxLoadSubModule(ScrnInfoPtr pScrn)
 | 
						|
{
 | 
						|
    if (vm86_tst()) {
 | 
						|
	if (xf86LoadSubModule(pScrn,"vm86"))
 | 
						|
	    return INT10_LOADED_VM86;
 | 
						|
    } 
 | 
						|
    if (xf86LoadSubModule(pScrn,"x86emu"))
 | 
						|
	return INT10_LOADED_X86EMU;
 | 
						|
 | 
						|
    return INT10_LOAD_FAILED;
 | 
						|
}
 | 
						|
 | 
						|
#endif /* DoSubModules */
 |