summaryrefslogtreecommitdiff
path: root/hw/kdrive/vesa
diff options
context:
space:
mode:
Diffstat (limited to 'hw/kdrive/vesa')
-rw-r--r--hw/kdrive/vesa/Makefile.am2
-rw-r--r--hw/kdrive/vesa/Xvesa.man21
-rw-r--r--hw/kdrive/vesa/vesa.c13
-rw-r--r--hw/kdrive/vesa/vm86.c57
-rw-r--r--hw/kdrive/vesa/vm86.h9
5 files changed, 83 insertions, 19 deletions
diff --git a/hw/kdrive/vesa/Makefile.am b/hw/kdrive/vesa/Makefile.am
index 2338672a8..8bfb8a919 100644
--- a/hw/kdrive/vesa/Makefile.am
+++ b/hw/kdrive/vesa/Makefile.am
@@ -31,10 +31,12 @@ Xvesa_LDADD = \
$(top_builddir)/miext/shadow/libshadow.a \
$(top_builddir)/randr/librandr.a \
$(top_builddir)/render/librender.a \
+ $(top_builddir)/xfixes/libxfixes.a \
$(top_builddir)/fb/libfb.a \
$(top_builddir)/mi/libmi.a \
$(top_builddir)/Xext/libXext.a \
$(top_builddir)/randr/librandr.a \
$(top_builddir)/render/librender.a \
+ $(top_builddir)/xfixes/libxfixes.a \
$(top_builddir)/dix/libxpstubs.a \
$(XSERVER_LIBS)
diff --git a/hw/kdrive/vesa/Xvesa.man b/hw/kdrive/vesa/Xvesa.man
index c09defdb6..fdac902ca 100644
--- a/hw/kdrive/vesa/Xvesa.man
+++ b/hw/kdrive/vesa/Xvesa.man
@@ -15,6 +15,7 @@ running the video BIOS in VM86 mode.
.B Xvesa
can use both standard VGA BIOS modes and any modes advertised by a
VESA BIOS if available.
+
.B Xvesa
runs untrusted code with full privileges, and is therefore a fairly
insecure X server.
@@ -29,8 +30,8 @@ specifies the VESA video mode to use. If mode
.I n
is not supported by your BIOS and hardware,
.B Xvesa
-will fail, hang your system, or cause your monitor to explode; you are
-on your own. This option overrides any
+will fail, hang your system, damage your hardware, or cause a global
+thermonuclear war; you are on your own. This option overrides any
.B -screen
options.
.TP 8
@@ -60,10 +61,24 @@ want to use this option.
pass RGB values in the order that works on broken BIOSes. Use this if
the colours are wrong in PseudoColor and 16 colour modes.
.TP 8
+.B -map-holes
+use a contiguous (hole-less) memory map. This fixes a segmentation
+violation with some rare BIOSes that violate the VESA specification,
+but may cause slightly higher memory usage on systems that overcommit
+memory.
+.TP 8
.B -verbose
emit diagnostic messages during BIOS initialization and teardown.
.SH KEYBOARD
-To be written.
+Multiple key presses recognized directly by
+.B Xvesa
+are:
+.TP 8
+.B Ctrl+Alt+Backspace
+Immediately kill the server.
+.TP 8
+.B Ctrl+Alt+F1...F12
+Switch to virtual console 1 through 12.
.SH BUGS
.B Xvesa
opens all IO ports and runs your VESA BIOS, which may be assumed to be
diff --git a/hw/kdrive/vesa/vesa.c b/hw/kdrive/vesa/vesa.c
index 4913dbd79..52cc3bcfa 100644
--- a/hw/kdrive/vesa/vesa.c
+++ b/hw/kdrive/vesa/vesa.c
@@ -38,6 +38,7 @@ Bool vesa_restore = FALSE;
Bool vesa_verbose = FALSE;
Bool vesa_force_text = FALSE;
Bool vesa_restore_font = TRUE;
+Bool vesa_map_holes = TRUE;
#define VesaPriv(scr) ((VesaScreenPrivPtr) (scr)->driver)
@@ -202,7 +203,7 @@ vesaInitialize (KdCardInfo *card, VesaCardPrivPtr priv)
{
int code;
- priv->vi = Vm86Setup();
+ priv->vi = Vm86Setup(vesa_map_holes);
if(!priv->vi)
goto fail;
@@ -231,7 +232,7 @@ vesaListModes (void)
int nmode;
int n;
- vi = Vm86Setup ();
+ vi = Vm86Setup (vesa_map_holes);
if (!vi)
{
ErrorF ("Can't setup vm86\n");
@@ -267,7 +268,7 @@ vesaTestMode (void)
int nmode;
int n;
- vi = Vm86Setup ();
+ vi = Vm86Setup (vesa_map_holes);
if (!vi)
{
ErrorF ("Can't setup vm86\n");
@@ -1854,6 +1855,12 @@ vesaProcessArgument (int argc, char **argv, int i)
} else if(!strcmp(argv[i], "-force-text")) {
vesa_force_text = TRUE;
return 1;
+ } else if(!strcmp(argv[i], "-map-holes")) {
+ vesa_map_holes = TRUE;
+ return 1;
+ } else if(!strcmp(argv[i], "-no-map-holes")) {
+ vesa_map_holes = FALSE;
+ return 1;
} else if(!strcmp(argv[i], "-trash-font")) {
vesa_restore_font = FALSE;
return 1;
diff --git a/hw/kdrive/vesa/vm86.c b/hw/kdrive/vesa/vm86.c
index b5a3983ea..da85b83a9 100644
--- a/hw/kdrive/vesa/vm86.c
+++ b/hw/kdrive/vesa/vm86.c
@@ -66,10 +66,11 @@ static const U8 retcode_data[2] =
{ 0xCD, 0xFF };
Vm86InfoPtr
-Vm86Setup(void)
+Vm86Setup(int mapHoles)
{
int devmem = -1, devzero = -1;
void *magicMem, *loMem, *hiMem;
+ void *hole1, *hole2;
U32 stack_base, ret_code;
Vm86InfoPtr vi = NULL;
@@ -85,6 +86,12 @@ Vm86Setup(void)
goto fail;
}
+ magicMem = MAP_FAILED;
+ loMem = MAP_FAILED;
+ hiMem = MAP_FAILED;
+ hole1 = MAP_FAILED;
+ hole2 = MAP_FAILED;
+
magicMem = mmap((void*)MAGICMEM_BASE, MAGICMEM_SIZE,
PROT_READ | PROT_WRITE | PROT_EXEC,
@@ -92,7 +99,18 @@ Vm86Setup(void)
if(magicMem == MAP_FAILED) {
ErrorF("Couldn't map magic memory\n");
- goto fail;
+ goto unmapfail;
+ }
+
+ if(mapHoles) {
+ hole1 = mmap((void*)HOLE1_BASE, HOLE1_SIZE,
+ PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_PRIVATE | MAP_FIXED, devzero, HOLE1_BASE);
+
+ if(hole1 == MAP_FAILED) {
+ ErrorF("Couldn't map first hole\n");
+ goto unmapfail;
+ }
}
loMem = mmap((void*)LOMEM_BASE, LOMEM_SIZE,
@@ -101,7 +119,18 @@ Vm86Setup(void)
if(loMem == MAP_FAILED) {
ErrorF("Couldn't map low memory\n");
munmap(magicMem, MAGICMEM_SIZE);
- goto fail;
+ goto unmapfail;
+ }
+
+ if(mapHoles) {
+ hole2 = mmap((void*)HOLE2_BASE, HOLE2_SIZE,
+ PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_PRIVATE | MAP_FIXED, devzero, HOLE2_BASE);
+
+ if(hole2 == MAP_FAILED) {
+ ErrorF("Couldn't map first hole\n");
+ goto unmapfail;
+ }
}
hiMem = mmap((void*)HIMEM_BASE, HIMEM_SIZE,
@@ -110,9 +139,7 @@ Vm86Setup(void)
devmem, HIMEM_BASE);
if(hiMem == MAP_FAILED) {
ErrorF("Couldn't map high memory\n");
- munmap(magicMem, MAGICMEM_SIZE);
- munmap(loMem, LOMEM_SIZE);
- goto fail;
+ goto unmapfail;
}
vi = xalloc(sizeof(Vm86InfoRec));
@@ -120,7 +147,9 @@ Vm86Setup(void)
goto unmapfail;
vi->magicMem = magicMem;
+ vi->hole1 = hole1;
vi->loMem = loMem;
+ vi->hole2 = hole2;
vi->hiMem = hiMem;
vi->brk = LOMEM_BASE;
@@ -150,9 +179,11 @@ Vm86Setup(void)
return vi;
unmapfail:
- munmap(magicMem, MAGICMEM_SIZE);
- munmap(loMem, LOMEM_SIZE);
- munmap(hiMem, HIMEM_SIZE);
+ if(magicMem != MAP_FAILED) munmap(magicMem, MAGICMEM_SIZE);
+ if(hole1 != MAP_FAILED) munmap(magicMem, HOLE1_SIZE);
+ if(loMem != MAP_FAILED) munmap(loMem, LOMEM_SIZE);
+ if(hole2 != MAP_FAILED) munmap(magicMem, HOLE2_SIZE);
+ if(hiMem != MAP_FAILED) munmap(hiMem, HIMEM_SIZE);
fail:
if(devmem >= 0)
close(devmem);
@@ -166,9 +197,11 @@ fail:
void
Vm86Cleanup(Vm86InfoPtr vi)
{
- munmap(vi->magicMem, MAGICMEM_SIZE);
- munmap(vi->loMem, LOMEM_SIZE);
- munmap(vi->hiMem, HIMEM_SIZE);
+ if(vi->magicMem != MAP_FAILED) munmap(vi->magicMem, MAGICMEM_SIZE);
+ if(vi->hole1 != MAP_FAILED) munmap(vi->magicMem, HOLE1_SIZE);
+ if(vi->loMem != MAP_FAILED) munmap(vi->loMem, LOMEM_SIZE);
+ if(vi->hole2 != MAP_FAILED) munmap(vi->magicMem, HOLE2_SIZE);
+ if(vi->hiMem != MAP_FAILED) munmap(vi->hiMem, HIMEM_SIZE);
xfree(vi);
}
diff --git a/hw/kdrive/vesa/vm86.h b/hw/kdrive/vesa/vm86.h
index e37cd7f28..dce777b39 100644
--- a/hw/kdrive/vesa/vm86.h
+++ b/hw/kdrive/vesa/vm86.h
@@ -91,6 +91,12 @@ typedef unsigned int U32;
#define HIMEM_BASE 0xA0000
#define HIMEM_SIZE (SYSMEM_BASE + SYSMEM_SIZE - HIMEM_BASE)
+#define HOLE1_BASE (MAGICMEM_BASE + MAGICMEM_SIZE)
+#define HOLE1_SIZE (LOMEM_BASE - HOLE1_BASE)
+
+#define HOLE2_BASE (LOMEM_BASE + LOMEM_SIZE)
+#define HOLE2_SIZE (HIMEM_BASE - HOLE2_BASE)
+
/* The BIOS ROM */
#define ROM_BASE 0xC0000
#define ROM_SIZE 0x30000
@@ -105,6 +111,7 @@ typedef unsigned int U32;
typedef struct _Vm86InfoRec {
void *magicMem, *loMem, *hiMem;
+ void *hole1, *hole2;
U32 brk;
struct vm86_struct vms;
U32 ret_code, stack_base;
@@ -121,7 +128,7 @@ typedef struct _Vm86InfoRec {
#define HML(vi,i) (*(U32*)(&MM(vi,i)))
Vm86InfoPtr
-Vm86Setup(void);
+Vm86Setup(int);
void
Vm86Cleanup(Vm86InfoPtr vi);