2003-11-14 16:48:57 +00:00
|
|
|
/*
|
|
|
|
|
* linux specific part of the int10 module
|
2008-11-21 18:50:01 +01:00
|
|
|
* Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2008 Egbert Eich
|
2003-11-14 16:48:57 +00:00
|
|
|
*/
|
2005-07-03 07:02:09 +00:00
|
|
|
#ifdef HAVE_XORG_CONFIG_H
|
|
|
|
|
#include <xorg-config.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
2003-11-14 16:48:57 +00:00
|
|
|
#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)
|
|
|
|
|
|
2006-02-13 04:56:27 +00:00
|
|
|
#include <fcntl.h>
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
#include <sys/mman.h>
|
|
|
|
|
#include <sys/ipc.h>
|
|
|
|
|
#include <sys/shm.h>
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
2003-11-14 16:48:57 +00:00
|
|
|
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 */
|
|
|
|
|
|
Rework symbol visibility for easier maintenance
Save in a few special cases, _X_EXPORT should not be used in C source
files. Instead, it should be used in headers, and the proper C source
include that header. Some special cases are symbols that need to be
shared between modules, but not expected to be used by external drivers,
and symbols that are accessible via LoaderSymbol/dlopen.
This patch also adds conditionally some new sdk header files, depending
on extensions enabled. These files were added to match pattern for
other extensions/modules, that is, have the headers "deciding" symbol
visibility in the sdk. These headers are:
o Xext/panoramiXsrv.h, Xext/panoramiX.h
o fbpict.h (unconditionally)
o vidmodeproc.h
o mioverlay.h (unconditionally, used only by xaa)
o xfixes.h (unconditionally, symbols required by dri2)
LoaderSymbol and similar functions now don't have different prototypes,
in loaderProcs.h and xf86Module.h, so that both headers can be included,
without the need of defining IN_LOADER.
xf86NewInputDevice() device prototype readded to xf86Xinput.h, but
not exported (and with a comment about it).
2008-12-03 05:43:34 -02:00
|
|
|
xf86Int10InfoPtr
|
2003-11-14 16:48:57 +00:00
|
|
|
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) {
|
2009-05-09 10:33:20 +10:00
|
|
|
DebugF("Mapping sys bios area\n");
|
2003-11-14 16:48:57 +00:00
|
|
|
if ((sysMem = mmap((void *)(SYS_BIOS), BIOS_SIZE,
|
2003-11-25 19:29:01 +00:00
|
|
|
PROT_READ | PROT_EXEC,
|
2003-11-14 16:48:57 +00:00
|
|
|
MAP_SHARED | MAP_FIXED, fd, SYS_BIOS))
|
|
|
|
|
== MAP_FAILED) {
|
|
|
|
|
xf86DrvMsg(screen, X_ERROR, "Cannot map SYS BIOS\n");
|
|
|
|
|
close(fd);
|
|
|
|
|
goto error0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!vidMem) {
|
2009-05-09 10:33:20 +10:00
|
|
|
DebugF("Mapping VRAM area\n");
|
2003-11-14 16:48:57 +00:00
|
|
|
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;
|
2007-01-16 14:49:19 -08:00
|
|
|
pInt->dev = xf86GetPciInfoForEntity(entityIndex);
|
|
|
|
|
|
2003-11-14 16:48:57 +00:00
|
|
|
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)) {
|
2009-05-09 10:33:20 +10:00
|
|
|
DebugF("Mapping high memory area\n");
|
2003-11-14 16:48:57 +00:00
|
|
|
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");
|
2004-07-30 20:51:09 +00:00
|
|
|
else
|
|
|
|
|
xf86DrvMsg(screen, X_ERROR,
|
|
|
|
|
"shmget(highmem) error: %s\n",strerror(errno));
|
2003-11-14 16:48:57 +00:00
|
|
|
goto error1;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2009-05-09 10:33:20 +10:00
|
|
|
DebugF("Mapping Video BIOS\n");
|
2003-11-14 16:48:57 +00:00
|
|
|
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;
|
|
|
|
|
|
2009-05-09 10:33:20 +10:00
|
|
|
DebugF("Mapping 640kB area\n");
|
2003-11-14 16:48:57 +00:00
|
|
|
if ((low_mem = shmget(counter++, V_RAM,
|
2004-07-30 20:51:09 +00:00
|
|
|
IPC_CREAT | SHM_R | SHM_W)) == -1) {
|
|
|
|
|
xf86DrvMsg(screen, X_ERROR,
|
|
|
|
|
"shmget(lowmem) error: %s\n",strerror(errno));
|
2003-11-14 16:48:57 +00:00
|
|
|
goto error2;
|
2004-07-30 20:51:09 +00:00
|
|
|
}
|
2003-11-14 16:48:57 +00:00
|
|
|
|
|
|
|
|
((linuxInt10Priv*)pInt->private)->lowMem = low_mem;
|
|
|
|
|
base = shmat(low_mem, 0, 0);
|
2004-07-30 20:51:09 +00:00
|
|
|
if (base == SHMERRORPTR) {
|
|
|
|
|
xf86DrvMsg(screen, X_ERROR,
|
|
|
|
|
"shmat(low_mem) error: %s\n",strerror(errno));
|
|
|
|
|
goto error3;
|
|
|
|
|
}
|
2003-11-14 16:48:57 +00:00
|
|
|
((linuxInt10Priv *)pInt->private)->base = base;
|
|
|
|
|
if (high_mem > -1) {
|
|
|
|
|
base_high = shmat(high_mem, 0, 0);
|
2004-07-30 20:51:09 +00:00
|
|
|
if (base_high == SHMERRORPTR) {
|
|
|
|
|
xf86DrvMsg(screen, X_ERROR,
|
|
|
|
|
"shmat(high_mem) error: %s\n",strerror(errno));
|
|
|
|
|
goto error3;
|
|
|
|
|
}
|
2003-11-14 16:48:57 +00:00
|
|
|
((linuxInt10Priv*)pInt->private)->base_high = base_high;
|
|
|
|
|
} else
|
|
|
|
|
((linuxInt10Priv*)pInt->private)->base_high = NULL;
|
|
|
|
|
|
2004-07-30 20:51:09 +00:00
|
|
|
if (!MapCurrentInt10(pInt))
|
|
|
|
|
goto error3;
|
|
|
|
|
|
2003-11-14 16:48:57 +00:00
|
|
|
Int10Current = pInt;
|
|
|
|
|
|
2009-05-09 10:33:20 +10:00
|
|
|
DebugF("Mapping int area\n");
|
2003-11-14 16:48:57 +00:00
|
|
|
if (xf86ReadBIOS(0, 0, (unsigned char *)0, LOW_PAGE_SIZE) < 0) {
|
|
|
|
|
xf86DrvMsg(screen, X_ERROR, "Cannot read int vect\n");
|
|
|
|
|
goto error3;
|
|
|
|
|
}
|
2009-05-09 10:33:20 +10:00
|
|
|
DebugF("done\n");
|
2003-11-14 16:48:57 +00:00
|
|
|
/*
|
|
|
|
|
* 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) {
|
2008-10-06 15:36:51 -04:00
|
|
|
memset((pointer)V_BIOS, 0, SYS_BIOS - V_BIOS);
|
2009-05-09 10:33:20 +10:00
|
|
|
DebugF("Reading BIOS\n");
|
2003-11-14 16:48:57 +00:00
|
|
|
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,
|
2008-11-30 02:59:34 -02:00
|
|
|
"Unable to retrieve all of segment 0x%06lX.\n",
|
|
|
|
|
(long)cs);
|
2009-05-09 10:33:20 +10:00
|
|
|
DebugF("done\n");
|
2003-11-14 16:48:57 +00:00
|
|
|
}
|
2006-07-14 15:13:35 -07:00
|
|
|
|
2007-07-27 13:23:15 -04:00
|
|
|
if (xf86IsEntityPrimary(entityIndex) && !(initPrimary(options))) {
|
|
|
|
|
if (!xf86int10GetBiosSegment(pInt, NULL))
|
2006-07-14 15:13:35 -07:00
|
|
|
goto error3;
|
2003-11-14 16:48:57 +00:00
|
|
|
|
|
|
|
|
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 {
|
2007-07-27 13:23:15 -04:00
|
|
|
const BusType location_type = xf86int10GetBiosLocationType(pInt);
|
2003-11-14 16:48:57 +00:00
|
|
|
|
|
|
|
|
switch (location_type) {
|
2006-07-14 15:13:35 -07:00
|
|
|
case BUS_PCI: {
|
2006-07-21 16:47:45 -07:00
|
|
|
int err;
|
2007-08-23 18:19:17 -07:00
|
|
|
struct pci_device *rom_device =
|
|
|
|
|
xf86GetPciInfoForEntity(pInt->entityIndex);
|
2006-07-21 16:47:45 -07:00
|
|
|
|
2008-05-20 13:59:09 +10:00
|
|
|
#if HAVE_PCI_DEVICE_ENABLE
|
|
|
|
|
pci_device_enable(rom_device);
|
|
|
|
|
#endif
|
|
|
|
|
|
2006-07-21 16:47:45 -07:00
|
|
|
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));
|
2003-11-14 16:48:57 +00:00
|
|
|
goto error3;
|
|
|
|
|
}
|
2006-07-21 16:47:45 -07:00
|
|
|
|
2003-11-14 16:48:57 +00:00
|
|
|
pInt->BIOSseg = V_BIOS >> 4;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
goto error3;
|
|
|
|
|
}
|
2006-07-14 15:13:35 -07:00
|
|
|
|
2003-11-14 16:48:57 +00:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
Rework symbol visibility for easier maintenance
Save in a few special cases, _X_EXPORT should not be used in C source
files. Instead, it should be used in headers, and the proper C source
include that header. Some special cases are symbols that need to be
shared between modules, but not expected to be used by external drivers,
and symbols that are accessible via LoaderSymbol/dlopen.
This patch also adds conditionally some new sdk header files, depending
on extensions enabled. These files were added to match pattern for
other extensions/modules, that is, have the headers "deciding" symbol
visibility in the sdk. These headers are:
o Xext/panoramiXsrv.h, Xext/panoramiX.h
o fbpict.h (unconditionally)
o vidmodeproc.h
o mioverlay.h (unconditionally, used only by xaa)
o xfixes.h (unconditionally, symbols required by dri2)
LoaderSymbol and similar functions now don't have different prototypes,
in loaderProcs.h and xf86Module.h, so that both headers can be included,
without the need of defining IN_LOADER.
xf86NewInputDevice() device prototype readded to xf86Xinput.h, but
not exported (and with a comment about it).
2008-12-03 05:43:34 -02:00
|
|
|
Bool
|
2003-11-14 16:48:57 +00:00
|
|
|
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");
|
2004-07-30 20:51:09 +00:00
|
|
|
xf86DrvMsg(pInt->scrnIndex, X_ERROR,
|
|
|
|
|
"shmat(low_mem) error: %s\n",strerror(errno));
|
2003-11-14 16:48:57 +00:00
|
|
|
return FALSE;
|
|
|
|
|
}
|
2008-11-21 18:50:01 +01:00
|
|
|
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));
|
|
|
|
|
|
2003-11-14 16:48:57 +00:00
|
|
|
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");
|
2004-07-30 20:51:09 +00:00
|
|
|
xf86DrvMsg(pInt->scrnIndex, X_ERROR,
|
|
|
|
|
"shmget error: %s\n",strerror(errno));
|
2003-11-14 16:48:57 +00:00
|
|
|
return FALSE;
|
|
|
|
|
}
|
2008-11-21 18:50:01 +01:00
|
|
|
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));
|
2003-11-14 16:48:57 +00:00
|
|
|
} 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;
|
|
|
|
|
}
|
|
|
|
|
|
Rework symbol visibility for easier maintenance
Save in a few special cases, _X_EXPORT should not be used in C source
files. Instead, it should be used in headers, and the proper C source
include that header. Some special cases are symbols that need to be
shared between modules, but not expected to be used by external drivers,
and symbols that are accessible via LoaderSymbol/dlopen.
This patch also adds conditionally some new sdk header files, depending
on extensions enabled. These files were added to match pattern for
other extensions/modules, that is, have the headers "deciding" symbol
visibility in the sdk. These headers are:
o Xext/panoramiXsrv.h, Xext/panoramiX.h
o fbpict.h (unconditionally)
o vidmodeproc.h
o mioverlay.h (unconditionally, used only by xaa)
o xfixes.h (unconditionally, symbols required by dri2)
LoaderSymbol and similar functions now don't have different prototypes,
in loaderProcs.h and xf86Module.h, so that both headers can be included,
without the need of defining IN_LOADER.
xf86NewInputDevice() device prototype readded to xf86Xinput.h, but
not exported (and with a comment about it).
2008-12-03 05:43:34 -02:00
|
|
|
void
|
2003-11-14 16:48:57 +00:00
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
Rework symbol visibility for easier maintenance
Save in a few special cases, _X_EXPORT should not be used in C source
files. Instead, it should be used in headers, and the proper C source
include that header. Some special cases are symbols that need to be
shared between modules, but not expected to be used by external drivers,
and symbols that are accessible via LoaderSymbol/dlopen.
This patch also adds conditionally some new sdk header files, depending
on extensions enabled. These files were added to match pattern for
other extensions/modules, that is, have the headers "deciding" symbol
visibility in the sdk. These headers are:
o Xext/panoramiXsrv.h, Xext/panoramiX.h
o fbpict.h (unconditionally)
o vidmodeproc.h
o mioverlay.h (unconditionally, used only by xaa)
o xfixes.h (unconditionally, symbols required by dri2)
LoaderSymbol and similar functions now don't have different prototypes,
in loaderProcs.h and xf86Module.h, so that both headers can be included,
without the need of defining IN_LOADER.
xf86NewInputDevice() device prototype readded to xf86Xinput.h, but
not exported (and with a comment about it).
2008-12-03 05:43:34 -02:00
|
|
|
void *
|
2003-11-14 16:48:57 +00:00
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
Rework symbol visibility for easier maintenance
Save in a few special cases, _X_EXPORT should not be used in C source
files. Instead, it should be used in headers, and the proper C source
include that header. Some special cases are symbols that need to be
shared between modules, but not expected to be used by external drivers,
and symbols that are accessible via LoaderSymbol/dlopen.
This patch also adds conditionally some new sdk header files, depending
on extensions enabled. These files were added to match pattern for
other extensions/modules, that is, have the headers "deciding" symbol
visibility in the sdk. These headers are:
o Xext/panoramiXsrv.h, Xext/panoramiX.h
o fbpict.h (unconditionally)
o vidmodeproc.h
o mioverlay.h (unconditionally, used only by xaa)
o xfixes.h (unconditionally, symbols required by dri2)
LoaderSymbol and similar functions now don't have different prototypes,
in loaderProcs.h and xf86Module.h, so that both headers can be included,
without the need of defining IN_LOADER.
xf86NewInputDevice() device prototype readded to xf86Xinput.h, but
not exported (and with a comment about it).
2008-12-03 05:43:34 -02:00
|
|
|
void
|
2003-11-14 16:48:57 +00:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
Rework symbol visibility for easier maintenance
Save in a few special cases, _X_EXPORT should not be used in C source
files. Instead, it should be used in headers, and the proper C source
include that header. Some special cases are symbols that need to be
shared between modules, but not expected to be used by external drivers,
and symbols that are accessible via LoaderSymbol/dlopen.
This patch also adds conditionally some new sdk header files, depending
on extensions enabled. These files were added to match pattern for
other extensions/modules, that is, have the headers "deciding" symbol
visibility in the sdk. These headers are:
o Xext/panoramiXsrv.h, Xext/panoramiX.h
o fbpict.h (unconditionally)
o vidmodeproc.h
o mioverlay.h (unconditionally, used only by xaa)
o xfixes.h (unconditionally, symbols required by dri2)
LoaderSymbol and similar functions now don't have different prototypes,
in loaderProcs.h and xf86Module.h, so that both headers can be included,
without the need of defining IN_LOADER.
xf86NewInputDevice() device prototype readded to xf86Xinput.h, but
not exported (and with a comment about it).
2008-12-03 05:43:34 -02:00
|
|
|
pointer
|
2003-11-14 16:48:57 +00:00
|
|
|
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 */
|