mirror of
https://github.com/X11Libre/xserver.git
synced 2026-10-28 02:21:08 +00:00
xfree86: remove the vm86 int10 backend
It has not compiled since21b216ad6("int10: Port off xf86ReadBIOS") in 2014, and meson has never been able to configure it. vm86() is only available on 32-bit x86 Linux kernels, where the default x86emu backend works too. Signed-off-by: Matt Turner <mattst88@gmail.com> Part-of: <https://gitlab.freedesktop.org/xorg/xserver/-/merge_requests/2369> (cherry picked from commit173c0d170f)
This commit is contained in:
parent
1ed8acae88
commit
894b058710
6 changed files with 8 additions and 899 deletions
|
|
@ -116,10 +116,7 @@ If the vm86() is to be used no memory access functions can be used.
|
|||
Therefore the layout of the real mode memory image has to meet certain
|
||||
requirements. Therefore when porting to other platforms a new setup
|
||||
code may have to be designed, too. The following section will give
|
||||
guidelines how this may be done. A sample implementation using SysV
|
||||
IPC to map the appropriate real mode memory image to address 0 in
|
||||
virtual address space just prior to execution may be found in
|
||||
xfree86/os-support/linux/int10/linux.c.
|
||||
guidelines how this may be done.
|
||||
|
||||
On non-PC like platforms emulation of certain PC features such as
|
||||
initialization of BIOS int vectors, sys_BIOS constants or PCI config
|
||||
|
|
@ -289,23 +286,6 @@ the resulting register values back to the xf86Int10InfoRec structure
|
|||
|
||||
should be called.
|
||||
|
||||
Helper functions are provided to aid the implementation of a vm86
|
||||
call:
|
||||
|
||||
Bool vm86_GP_fault(xf86Int10InfoPtr pInt);
|
||||
|
||||
This function handles instructions which cause a vm86 call to
|
||||
trap. PIO access is handled by the in/out calls as defined in
|
||||
compiler.h. Optionally the PIO instructions can be logged by defining
|
||||
PRINT_PORT in xf86int10.h. This is meant for debugging purposes.
|
||||
|
||||
Unknown instructions and 'hlt' cause vm86_GP_fault() to return
|
||||
FALSE. Otherwise TRUE is returned.
|
||||
|
||||
Note: This function is currently based on the Linux vm86 call. It
|
||||
might have to be modified or even rewritten for other OS. So your
|
||||
mileage may vary.
|
||||
|
||||
Functions to dump memory, code, xf86 CPU register values and stack are
|
||||
also provided. Take a look at helper.c To view a memory range the
|
||||
function
|
||||
|
|
@ -325,8 +305,7 @@ provided for memory byte/work/long read/write access
|
|||
MEM_WB(name,addr,val),MEM_WL(name,addr,val),MEM_WL(name,addr,val)) of
|
||||
the real mode memory environment. 'name' will contain a pointer to the
|
||||
current xf86Int10InfoRec. Currently defines are available for
|
||||
vm86-mode under Linux and x86emu. They may be activated by defining
|
||||
_X86EMU or _VM86_LINUX respectively.
|
||||
x86emu. They may be activated by defining _X86EMU.
|
||||
|
||||
Note: Emulators usually are not able to pass this pointer when calling
|
||||
memory access functions. In this case a global variable should be
|
||||
|
|
|
|||
|
|
@ -36,14 +36,6 @@ if int10 == 'x86emu'
|
|||
int10_link += xorg_x86emu
|
||||
endif
|
||||
|
||||
if int10 == 'vm86'
|
||||
srcs_xorg_int10 += [
|
||||
'vm86/linux_vm86.c',
|
||||
'linux.c',
|
||||
]
|
||||
int10_c_args += '-D_VM86_LINUX'
|
||||
endif
|
||||
|
||||
xorg_int10 = shared_module('int10',
|
||||
srcs_xorg_int10,
|
||||
include_directories: [
|
||||
|
|
|
|||
|
|
@ -25,58 +25,14 @@
|
|||
* authorization from the copyright holder(s) and author(s).
|
||||
*/
|
||||
|
||||
#ifdef HAVE_XORG_CONFIG_H
|
||||
#include <xorg-config.h>
|
||||
#endif
|
||||
|
||||
#ifndef _INT10DEFINES_H_
|
||||
#define _INT10DEFINES_H_ 1
|
||||
|
||||
#ifdef _VM86_LINUX
|
||||
|
||||
#include <asm/vm86.h>
|
||||
|
||||
#define CPU_R(type,name,num) \
|
||||
(((type *)&(((struct vm86_struct *)REG->cpuRegs)->regs.name))[num])
|
||||
#define CPU_RD(name,num) CPU_R(CARD32,name,num)
|
||||
#define CPU_RW(name,num) CPU_R(CARD16,name,num)
|
||||
#define CPU_RB(name,num) CPU_R(CARD8,name,num)
|
||||
|
||||
#define X86_EAX CPU_RD(eax,0)
|
||||
#define X86_EBX CPU_RD(ebx,0)
|
||||
#define X86_ECX CPU_RD(ecx,0)
|
||||
#define X86_EDX CPU_RD(edx,0)
|
||||
#define X86_ESI CPU_RD(esi,0)
|
||||
#define X86_EDI CPU_RD(edi,0)
|
||||
#define X86_EBP CPU_RD(ebp,0)
|
||||
#define X86_EIP CPU_RD(eip,0)
|
||||
#define X86_ESP CPU_RD(esp,0)
|
||||
#define X86_EFLAGS CPU_RD(eflags,0)
|
||||
|
||||
#define X86_FLAGS CPU_RW(eflags,0)
|
||||
#define X86_AX CPU_RW(eax,0)
|
||||
#define X86_BX CPU_RW(ebx,0)
|
||||
#define X86_CX CPU_RW(ecx,0)
|
||||
#define X86_DX CPU_RW(edx,0)
|
||||
#define X86_SI CPU_RW(esi,0)
|
||||
#define X86_DI CPU_RW(edi,0)
|
||||
#define X86_BP CPU_RW(ebp,0)
|
||||
#define X86_IP CPU_RW(eip,0)
|
||||
#define X86_SP CPU_RW(esp,0)
|
||||
#define X86_CS CPU_RW(cs,0)
|
||||
#define X86_DS CPU_RW(ds,0)
|
||||
#define X86_ES CPU_RW(es,0)
|
||||
#define X86_SS CPU_RW(ss,0)
|
||||
#define X86_FS CPU_RW(fs,0)
|
||||
#define X86_GS CPU_RW(gs,0)
|
||||
|
||||
#define X86_AL CPU_RB(eax,0)
|
||||
#define X86_BL CPU_RB(ebx,0)
|
||||
#define X86_CL CPU_RB(ecx,0)
|
||||
#define X86_DL CPU_RB(edx,0)
|
||||
|
||||
#define X86_AH CPU_RB(eax,1)
|
||||
#define X86_BH CPU_RB(ebx,1)
|
||||
#define X86_CH CPU_RB(ecx,1)
|
||||
#define X86_DH CPU_RB(edx,1)
|
||||
|
||||
#elif defined(_X86EMU)
|
||||
#ifdef _X86EMU
|
||||
|
||||
#include "xf86x86emu.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -1,495 +0,0 @@
|
|||
/*
|
||||
* linux specific part of the int10 module
|
||||
* Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2008 Egbert Eich
|
||||
*/
|
||||
#include <xorg-config.h>
|
||||
|
||||
#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 (void *)(-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 x_server_generation_t 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;
|
||||
char *alloc;
|
||||
} linuxInt10Priv;
|
||||
|
||||
static Bool
|
||||
readLegacy(struct pci_device *dev, unsigned char *buf, int base, int len)
|
||||
{
|
||||
void *map;
|
||||
|
||||
if (pci_device_map_legacy(dev, base, len, 0, &map))
|
||||
return FALSE;
|
||||
|
||||
memcpy(buf, map, len);
|
||||
pci_device_unmap_legacy(dev, man, len);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
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;
|
||||
ScrnInfoPtr pScrn;
|
||||
if (int10Generation != serverGeneration) {
|
||||
counter = 0;
|
||||
int10Generation = serverGeneration;
|
||||
}
|
||||
|
||||
pScrn = xf86FindScreenForEntity(entityIndex);
|
||||
screen = pScrn->scrnIndex;
|
||||
|
||||
options = xf86HandleInt10Options(pScrn, entityIndex);
|
||||
|
||||
if (int10skip(options)) {
|
||||
free(options);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((!vidMem) || (!sysMem)) {
|
||||
if ((fd = open(DEV_MEM, O_RDWR, 0)) >= 0) {
|
||||
if (!sysMem) {
|
||||
DebugF("Mapping sys bios area\n");
|
||||
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) {
|
||||
DebugF("Mapping VRAM area\n");
|
||||
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) XNFcallocarray(1, sizeof(xf86Int10InfoRec));
|
||||
pInt->pScrn = pScrn;
|
||||
pInt->entityIndex = entityIndex;
|
||||
pInt->dev = xf86GetPciInfoForEntity(entityIndex);
|
||||
|
||||
if (!xf86Int10ExecSetup(pInt))
|
||||
goto error0;
|
||||
pInt->mem = &linuxMem;
|
||||
pagesize = getpagesize();
|
||||
pInt->private = (void *) XNFcallocarray(1, sizeof(linuxInt10Priv));
|
||||
((linuxInt10Priv *) pInt->private)->alloc =
|
||||
(void *) XNFcallocarray(1, ALLOC_ENTRIES(pagesize));
|
||||
|
||||
if (!xf86IsEntityPrimary(entityIndex)) {
|
||||
DebugF("Mapping high memory area\n");
|
||||
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 {
|
||||
DebugF("Mapping Video BIOS\n");
|
||||
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;
|
||||
|
||||
DebugF("Mapping 640kB area\n");
|
||||
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;
|
||||
|
||||
DebugF("Mapping int area\n");
|
||||
/* note: yes, we really are writing the 0 page here */
|
||||
if (!readLegacy(pInt->dev, (unsigned char *) 0, 0, LOW_PAGE_SIZE)) {
|
||||
xf86DrvMsg(screen, X_ERROR, "Cannot read int vect\n");
|
||||
goto error3;
|
||||
}
|
||||
DebugF("done\n");
|
||||
/*
|
||||
* 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((void *) V_BIOS, 0, SYS_BIOS - V_BIOS);
|
||||
DebugF("Reading BIOS\n");
|
||||
for (cs = V_BIOS; cs < SYS_BIOS; cs += V_BIOS_SIZE)
|
||||
if (!readLegacy(pInt->dev, (void *)cs, cs, V_BIOS_SIZE))
|
||||
xf86DrvMsg(screen, X_WARNING,
|
||||
"Unable to retrieve all of segment 0x%06lX.\n",
|
||||
(long) cs);
|
||||
DebugF("done\n");
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
pci_device_enable(rom_device);
|
||||
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
|
||||
|
||||
free(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);
|
||||
free(((linuxInt10Priv *) pInt->private)->alloc);
|
||||
free(pInt->private);
|
||||
error0:
|
||||
free(options);
|
||||
free(pInt);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Bool
|
||||
MapCurrentInt10(xf86Int10InfoPtr pInt)
|
||||
{
|
||||
void *addr;
|
||||
int fd = -1;
|
||||
|
||||
if (Int10Current) {
|
||||
shmdt(0);
|
||||
if (((linuxInt10Priv *) Int10Current->private)->highMem >= 0)
|
||||
shmdt((char *) HIGH_MEM);
|
||||
else
|
||||
munmap((void *) V_BIOS, (SYS_BIOS - V_BIOS));
|
||||
}
|
||||
addr =
|
||||
shmat(((linuxInt10Priv *) pInt->private)->lowMem, (char *) 1, SHM_RND);
|
||||
if (addr == SHMERRORPTR) {
|
||||
xf86DrvMsg(pInt->pScrn->scrnIndex, X_ERROR, "Cannot shmat() low memory\n");
|
||||
xf86DrvMsg(pInt->pScrn->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->pScrn->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->pScrn->scrnIndex, X_ERROR,
|
||||
"Cannot shmat() high memory\n");
|
||||
xf86DrvMsg(pInt->pScrn->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->pScrn->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->pScrn->scrnIndex, X_ERROR, "Cannot map V_BIOS\n");
|
||||
close(fd);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
xf86DrvMsg(pInt->pScrn->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((void *) 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);
|
||||
free(((linuxInt10Priv *) pInt->private)->alloc);
|
||||
free(pInt->private);
|
||||
free(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;
|
||||
}
|
||||
|
||||
void *
|
||||
xf86int10Addr(xf86Int10InfoPtr pInt, CARD32 addr)
|
||||
{
|
||||
if (addr < V_RAM)
|
||||
return ((linuxInt10Priv *) pInt->private)->base + addr;
|
||||
else if (addr < V_BIOS)
|
||||
return (void *) (memType) addr;
|
||||
else if (addr < SYS_BIOS) {
|
||||
if (((linuxInt10Priv *) pInt->private)->base_high)
|
||||
return (void *) (((linuxInt10Priv *) pInt->private)->base_high
|
||||
- V_BIOS + addr);
|
||||
else
|
||||
return (void *) (memType) addr;
|
||||
}
|
||||
else
|
||||
return (void *) (memType) addr;
|
||||
}
|
||||
|
|
@ -1,323 +0,0 @@
|
|||
#include <xorg-config.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "xf86.h"
|
||||
#include "xf86_OSproc.h"
|
||||
#include "xf86Pci.h"
|
||||
#include "compiler.h"
|
||||
#define _INT10_PRIVATE
|
||||
#include "xf86int10.h"
|
||||
|
||||
#define REG pInt
|
||||
|
||||
#ifdef _VM86_LINUX
|
||||
#include "int10Defines.h"
|
||||
|
||||
static int vm86_rep(struct vm86_struct *ptr);
|
||||
static struct vm86_struct vm86_s;
|
||||
|
||||
Bool
|
||||
xf86Int10ExecSetup(xf86Int10InfoPtr pInt)
|
||||
{
|
||||
#define VM86S ((struct vm86_struct *)pInt->cpuRegs)
|
||||
|
||||
pInt->cpuRegs = &vm86_s;
|
||||
VM86S->flags = 0;
|
||||
VM86S->screen_bitmap = 0;
|
||||
VM86S->cpu_type = CPU_586;
|
||||
memset(&VM86S->int_revectored, 0xff, sizeof(VM86S->int_revectored));
|
||||
memset(&VM86S->int21_revectored, 0xff, sizeof(VM86S->int21_revectored));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* get the linear address */
|
||||
#define LIN_PREF_SI ((pref_seg << 4) + X86_SI)
|
||||
#define LWECX ((prefix66 ^ prefix67) ? X86_ECX : X86_CX)
|
||||
#define LWECX_ZERO {if (prefix66 ^ prefix67) X86_ECX = 0; else X86_CX = 0;}
|
||||
#define DF (1 << 10)
|
||||
|
||||
/* vm86 fault handling */
|
||||
static Bool
|
||||
vm86_GP_fault(xf86Int10InfoPtr pInt)
|
||||
{
|
||||
unsigned char *csp, *lina;
|
||||
CARD32 org_eip;
|
||||
int pref_seg;
|
||||
int done, is_rep, prefix66, prefix67;
|
||||
|
||||
csp = lina = SEG_ADR((unsigned char *), X86_CS, IP);
|
||||
|
||||
is_rep = 0;
|
||||
prefix66 = prefix67 = 0;
|
||||
pref_seg = -1;
|
||||
|
||||
/* eat up prefixes */
|
||||
done = 0;
|
||||
do {
|
||||
switch (MEM_RB(pInt, (int) csp++)) {
|
||||
case 0x66: /* operand prefix */
|
||||
prefix66 = 1;
|
||||
break;
|
||||
case 0x67: /* address prefix */
|
||||
prefix67 = 1;
|
||||
break;
|
||||
case 0x2e: /* CS */
|
||||
pref_seg = X86_CS;
|
||||
break;
|
||||
case 0x3e: /* DS */
|
||||
pref_seg = X86_DS;
|
||||
break;
|
||||
case 0x26: /* ES */
|
||||
pref_seg = X86_ES;
|
||||
break;
|
||||
case 0x36: /* SS */
|
||||
pref_seg = X86_SS;
|
||||
break;
|
||||
case 0x65: /* GS */
|
||||
pref_seg = X86_GS;
|
||||
break;
|
||||
case 0x64: /* FS */
|
||||
pref_seg = X86_FS;
|
||||
break;
|
||||
case 0xf0: /* lock */
|
||||
break;
|
||||
case 0xf2: /* repnz */
|
||||
case 0xf3: /* rep */
|
||||
is_rep = 1;
|
||||
break;
|
||||
default:
|
||||
done = 1;
|
||||
}
|
||||
} while (!done);
|
||||
csp--; /* oops one too many */
|
||||
org_eip = X86_EIP;
|
||||
X86_IP += (csp - lina);
|
||||
|
||||
switch (MEM_RB(pInt, (int) csp)) {
|
||||
case 0x6c: /* insb */
|
||||
/* NOTE: ES can't be overwritten; prefixes 66,67 should use esi,edi,ecx
|
||||
* but is anyone using extended regs in real mode? */
|
||||
/* WARNING: no test for DI wrapping! */
|
||||
X86_EDI += port_rep_inb(pInt, X86_DX, SEG_EADR((CARD32), X86_ES, DI),
|
||||
X86_FLAGS & DF, is_rep ? LWECX : 1);
|
||||
if (is_rep)
|
||||
LWECX_ZERO;
|
||||
X86_IP++;
|
||||
break;
|
||||
|
||||
case 0x6d: /* (rep) insw / insd */
|
||||
/* NOTE: ES can't be overwritten */
|
||||
/* WARNING: no test for _DI wrapping! */
|
||||
if (prefix66) {
|
||||
X86_DI += port_rep_inl(pInt, X86_DX, SEG_ADR((CARD32), X86_ES, DI),
|
||||
X86_EFLAGS & DF, is_rep ? LWECX : 1);
|
||||
}
|
||||
else {
|
||||
X86_DI += port_rep_inw(pInt, X86_DX, SEG_ADR((CARD32), X86_ES, DI),
|
||||
X86_FLAGS & DF, is_rep ? LWECX : 1);
|
||||
}
|
||||
if (is_rep)
|
||||
LWECX_ZERO;
|
||||
X86_IP++;
|
||||
break;
|
||||
|
||||
case 0x6e: /* (rep) outsb */
|
||||
if (pref_seg < 0)
|
||||
pref_seg = X86_DS;
|
||||
/* WARNING: no test for _SI wrapping! */
|
||||
X86_SI += port_rep_outb(pInt, X86_DX, (CARD32) LIN_PREF_SI,
|
||||
X86_FLAGS & DF, is_rep ? LWECX : 1);
|
||||
if (is_rep)
|
||||
LWECX_ZERO;
|
||||
X86_IP++;
|
||||
break;
|
||||
|
||||
case 0x6f: /* (rep) outsw / outsd */
|
||||
if (pref_seg < 0)
|
||||
pref_seg = X86_DS;
|
||||
/* WARNING: no test for _SI wrapping! */
|
||||
if (prefix66) {
|
||||
X86_SI += port_rep_outl(pInt, X86_DX, (CARD32) LIN_PREF_SI,
|
||||
X86_EFLAGS & DF, is_rep ? LWECX : 1);
|
||||
}
|
||||
else {
|
||||
X86_SI += port_rep_outw(pInt, X86_DX, (CARD32) LIN_PREF_SI,
|
||||
X86_FLAGS & DF, is_rep ? LWECX : 1);
|
||||
}
|
||||
if (is_rep)
|
||||
LWECX_ZERO;
|
||||
X86_IP++;
|
||||
break;
|
||||
|
||||
case 0xe5: /* inw xx, inl xx */
|
||||
if (prefix66)
|
||||
X86_EAX = x_inl(csp[1]);
|
||||
else
|
||||
X86_AX = x_inw(csp[1]);
|
||||
X86_IP += 2;
|
||||
break;
|
||||
|
||||
case 0xe4: /* inb xx */
|
||||
X86_AL = x_inb(csp[1]);
|
||||
X86_IP += 2;
|
||||
break;
|
||||
|
||||
case 0xed: /* inw dx, inl dx */
|
||||
if (prefix66)
|
||||
X86_EAX = x_inl(X86_DX);
|
||||
else
|
||||
X86_AX = x_inw(X86_DX);
|
||||
X86_IP += 1;
|
||||
break;
|
||||
|
||||
case 0xec: /* inb dx */
|
||||
X86_AL = x_inb(X86_DX);
|
||||
X86_IP += 1;
|
||||
break;
|
||||
|
||||
case 0xe7: /* outw xx */
|
||||
if (prefix66)
|
||||
x_outl(csp[1], X86_EAX);
|
||||
else
|
||||
x_outw(csp[1], X86_AX);
|
||||
X86_IP += 2;
|
||||
break;
|
||||
|
||||
case 0xe6: /* outb xx */
|
||||
x_outb(csp[1], X86_AL);
|
||||
X86_IP += 2;
|
||||
break;
|
||||
|
||||
case 0xef: /* outw dx */
|
||||
if (prefix66)
|
||||
x_outl(X86_DX, X86_EAX);
|
||||
else
|
||||
x_outw(X86_DX, X86_AX);
|
||||
X86_IP += 1;
|
||||
break;
|
||||
|
||||
case 0xee: /* outb dx */
|
||||
x_outb(X86_DX, X86_AL);
|
||||
X86_IP += 1;
|
||||
break;
|
||||
|
||||
case 0xf4:
|
||||
DebugF("hlt at %p\n", lina);
|
||||
return FALSE;
|
||||
|
||||
case 0x0f:
|
||||
xf86DrvMsg(pInt->pScrn->scrnIndex, X_ERROR,
|
||||
"CPU 0x0f Trap at CS:EIP=0x%4.4x:0x%8.8lx\n", X86_CS,
|
||||
X86_EIP);
|
||||
goto op0ferr;
|
||||
|
||||
default:
|
||||
xf86DrvMsg(pInt->pScrn->scrnIndex, X_ERROR, "unknown reason for exception\n");
|
||||
|
||||
op0ferr:
|
||||
dump_registers(pInt);
|
||||
stack_trace(pInt);
|
||||
dump_code(pInt);
|
||||
xf86DrvMsg(pInt->pScrn->scrnIndex, X_ERROR, "cannot continue\n");
|
||||
return FALSE;
|
||||
} /* end of switch() */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int
|
||||
do_vm86(xf86Int10InfoPtr pInt)
|
||||
{
|
||||
int retval;
|
||||
|
||||
retval = vm86_rep(VM86S);
|
||||
|
||||
switch (VM86_TYPE(retval)) {
|
||||
case VM86_UNKNOWN:
|
||||
if (!vm86_GP_fault(pInt))
|
||||
return 0;
|
||||
break;
|
||||
case VM86_STI:
|
||||
xf86DrvMsg(pInt->pScrn->scrnIndex, X_ERROR, "vm86_sti :-((\n");
|
||||
dump_registers(pInt);
|
||||
dump_code(pInt);
|
||||
stack_trace(pInt);
|
||||
return 0;
|
||||
case VM86_INTx:
|
||||
pInt->num = VM86_ARG(retval);
|
||||
if (!int_handler(pInt)) {
|
||||
xf86DrvMsg(pInt->pScrn->scrnIndex, X_ERROR,
|
||||
"Unknown vm86_int: 0x%X\n\n", VM86_ARG(retval));
|
||||
dump_registers(pInt);
|
||||
dump_code(pInt);
|
||||
stack_trace(pInt);
|
||||
return 0;
|
||||
}
|
||||
/* I'm not sure yet what to do if we can handle ints */
|
||||
break;
|
||||
case VM86_SIGNAL:
|
||||
return 1;
|
||||
/*
|
||||
* we used to warn here and bail out - but now the sigio stuff
|
||||
* always fires signals at us. So we just ignore them for now.
|
||||
*/
|
||||
xf86DrvMsg(pInt->pScrn->scrnIndex, X_WARNING, "received signal\n");
|
||||
return 0;
|
||||
default:
|
||||
xf86DrvMsg(pInt->pScrn->scrnIndex, X_ERROR, "unknown type(0x%x)=0x%x\n",
|
||||
VM86_ARG(retval), VM86_TYPE(retval));
|
||||
dump_registers(pInt);
|
||||
dump_code(pInt);
|
||||
stack_trace(pInt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
xf86ExecX86int10(xf86Int10InfoPtr pInt)
|
||||
{
|
||||
int sig = setup_int(pInt);
|
||||
|
||||
if (int_handler(pInt))
|
||||
while (do_vm86(pInt)) {
|
||||
};
|
||||
|
||||
finish_int(pInt, sig);
|
||||
}
|
||||
|
||||
static int
|
||||
vm86_rep(struct vm86_struct *ptr)
|
||||
{
|
||||
int __res;
|
||||
|
||||
/* NOLINTBEGIN(hicpp-no-assembler) */
|
||||
#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"
|
||||
"push %%gs\n\t"
|
||||
"movl %2,%%ebx\n\t"
|
||||
"movl %1,%%eax\n\t"
|
||||
"int $0x80\n\t" "pop %%gs\n\t" "popl %%ebx":"=a"(__res)
|
||||
:"n"((int) 113), "r"((struct vm86_struct *) ptr));
|
||||
#else
|
||||
__asm__ __volatile__("push %%gs\n\t"
|
||||
"int $0x80\n\t"
|
||||
"pop %%gs":"=a"(__res):"a"((int) 113),
|
||||
"b"((struct vm86_struct *) ptr));
|
||||
#endif
|
||||
/* NOLINTEND(hicpp-no-assembler) */
|
||||
|
||||
if (__res < 0) {
|
||||
errno = -__res;
|
||||
__res = -1;
|
||||
}
|
||||
else
|
||||
errno = 0;
|
||||
return __res;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -68,7 +68,7 @@ option('listen_unix', type: 'boolean', value: true,
|
|||
option('listen_local', type: 'boolean', value: true,
|
||||
description: 'Listen on local by default')
|
||||
|
||||
option('int10', type: 'combo', choices: ['stub', 'x86emu', 'vm86', 'auto', 'false'],
|
||||
option('int10', type: 'combo', choices: ['stub', 'x86emu', 'auto', 'false'],
|
||||
value: 'auto',
|
||||
description: 'Xorg int10 backend (default: usually x86emu)')
|
||||
option('suid_wrapper', type: 'boolean', value: false,
|
||||
|
|
|
|||
Loading…
Reference in a new issue