xfree86: remove the vm86 int10 backend

It has not compiled since 21b216ad6 ("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 commit 173c0d170f)
This commit is contained in:
Matt Turner 2026-10-21 21:19:46 -04:00 • committed by Enrico Weigelt, metux IT consult
commit 894b058710
6 changed files with 8 additions and 899 deletions

View file

@ -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

View file

@ -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: [

View file

@ -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"

View file

@ -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;
}

View file

@ -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

View file

@ -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,