[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] x86 vmx: Remove vmxassist.



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1202299675 0
# Node ID 9d0e86d8c1d1360be64921928ae98b3693adfc73
# Parent  f8db1c6baad90b038e1cf4f91c3a829793344798
x86 vmx: Remove vmxassist.
Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx>
---
 tools/firmware/README                 |   83 -
 tools/firmware/vmxassist/Makefile     |   81 -
 tools/firmware/vmxassist/gen.c        |   52 
 tools/firmware/vmxassist/head.S       |   94 -
 tools/firmware/vmxassist/machine.h    |  199 ---
 tools/firmware/vmxassist/setup.c      |  337 -----
 tools/firmware/vmxassist/trap.S       |  179 ---
 tools/firmware/vmxassist/util.c       |  430 -------
 tools/firmware/vmxassist/util.h       |   45 
 tools/firmware/vmxassist/vm86.c       | 1992 ----------------------------------
 tools/firmware/vmxassist/vm86.h       |   64 -
 tools/firmware/vmxassist/vmxassist.ld |   32 
 xen/include/public/hvm/vmx_assist.h   |  122 --
 tools/firmware/Makefile               |    1 
 tools/firmware/hvmloader/Makefile     |    3 
 tools/firmware/hvmloader/config.h     |    1 
 tools/firmware/hvmloader/hvmloader.c  |   28 
 xen/arch/x86/Rules.mk                 |    5 
 xen/arch/x86/hvm/hvm.c                |   13 
 xen/arch/x86/hvm/vmx/Makefile         |    2 
 xen/arch/x86/hvm/vmx/vmx.c            |  298 -----
 xen/arch/x86/hvm/vmx/x86_32/exits.S   |    4 
 xen/arch/x86/hvm/vmx/x86_64/exits.S   |    4 
 xen/arch/x86/hvm/vpic.c               |    5 
 xen/include/asm-x86/hvm/vmx/vmcs.h    |   13 
 25 files changed, 5 insertions(+), 4082 deletions(-)

diff -r f8db1c6baad9 -r 9d0e86d8c1d1 tools/firmware/Makefile
--- a/tools/firmware/Makefile   Tue Feb 05 23:27:12 2008 +0000
+++ b/tools/firmware/Makefile   Wed Feb 06 12:07:55 2008 +0000
@@ -9,7 +9,6 @@ SUBDIRS :=
 SUBDIRS :=
 SUBDIRS += rombios rombios/32bit
 SUBDIRS += vgabios
-SUBDIRS += vmxassist
 SUBDIRS += extboot
 #SUBDIRS += etherboot
 SUBDIRS += hvmloader
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 tools/firmware/README
--- a/tools/firmware/README     Tue Feb 05 23:27:12 2008 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,88 +0,0 @@
-Domain firmware support
------------------------
-
-One of the key advantages of full virtualization hardware support (such
-as Intel's VT or AMD's SVM extensions) is the ability to run unmodified
-guest operating systems.  However, since most OSes rely on BIOS support
-during their early bringup, we need to provide a surrogate ROMBIOS and
-VGABIOS firmware layer.
-
-What's more, we need to support real-mode which is required by
-the firmware and bootstrap loaders. Real-mode support is especially
-challenging for Intel's VMX (VT) enabled CPUs where there is no real-mode
-support for VMX guest partitions. In this case you either have to do full
-emulation (full real-mode emulator; more complete but potentially slower)
-or partial emulation (use the VM8086 extensions, emulate only those
-instructions that are missing; faster, but potentially incomplete). The
-vmxassist code in this subdirectory uses the later approach because it
-is smaller and faster.
-
-The approach is relatively straight forward. Vmxloader contains three
-payloads (rombios, vgabios and vmxassist) and it is bootstrapped as any
-other 32-bit OS. Vmxloader copies its payloads to the addresses below
-and transfers control to vmxassist.
-
-       vgabios         VGABIOS (standard and Cirrus).
-                       Resides at C000:0000.
-
-       vmxassist       VMXAssist VM86 realmode emulator for VMX.
-                       Resides at D000:0000.
-
-       rombios         ROMBIOS code. Derived from Bochs.
-                       Resides at F000:0000
-
-Vmxassist first sets up it own world (GDT, IDT, TR, etc), enables
-VM8086 and then transfers control to F000:FFF0 and executes 16-bit
-code. Unsupported instructions cause a general protection failure at
-which point vmxassist kicks in and emulates the offending instruction.
-Whever the emulated code transitions to 32-bit protected mode, vmxassist
-will go away. Whenever 32-bit protected code transitions to real-mode,
-Xen/VMX will detect this and transfer control to vmxassist.
-
-Most of the vmxassist complexity comes from properly handling the
-real to protected mode and protected to real mode transitions and
-the proper emulation of the segment registers. Even though the Intel
-manual clearly states that you should immediately perform a jmp far
-after a mode transition, many operating systems execute additional
-instructions and some even refer to segment selectors and pop data
-from the stack. Vmxassist contains a number of work arounds for these
-OSes.
-
-
-Acknowledgements
-----------------
-
-The rombios was taken (largely unmodified) from Bochs, which was written
-by Kevin Lawton. The VGABIOS was written by Christophe Bothamy. Arun Sharma,
-Asit Mallick and Nitin Kamble (Intel) provided the E820 patches and lots
-of useful feedback.
-
-
-Contact
--------
-
-Leendert van Doorn
-IBM T.J. Watson Research Center
-19 Skyline Drive
-Hawthorne, NY 10532
-leendert@xxxxxxxxxxxxxx
-
-
-Tested Operating Systems
-------------------------
-
-Since vmxassist uses partial emulation, it may always miss opcodes
-that are required by a particular OS. The table below lists the OSes
-I have tried.  The Install column indicates a full CD/DVD install into
-a VMX partition. The Disk column indicates booting from prefabricated
-disk image.
-
-Operating System                       Install         Disk
-------------------------------------------------------------
-RedHat Enterprise Linux (RHEL3_U5)     Yes             Yes
-Fedora Code (FC3)                      (-)             Yes
-FreeBSD 5.3                            (-)             Yes
-MS-DOS 5.0                             (-)             Yes
-
-(-) not tried yet
-
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 tools/firmware/hvmloader/Makefile
--- a/tools/firmware/hvmloader/Makefile Tue Feb 05 23:27:12 2008 +0000
+++ b/tools/firmware/hvmloader/Makefile Wed Feb 06 12:07:55 2008 +0000
@@ -50,11 +50,10 @@ acpi/acpi.a:
 acpi/acpi.a:
        $(MAKE) -C acpi
 
-roms.h: ../rombios/BIOS-bochs-latest ../vgabios/VGABIOS-lgpl-latest.bin 
../vgabios/VGABIOS-lgpl-latest.cirrus.bin ../vmxassist/vmxassist.bin 
../etherboot/eb-roms.h ../extboot/extboot.bin
+roms.h: ../rombios/BIOS-bochs-latest ../vgabios/VGABIOS-lgpl-latest.bin 
../vgabios/VGABIOS-lgpl-latest.cirrus.bin ../etherboot/eb-roms.h 
../extboot/extboot.bin
        sh ./mkhex rombios ../rombios/BIOS-bochs-latest > roms.h
        sh ./mkhex vgabios_stdvga ../vgabios/VGABIOS-lgpl-latest.bin >> roms.h
        sh ./mkhex vgabios_cirrusvga ../vgabios/VGABIOS-lgpl-latest.cirrus.bin 
>> roms.h
-       sh ./mkhex vmxassist ../vmxassist/vmxassist.bin >> roms.h
        cat ../etherboot/eb-roms.h >> roms.h
        sh ./mkhex extboot ../extboot/extboot.bin >> roms.h
 
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 tools/firmware/hvmloader/config.h
--- a/tools/firmware/hvmloader/config.h Tue Feb 05 23:27:12 2008 +0000
+++ b/tools/firmware/hvmloader/config.h Wed Feb 06 12:07:55 2008 +0000
@@ -21,7 +21,6 @@
 #define HYPERCALL_PHYSICAL_ADDRESS    0x00080000
 #define VGABIOS_PHYSICAL_ADDRESS      0x000C0000
 #define ETHERBOOT_PHYSICAL_ADDRESS    0x000C8000
-#define VMXASSIST_PHYSICAL_ADDRESS    0x000D0000
 #define EXTBOOT_PHYSICAL_ADDRESS      0x000DF800
 #define SMBIOS_PHYSICAL_ADDRESS       0x000E9000
 #define SMBIOS_MAXIMUM_SIZE           0x00001000
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 tools/firmware/hvmloader/hvmloader.c
--- a/tools/firmware/hvmloader/hvmloader.c      Tue Feb 05 23:27:12 2008 +0000
+++ b/tools/firmware/hvmloader/hvmloader.c      Wed Feb 06 12:07:55 2008 +0000
@@ -1,5 +1,5 @@
 /*
- * hvmloader.c: HVM ROMBIOS/VGABIOS/ACPI/VMXAssist image loader.
+ * hvmloader.c: HVM bootloader.
  *
  * Leendert van Doorn, leendert@xxxxxxxxxxxxxx
  * Copyright (c) 2005, International Business Machines Corporation.
@@ -40,7 +40,6 @@ asm(
     "    cli                         \n"
     "    movl $stack_top,%esp        \n"
     "    movl %esp,%ebp              \n"
-    "    movl %eax,initial_eax       \n"
     "    call main                   \n"
     /* Relocate real-mode trampoline to 0x0. */
     "    mov  $trampoline_start,%esi \n"
@@ -98,8 +97,6 @@ asm(
     "stack_top:                      \n"
     );
 
-static unsigned int initial_eax;
-
 void create_mp_tables(void);
 int hvm_write_smbios_tables(void);
 
@@ -122,12 +119,6 @@ check_amd(void)
         "=d" (*(int *)(&id[4]))
         : "a" (0) );
     return __builtin_memcmp(id, "AuthenticAMD", 12) == 0;
-}
-
-static int
-use_vmxassist(void)
-{
-    return !check_amd() && !initial_eax;
 }
 
 static void
@@ -506,10 +497,6 @@ int main(void)
         printf(" %05x-%05x: Extboot ROM\n",
                EXTBOOT_PHYSICAL_ADDRESS,
                EXTBOOT_PHYSICAL_ADDRESS + extboot_sz - 1);
-    if ( use_vmxassist() )
-        printf(" %05x-%05x: VMXAssist\n",
-               VMXASSIST_PHYSICAL_ADDRESS,
-               VMXASSIST_PHYSICAL_ADDRESS + sizeof(vmxassist) - 1);
     if ( smbios_sz )
         printf(" %05x-%05x: SMBIOS tables\n",
                SMBIOS_PHYSICAL_ADDRESS,
@@ -523,19 +510,6 @@ int main(void)
                ROMBIOS_PHYSICAL_ADDRESS,
                ROMBIOS_PHYSICAL_ADDRESS + rombios_sz - 1);
 
-    if ( use_vmxassist() )
-    {
-        printf("Loading VMXAssist ...\n");
-        memcpy((void *)VMXASSIST_PHYSICAL_ADDRESS,
-               vmxassist, sizeof(vmxassist));
-
-        printf("VMX go ...\n");
-        __asm__ __volatile__(
-            "jmp *%%eax"
-            : : "a" (VMXASSIST_PHYSICAL_ADDRESS), "d" (0)
-            );
-    }
-
     printf("Invoking ROMBIOS ...\n");
     return 0;
 }
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 tools/firmware/vmxassist/Makefile
--- a/tools/firmware/vmxassist/Makefile Tue Feb 05 23:27:12 2008 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-#
-# Makefile
-#
-# Leendert van Doorn, leendert@xxxxxxxxxxxxxx
-# Copyright (c) 2005, International Business Machines Corporation.
-#
-# This program is free software; you can redistribute it and/or modify it
-# under the terms and conditions of the GNU General Public License,
-# version 2, as published by the Free Software Foundation.
-#
-# This program is distributed in the hope it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
-# more details.
-#
-# You should have received a copy of the GNU General Public License along with
-# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-# Place - Suite 330, Boston, MA 02111-1307 USA.
-#
-
-# External CFLAGS can do more harm than good.
-CFLAGS :=
-
-override XEN_TARGET_ARCH = x86_32
-XEN_ROOT = ../../..
-include $(XEN_ROOT)/tools/Rules.mk
-
-# The emulator code lives in ROM space
-TEXTADDR=0x000D0000
-
-DEFINES=-DDEBUG -DTEXTADDR=$(TEXTADDR)
-XENINC=$(CFLAGS_include)
-
-# Disable PIE/SSP if GCC supports them. They can break us.
-CFLAGS  += $(call cc-option,$(CC),-nopie,)
-CFLAGS  += $(call cc-option,$(CC),-fno-stack-protector,)
-CFLAGS  += $(call cc-option,$(CC),-fno-stack-protector-all,)
-
-CPP      = cpp -P
-CFLAGS  += $(DEFINES) -I. $(XENINC) -fno-builtin -O2 -msoft-float
-
-OBJECTS = head.o trap.o vm86.o setup.o util.o
-
-.PHONY: all
-all: vmxassist.bin
-
-vmxassist.bin: vmxassist.ld $(OBJECTS)
-       $(CPP) $(DEFINES) vmxassist.ld > vmxassist.tmp
-       $(LD) -o vmxassist $(LDFLAGS_DIRECT) --fatal-warnings -N -T 
vmxassist.tmp $(OBJECTS)
-       nm -n vmxassist > vmxassist.sym
-       $(OBJCOPY) -p -O binary -R .note -R .comment -R .bss -S --gap-fill=0 
vmxassist vmxassist.tmp
-       dd if=vmxassist.tmp of=vmxassist.bin ibs=512 conv=sync
-       rm -f vmxassist.tmp
-
-head.o: machine.h vm86.h head.S
-       $(CC) $(CFLAGS) -D__ASSEMBLY__ $(DEFINES) -c head.S
-
-trap.o: machine.h vm86.h offsets.h trap.S
-       $(CC) $(CFLAGS) -D__ASSEMBLY__ $(DEFINES) -c trap.S
-
-vm86.o: machine.h vm86.h vm86.c
-       $(CC) $(CFLAGS) -c vm86.c
-
-setup.o: machine.h vm86.h setup.c
-       $(CC) $(CFLAGS) -c setup.c
-
-util.o: machine.h vm86.h util.c
-       $(CC) $(CFLAGS) -c util.c
-
-offsets.h: gen
-       ./gen > offsets.h
-
-gen:   vm86.h gen.c
-       $(HOSTCC) $(HOSTCFLAGS) -I. $(XENINC) -o gen gen.c
-
-.PHONY: clean
-clean:
-       rm -f vmxassist vmxassist.tmp vmxassist.bin vmxassist.run vmxassist.sym 
head.s
-       rm -f $(OBJECTS)
-       rm -f gen gen.o offsets.h
-
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 tools/firmware/vmxassist/gen.c
--- a/tools/firmware/vmxassist/gen.c    Tue Feb 05 23:27:12 2008 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * gen.c: Generate assembler symbols.
- *
- * Leendert van Doorn, leendert@xxxxxxxxxxxxxx
- * Copyright (c) 2005, International Business Machines Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- */
-#include <stdio.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <vm86.h>
-
-int
-main(void)
-{
-       printf("/* MACHINE GENERATED; DO NOT EDIT */\n");
-       printf("#define VMX_ASSIST_CTX_GS_SEL   0x%x\n",
-               (unsigned int)offsetof(struct vmx_assist_context, gs_sel));
-       printf("#define VMX_ASSIST_CTX_FS_SEL   0x%x\n",
-               (unsigned int)offsetof(struct vmx_assist_context, fs_sel));
-       printf("#define VMX_ASSIST_CTX_DS_SEL   0x%x\n",
-               (unsigned int)offsetof(struct vmx_assist_context, ds_sel));
-       printf("#define VMX_ASSIST_CTX_ES_SEL   0x%x\n",
-               (unsigned int)offsetof(struct vmx_assist_context, es_sel));
-       printf("#define VMX_ASSIST_CTX_SS_SEL   0x%x\n",
-               (unsigned int)offsetof(struct vmx_assist_context, ss_sel));
-       printf("#define VMX_ASSIST_CTX_ESP      0x%x\n",
-               (unsigned int)offsetof(struct vmx_assist_context, esp));
-       printf("#define VMX_ASSIST_CTX_EFLAGS   0x%x\n",
-               (unsigned int)offsetof(struct vmx_assist_context, eflags));
-       printf("#define VMX_ASSIST_CTX_CS_SEL   0x%x\n",
-               (unsigned int)offsetof(struct vmx_assist_context, cs_sel));
-       printf("#define VMX_ASSIST_CTX_EIP      0x%x\n",
-               (unsigned int)offsetof(struct vmx_assist_context, eip));
-
-       printf("#define VMX_ASSIST_CTX_CR0      0x%x\n",
-               (unsigned int)offsetof(struct vmx_assist_context, cr0));
-
-       return 0;
-}
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 tools/firmware/vmxassist/head.S
--- a/tools/firmware/vmxassist/head.S   Tue Feb 05 23:27:12 2008 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +0,0 @@
-/*
- * head.S: VMXAssist runtime start off.
- *
- * Leendert van Doorn, leendert@xxxxxxxxxxxxxx
- * Copyright (c) 2005, International Business Machines Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- */
-#include "vm86.h"
-#include "machine.h"
-
-/*
- * When a partition tries to mask off the CR0_PE bit a world
- * switch happens to the environment below. The magic indicates
- * that this is a valid context.
- */
-       jmp     _start
-
-       .align  8
-       .long   VMXASSIST_MAGIC
-       .long   newctx                  /* new context */
-       .long   oldctx                  /* old context */
-
-/*
- * This is the real start. Control was transfered to this point
- * with CR0_PE set and executing in some 32-bit segment. We call
- * main and setup our own environment.
- */
-       .globl  _start
-       .code32
-_start:
-       cli
-
-       /* save register parameters to C land */
-
-       /* clear bss */
-       cld
-       xorb    %al, %al
-       movl    $_bbss, %edi
-       movl    $_ebss, %ecx
-       subl    %edi, %ecx
-       rep     stosb
-
-       movl    %edx, booting_cpu
-       movl    %ebx, booting_vector
-
-       /* make sure we are in a sane world */
-       clts
-
-       /* setup my own stack */
-       movl    $stack_top, %esp
-       movl    %esp, %ebp
-
-       /* go ... */
-       call    main
-       jmp     halt
-
-/*
- * Something bad happened, print invoking %eip and loop forever
- */
-       .align  4
-       .globl  halt
-halt:
-       push    $halt_msg
-       call    printf
-       cli
-       jmp     .
-
-       .data
-halt_msg:
-       .asciz  "Halt called from %%eip 0x%x\n"
-
-
-/*
- * Our stack
- */
-       .bss
-       .align  8
-       .globl  stack, stack_top
-stack:
-       .skip   STACK_SIZE
-stack_top:
-
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 tools/firmware/vmxassist/machine.h
--- a/tools/firmware/vmxassist/machine.h        Tue Feb 05 23:27:12 2008 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,199 +0,0 @@
-/*
- * machine.h: Intel CPU specific definitions
- *
- * Leendert van Doorn, leendert@xxxxxxxxxxxxxx
- * Copyright (c) 2005, International Business Machines Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- */
-#ifndef __MACHINE_H__
-#define __MACHINE_H__
-
-/* the size of our stack (4KB) */
-#define STACK_SIZE     8192
-
-#define TSS_SELECTOR   0x08
-#define CODE_SELECTOR  0x10
-#define DATA_SELECTOR  0x18
-
-#define CR0_PE         (1 << 0)
-#define CR0_EM         (1 << 2)
-#define        CR0_TS          (1 << 3)
-#define CR0_NE         (1 << 5)
-#define CR0_PG         (1 << 31)
-
-#define CR4_VME                (1 << 0)
-#define CR4_PVI                (1 << 1)
-#define CR4_PSE                (1 << 4)
-#define CR4_PAE                (1 << 5)
-
-#define EFLAGS_CF      (1 << 0)
-#define EFLAGS_PF      (1 << 2)
-#define EFLAGS_AF      (1 << 4)
-#define EFLAGS_ZF      (1 << 6)
-#define EFLAGS_SF      (1 << 7)
-#define EFLAGS_TF      (1 << 8)
-#define EFLAGS_IF      (1 << 9)
-#define EFLAGS_DF      (1 << 10)
-#define EFLAGS_OF      (1 << 11)
-#define EFLAGS_IOPL    (3 << 12)
-#define EFLAGS_VM      ((1 << 17) | EFLAGS_IOPL)
-#define EFLAGS_VIF     (1 << 19)
-#define EFLAGS_VIP     (1 << 20)
-
-#define        LOG_PGSIZE      12      /* log2(page size) */
-#define        LOG_PDSIZE      22      /* log2(page directory size) */
-
-/* Derived constants */
-#define        PGSIZE          (1 << LOG_PGSIZE)       /* page size */
-#define        PGMASK          (~(PGSIZE - 1))         /* page mask */
-#define        LPGSIZE         (1 << LOG_PDSIZE)       /* large page size */
-#define        LPGMASK         (~(LPGSIZE - 1))        /* large page mask */
-
-/* Programmable Interrupt Contoller (PIC) defines */
-#define        PIC_MASTER      0x20
-#define        PIC_SLAVE       0xA0
-
-#define        PIC_CMD         0       /* command */
-#define        PIC_ISR         0       /* interrupt status */
-#define        PIC_IMR         1       /* interrupt mask */
-
-
-#ifndef __ASSEMBLY__
-
-struct dtr {
-       unsigned short  size;
-       unsigned long   base __attribute__ ((packed));
-};
-
-struct tss {
-       unsigned short  prev_link;
-       unsigned short  _1;
-       unsigned long   esp0;
-       unsigned short  ss0;
-       unsigned short  _2;
-       unsigned long   esp1;
-       unsigned short  ss1;
-       unsigned short  _3;
-       unsigned long   esp2;
-       unsigned short  ss2;
-       unsigned short  _4;
-       unsigned long   cr3;
-       unsigned long   eip;
-       unsigned long   eflags;
-       unsigned long   eax;
-       unsigned long   ecx;
-       unsigned long   edx;
-       unsigned long   ebx;
-       unsigned long   esi;
-       unsigned long   edi;
-       unsigned long   esp;
-       unsigned long   ebp;
-       unsigned long   es;
-       unsigned long   cs;
-       unsigned long   ss;
-       unsigned long   ds;
-       unsigned long   fs;
-       unsigned long   gs;
-       unsigned short  ldt_segment;
-       unsigned short  _5;
-       unsigned short  _6;
-       unsigned short  iomap_base;
-#ifdef ENABLE_VME
-       unsigned long   int_redir[8];
-#endif
-       unsigned char   iomap[8193];
-};
-
-static inline void
-outw(unsigned short addr, unsigned short val)
-{
-       __asm__ __volatile__ ("outw %%ax, %%dx" :: "d"(addr), "a"(val));
-}
-
-static inline void
-outb(unsigned short addr, unsigned char val)
-{
-       __asm__ __volatile__ ("outb %%al, %%dx" :: "d"(addr), "a"(val));
-}
-
-static inline unsigned char
-inb(unsigned short addr)
-{
-       unsigned char val;
-
-       __asm__ __volatile__ ("inb %w1,%0" : "=a" (val) : "Nd" (addr));
-       return val;
-}
-
-static inline unsigned
-get_cmos(int reg)
-{
-       outb(0x70, reg);
-       return inb(0x71);
-}
-
-static inline unsigned
-get_cr0(void)
-{
-        unsigned rv;
-        __asm__ __volatile__("movl %%cr0, %0" : "=r"(rv));
-        return rv;
-}
-
-static inline void
-set_cr0(unsigned value)
-{
-       __asm__ __volatile__(
-               "movl   %0, %%cr0\n"
-               "jmp    1f\n"
-               "1:     nop\n"
-               : /* no outputs */
-               : "r"(value)
-       );
-}
-
-static inline unsigned
-get_cr2(void)
-{
-       unsigned rv;
-
-       __asm__ __volatile__("movl %%cr2, %0" : "=r"(rv));
-       return rv;
-}
-
-static inline unsigned
-get_cr4(void)
-{
-        unsigned rv;
-        __asm__ __volatile__("movl %%cr4, %0" : "=r"(rv));
-        return rv;
-}
-
-static inline void
-set_cr3(unsigned addr)
-{
-        __asm__ __volatile__("movl %0, %%cr3" : /* no outputs */ : "r"(addr));
-}
-
-static inline void
-set_cr4(unsigned value)
-{
-       __asm__ __volatile__("movl %0, %%cr4" : /* no outputs */ : "r"(value));
-}
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* __MACHINE_H__ */
-
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 tools/firmware/vmxassist/setup.c
--- a/tools/firmware/vmxassist/setup.c  Tue Feb 05 23:27:12 2008 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,337 +0,0 @@
-/*
- * setup.c: Setup the world for vmxassist.
- *
- * Leendert van Doorn, leendert@xxxxxxxxxxxxxx
- * Copyright (c) 2005, International Business Machines Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- */
-#include "vm86.h"
-#include "util.h"
-#include "machine.h"
-
-#if (VMXASSIST_BASE != TEXTADDR)
-#error VMXAssist base mismatch
-#endif
-
-#define        NR_PGD          (PGSIZE / sizeof(unsigned))
-
-#define        min(a, b)       ((a) > (b) ? (b) : (a))
-
-/* Which CPU are we booting, and what is the initial CS segment? */
-int booting_cpu, booting_vector;
-
-unsigned long long gdt[] __attribute__ ((aligned(32))) = {
-       0x0000000000000000ULL,          /* 0x00: reserved */
-       0x0000890000000000ULL,          /* 0x08: 32-bit TSS */
-       0x00CF9A000000FFFFULL,          /* 0x10: CS 32-bit */
-       0x00CF92000000FFFFULL,          /* 0x18: DS 32-bit */
-};
-
-struct dtr gdtr = { sizeof(gdt)-1, (unsigned long) &gdt };
-
-struct tss tss __attribute__ ((aligned(4)));
-
-unsigned long long idt[NR_TRAPS] __attribute__ ((aligned(32)));
-
-struct dtr idtr = { sizeof(idt)-1, (unsigned long) &idt };
-
-struct vmx_assist_context oldctx;
-struct vmx_assist_context newctx;
-
-unsigned long memory_size;
-int initialize_real_mode;
-
-extern char stack_top[];
-extern unsigned trap_handlers[];
-
-void
-banner(void)
-{
-       printf("VMXAssist (%s)\n", __DATE__);
-
-       /* Bochs its way to convey memory size */
-       memory_size = ((get_cmos(0x35) << 8) | get_cmos(0x34)) << 6;
-       if (memory_size > 0x3bc000)
-               memory_size = 0x3bc000;
-       memory_size = (memory_size << 10) + 0xF00000;
-       if (memory_size <= 0xF00000)
-               memory_size =
-                   (((get_cmos(0x31) << 8) | get_cmos(0x30)) + 0x400) << 10;
-       memory_size += 0x400 << 10; /* + 1MB */
-
-       printf("Memory size %ld MB\n", memory_size >> 20);
-       printf("E820 map:\n");
-       print_e820_map(HVM_E820, *HVM_E820_NR);
-       printf("\n");
-}
-
-void
-setup_gdt(void)
-{
-       unsigned long long addr = (unsigned long long) &tss;
-
-       /* setup task state segment */
-       memset(&tss, 0, sizeof(tss));
-       tss.ss0 = DATA_SELECTOR;
-       tss.esp0 = (unsigned) stack_top;
-       tss.iomap_base = offsetof(struct tss, iomap);
-       tss.iomap[sizeof(tss.iomap)-1] = 0xff;
-
-       /* initialize gdt's tss selector */
-       gdt[TSS_SELECTOR / sizeof(gdt[0])] |=
-               ((addr & 0xFF000000) << (56-24)) |
-               ((addr & 0x00FF0000) << (32-16)) |
-               ((addr & 0x0000FFFF) << (16)) |
-               (sizeof(tss) - 1);
-
-       /* switch to our own gdt and set current tss */
-       __asm__ __volatile__ ("lgdt %0" : : "m" (gdtr));
-       __asm__ __volatile__ ("movl %%eax,%%ds;"
-                             "movl %%eax,%%es;"
-                             "movl %%eax,%%fs;"
-                             "movl %%eax,%%gs;"
-                             "movl %%eax,%%ss" : : "a" (DATA_SELECTOR));
-
-       __asm__ __volatile__ ("ljmp %0,$1f; 1:" : : "i" (CODE_SELECTOR));
-
-       __asm__ __volatile__ ("ltr %%ax" : : "a" (TSS_SELECTOR));
-}
-
-void
-set_intr_gate(int i, unsigned handler)
-{
-       unsigned long long addr = handler;
-
-       idt[i] = ((addr & 0xFFFF0000ULL) << 32) | (0x8E00ULL << 32) |
-               (addr & 0xFFFFULL) | (CODE_SELECTOR << 16);
-}
-
-void
-setup_idt(void)
-{
-       int i;
-
-       for (i = 0; i < NR_TRAPS; i++)
-               set_intr_gate(i, trap_handlers[i]);
-       __asm__ __volatile__ ("lidt %0" : : "m" (idtr));
-}
-
-void
-setup_pic(void)
-{
-       /* mask all interrupts */
-       outb(PIC_MASTER + PIC_IMR, 0xFF);
-       outb(PIC_SLAVE + PIC_IMR, 0xFF);
-
-       /* setup master PIC */
-       outb(PIC_MASTER + PIC_CMD, 0x11); /* edge triggered, cascade, ICW4 */
-       outb(PIC_MASTER + PIC_IMR, NR_EXCEPTION_HANDLER);
-       outb(PIC_MASTER + PIC_IMR, 1 << 2); /* slave on channel 2 */
-       outb(PIC_MASTER + PIC_IMR, 0x01);
-
-       /* setup slave PIC */
-       outb(PIC_SLAVE + PIC_CMD, 0x11); /* edge triggered, cascade, ICW4 */
-       outb(PIC_SLAVE + PIC_IMR, NR_EXCEPTION_HANDLER + 8);
-       outb(PIC_SLAVE + PIC_IMR, 0x02); /* slave identity is 2 */
-       outb(PIC_SLAVE + PIC_IMR, 0x01);
-
-       /* enable all interrupts */
-       outb(PIC_MASTER + PIC_IMR, 0);
-       outb(PIC_SLAVE + PIC_IMR, 0);
-}
-
-void
-setiomap(int port)
-{
-       tss.iomap[port >> 3] |= 1 << (port & 7);
-}
-
-void
-enter_real_mode(struct regs *regs)
-{
-       /* mask off TSS busy bit */
-       gdt[TSS_SELECTOR / sizeof(gdt[0])] &= ~0x0000020000000000ULL;
-
-       /* start 8086 emulation of BIOS */
-       if (initialize_real_mode) {
-               initialize_real_mode = 0;
-               regs->eflags |= EFLAGS_VM | 0x02;
-               regs->ves = regs->vds = regs->vfs = regs->vgs = 0xF000;
-               if (booting_cpu == 0) {
-                       regs->cs = 0xF000; /* ROM BIOS POST entry point */
-                       regs->eip = 0xFFF0;
-               } else {
-                       regs->cs = booting_vector << 8; /* AP entry point */
-                       regs->eip = 0;
-               }
-
-               regs->uesp = regs->uss = 0;
-               regs->eax = regs->ecx = regs->edx = regs->ebx = 0;
-               regs->esp = regs->ebp = regs->esi = regs->edi = 0;
-
-               /* intercept accesses to the PIC */
-               setiomap(PIC_MASTER+PIC_CMD);
-               setiomap(PIC_MASTER+PIC_IMR);
-               setiomap(PIC_SLAVE+PIC_CMD);
-               setiomap(PIC_SLAVE+PIC_IMR);
-
-               printf("Starting emulated 16-bit real-mode: ip=%04x:%04x\n",
-                       regs->cs, regs->eip);
-
-               mode = VM86_REAL; /* becomes previous mode */
-               set_mode(regs, VM86_REAL);
-
-               /* this should get us into 16-bit mode */
-               return;
-       }
-
-       /* go from protected to real mode */
-       set_mode(regs, VM86_PROTECTED_TO_REAL);
-       emulate(regs);
-       if (mode != VM86_REAL)
-               panic("failed to emulate between clear PE and long jump.\n");
-}
-
-/*
- * Setup the environment for VMX assist.
- * This environment consists of flat segments (code and data),
- * its own gdt, idt, and tr.
- */
-void
-setup_ctx(void)
-{
-       struct vmx_assist_context *c = &newctx;
-
-       memset(c, 0, sizeof(*c));
-       c->eip = (unsigned long) switch_to_real_mode;
-       c->esp = (unsigned) stack_top;
-       c->eflags = 0x2; /* no interrupts, please */
-
-       /*
-        * Obviously, vmx assist is not running with CR0_PE disabled.
-        * The reason why the vmx assist cr0 has CR0.PE disabled is
-        * that a transtion to CR0.PE causes a world switch. It seems
-        * more natural to enable CR0.PE to cause a world switch to
-        * protected mode rather than disabling it.
-        */
-       c->cr0 = (get_cr0() | CR0_NE) & ~CR0_PE;
-       c->cr3 = 0;
-       c->cr4 = get_cr4();
-
-       c->idtr_limit = sizeof(idt)-1;
-       c->idtr_base = (unsigned long) &idt;
-
-       c->gdtr_limit = sizeof(gdt)-1;
-       c->gdtr_base = (unsigned long) &gdt;
-
-       c->cs_sel = CODE_SELECTOR;
-       c->cs_limit = 0xFFFFFFFF;
-       c->cs_base = 0;
-       c->cs_arbytes.fields.seg_type = 0xb;
-       c->cs_arbytes.fields.s = 1;
-       c->cs_arbytes.fields.dpl = 0;
-       c->cs_arbytes.fields.p = 1;
-       c->cs_arbytes.fields.avl = 0;
-       c->cs_arbytes.fields.default_ops_size = 1;
-       c->cs_arbytes.fields.g = 1;
-
-       c->ds_sel = DATA_SELECTOR;
-       c->ds_limit = 0xFFFFFFFF;
-       c->ds_base = 0;
-       c->ds_arbytes = c->cs_arbytes;
-       c->ds_arbytes.fields.seg_type = 0x3;
-
-       c->es_sel = DATA_SELECTOR;
-       c->es_limit = 0xFFFFFFFF;
-       c->es_base = 0;
-       c->es_arbytes = c->ds_arbytes;
-
-       c->ss_sel = DATA_SELECTOR;
-       c->ss_limit = 0xFFFFFFFF;
-       c->ss_base = 0;
-       c->ss_arbytes = c->ds_arbytes;
-
-       c->fs_sel = DATA_SELECTOR;
-       c->fs_limit = 0xFFFFFFFF;
-       c->fs_base = 0;
-       c->fs_arbytes = c->ds_arbytes;
-
-       c->gs_sel = DATA_SELECTOR;
-       c->gs_limit = 0xFFFFFFFF;
-       c->gs_base = 0;
-       c->gs_arbytes = c->ds_arbytes;
-
-       c->tr_sel = TSS_SELECTOR;
-       c->tr_limit = sizeof(tss) - 1;
-       c->tr_base = (unsigned long) &tss;
-       c->tr_arbytes.fields.seg_type = 0xb; /* 0x9 | 0x2 (busy) */
-       c->tr_arbytes.fields.s = 0;
-       c->tr_arbytes.fields.dpl = 0;
-       c->tr_arbytes.fields.p = 1;
-       c->tr_arbytes.fields.avl = 0;
-       c->tr_arbytes.fields.default_ops_size = 0;
-       c->tr_arbytes.fields.g = 0;
-
-       c->ldtr_sel = 0;
-       c->ldtr_limit = 0;
-       c->ldtr_base = 0;
-       c->ldtr_arbytes = c->ds_arbytes;
-       c->ldtr_arbytes.fields.seg_type = 0x2;
-       c->ldtr_arbytes.fields.s = 0;
-       c->ldtr_arbytes.fields.dpl = 0;
-       c->ldtr_arbytes.fields.p = 1;
-       c->ldtr_arbytes.fields.avl = 0;
-       c->ldtr_arbytes.fields.default_ops_size = 0;
-       c->ldtr_arbytes.fields.g = 0;
-}
-
-/*
- * Start BIOS by causing a world switch to vmxassist, which causes
- * VM8086 to be enabled and control is transfered to F000:FFF0.
- */
-void
-start_bios(void)
-{
-       if (booting_cpu == 0)
-               printf("Start BIOS ...\n");
-       else
-               printf("Start AP %d from %08x ...\n",
-                      booting_cpu, booting_vector << 12);
-
-       initialize_real_mode = 1;
-       set_cr0(get_cr0() & ~CR0_PE);
-       panic("vmxassist returned"); /* "cannot happen" */
-}
-
-int
-main(void)
-{
-       if (booting_cpu == 0)
-               banner();
-
-       setup_gdt();
-       setup_idt();
-
-       set_cr4(get_cr4() | CR4_VME);
-
-       setup_ctx();
-
-       if (booting_cpu == 0)
-               setup_pic();
-
-       start_bios();
-
-       return 0;
-}
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 tools/firmware/vmxassist/trap.S
--- a/tools/firmware/vmxassist/trap.S   Tue Feb 05 23:27:12 2008 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,179 +0,0 @@
-/*
- * trap.S: Trap and world switch handlers
- *
- * Leendert van Doorn, leendert@xxxxxxxxxxxxxx
- * Copyright (c) 2005, International Business Machines Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- */
-#include "machine.h"
-#include "vm86.h"
-#include "offsets.h"
-
-/*
- * All processor exception/faults/interrupts end up here.
- *
- * On an exception/fault, the processor pushes CS:EIP, SS, ESP and an
- * optional error code onto the stack. The common_trap routine
- * below saves the processor context and transfers control to trap()
- * whose job it is to virtualize and pass on the trap.
- */
-       .macro  TRAP_HANDLER trapno error
-       .text
-       .align  16
-1:     .if     \error == 0
-       pushl   $0                      /* dummy error code */
-       .endif
-       pushl   $\trapno
-       jmp     common_trap
-       .section .rodata
-       .long   1b
-       .text
-       .endm
-
-       .section .rodata
-       .code32
-       .align  4
-       .global trap_handlers
-trap_handlers:
-       TRAP_HANDLER    0, 0    /* divide error */
-       TRAP_HANDLER    1, 0    /* debug */
-       TRAP_HANDLER    2, 0    /* NMI interrupt */
-       TRAP_HANDLER    3, 0    /* breakpoint */
-       TRAP_HANDLER    4, 0    /* overflow */
-       TRAP_HANDLER    5, 0    /* BOUND range exceeded */
-       TRAP_HANDLER    6, 0    /* invalid opcode */
-       TRAP_HANDLER    7, 0    /* device not available */
-       TRAP_HANDLER    8, 1    /* double fault */
-       TRAP_HANDLER    9, 0    /* coprocessor segment overrun */
-       TRAP_HANDLER    10, 1   /* invalid TSS */
-       TRAP_HANDLER    11, 1   /* segment not present */
-       TRAP_HANDLER    12, 1   /* stack-segment fault */
-       TRAP_HANDLER    13, 1   /* general protection */
-       TRAP_HANDLER    14, 1   /* page fault */
-       TRAP_HANDLER    15, 0   /* reserved */
-       TRAP_HANDLER    16, 0   /* FPU floating-point error */
-       TRAP_HANDLER    17, 1   /* alignment check */
-       TRAP_HANDLER    18, 0   /* machine check */
-       TRAP_HANDLER    19, 0   /* SIMD floating-point error */
-       TRAP_HANDLER    20, 0   /* reserved */
-       TRAP_HANDLER    21, 0   /* reserved */
-       TRAP_HANDLER    22, 0   /* reserved */
-       TRAP_HANDLER    23, 0   /* reserved */
-       TRAP_HANDLER    24, 0   /* reserved */
-       TRAP_HANDLER    25, 0   /* reserved */
-       TRAP_HANDLER    26, 0   /* reserved */
-       TRAP_HANDLER    27, 0   /* reserved */
-       TRAP_HANDLER    28, 0   /* reserved */
-       TRAP_HANDLER    29, 0   /* reserved */
-       TRAP_HANDLER    30, 0   /* reserved */
-       TRAP_HANDLER    31, 0   /* reserved */
-       TRAP_HANDLER    32, 0   /* irq 0 */
-       TRAP_HANDLER    33, 0   /* irq 1 */
-       TRAP_HANDLER    34, 0   /* irq 2 */
-       TRAP_HANDLER    35, 0   /* irq 3 */
-       TRAP_HANDLER    36, 0   /* irq 4 */
-       TRAP_HANDLER    37, 0   /* irq 5 */
-       TRAP_HANDLER    38, 0   /* irq 6 */
-       TRAP_HANDLER    39, 0   /* irq 7 */
-       TRAP_HANDLER    40, 0   /* irq 8 */
-       TRAP_HANDLER    41, 0   /* irq 9 */
-       TRAP_HANDLER    42, 0   /* irq 10 */
-       TRAP_HANDLER    43, 0   /* irq 11 */
-       TRAP_HANDLER    44, 0   /* irq 12 */
-       TRAP_HANDLER    45, 0   /* irq 13 */
-       TRAP_HANDLER    46, 0   /* irq 14 */
-       TRAP_HANDLER    47, 0   /* irq 15 */
-
-       .text
-       .code32
-       .align  16
-common_trap:                           /* common trap handler */
-       pushal
-
-       movl    $(DATA_SELECTOR), %eax  /* make sure these are sane */
-       movl    %eax, %ds
-       movl    %eax, %es
-       movl    %eax, %fs
-       movl    %eax, %gs
-       movl    %esp, %ebp
-
-       pushl   %ebp
-       pushl   36(%ebp)
-       pushl   32(%ebp)
-       call    trap                    /* trap(trapno, errno, regs) */
-       addl    $12, %esp
-
-trap_return:
-       popal
-       addl    $8, %esp                /* skip trapno, errno */
-       iret
-       /* NOT REACHED */
-
-
-/*
- * A world switch to real mode occured. The hypervisor saved the
- * executing context into "oldctx" and instantiated "newctx", which
- * gets us here. Here we push a stack frame that is compatible with
- * a trap frame (see above) so that we can handle this event as a
- * regular trap.
- */
-       .text
-       .align  16
-       .globl  switch_to_real_mode
-switch_to_real_mode:
-       pushl   oldctx+VMX_ASSIST_CTX_GS_SEL /* 16 to 32-bit transition */
-       pushl   oldctx+VMX_ASSIST_CTX_FS_SEL
-       pushl   oldctx+VMX_ASSIST_CTX_DS_SEL
-       pushl   oldctx+VMX_ASSIST_CTX_ES_SEL
-       pushl   oldctx+VMX_ASSIST_CTX_SS_SEL
-       pushl   oldctx+VMX_ASSIST_CTX_ESP
-       pushl   oldctx+VMX_ASSIST_CTX_EFLAGS
-       pushl   oldctx+VMX_ASSIST_CTX_CS_SEL
-       pushl   oldctx+VMX_ASSIST_CTX_EIP
-       pushl   $-1                     /* trapno, errno */
-       pushl   $-1
-       pushal
-
-       movl    %esp, %ebp
-       pushl   %ebp
-       call    enter_real_mode
-       addl    $4, %esp
-
-       jmp     trap_return
-       /* NOT REACHED */
-
-
-/*
- * Switch to protected mode. At this point all the registers have
- * been reloaded by trap_return and all we have to do is cause a
- * world switch by turning on CR0.PE.
- */
-       .text
-       .align  16
-       .globl  switch_to_protected_mode
-switch_to_protected_mode:
-       movl    oldctx+VMX_ASSIST_CTX_CR0, %esp
-       movl    %esp, %cr0              /* actual world switch ! */
-
-       /* NOT REACHED */
-       pushl   $switch_failed
-       call    panic
-       jmp     .
-
-       .data
-       .align  4
-switch_failed:
-       .asciz  "World switch to protected mode failed\n"
-
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 tools/firmware/vmxassist/util.c
--- a/tools/firmware/vmxassist/util.c   Tue Feb 05 23:27:12 2008 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,430 +0,0 @@
-/*
- * util.c: Commonly used utility functions.
- *
- * Leendert van Doorn, leendert@xxxxxxxxxxxxxx
- * Copyright (c) 2005, International Business Machines Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- */
-#include <stdarg.h>
-
-#include "util.h"
-#include "machine.h"
-
-#define        isdigit(c)      ((c) >= '0' && (c) <= '9')
-#define        min(a, b)       ((a) < (b) ? (a) : (b))
-
-static void putchar(int);
-static char *printnum(char *, unsigned long, int);
-static void _doprint(void (*)(int), const char *, va_list);
-
-void
-cpuid_addr_value(uint64_t addr, uint64_t *value)
-{
-       uint32_t addr_low   = (uint32_t)addr;
-       uint32_t addr_high  = (uint32_t)(addr >> 32);
-       uint32_t value_low, value_high;
-       static unsigned int addr_leaf;
-
-       if (!addr_leaf) {
-               unsigned int eax, ebx, ecx, edx;
-               __asm__ __volatile__(
-                       "cpuid"
-                       : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx)
-                       : "0" (0x40000000));
-               addr_leaf = eax + 1;
-       }
-
-       __asm__ __volatile__(
-               "cpuid"
-               : "=c" (value_low), "=d" (value_high)
-               : "a" (addr_leaf), "0" (addr_low), "1" (addr_high)
-               : "ebx");
-
-       *value = (uint64_t)value_high << 32 | value_low;
-}
-
-void
-dump_regs(struct regs *regs)
-{
-       printf("eax    %8x ecx    %8x edx    %8x ebx    %8x\n",
-               regs->eax, regs->ecx, regs->edx, regs->ebx);
-       printf("esp    %8x ebp    %8x esi    %8x edi    %8x\n",
-               regs->esp, regs->ebp, regs->esi, regs->edi);
-       printf("trapno %8x errno  %8x\n", regs->trapno, regs->errno);
-       printf("eip    %8x cs     %8x eflags %8x\n",
-               regs->eip, regs->cs, regs->eflags);
-       printf("uesp   %8x uss    %8x\n",
-               regs->uesp, regs->uss);
-       printf("ves    %8x vds    %8x vfs    %8x vgs    %8x\n",
-               regs->ves, regs->vds, regs->vfs, regs->vgs);
-
-       printf("cr0    %8lx cr2    %8x cr3    %8lx cr4    %8lx\n\n",
-               (long)oldctx.cr0, get_cr2(),
-               (long)oldctx.cr3, (long)oldctx.cr4);
-}
-
-#ifdef DEBUG
-void
-hexdump(unsigned char *data, int sz)
-{
-       unsigned char *d;
-       int i;
-
-       for (d = data; sz > 0; d += 16, sz -= 16) {
-               int n = sz > 16 ? 16 : sz;
-
-               printf("%08x: ", (unsigned)d);
-               for (i = 0; i < n; i++)
-                       printf("%02x%c", d[i], i == 7 ? '-' : ' ');
-               for (; i < 16; i++)
-                       printf("  %c", i == 7 ? '-' : ' ');
-               printf("   ");
-               for (i = 0; i < n; i++)
-                       printf("%c", d[i] >= ' ' && d[i] <= '~' ? d[i] : '.');
-               printf("\n");
-       }
-}
-
-void
-print_e820_map(struct e820entry *map, int entries)
-{
-       struct e820entry *m;
-
-       if (entries > 32)
-               entries = 32;
-
-       for (m = map; m < &map[entries]; m++) {
-               printf("%08lx%08lx - %08lx%08lx ",
-                       (unsigned long) (m->addr >> 32),
-                       (unsigned long) (m->addr),
-                       (unsigned long) ((m->addr+m->size) >> 32),
-                       (unsigned long) ((m->addr+m->size)));
-
-               switch (m->type) {
-               case E820_RAM:
-                       printf("(RAM)\n"); break;
-               case E820_RESERVED:
-                       printf("(Reserved)\n"); break;
-               case E820_ACPI:
-                       printf("(ACPI Data)\n"); break;
-               case E820_NVS:
-                       printf("(ACPI NVS)\n"); break;
-               default:
-                       printf("(Type %ld)\n", m->type); break;
-               }
-       }
-}
-
-void
-dump_dtr(unsigned long addr, unsigned long size)
-{
-       unsigned long long entry;
-       unsigned long base, limit;
-       int i;
-
-       for (i = 0; i < size; i += 8) {
-               entry = ((unsigned long long *) addr)[i >> 3];
-               base = (((entry >> (56-24)) & 0xFF000000) |
-                       ((entry >> (32-16)) & 0x00FF0000) |
-                       ((entry >> (   16)) & 0x0000FFFF));
-               limit = (((entry >> (48-16)) & 0x000F0000) |
-                        ((entry           ) & 0x0000FFFF));
-               if (entry & (1ULL << (23+32))) /* G */
-                       limit = (limit << 12) | 0xFFF;
-
-               printf("[0x%x] = 0x%08x%08x, base 0x%lx, limit 0x%lx\n", i,
-                       (unsigned)(entry >> 32), (unsigned)(entry),
-                       base, limit);
-       }
-}
-
-void
-dump_vmx_context(struct vmx_assist_context *c)
-{
-       printf("eip 0x%lx, esp 0x%lx, eflags 0x%lx\n",
-               (long) c->eip, (long) c->esp, (long) c->eflags);
-
-       printf("cr0 0x%lx, cr3 0x%lx, cr4 0x%lx\n",
-               (long)c->cr0, (long)c->cr3, (long)c->cr4);
-
-       printf("idtr: limit 0x%lx, base 0x%lx\n",
-               (long)c->idtr_limit, (long)c->idtr_base);
-
-       printf("gdtr: limit 0x%lx, base 0x%lx\n",
-               (long)c->gdtr_limit, (long)c->gdtr_base);
-
-       printf("cs: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
-               (long)c->cs_sel, (long)c->cs_limit, (long)c->cs_base);
-       printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
-               c->cs_arbytes.fields.seg_type,
-               c->cs_arbytes.fields.s,
-               c->cs_arbytes.fields.dpl,
-               c->cs_arbytes.fields.p,
-               c->cs_arbytes.fields.avl,
-               c->cs_arbytes.fields.default_ops_size,
-               c->cs_arbytes.fields.g,
-               c->cs_arbytes.fields.null_bit);
-
-       printf("ds: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
-               (long)c->ds_sel, (long)c->ds_limit, (long)c->ds_base);
-       printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
-               c->ds_arbytes.fields.seg_type,
-               c->ds_arbytes.fields.s,
-               c->ds_arbytes.fields.dpl,
-               c->ds_arbytes.fields.p,
-               c->ds_arbytes.fields.avl,
-               c->ds_arbytes.fields.default_ops_size,
-               c->ds_arbytes.fields.g,
-               c->ds_arbytes.fields.null_bit);
-
-       printf("es: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
-               (long)c->es_sel, (long)c->es_limit, (long)c->es_base);
-       printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
-               c->es_arbytes.fields.seg_type,
-               c->es_arbytes.fields.s,
-               c->es_arbytes.fields.dpl,
-               c->es_arbytes.fields.p,
-               c->es_arbytes.fields.avl,
-               c->es_arbytes.fields.default_ops_size,
-               c->es_arbytes.fields.g,
-               c->es_arbytes.fields.null_bit);
-
-       printf("ss: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
-               (long)c->ss_sel, (long)c->ss_limit, (long)c->ss_base);
-       printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
-               c->ss_arbytes.fields.seg_type,
-               c->ss_arbytes.fields.s,
-               c->ss_arbytes.fields.dpl,
-               c->ss_arbytes.fields.p,
-               c->ss_arbytes.fields.avl,
-               c->ss_arbytes.fields.default_ops_size,
-               c->ss_arbytes.fields.g,
-               c->ss_arbytes.fields.null_bit);
-
-       printf("fs: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
-               (long)c->fs_sel, (long)c->fs_limit, (long)c->fs_base);
-       printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
-               c->fs_arbytes.fields.seg_type,
-               c->fs_arbytes.fields.s,
-               c->fs_arbytes.fields.dpl,
-               c->fs_arbytes.fields.p,
-               c->fs_arbytes.fields.avl,
-               c->fs_arbytes.fields.default_ops_size,
-               c->fs_arbytes.fields.g,
-               c->fs_arbytes.fields.null_bit);
-
-       printf("gs: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
-               (long)c->gs_sel, (long)c->gs_limit, (long)c->gs_base);
-       printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
-               c->gs_arbytes.fields.seg_type,
-               c->gs_arbytes.fields.s,
-               c->gs_arbytes.fields.dpl,
-               c->gs_arbytes.fields.p,
-               c->gs_arbytes.fields.avl,
-               c->gs_arbytes.fields.default_ops_size,
-               c->gs_arbytes.fields.g,
-               c->gs_arbytes.fields.null_bit);
-
-       printf("tr: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
-               (long)c->tr_sel, (long)c->tr_limit, (long)c->tr_base);
-       printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
-               c->tr_arbytes.fields.seg_type,
-               c->tr_arbytes.fields.s,
-               c->tr_arbytes.fields.dpl,
-               c->tr_arbytes.fields.p,
-               c->tr_arbytes.fields.avl,
-               c->tr_arbytes.fields.default_ops_size,
-               c->tr_arbytes.fields.g,
-               c->tr_arbytes.fields.null_bit);
-
-       printf("ldtr: sel 0x%lx, limit 0x%lx, base 0x%lx\n",
-               (long)c->ldtr_sel, (long)c->ldtr_limit, (long)c->ldtr_base);
-       printf("\ttype %d, s %d, dpl %d, p %d, avl %d, ops %d, g %d, nul %d\n",
-               c->ldtr_arbytes.fields.seg_type,
-               c->ldtr_arbytes.fields.s,
-               c->ldtr_arbytes.fields.dpl,
-               c->ldtr_arbytes.fields.p,
-               c->ldtr_arbytes.fields.avl,
-               c->ldtr_arbytes.fields.default_ops_size,
-               c->ldtr_arbytes.fields.g,
-               c->ldtr_arbytes.fields.null_bit);
-
-       printf("GDTR <0x%lx,0x%lx>:\n",
-               (long)c->gdtr_base, (long)c->gdtr_limit);
-       dump_dtr(c->gdtr_base, c->gdtr_limit);
-}
-#endif /* DEBUG */
-
-/*
- * Lightweight printf that doesn't drag in everything under the sun.
- */
-int
-printf(const char *fmt, ...)
-{
-       va_list ap;
-
-       va_start(ap, fmt);
-       _doprint(putchar, fmt, ap);
-       va_end(ap);
-       return 0; /* for gcc compat */
-}
-
-int
-vprintf(const char *fmt, va_list ap)
-{
-       _doprint(putchar, fmt, ap);
-       return 0; /* for gcc compat */
-}
-
-void
-panic(const char *fmt, ...)
-{
-       va_list ap;
-
-       va_start(ap, fmt);
-       _doprint(putchar, fmt, ap);
-       putchar('\n');
-       va_end(ap);
-       halt();
-}
-
-unsigned
-strlen(const char *s)
-{
-       const char *q = s;
-
-       while (*s++)
-               /* void */;
-       return s - q - 1;
-}
-
-static void
-putchar(int ch)
-{
-       outb(0xE9, ch);
-}
-
-/*
- * A stripped down version of doprint,
- * but still powerful enough for most tasks.
- */
-static void
-_doprint(void (*put)(int), const char *fmt, va_list ap)
-{
-       register char *str, c;
-       int lflag, zflag, nflag;
-       char buffer[17];
-       unsigned value;
-       int i, slen, pad;
-
-       for ( ; *fmt != '\0'; fmt++) {
-               pad = zflag = nflag = lflag = 0;
-               if (*fmt == '%') {
-                       c = *++fmt;
-                       if (c == '-' || isdigit(c)) {
-                               if (c == '-') {
-                                       nflag = 1;
-                                       c = *++fmt;
-                               }
-                               zflag = c == '0';
-                               for (pad = 0; isdigit(c); c = *++fmt)
-                                       pad = (pad * 10) + c - '0';
-                       }
-                       if (c == 'l') { /* long extension */
-                               lflag = 1;
-                               c = *++fmt;
-                       }
-                       if (c == 'd' || c == 'u' || c == 'o' || c == 'x') {
-                               if (lflag)
-                                       value = va_arg(ap, unsigned);
-                               else
-                                       value = (unsigned) va_arg(ap, unsigned 
int);
-                               str = buffer;
-                               printnum(str, value,
-                                       c == 'o' ? 8 : (c == 'x' ? 16 : 10));
-                               goto printn;
-                       } else if (c == 'O' || c == 'D' || c == 'X') {
-                               value = va_arg(ap, unsigned);
-                               str = buffer;
-                               printnum(str, value,
-                                       c == 'O' ? 8 : (c == 'X' ? 16 : 10));
-                       printn:
-                               slen = strlen(str);
-                               for (i = pad - slen; i > 0; i--)
-                                       put(zflag ? '0' : ' ');
-                               while (*str) put(*str++);
-                       } else if (c == 's') {
-                               str = va_arg(ap, char *);
-                               slen = strlen(str);
-                               if (nflag == 0)
-                                       for (i = pad - slen; i > 0; i--) put(' 
');
-                               while (*str) put(*str++);
-                               if (nflag)
-                                       for (i = pad - slen; i > 0; i--) put(' 
');
-                       } else if (c == 'c')
-                               put(va_arg(ap, int));
-                       else
-                               put(*fmt);
-               } else
-                       put(*fmt);
-       }
-}
-
-static char *
-printnum(char *p, unsigned long num, int base)
-{
-       unsigned long n;
-
-       if ((n = num/base) > 0)
-               p = printnum(p, n, base);
-       *p++ = "0123456789ABCDEF"[(int)(num % base)];
-       *p = '\0';
-       return p;
-}
-
-void *
-memset(void *s, int c, unsigned n)
-{
-        int t0, t1;
-
-        __asm__ __volatile__ ("cld; rep; stosb"
-                : "=&c" (t0), "=&D" (t1)
-                : "a" (c), "1" (s), "0" (n)
-                : "memory");
-        return s;
-}
-
-void *
-memcpy(void *dest, const void *src, unsigned n)
-{
-       int t0, t1, t2;
-
-       __asm__ __volatile__(
-               "cld\n"
-               "rep; movsl\n"
-               "testb $2,%b4\n"
-               "je 1f\n"
-               "movsw\n"
-               "1: testb $1,%b4\n"
-               "je 2f\n"
-               "movsb\n"
-               "2:"
-               : "=&c" (t0), "=&D" (t1), "=&S" (t2)
-               : "0" (n/4), "q" (n), "1" ((long) dest), "2" ((long) src)
-               : "memory"
-       );
-       return dest;
-}
-
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 tools/firmware/vmxassist/util.h
--- a/tools/firmware/vmxassist/util.h   Tue Feb 05 23:27:12 2008 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +0,0 @@
-/*
- * util.h: Useful utility functions.
- *
- * Leendert van Doorn, leendert@xxxxxxxxxxxxxx
- * Copyright (c) 2005, International Business Machines Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- */
-#ifndef __UTIL_H__
-#define __UTIL_H__
-
-#include <stdarg.h>
-#include <vm86.h>
-
-#define        offsetof(type, member)  ((unsigned) &((type *)0)->member)
-
-struct vmx_assist_context;
-
-#include "../hvmloader/e820.h"
-
-extern void cpuid_addr_value(uint64_t addr, uint64_t *value);
-extern void hexdump(unsigned char *, int);
-extern void dump_regs(struct regs *);
-extern void dump_vmx_context(struct vmx_assist_context *);
-extern void print_e820_map(struct e820entry *, int);
-extern void dump_dtr(unsigned long, unsigned long);
-extern void *memcpy(void *, const void *, unsigned);
-extern void *memset(void *, int, unsigned);
-extern int printf(const char *fmt, ...);
-extern int vprintf(const char *fmt, va_list ap);
-extern void panic(const char *format, ...);
-extern void halt(void);
-
-#endif /* __UTIL_H__ */
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 tools/firmware/vmxassist/vm86.c
--- a/tools/firmware/vmxassist/vm86.c   Tue Feb 05 23:27:12 2008 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,1992 +0,0 @@
-/*
- * vm86.c: A vm86 emulator. The main purpose of this emulator is to do as
- * little work as possible.
- *
- * Leendert van Doorn, leendert@xxxxxxxxxxxxxx
- * Copyright (c) 2005-2006, International Business Machines Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- */
-#include "vm86.h"
-#include "util.h"
-#include "machine.h"
-
-#define        HIGHMEM         (1 << 20)               /* 1MB */
-#define        MASK16(v)       ((v) & 0xFFFF)
-
-#define        DATA32          0x0001
-#define        ADDR32          0x0002
-#define        SEG_CS          0x0004
-#define        SEG_DS          0x0008
-#define        SEG_ES          0x0010
-#define        SEG_SS          0x0020
-#define        SEG_FS          0x0040
-#define        SEG_GS          0x0080
-#define REP            0x0100
-
-static unsigned prev_eip = 0;
-enum vm86_mode mode = 0;
-
-static struct regs saved_rm_regs;
-
-#ifdef DEBUG
-int traceset = 0;
-
-char *states[] = {
-       "<VM86_REAL>",
-       "<VM86_REAL_TO_PROTECTED>",
-       "<VM86_PROTECTED_TO_REAL>",
-       "<VM86_PROTECTED>"
-};
-
-static char *rnames[] = { "ax", "cx", "dx", "bx", "sp", "bp", "si", "di" };
-#endif /* DEBUG */
-
-#define PDE_PS                         (1 << 7)
-#define PT_ENTRY_PRESENT       0x1
-
-/* We only support access to <=4G physical memory due to 1:1 mapping */
-static uint64_t
-guest_linear_to_phys(uint32_t base)
-{
-       uint32_t gcr3 = oldctx.cr3;
-       uint64_t l2_mfn;
-       uint64_t l1_mfn;
-       uint64_t l0_mfn;
-
-       if (!(oldctx.cr0 & CR0_PG))
-               return base;
-
-       if (!(oldctx.cr4 & CR4_PAE)) {
-               l1_mfn = ((uint32_t *)(long)gcr3)[(base >> 22) & 0x3ff];
-               if (!(l1_mfn & PT_ENTRY_PRESENT))
-                       panic("l2 entry not present\n");
-
-               if ((oldctx.cr4 & CR4_PSE) && (l1_mfn & PDE_PS)) {
-                       l0_mfn = l1_mfn & 0xffc00000;
-                       return l0_mfn + (base & 0x3fffff);
-               }
-
-               l1_mfn &= 0xfffff000;
-
-               l0_mfn = ((uint32_t *)(long)l1_mfn)[(base >> 12) & 0x3ff];
-               if (!(l0_mfn & PT_ENTRY_PRESENT))
-                       panic("l1 entry not present\n");
-               l0_mfn &= 0xfffff000;
-
-               return l0_mfn + (base & 0xfff);
-       } else {
-               l2_mfn = ((uint64_t *)(long)gcr3)[(base >> 30) & 0x3];
-               if (!(l2_mfn & PT_ENTRY_PRESENT))
-                       panic("l3 entry not present\n");
-               l2_mfn &= 0xffffff000ULL;
-
-               if (l2_mfn & 0xf00000000ULL) {
-                       printf("l2 page above 4G\n");
-                       cpuid_addr_value(l2_mfn + 8 * ((base >> 21) & 0x1ff), 
&l1_mfn);
-               } else
-                       l1_mfn = ((uint64_t *)(long)l2_mfn)[(base >> 21) & 
0x1ff];
-               if (!(l1_mfn & PT_ENTRY_PRESENT))
-                       panic("l2 entry not present\n");
-
-               if (l1_mfn & PDE_PS) { /* CR4.PSE is ignored in PAE mode */
-                       l0_mfn = l1_mfn & 0xfffe00000ULL;
-                       return l0_mfn + (base & 0x1fffff);
-               }
-
-               l1_mfn &= 0xffffff000ULL;
-
-               if (l1_mfn & 0xf00000000ULL) {
-                       printf("l1 page above 4G\n");
-                       cpuid_addr_value(l1_mfn + 8 * ((base >> 12) & 0x1ff), 
&l0_mfn);
-               } else
-                       l0_mfn = ((uint64_t *)(long)l1_mfn)[(base >> 12) & 
0x1ff];
-               if (!(l0_mfn & PT_ENTRY_PRESENT))
-                       panic("l1 entry not present\n");
-
-               l0_mfn &= 0xffffff000ULL;
-
-               return l0_mfn + (base & 0xfff);
-       }
-}
-
-static unsigned
-address(struct regs *regs, unsigned seg, unsigned off)
-{
-       uint64_t gdt_phys_base;
-       unsigned long long entry;
-       unsigned seg_base, seg_limit;
-       unsigned entry_low, entry_high;
-
-       if (seg == 0) {
-               if (mode == VM86_REAL || mode == VM86_REAL_TO_PROTECTED)
-                       return off;
-               else
-                       panic("segment is zero, but not in real mode!\n");
-       }
-
-       if (mode == VM86_REAL || seg > oldctx.gdtr_limit ||
-               (mode == VM86_REAL_TO_PROTECTED && regs->cs == seg))
-               return ((seg & 0xFFFF) << 4) + off;
-
-       gdt_phys_base = guest_linear_to_phys(oldctx.gdtr_base);
-       if (gdt_phys_base != (uint32_t)gdt_phys_base) {
-               printf("gdt base address above 4G\n");
-               cpuid_addr_value(gdt_phys_base + 8 * (seg >> 3), &entry);
-       } else
-               entry = ((unsigned long long *)(long)gdt_phys_base)[seg >> 3];
-
-       entry_high = entry >> 32;
-       entry_low = entry & 0xFFFFFFFF;
-
-       seg_base  = (entry_high & 0xFF000000) | ((entry >> 16) & 0xFFFFFF);
-       seg_limit = (entry_high & 0xF0000) | (entry_low & 0xFFFF);
-
-       if (entry_high & 0x8000 &&
-               ((entry_high & 0x800000 && off >> 12 <= seg_limit) ||
-               (!(entry_high & 0x800000) && off <= seg_limit)))
-               return seg_base + off;
-
-       panic("should never reach here in function address():\n\t"
-                 "entry=0x%08x%08x, mode=%d, seg=0x%08x, offset=0x%08x\n",
-                 entry_high, entry_low, mode, seg, off);
-
-       return 0;
-}
-
-#ifdef DEBUG
-void
-trace(struct regs *regs, int adjust, char *fmt, ...)
-{
-       unsigned off = regs->eip - adjust;
-       va_list ap;
-
-       if ((traceset & (1 << mode)) &&
-               (mode == VM86_REAL_TO_PROTECTED || mode == VM86_REAL)) {
-               /* 16-bit, seg:off addressing */
-               unsigned addr = address(regs, regs->cs, off);
-               printf("0x%08x: 0x%x:0x%04x ", addr, regs->cs, off);
-               printf("(%d) ", mode);
-               va_start(ap, fmt);
-               vprintf(fmt, ap);
-               va_end(ap);
-               printf("\n");
-       }
-       if ((traceset & (1 << mode)) &&
-               (mode == VM86_PROTECTED_TO_REAL || mode == VM86_PROTECTED)) {
-               /* 16-bit, gdt addressing */
-               unsigned addr = address(regs, regs->cs, off);
-               printf("0x%08x: 0x%x:0x%08x ", addr, regs->cs, off);
-               printf("(%d) ", mode);
-               va_start(ap, fmt);
-               vprintf(fmt, ap);
-               va_end(ap);
-               printf("\n");
-       }
-}
-#endif /* DEBUG */
-
-static inline unsigned
-read32(unsigned addr)
-{
-       return *(unsigned long *) addr;
-}
-
-static inline unsigned
-read16(unsigned addr)
-{
-       return *(unsigned short *) addr;
-}
-
-static inline unsigned
-read8(unsigned addr)
-{
-       return *(unsigned char *) addr;
-}
-
-static inline void
-write32(unsigned addr, unsigned value)
-{
-       *(unsigned long *) addr = value;
-}
-
-static inline void
-write16(unsigned addr, unsigned value)
-{
-       *(unsigned short *) addr = value;
-}
-
-static inline void
-write8(unsigned addr, unsigned value)
-{
-       *(unsigned char *) addr = value;
-}
-
-static inline void
-push32(struct regs *regs, unsigned value)
-{
-       regs->uesp -= 4;
-       write32(address(regs, regs->uss, MASK16(regs->uesp)), value);
-}
-
-static inline void
-push16(struct regs *regs, unsigned value)
-{
-       regs->uesp -= 2;
-       write16(address(regs, regs->uss, MASK16(regs->uesp)), value);
-}
-
-static inline unsigned
-pop32(struct regs *regs)
-{
-       unsigned value = read32(address(regs, regs->uss, MASK16(regs->uesp)));
-       regs->uesp += 4;
-       return value;
-}
-
-static inline unsigned
-pop16(struct regs *regs)
-{
-       unsigned value = read16(address(regs, regs->uss, MASK16(regs->uesp)));
-       regs->uesp += 2;
-       return value;
-}
-
-static inline unsigned
-fetch32(struct regs *regs)
-{
-       unsigned addr = address(regs, regs->cs, MASK16(regs->eip));
-
-       regs->eip += 4;
-       return read32(addr);
-}
-
-static inline unsigned
-fetch16(struct regs *regs)
-{
-       unsigned addr = address(regs, regs->cs, MASK16(regs->eip));
-
-       regs->eip += 2;
-       return read16(addr);
-}
-
-static inline unsigned
-fetch8(struct regs *regs)
-{
-       unsigned addr = address(regs, regs->cs, MASK16(regs->eip));
-
-       regs->eip++;
-       return read8(addr);
-}
-
-static unsigned
-getreg32(struct regs *regs, int r)
-{
-       switch (r & 7) {
-       case 0: return regs->eax;
-       case 1: return regs->ecx;
-       case 2: return regs->edx;
-       case 3: return regs->ebx;
-       case 4: return regs->uesp;
-       case 5: return regs->ebp;
-       case 6: return regs->esi;
-       case 7: return regs->edi;
-       }
-       return ~0;
-}
-
-static unsigned
-getreg16(struct regs *regs, int r)
-{
-       return MASK16(getreg32(regs, r));
-}
-
-static unsigned
-getreg8(struct regs *regs, int r)
-{
-       switch (r & 7) {
-       case 0: return regs->eax & 0xFF; /* al */
-       case 1: return regs->ecx & 0xFF; /* cl */
-       case 2: return regs->edx & 0xFF; /* dl */
-       case 3: return regs->ebx & 0xFF; /* bl */
-       case 4: return (regs->eax >> 8) & 0xFF; /* ah */
-       case 5: return (regs->ecx >> 8) & 0xFF; /* ch */
-       case 6: return (regs->edx >> 8) & 0xFF; /* dh */
-       case 7: return (regs->ebx >> 8) & 0xFF; /* bh */
-       }
-       return ~0;
-}
-
-static void
-setreg32(struct regs *regs, int r, unsigned v)
-{
-       switch (r & 7) {
-       case 0: regs->eax = v; break;
-       case 1: regs->ecx = v; break;
-       case 2: regs->edx = v; break;
-       case 3: regs->ebx = v; break;
-       case 4: regs->uesp = v; break;
-       case 5: regs->ebp = v; break;
-       case 6: regs->esi = v; break;
-       case 7: regs->edi = v; break;
-       }
-}
-
-static void
-setreg16(struct regs *regs, int r, unsigned v)
-{
-       setreg32(regs, r, (getreg32(regs, r) & ~0xFFFF) | MASK16(v));
-}
-
-static void
-setreg8(struct regs *regs, int r, unsigned v)
-{
-       v &= 0xFF;
-       switch (r & 7) {
-       case 0: regs->eax = (regs->eax & ~0xFF) | v; break;
-       case 1: regs->ecx = (regs->ecx & ~0xFF) | v; break;
-       case 2: regs->edx = (regs->edx & ~0xFF) | v; break;
-       case 3: regs->ebx = (regs->ebx & ~0xFF) | v; break;
-       case 4: regs->eax = (regs->eax & ~0xFF00) | (v << 8); break;
-       case 5: regs->ecx = (regs->ecx & ~0xFF00) | (v << 8); break;
-       case 6: regs->edx = (regs->edx & ~0xFF00) | (v << 8); break;
-       case 7: regs->ebx = (regs->ebx & ~0xFF00) | (v << 8); break;
-       }
-}
-
-static unsigned
-segment(unsigned prefix, struct regs *regs, unsigned seg)
-{
-       if (prefix & SEG_ES)
-               seg = regs->ves;
-       if (prefix & SEG_DS)
-               seg = regs->vds;
-       if (prefix & SEG_CS)
-               seg = regs->cs;
-       if (prefix & SEG_SS)
-               seg = regs->uss;
-       if (prefix & SEG_FS)
-               seg = regs->vfs;
-       if (prefix & SEG_GS)
-               seg = regs->vgs;
-       return seg;
-}
-
-static unsigned
-sib(struct regs *regs, int mod, unsigned byte)
-{
-       unsigned scale = (byte >> 6) & 3;
-       int index = (byte >> 3) & 7;
-       int base = byte & 7;
-       unsigned addr = 0;
-
-       switch (mod) {
-       case 0:
-               if (base == 5)
-                       addr = fetch32(regs);
-               else
-                       addr = getreg32(regs, base);
-               break;
-       case 1:
-               addr = getreg32(regs, base) + (char) fetch8(regs);
-               break;
-       case 2:
-               addr = getreg32(regs, base) + fetch32(regs);
-               break;
-       }
-
-       if (index != 4)
-               addr += getreg32(regs, index) << scale;
-
-       return addr;
-}
-
-/*
- * Operand (modrm) decode
- */
-static unsigned
-operand(unsigned prefix, struct regs *regs, unsigned modrm)
-{
-       int mod, disp = 0, seg;
-
-       seg = segment(prefix, regs, regs->vds);
-
-       if (prefix & ADDR32) { /* 32-bit addressing */
-               switch ((mod = (modrm >> 6) & 3)) {
-               case 0:
-                       switch (modrm & 7) {
-                       case 0: return address(regs, seg, regs->eax);
-                       case 1: return address(regs, seg, regs->ecx);
-                       case 2: return address(regs, seg, regs->edx);
-                       case 3: return address(regs, seg, regs->ebx);
-                       case 4: return address(regs, seg,
-                                                  sib(regs, mod, 
fetch8(regs)));
-                       case 5: return address(regs, seg, fetch32(regs));
-                       case 6: return address(regs, seg, regs->esi);
-                       case 7: return address(regs, seg, regs->edi);
-                       }
-                       break;
-               case 1:
-               case 2:
-                       if ((modrm & 7) != 4) {
-                               if (mod == 1)
-                                       disp = (char) fetch8(regs);
-                               else
-                                       disp = (int) fetch32(regs);
-                       }
-                       switch (modrm & 7) {
-                       case 0: return address(regs, seg, regs->eax + disp);
-                       case 1: return address(regs, seg, regs->ecx + disp);
-                       case 2: return address(regs, seg, regs->edx + disp);
-                       case 3: return address(regs, seg, regs->ebx + disp);
-                       case 4: return address(regs, seg,
-                                                  sib(regs, mod, 
fetch8(regs)));
-                       case 5: return address(regs, seg, regs->ebp + disp);
-                       case 6: return address(regs, seg, regs->esi + disp);
-                       case 7: return address(regs, seg, regs->edi + disp);
-                       }
-                       break;
-               case 3:
-                       return getreg32(regs, modrm);
-               }
-       } else { /* 16-bit addressing */
-               switch ((mod = (modrm >> 6) & 3)) {
-               case 0:
-                       switch (modrm & 7) {
-                       case 0: return address(regs, seg, MASK16(regs->ebx) +
-                                       MASK16(regs->esi));
-                       case 1: return address(regs, seg, MASK16(regs->ebx) +
-                                       MASK16(regs->edi));
-                       case 2: return address(regs, seg, MASK16(regs->ebp) +
-                                       MASK16(regs->esi));
-                       case 3: return address(regs, seg, MASK16(regs->ebp) +
-                                       MASK16(regs->edi));
-                       case 4: return address(regs, seg, MASK16(regs->esi));
-                       case 5: return address(regs, seg, MASK16(regs->edi));
-                       case 6: return address(regs, seg, fetch16(regs));
-                       case 7: return address(regs, seg, MASK16(regs->ebx));
-                       }
-                       break;
-               case 1:
-               case 2:
-                       if (mod == 1)
-                               disp = (char) fetch8(regs);
-                       else
-                               disp = (int) fetch16(regs);
-                       switch (modrm & 7) {
-                       case 0: return address(regs, seg, MASK16(regs->ebx) +
-                                       MASK16(regs->esi) + disp);
-                       case 1: return address(regs, seg, MASK16(regs->ebx) +
-                                       MASK16(regs->edi) + disp);
-                       case 2: return address(regs, seg, MASK16(regs->ebp) +
-                                       MASK16(regs->esi) + disp);
-                       case 3: return address(regs, seg, MASK16(regs->ebp) +
-                                       MASK16(regs->edi) + disp);
-                       case 4: return address(regs, seg,
-                                       MASK16(regs->esi) + disp);
-                       case 5: return address(regs, seg,
-                                       MASK16(regs->edi) + disp);
-                       case 6: return address(regs, seg,
-                                       MASK16(regs->ebp) + disp);
-                       case 7: return address(regs, seg,
-                                       MASK16(regs->ebx) + disp);
-                       }
-                       break;
-               case 3:
-                       return getreg16(regs, modrm);
-               }
-       }
-
-       return 0;
-}
-
-/*
- * Load new IDT
- */
-static int
-lidt(struct regs *regs, unsigned prefix, unsigned modrm)
-{
-       unsigned eip = regs->eip - 3;
-       unsigned addr = operand(prefix, regs, modrm);
-
-       oldctx.idtr_limit = ((struct dtr *) addr)->size;
-       if ((prefix & DATA32) == 0)
-               oldctx.idtr_base = ((struct dtr *) addr)->base & 0xFFFFFF;
-       else
-               oldctx.idtr_base = ((struct dtr *) addr)->base;
-       TRACE((regs, regs->eip - eip, "lidt 0x%x <%d, 0x%x>",
-               addr, oldctx.idtr_limit, oldctx.idtr_base));
-
-       return 1;
-}
-
-/*
- * Load new GDT
- */
-static int
-lgdt(struct regs *regs, unsigned prefix, unsigned modrm)
-{
-       unsigned eip = regs->eip - 3;
-       unsigned addr = operand(prefix, regs, modrm);
-
-       oldctx.gdtr_limit = ((struct dtr *) addr)->size;
-       if ((prefix & DATA32) == 0)
-               oldctx.gdtr_base = ((struct dtr *) addr)->base & 0xFFFFFF;
-       else
-               oldctx.gdtr_base = ((struct dtr *) addr)->base;
-       TRACE((regs, regs->eip - eip, "lgdt 0x%x <%d, 0x%x>",
-               addr, oldctx.gdtr_limit, oldctx.gdtr_base));
-
-       return 1;
-}
-
-/*
- * Modify CR0 either through an lmsw instruction.
- */
-static int
-lmsw(struct regs *regs, unsigned prefix, unsigned modrm)
-{
-       unsigned eip = regs->eip - 3;
-       unsigned ax = operand(prefix, regs, modrm) & 0xF;
-       unsigned cr0 = (oldctx.cr0 & 0xFFFFFFF0) | ax;
-
-       TRACE((regs, regs->eip - eip, "lmsw 0x%x", ax));
-       oldctx.cr0 = cr0 | CR0_PE | CR0_NE;
-       if (cr0 & CR0_PE)
-               set_mode(regs, VM86_REAL_TO_PROTECTED);
-
-       return 1;
-}
-
-/*
- * We need to handle moves that address memory beyond the 64KB segment
- * limit that VM8086 mode enforces.
- */
-static int
-movr(struct regs *regs, unsigned prefix, unsigned opc)
-{
-       unsigned eip = regs->eip - 1;
-       unsigned modrm = fetch8(regs);
-       unsigned addr = operand(prefix, regs, modrm);
-       unsigned val, r = (modrm >> 3) & 7;
-
-       if ((modrm & 0xC0) == 0xC0) {
-               /*
-                * Emulate all guest instructions in protected to real mode.
-                */
-               if (mode != VM86_PROTECTED_TO_REAL)
-                       return 0;
-       }
-
-       switch (opc) {
-       case 0x88: /* addr32 mov r8, r/m8 */
-               val = getreg8(regs, r);
-               TRACE((regs, regs->eip - eip,
-                       "movb %%e%s, *0x%x", rnames[r], addr));
-               write8(addr, val);
-               return 1;
-
-       case 0x8A: /* addr32 mov r/m8, r8 */
-               TRACE((regs, regs->eip - eip,
-                       "movb *0x%x, %%%s", addr, rnames[r]));
-               setreg8(regs, r, read8(addr));
-               return 1;
-
-       case 0x89: /* addr32 mov r16, r/m16 */
-               val = getreg32(regs, r);
-               if ((modrm & 0xC0) == 0xC0) {
-                       if (prefix & DATA32)
-                               setreg32(regs, modrm & 7, val);
-                       else
-                               setreg16(regs, modrm & 7, MASK16(val));
-                       return 1;
-               }
-
-               if (prefix & DATA32) {
-                       TRACE((regs, regs->eip - eip,
-                               "movl %%e%s, *0x%x", rnames[r], addr));
-                       write32(addr, val);
-               } else {
-                       TRACE((regs, regs->eip - eip,
-                               "movw %%%s, *0x%x", rnames[r], addr));
-                       write16(addr, MASK16(val));
-               }
-               return 1;
-
-       case 0x8B: /* mov r/m16, r16 */
-               if ((modrm & 0xC0) == 0xC0) {
-                       if (prefix & DATA32)
-                               setreg32(regs, r, addr);
-                       else
-                               setreg16(regs, r, MASK16(addr));
-                       return 1;
-               }
-
-               if (prefix & DATA32) {
-                       TRACE((regs, regs->eip - eip,
-                               "movl *0x%x, %%e%s", addr, rnames[r]));
-                       setreg32(regs, r, read32(addr));
-               } else {
-                       TRACE((regs, regs->eip - eip,
-                               "movw *0x%x, %%%s", addr, rnames[r]));
-                       setreg16(regs, r, read16(addr));
-               }
-               return 1;
-
-       case 0xC6: /* addr32 movb $imm, r/m8 */
-               if ((modrm >> 3) & 7)
-                       return 0;
-               val = fetch8(regs);
-               write8(addr, val);
-               TRACE((regs, regs->eip - eip, "movb $0x%x, *0x%x",
-                                                       val, addr));
-               return 1;
-       }
-       return 0;
-}
-
-/*
- * We need to handle string moves that address memory beyond the 64KB segment
- * limit that VM8086 mode enforces.
- */
-static inline int
-movs(struct regs *regs, unsigned prefix, unsigned opc)
-{
-       unsigned eip = regs->eip - 1;
-       unsigned sseg = segment(prefix, regs, regs->vds);
-       unsigned dseg = regs->ves;
-       unsigned saddr, daddr;
-       unsigned count = 1;
-       int incr = ((regs->eflags & EFLAGS_DF) == 0) ? 1 : -1;
-
-       saddr = address(regs, sseg, regs->esi);
-       daddr = address(regs, dseg, regs->edi);
-
-       if ((prefix & REP) != 0) {
-               count = regs->ecx;
-               regs->ecx = 0;
-       }
-
-       switch (opc) {
-       case 0xA4: /* movsb */
-               regs->esi += (incr * count);
-               regs->edi += (incr * count);
-
-               while (count-- != 0) {
-                       write8(daddr, read8(saddr));
-                       daddr += incr;
-                       saddr += incr;
-               }
-               TRACE((regs, regs->eip - eip, "movsb (%%esi),%%es:(%%edi)"));
-               break;
-
-       case 0xA5: /* movsw */
-               if ((prefix & DATA32) == 0) {
-                       incr = 2 * incr;
-                       regs->esi += (incr * count);
-                       regs->edi += (incr * count);
-
-                       while (count-- != 0) {
-                               write16(daddr, read16(saddr));
-                               daddr += incr;
-                               saddr += incr;
-                       }
-               } else {
-                       incr = 4 * incr;
-                       regs->esi += (incr * count);
-                       regs->edi += (incr * count);
-
-                       while (count-- != 0) {
-                               write32(daddr, read32(saddr));
-                               daddr += incr;
-                               saddr += incr;
-                       }
-               }                       
-               TRACE((regs, regs->eip - eip, "movsw %s(%%esi),%%es:(%%edi)"));
-               break;
-       }
-
-       return 1;
-}
-
-static inline int
-lods(struct regs *regs, unsigned prefix, unsigned opc)
-{
-       unsigned eip = regs->eip - 1;
-       unsigned seg = segment(prefix, regs, regs->vds);
-       unsigned addr = address(regs, seg, regs->esi);
-       unsigned count = 1;
-       int incr = ((regs->eflags & EFLAGS_DF) == 0) ? 1 : -1;
-
-       if ((prefix & REP) != 0) {
-               count = regs->ecx;
-               regs->ecx = 0;
-       }
-
-       switch (opc) {
-       case 0xAD: /* lodsw */
-               if ((prefix & DATA32) == 0) {
-                       incr = 2 * incr;
-                       regs->esi += (incr * count);
-                       while (count-- != 0) {
-                               setreg16(regs, 0, read16(addr));
-                               addr += incr;
-                       }
-
-                       TRACE((regs, regs->eip - eip, "lodsw (%%esi),%%ax"));
-               } else {
-                       incr = 4 * incr;
-                       regs->esi += (incr * count);
-                       while (count-- != 0) {
-                               setreg32(regs, 0, read32(addr));
-                               addr += incr;
-                       }
-                       TRACE((regs, regs->eip - eip, "lodsw (%%esi),%%eax"));
-               }
-               break;
-       }
-       return 1;
-}
-/*
- * Move to and from a control register.
- */
-static int
-movcr(struct regs *regs, unsigned prefix, unsigned opc)
-{
-       unsigned eip = regs->eip - 2;
-       unsigned modrm = fetch8(regs);
-       unsigned cr = (modrm >> 3) & 7;
-
-       if ((modrm & 0xC0) != 0xC0) /* only registers */
-               return 0;
-
-       switch (opc) {
-       case 0x20: /* mov Rd, Cd */
-               TRACE((regs, regs->eip - eip, "movl %%cr%d, %%eax", cr));
-               switch (cr) {
-               case 0:
-                       setreg32(regs, modrm,
-                               oldctx.cr0 & ~(CR0_PE | CR0_NE));
-                       break;
-               case 2:
-                       setreg32(regs, modrm, get_cr2());
-                       break;
-               case 3:
-                       setreg32(regs, modrm, oldctx.cr3);
-                       break;
-               case 4:
-                       setreg32(regs, modrm, oldctx.cr4);
-                       break;
-               }
-               break;
-       case 0x22: /* mov Cd, Rd */
-               TRACE((regs, regs->eip - eip, "movl %%eax, %%cr%d", cr));
-               switch (cr) {
-               case 0:
-                       oldctx.cr0 = getreg32(regs, modrm) | (CR0_PE | CR0_NE);
-                       if (getreg32(regs, modrm) & CR0_PE)
-                               set_mode(regs, VM86_REAL_TO_PROTECTED);
-                       else
-                               set_mode(regs, VM86_REAL);
-                       break;
-               case 3:
-                       oldctx.cr3 = getreg32(regs, modrm);
-                       break;
-               case 4:
-                       oldctx.cr4 = getreg32(regs, modrm);
-                       break;
-               }
-               break;
-       }
-
-       return 1;
-}
-
-static inline void set_eflags_ZF(unsigned mask, unsigned v1, struct regs *regs)
-{
-       if ((v1 & mask) == 0)
-               regs->eflags |= EFLAGS_ZF;
-       else
-               regs->eflags &= ~EFLAGS_ZF;
-}
-
-static void set_eflags_add(unsigned hi_bit_mask, unsigned v1, unsigned v2,
-                               unsigned result, struct regs *regs)
-{
-       int bit_count;
-       unsigned tmp;
-       unsigned full_mask;
-       unsigned nonsign_mask;
-
-       /* Carry out of high order bit? */
-       if ( v1 & v2 & hi_bit_mask )
-               regs->eflags |= EFLAGS_CF;
-       else
-               regs->eflags &= ~EFLAGS_CF;
-
-       /* Even parity in least significant byte? */
-       tmp = result & 0xff;
-       for (bit_count = 0; tmp != 0; bit_count++)
-               tmp &= (tmp - 1);
-
-       if (bit_count & 1)
-               regs->eflags &= ~EFLAGS_PF;
-       else
-               regs->eflags |= EFLAGS_PF;
-
-       /* Carry out of least significant BCD digit? */
-       if ( v1 & v2 & (1<<3) )
-               regs->eflags |= EFLAGS_AF;
-       else
-               regs->eflags &= ~EFLAGS_AF;
-
-       /* Result is zero? */
-       full_mask = (hi_bit_mask - 1) | hi_bit_mask;
-       set_eflags_ZF(full_mask, result, regs);
-
-       /* Sign of result? */
-       if ( result & hi_bit_mask )
-               regs->eflags |= EFLAGS_SF;
-       else
-               regs->eflags &= ~EFLAGS_SF;
-
-       /* Carry out of highest non-sign bit? */
-       nonsign_mask = (hi_bit_mask >> 1) & ~hi_bit_mask;
-       if ( v1 & v2 & hi_bit_mask )
-               regs->eflags |= EFLAGS_OF;
-       else
-               regs->eflags &= ~EFLAGS_OF;
-
-}
-
-/*
- * We need to handle cmp opcodes that address memory beyond the 64KB
- * segment limit that VM8086 mode enforces.
- */
-static int
-cmp(struct regs *regs, unsigned prefix, unsigned opc)
-{
-       unsigned eip = regs->eip - 1;
-       unsigned modrm = fetch8(regs);
-       unsigned addr = operand(prefix, regs, modrm);
-       unsigned diff, val, r = (modrm >> 3) & 7;
-
-       if ((modrm & 0xC0) == 0xC0) /* no registers */
-               return 0;
-
-       switch (opc) {
-       case 0x39: /* addr32 cmp r16, r/m16 */
-               val = getreg32(regs, r);
-               if (prefix & DATA32) {
-                       diff = read32(addr) - val;
-                       set_eflags_ZF(~0, diff, regs);
-
-                       TRACE((regs, regs->eip - eip,
-                               "cmp %%e%s, *0x%x (0x%x)",
-                               rnames[r], addr, diff));
-               } else {
-                       diff = read16(addr) - val;
-                       set_eflags_ZF(0xFFFF, diff, regs);
-
-                       TRACE((regs, regs->eip - eip,
-                               "cmp %%%s, *0x%x (0x%x)",
-                               rnames[r], addr, diff));
-               }
-               break;
-
-       /* other cmp opcodes ... */
-       }
-       return 1;
-}
-
-/*
- * We need to handle test opcodes that address memory beyond the 64KB
- * segment limit that VM8086 mode enforces.
- */
-static int
-test(struct regs *regs, unsigned prefix, unsigned opc)
-{
-       unsigned eip = regs->eip - 1;
-       unsigned modrm = fetch8(regs);
-       unsigned addr = operand(prefix, regs, modrm);
-       unsigned val, diff;
-
-       if ((modrm & 0xC0) == 0xC0) /* no registers */
-               return 0;
-
-       switch (opc) {
-       case 0xF6: /* testb $imm, r/m8 */
-               if ((modrm >> 3) & 7)
-                       return 0;
-               val = fetch8(regs);
-               diff = read8(addr) & val;
-               set_eflags_ZF(0xFF, diff, regs);
-
-               TRACE((regs, regs->eip - eip, "testb $0x%x, *0x%x (0x%x)",
-                                                       val, addr, diff));
-               break;
-
-       /* other test opcodes ... */
-       }
-
-       return 1;
-}
-
-/*
- * We need to handle add opcodes that address memory beyond the 64KB
- * segment limit that VM8086 mode enforces.
- */
-static int
-add(struct regs *regs, unsigned prefix, unsigned opc)
-{
-       unsigned eip = regs->eip - 1;
-       unsigned modrm = fetch8(regs);
-       unsigned addr = operand(prefix, regs, modrm);
-       unsigned r = (modrm >> 3) & 7;
-
-       unsigned val1 = 0;
-       unsigned val2 = 0;
-       unsigned result = 0;
-       unsigned hi_bit;
-
-       if ((modrm & 0xC0) == 0xC0) /* no registers */
-               return 0;
-
-       switch (opc) {
-       case 0x00: /* addr32 add r8, r/m8 */
-               val1 = getreg8(regs, r);
-               val2 = read8(addr);
-               result = val1 + val2;
-               write8(addr, result);
-               TRACE((regs, regs->eip - eip,
-                       "addb %%e%s, *0x%x", rnames[r], addr));
-               break;
-               
-       case 0x01: /* addr32 add r16, r/m16 */
-               if (prefix & DATA32) {
-                       val1 = getreg32(regs, r);
-                       val2 = read32(addr);
-                       result = val1 + val2;
-                       write32(addr, result);
-                       TRACE((regs, regs->eip - eip,
-                               "addl %%e%s, *0x%x", rnames[r], addr));
-               } else {
-                       val1 = getreg16(regs, r);
-                       val2 = read16(addr);
-                       result = val1 + val2;
-                       write16(addr, result);
-                       TRACE((regs, regs->eip - eip,
-                               "addw %%e%s, *0x%x", rnames[r], addr));
-               }
-               break;
-               
-       case 0x03: /* addr32 add r/m16, r16 */
-               if (prefix & DATA32) {
-                       val1 = getreg32(regs, r);
-                       val2 = read32(addr);
-                       result = val1 + val2;
-                       setreg32(regs, r, result);
-                       TRACE((regs, regs->eip - eip,
-                               "addl *0x%x, %%e%s", addr, rnames[r]));
-               } else {
-                       val1 = getreg16(regs, r);
-                       val2 = read16(addr);
-                       result = val1 + val2;
-                       setreg16(regs, r, result);
-                       TRACE((regs, regs->eip - eip,
-                               "addw *0x%x, %%%s", addr, rnames[r]));
-               }
-               break;
-       }
-
-       if (opc == 0x00)
-               hi_bit = (1<<7);
-       else
-               hi_bit = (prefix & DATA32) ? (1<<31) : (1<<15);
-       set_eflags_add(hi_bit, val1, val2, result, regs);
-
-       return 1;
-}
-
-/*
- * We need to handle pop opcodes that address memory beyond the 64KB
- * segment limit that VM8086 mode enforces.
- */
-static int
-pop(struct regs *regs, unsigned prefix, unsigned opc)
-{
-       unsigned eip = regs->eip - 1;
-       unsigned modrm = fetch8(regs);
-       unsigned addr = operand(prefix, regs, modrm);
-
-       if ((modrm & 0xC0) == 0xC0) /* no registers */
-               return 0;
-
-       switch (opc) {
-       case 0x8F: /* pop r/m16 */
-               if ((modrm >> 3) & 7)
-                       return 0;
-               if (prefix & DATA32)
-                       write32(addr, pop32(regs));
-               else
-                       write16(addr, pop16(regs));
-               TRACE((regs, regs->eip - eip, "pop *0x%x", addr));
-               break;
-
-       /* other pop opcodes ... */
-       }
-
-       return 1;
-}
-
-static int
-mov_to_seg(struct regs *regs, unsigned prefix, unsigned opc)
-{
-       unsigned modrm = fetch8(regs);
-
-       /*
-        * Emulate segment loads in:
-        * 1) real->protected mode.
-        * 2) protected->real mode.
-        */
-       if (mode != VM86_REAL_TO_PROTECTED &&
-           mode != VM86_PROTECTED_TO_REAL)
-               return 0;
-
-       /* Register source only. */
-       if ((modrm & 0xC0) != 0xC0)
-               goto fail;
-
-       switch ((modrm & 0x38) >> 3) {
-       case 0: /* es */
-               regs->ves = getreg16(regs, modrm);
-               if (mode == VM86_PROTECTED_TO_REAL)
-                       return 1;
-               saved_rm_regs.ves = 0;
-               oldctx.es_sel = regs->ves;
-               return 1;
-
-       /* case 1: cs */
-
-       case 2: /* ss */
-               regs->uss = getreg16(regs, modrm);
-               if (mode == VM86_PROTECTED_TO_REAL)
-                       return 1;
-               saved_rm_regs.uss = 0;
-               oldctx.ss_sel = regs->uss;
-               return 1;
-       case 3: /* ds */
-               regs->vds = getreg16(regs, modrm);
-               if (mode == VM86_PROTECTED_TO_REAL)
-                       return 1;
-               saved_rm_regs.vds = 0;
-               oldctx.ds_sel = regs->vds;
-               return 1;
-       case 4: /* fs */
-               regs->vfs = getreg16(regs, modrm);
-               if (mode == VM86_PROTECTED_TO_REAL)
-                       return 1;
-               saved_rm_regs.vfs = 0;
-               oldctx.fs_sel = regs->vfs;
-               return 1;
-       case 5: /* gs */
-               regs->vgs = getreg16(regs, modrm);
-               if (mode == VM86_PROTECTED_TO_REAL)
-                       return 1;
-               saved_rm_regs.vgs = 0;
-               oldctx.gs_sel = regs->vgs;
-               return 1;
-       }
-
- fail:
-       printf("%s:%d: missed opcode %02x %02x\n",
-                  __FUNCTION__, __LINE__, opc, modrm);
-       return 0;
-}
-
-/*
- * Emulate a segment load in protected mode
- */
-static int
-load_seg(unsigned long sel, uint32_t *base, uint32_t *limit, union 
vmcs_arbytes *arbytes)
-{
-       uint64_t gdt_phys_base;
-       unsigned long long entry;
-
-       /* protected mode: use seg as index into gdt */
-       if (sel > oldctx.gdtr_limit)
-               return 0;
-
-       if (sel == 0) {
-               arbytes->fields.null_bit = 1;
-               return 1;
-       }
-
-       gdt_phys_base = guest_linear_to_phys(oldctx.gdtr_base);
-       if (gdt_phys_base != (uint32_t)gdt_phys_base) {
-               printf("gdt base address above 4G\n");
-               cpuid_addr_value(gdt_phys_base + 8 * (sel >> 3), &entry);
-       } else
-               entry = ((unsigned long long *)(long)gdt_phys_base)[sel >> 3];
-
-       /* Check the P bit first */
-       if (!((entry >> (15+32)) & 0x1) && sel != 0)
-               return 0;
-
-       *base =  (((entry >> (56-24)) & 0xFF000000) |
-                 ((entry >> (32-16)) & 0x00FF0000) |
-                 ((entry >> (   16)) & 0x0000FFFF));
-       *limit = (((entry >> (48-16)) & 0x000F0000) |
-                 (entry & 0x0000FFFF));
-
-       arbytes->bytes = 0;
-       arbytes->fields.seg_type = (entry >> (8+32)) & 0xF; /* TYPE */
-       arbytes->fields.s = (entry >> (12+32)) & 0x1; /* S */
-       if (arbytes->fields.s)
-               arbytes->fields.seg_type |= 1; /* accessed */
-       arbytes->fields.dpl = (entry >> (13+32)) & 0x3; /* DPL */
-       arbytes->fields.p = (entry >> (15+32)) & 0x1; /* P */
-       arbytes->fields.avl = (entry >> (20+32)) & 0x1; /* AVL */
-       arbytes->fields.default_ops_size = (entry >> (22+32)) & 0x1; /* D */
-
-       if (entry & (1ULL << (23+32))) { /* G */
-               arbytes->fields.g = 1;
-               *limit = (*limit << 12) | 0xFFF;
-       }
-
-       return 1;
-}
-
-/*
- * Emulate a protected mode segment load, falling back to clearing it if
- * the descriptor was invalid.
- */
-static void
-load_or_clear_seg(unsigned long sel, uint32_t *base, uint32_t *limit, union 
vmcs_arbytes *arbytes)
-{
-       if (!load_seg(sel, base, limit, arbytes))
-               load_seg(0, base, limit, arbytes);
-}
-
-static unsigned char rm_irqbase[2];
-
-/*
- * Transition to protected mode
- */
-static void
-protected_mode(struct regs *regs)
-{
-       extern char stack_top[];
-
-       oldctx.rm_irqbase[0] = rm_irqbase[0];
-       oldctx.rm_irqbase[1] = rm_irqbase[1];
-
-       regs->eflags &= ~(EFLAGS_TF|EFLAGS_VM);
-
-       oldctx.eip = regs->eip;
-       oldctx.esp = regs->uesp;
-       oldctx.eflags = regs->eflags;
-
-       /* reload all segment registers */
-       if (!load_seg(regs->cs, &oldctx.cs_base,
-                               &oldctx.cs_limit, &oldctx.cs_arbytes))
-               panic("Invalid %%cs=0x%x for protected mode\n", regs->cs);
-       oldctx.cs_sel = regs->cs;
-
-       load_or_clear_seg(oldctx.es_sel, &oldctx.es_base,
-                         &oldctx.es_limit, &oldctx.es_arbytes);
-       load_or_clear_seg(oldctx.ss_sel, &oldctx.ss_base,
-                         &oldctx.ss_limit, &oldctx.ss_arbytes);
-       load_or_clear_seg(oldctx.ds_sel, &oldctx.ds_base,
-                         &oldctx.ds_limit, &oldctx.ds_arbytes);
-       load_or_clear_seg(oldctx.fs_sel, &oldctx.fs_base,
-                         &oldctx.fs_limit, &oldctx.fs_arbytes);
-       load_or_clear_seg(oldctx.gs_sel, &oldctx.gs_base,
-                         &oldctx.gs_limit, &oldctx.gs_arbytes);
-
-       /* initialize jump environment to warp back to protected mode */
-       regs->uss = DATA_SELECTOR;
-       regs->uesp = (unsigned long)stack_top;
-       regs->cs = CODE_SELECTOR;
-       regs->eip = (unsigned long)switch_to_protected_mode;
-
-       /* this should get us into 32-bit mode */
-}
-
-/*
- * Start real-mode emulation
- */
-static void
-real_mode(struct regs *regs)
-{
-       regs->eflags |= EFLAGS_VM | 0x02;
-
-       /*
-        * When we transition from protected to real-mode and we
-        * have not reloaded the segment descriptors yet, they are
-        * interpreted as if they were in protect mode.
-        * We emulate this behavior by assuming that these memory
-        * reference are below 1MB and set %ss, %ds, %es accordingly.
-        */
-       if (regs->uss != 0) {
-               if (regs->uss >= HIGHMEM)
-                       panic("%%ss 0x%lx higher than 1MB", regs->uss);
-               regs->uss = address(regs, regs->uss, 0) >> 4;
-       } else {
-               regs->uss = saved_rm_regs.uss;
-       }
-       if (regs->vds != 0) {
-               if (regs->vds >= HIGHMEM)
-                       panic("%%ds 0x%lx higher than 1MB", regs->vds);
-               regs->vds = address(regs, regs->vds, 0) >> 4;
-       } else {
-               regs->vds = saved_rm_regs.vds;
-       }
-       if (regs->ves != 0) {
-               if (regs->ves >= HIGHMEM)
-                       panic("%%es 0x%lx higher than 1MB", regs->ves);
-               regs->ves = address(regs, regs->ves, 0) >> 4;
-       } else {
-               regs->ves = saved_rm_regs.ves;
-       }
-
-       /* this should get us into 16-bit mode */
-}
-
-/*
- * This is the smarts of the emulator and handles the mode transitions. The
- * emulator handles 4 different modes. 1) VM86_REAL: emulated real-mode,
- * Just handle those instructions that are not supported under VM8086.
- * 2) VM86_REAL_TO_PROTECTED: going from real-mode to protected mode. In
- * this we single step through the instructions until we reload the
- * new %cs (some OSes do a lot of computations before reloading %cs). 2)
- * VM86_PROTECTED_TO_REAL when we are going from protected to real mode. In
- * this case we emulate the instructions by hand. Finally, 4) VM86_PROTECTED
- * when we transitioned to protected mode and we should abandon the
- * emulator. No instructions are emulated when in VM86_PROTECTED mode.
- */
-void
-set_mode(struct regs *regs, enum vm86_mode newmode)
-{
-       switch (newmode) {
-       case VM86_REAL:
-               if (mode == VM86_PROTECTED_TO_REAL ||
-                   mode == VM86_REAL_TO_PROTECTED) {
-                       regs->eflags &= ~EFLAGS_TF;
-                       real_mode(regs);
-               } else if (mode != VM86_REAL)
-                       panic("unexpected real mode transition");
-               break;
-
-       case VM86_REAL_TO_PROTECTED:
-               if (mode == VM86_REAL) {
-                       regs->eflags |= EFLAGS_TF;
-                       saved_rm_regs.vds = regs->vds;
-                       saved_rm_regs.ves = regs->ves;
-                       saved_rm_regs.vfs = regs->vfs;
-                       saved_rm_regs.vgs = regs->vgs;
-                       saved_rm_regs.uss = regs->uss;
-                       oldctx.ds_sel = 0;
-                       oldctx.es_sel = 0;
-                       oldctx.fs_sel = 0;
-                       oldctx.gs_sel = 0;
-                       oldctx.ss_sel = 0;
-               } else if (mode != VM86_REAL_TO_PROTECTED)
-                       panic("unexpected real-to-protected mode transition");
-               break;
-
-       case VM86_PROTECTED_TO_REAL:
-               if (mode != VM86_PROTECTED)
-                       panic("unexpected protected-to-real mode transition");
-               break;
-
-       case VM86_PROTECTED:
-               if (mode != VM86_REAL_TO_PROTECTED)
-                       panic("unexpected protected mode transition");
-               protected_mode(regs);
-               break;
-       }
-
-       mode = newmode;
-       if (mode != VM86_PROTECTED)
-               TRACE((regs, 0, states[mode]));
-}
-
-static void
-jmpl(struct regs *regs, int prefix)
-{
-       unsigned n = regs->eip;
-       unsigned cs, eip;
-
-       eip = (prefix & DATA32) ? fetch32(regs) : fetch16(regs);
-       cs = fetch16(regs);
-
-       TRACE((regs, (regs->eip - n) + 1, "jmpl 0x%x:0x%x", cs, eip));
-
-       regs->cs = cs;
-       regs->eip = eip;
-
-       if (mode == VM86_REAL_TO_PROTECTED)             /* jump to protected 
mode */
-               set_mode(regs, VM86_PROTECTED);
-       else if (mode == VM86_PROTECTED_TO_REAL)        /* jump to real mode */
-               set_mode(regs, VM86_REAL);
-       else
-               panic("jmpl");
-}
-
-static void
-jmpl_indirect(struct regs *regs, int prefix, unsigned modrm)
-{
-       unsigned n = regs->eip;
-       unsigned cs, eip;
-       unsigned addr;
-
-       addr = operand(prefix, regs, modrm);
-
-       eip = (prefix & DATA32) ? read32(addr) : read16(addr);
-       addr += (prefix & DATA32) ? 4 : 2;
-       cs = read16(addr);
-
-       TRACE((regs, (regs->eip - n) + 1, "jmpl 0x%x:0x%x", cs, eip));
-
-       regs->cs = cs;
-       regs->eip = eip;
-
-       if (mode == VM86_REAL_TO_PROTECTED)             /* jump to protected 
mode */
-               set_mode(regs, VM86_PROTECTED);
-       else if (mode == VM86_PROTECTED_TO_REAL)        /* jump to real mode */
-               set_mode(regs, VM86_REAL);
-       else
-               panic("jmpl");
-}
-
-static void
-retl(struct regs *regs, int prefix)
-{
-       unsigned cs, eip;
-
-       if (prefix & DATA32) {
-               eip = pop32(regs);
-               cs = MASK16(pop32(regs));
-       } else {
-               eip = pop16(regs);
-               cs = pop16(regs);
-       }
-
-       TRACE((regs, 1, "retl (to 0x%x:0x%x)", cs, eip));
-
-       regs->cs = cs;
-       regs->eip = eip;
-
-       if (mode == VM86_REAL_TO_PROTECTED)             /* jump to protected 
mode */
-               set_mode(regs, VM86_PROTECTED);
-       else if (mode == VM86_PROTECTED_TO_REAL)        /* jump to real mode */
-               set_mode(regs, VM86_REAL);
-       else
-               panic("retl");
-}
-
-static void
-interrupt(struct regs *regs, int n)
-{
-       TRACE((regs, 0, "external interrupt %d", n));
-       push16(regs, regs->eflags);
-       push16(regs, regs->cs);
-       push16(regs, regs->eip);
-       regs->eflags &= ~EFLAGS_IF;
-       regs->eip = read16(address(regs, 0, n * 4));
-       regs->cs = read16(address(regs, 0, n * 4 + 2));
-}
-
-/*
- * Most port I/O operations are passed unmodified. We do have to be
- * careful and make sure the emulated program isn't remapping the
- * interrupt vectors. The following simple state machine catches
- * these attempts and rewrites them.
- */
-static int
-outbyte(struct regs *regs, unsigned prefix, unsigned opc)
-{
-       static char icw2[2] = { 0 };
-       int al, port;
-
-       switch (opc) {
-       case 0xE6: /* outb port, al */
-               port = fetch8(regs);
-               break;
-       case 0xEE: /* outb (%dx), al */
-               port = MASK16(regs->edx);
-               break;
-       default:
-               return 0;
-       }
-
-       al = regs->eax & 0xFF;
-
-       switch (port) {
-       case PIC_MASTER + PIC_CMD:
-               if (al & (1 << 4)) /* A0=0,D4=1 -> ICW1 */
-                       icw2[0] = 1;
-               break;
-       case PIC_MASTER + PIC_IMR:
-               if (icw2[0]) {
-                       icw2[0] = 0;
-                       printf("Remapping master: ICW2 0x%x -> 0x%x\n",
-                               al, NR_EXCEPTION_HANDLER);
-                       rm_irqbase[0] = al;
-                       al = NR_EXCEPTION_HANDLER;
-               }
-               break;
-
-       case PIC_SLAVE  + PIC_CMD:
-               if (al & (1 << 4)) /* A0=0,D4=1 -> ICW1 */
-                       icw2[1] = 1;
-               break;
-       case PIC_SLAVE  + PIC_IMR:
-               if (icw2[1]) {
-                       icw2[1] = 0;
-                       printf("Remapping slave: ICW2 0x%x -> 0x%x\n",
-                               al, NR_EXCEPTION_HANDLER+8);
-                       rm_irqbase[1] = al;
-                       al = NR_EXCEPTION_HANDLER+8;
-               }
-               break;
-       }
-
-       outb(port, al);
-       return 1;
-}
-
-static int
-inbyte(struct regs *regs, unsigned prefix, unsigned opc)
-{
-       int port;
-
-       switch (opc) {
-       case 0xE4: /* inb al, port */
-               port = fetch8(regs);
-               break;
-       case 0xEC: /* inb al, (%dx) */
-               port = MASK16(regs->edx);
-               break;
-       default:
-               return 0;
-       }
-
-       regs->eax = (regs->eax & ~0xFF) | inb(port);
-       return 1;
-}
-
-static void
-pushrm(struct regs *regs, int prefix, unsigned modrm)
-{
-       unsigned n = regs->eip;
-       unsigned addr;
-       unsigned data;
-
-       addr = operand(prefix, regs, modrm);
-
-       if (prefix & DATA32) {
-               data = read32(addr);
-               push32(regs, data);
-       } else {
-               data = read16(addr);
-               push16(regs, data);
-       }
-
-       TRACE((regs, (regs->eip - n) + 1, "push *0x%x", addr));
-}
-
-enum { OPC_INVALID, OPC_EMULATED };
-
-#define rdmsr(msr,val1,val2)                           \
-       __asm__ __volatile__(                           \
-               "rdmsr"                                 \
-               : "=a" (val1), "=d" (val2)              \
-               : "c" (msr))
-
-#define wrmsr(msr,val1,val2)                           \
-       __asm__ __volatile__(                           \
-               "wrmsr"                                 \
-               : /* no outputs */                      \
-               : "c" (msr), "a" (val1), "d" (val2))
-
-/*
- * Emulate a single instruction, including all its prefixes. We only implement
- * a small subset of the opcodes, and not all opcodes are implemented for each
- * of the four modes we can operate in.
- */
-static int
-opcode(struct regs *regs)
-{
-       unsigned eip = regs->eip;
-       unsigned opc, modrm, disp;
-       unsigned prefix = 0;
-
-       if (mode == VM86_PROTECTED_TO_REAL &&
-               oldctx.cs_arbytes.fields.default_ops_size) {
-               prefix |= DATA32;
-               prefix |= ADDR32;
-       }
-
-       for (;;) {
-               switch ((opc = fetch8(regs))) {
-
-               case 0x00: /* addr32 add r8, r/m8 */
-               case 0x01: /* addr32 add r16, r/m16 */
-               case 0x03: /* addr32 add r/m16, r16 */
-                       if (mode != VM86_REAL && mode != VM86_REAL_TO_PROTECTED)
-                               goto invalid;
-                       if ((prefix & ADDR32) == 0)
-                               goto invalid;
-                       if (!add(regs, prefix, opc))
-                               goto invalid;
-                       return OPC_EMULATED;
-                       
-               case 0x07: /* pop %es */
-                       regs->ves = (prefix & DATA32) ?
-                               pop32(regs) : pop16(regs);
-                       TRACE((regs, regs->eip - eip, "pop %%es"));
-                       if (mode == VM86_REAL_TO_PROTECTED) {
-                               saved_rm_regs.ves = 0;
-                               oldctx.es_sel = regs->ves;
-                       }
-                       return OPC_EMULATED;
-
-               case 0x0F: /* two byte opcode */
-                       if (mode == VM86_PROTECTED)
-                               goto invalid;
-                       switch ((opc = fetch8(regs))) {
-                       case 0x01:
-                               switch (((modrm = fetch8(regs)) >> 3) & 7) {
-                               case 0: /* sgdt */
-                               case 1: /* sidt */
-                                       goto invalid;
-                               case 2: /* lgdt */
-                                       if (!lgdt(regs, prefix, modrm))
-                                               goto invalid;
-                                       return OPC_EMULATED;
-                               case 3: /* lidt */
-                                       if (!lidt(regs, prefix, modrm))
-                                               goto invalid;
-                                       return OPC_EMULATED;
-                               case 4: /* smsw */
-                                       goto invalid;
-                               case 5:
-                                       goto invalid;
-                               case 6: /* lmsw */
-                                       if (!lmsw(regs, prefix, modrm))
-                                               goto invalid;
-                                       return OPC_EMULATED;
-                               case 7: /* invlpg */
-                                       goto invalid;
-                               }
-                               break;
-                       case 0x06: /* clts */
-                               oldctx.cr0 &= ~CR0_TS;
-                               return OPC_EMULATED;
-                       case 0x09: /* wbinvd */
-                               return OPC_EMULATED;
-                       case 0x20: /* mov Rd, Cd (1h) */
-                       case 0x22:
-                               if (!movcr(regs, prefix, opc))
-                                       goto invalid;
-                               return OPC_EMULATED;
-                       case 0x30: /* WRMSR */
-                               wrmsr(regs->ecx, regs->eax, regs->edx);
-                               return OPC_EMULATED;
-                       case 0x32: /* RDMSR */
-                               rdmsr(regs->ecx, regs->eax, regs->edx);
-                               return OPC_EMULATED;
-                       default:
-                               goto invalid;
-                       }
-                       goto invalid;
-
-               case 0x1F: /* pop %ds */
-                       regs->vds = (prefix & DATA32) ?
-                               pop32(regs) : pop16(regs);
-                       TRACE((regs, regs->eip - eip, "pop %%ds"));
-                       if (mode == VM86_REAL_TO_PROTECTED) {
-                               saved_rm_regs.vds = 0;
-                               oldctx.ds_sel = regs->vds;
-                       }
-                       return OPC_EMULATED;
-
-               case 0x26:
-                       TRACE((regs, regs->eip - eip, "%%es:"));
-                       prefix |= SEG_ES;
-                       continue;
-
-               case 0x2E:
-                       TRACE((regs, regs->eip - eip, "%%cs:"));
-                       prefix |= SEG_CS;
-                       continue;
-
-               case 0x36:
-                       TRACE((regs, regs->eip - eip, "%%ss:"));
-                       prefix |= SEG_SS;
-                       continue;
-
-               case 0x39: /* addr32 cmp r16, r/m16 */
-               case 0x3B: /* addr32 cmp r/m16, r16 */
-                       if (mode == VM86_PROTECTED_TO_REAL || !(prefix & 
ADDR32))
-                               goto invalid;
-                       if (!cmp(regs, prefix, opc))
-                               goto invalid;
-                       return OPC_EMULATED;
-
-               case 0x3E:
-                       TRACE((regs, regs->eip - eip, "%%ds:"));
-                       prefix |= SEG_DS;
-                       continue;
-
-               case 0x64:
-                       TRACE((regs, regs->eip - eip, "%%fs:"));
-                       prefix |= SEG_FS;
-                       continue;
-
-               case 0x65:
-                       TRACE((regs, regs->eip - eip, "%%gs:"));
-                       prefix |= SEG_GS;
-                       continue;
-
-               case 0x66:
-                       if (mode == VM86_PROTECTED_TO_REAL &&
-                               oldctx.cs_arbytes.fields.default_ops_size) {
-                               TRACE((regs, regs->eip - eip, "data16"));
-                               prefix &= ~DATA32;
-                       } else {
-                               TRACE((regs, regs->eip - eip, "data32"));
-                               prefix |= DATA32;
-                       }
-                       continue;
-
-               case 0x67:
-                       if (mode == VM86_PROTECTED_TO_REAL &&
-                               oldctx.cs_arbytes.fields.default_ops_size) {
-                               TRACE((regs, regs->eip - eip, "addr16"));
-                               prefix &= ~ADDR32;
-                       } else {
-                               TRACE((regs, regs->eip - eip, "addr32"));
-                               prefix |= ADDR32;
-                       }
-                       continue;
-
-               case 0x88: /* addr32 mov r8, r/m8 */
-               case 0x8A: /* addr32 mov r/m8, r8 */
-                       if (mode == VM86_PROTECTED_TO_REAL || !(prefix & 
ADDR32))
-                               goto invalid;
-                       if (!movr(regs, prefix, opc))
-                               goto invalid;
-                       return OPC_EMULATED;
-
-               case 0x89: /* mov r16, r/m16 */
-               case 0x8B: /* mov r/m16, r16 */
-                       if (mode != VM86_PROTECTED_TO_REAL && !(prefix & 
ADDR32))
-                               goto invalid;
-                       if (!movr(regs, prefix, opc))
-                               goto invalid;
-                       return OPC_EMULATED;
-
-               case 0x8E: /* mov r16, sreg */
-                       if (!mov_to_seg(regs, prefix, opc))
-                               goto invalid;
-                       return OPC_EMULATED;
-
-               case 0x8F: /* addr32 pop r/m16 */
-                       if (!(prefix & ADDR32))
-                               goto invalid;
-                       if (!pop(regs, prefix, opc))
-                               goto invalid;
-                       return OPC_EMULATED;
-
-               case 0x90: /* nop */
-                       TRACE((regs, regs->eip - eip, "nop"));
-                       return OPC_EMULATED;
-
-               case 0x9C: /* pushf */
-                       TRACE((regs, regs->eip - eip, "pushf"));
-                       if (prefix & DATA32)
-                               push32(regs, regs->eflags & ~EFLAGS_VM);
-                       else
-                               push16(regs, regs->eflags & ~EFLAGS_VM);
-                       return OPC_EMULATED;
-
-               case 0x9D: /* popf */
-                       TRACE((regs, regs->eip - eip, "popf"));
-                       if (prefix & DATA32)
-                               regs->eflags = pop32(regs);
-                       else
-                               regs->eflags = (regs->eflags & 0xFFFF0000L) |
-                                                               pop16(regs);
-                       regs->eflags |= EFLAGS_VM;
-                       return OPC_EMULATED;
-
-               case 0xA1: /* mov ax, r/m16 */
-               {
-                       int addr, data;
-                       int seg = segment(prefix, regs, regs->vds);
-                       int offset = prefix & ADDR32 ? fetch32(regs) : 
fetch16(regs);
-
-                       if (prefix & DATA32) {
-                               addr = address(regs, seg, offset);
-                               data = read32(addr);
-                               setreg32(regs, 0, data);
-                       } else {
-                               addr = address(regs, seg, offset);
-                               data = read16(addr);
-                               setreg16(regs, 0, data);
-                       }
-                       TRACE((regs, regs->eip - eip, "mov *0x%x, %%ax", addr));
-                       return OPC_EMULATED;
-               }
-
-               case 0xA4: /* movsb */
-               case 0xA5: /* movsw */
-                       if ((prefix & ADDR32) == 0)
-                               goto invalid;
-                       if (!movs(regs, prefix, opc))
-                               goto invalid;
-                       return OPC_EMULATED;
-
-               case 0xAD: /* lodsw */
-                       if ((prefix & ADDR32) == 0)
-                               goto invalid;
-                       if (!lods(regs, prefix, opc))
-                               goto invalid;
-                       return OPC_EMULATED;
-                       
-               case 0xBB: /* mov bx, imm16 */
-               {
-                       int data;
-                       if (prefix & DATA32) {
-                               data = fetch32(regs);
-                               setreg32(regs, 3, data);
-                       } else {
-                               data = fetch16(regs);
-                               setreg16(regs, 3, data);
-                       }
-                       TRACE((regs, regs->eip - eip, "mov $0x%x, %%bx", data));
-                       return OPC_EMULATED;
-               }
-
-               case 0xC6: /* addr32 movb $imm, r/m8 */
-                       if (!(prefix & ADDR32))
-                               goto invalid;
-                       if (!movr(regs, prefix, opc))
-                               goto invalid;
-                       return OPC_EMULATED;
-
-               case 0xCB: /* retl */
-                       if (mode == VM86_REAL_TO_PROTECTED ||
-                               mode == VM86_PROTECTED_TO_REAL) {
-                               retl(regs, prefix);
-                               return OPC_INVALID;
-                       }
-                       goto invalid;
-
-               case 0xCD: /* int $n */
-                       TRACE((regs, regs->eip - eip, "int"));
-                       interrupt(regs, fetch8(regs));
-                       return OPC_EMULATED;
-
-               case 0xCF: /* iret */
-                       if (prefix & DATA32) {
-                               TRACE((regs, regs->eip - eip, "data32 iretd"));
-                               regs->eip = pop32(regs);
-                               regs->cs = pop32(regs);
-                               regs->eflags = pop32(regs);
-                       } else {
-                               TRACE((regs, regs->eip - eip, "iret"));
-                               regs->eip = pop16(regs);
-                               regs->cs = pop16(regs);
-                               regs->eflags = (regs->eflags & 0xFFFF0000L) |
-                                                               pop16(regs);
-                       }
-                       return OPC_EMULATED;
-
-               case 0xE4: /* inb al, port */
-                       if (!inbyte(regs, prefix, opc))
-                               goto invalid;
-                       return OPC_EMULATED;
-
-               case 0xE6: /* outb port, al */
-                       if (!outbyte(regs, prefix, opc))
-                               goto invalid;
-                       return OPC_EMULATED;
-
-               case 0xEA: /* jmpl */
-                       if (mode == VM86_REAL_TO_PROTECTED ||
-                               mode == VM86_PROTECTED_TO_REAL) {
-                               jmpl(regs, prefix);
-                               return OPC_INVALID;
-                       }
-                       goto invalid;
-
-               case 0xFF:
-               {
-                       unsigned modrm = fetch8(regs);
-                       switch((modrm >> 3) & 7) {
-                       case 5: /* jmpl (indirect) */
-                               if (mode == VM86_REAL_TO_PROTECTED ||
-                                       mode == VM86_PROTECTED_TO_REAL) {
-                                       jmpl_indirect(regs, prefix, modrm);
-                                       return OPC_INVALID;
-                               }
-                               goto invalid;
-
-                       case 6: /* push r/m16 */
-                               pushrm(regs, prefix, modrm);
-                               return OPC_EMULATED;
-
-                       default:
-                               goto invalid;
-                       }
-               }
-
-               case 0xEB: /* short jump */
-                       if (mode == VM86_REAL_TO_PROTECTED ||
-                               mode == VM86_PROTECTED_TO_REAL) {
-                               disp = (char) fetch8(regs);
-                               TRACE((regs, 2, "jmp 0x%x", regs->eip + disp));
-                               regs->eip += disp;
-                               return OPC_EMULATED;
-                       }
-                       goto invalid;
-
-               case 0xEC: /* inb al, (%dx) */
-                       if (!inbyte(regs, prefix, opc))
-                               goto invalid;
-                       return OPC_EMULATED;
-
-               case 0xEE: /* outb (%dx), al */
-                       if (!outbyte(regs, prefix, opc))
-                               goto invalid;
-                       return OPC_EMULATED;
-
-               case 0xF0: /* lock */
-                       TRACE((regs, regs->eip - eip, "lock"));
-                       continue;
-
-               case 0xF4: /* hlt */
-                       TRACE((regs, regs->eip - eip, "hlt"));
-                       /* Do something power-saving here! */
-                       return OPC_EMULATED;
-
-               case 0xF3: /* rep/repe/repz */
-                       TRACE((regs, regs->eip - eip, "rep"));
-                       prefix |= REP;
-                       continue;
-
-               case 0xF6: /* addr32 testb $imm, r/m8 */
-                       if (!(prefix & ADDR32))
-                               goto invalid;
-                       if (!test(regs, prefix, opc))
-                               goto invalid;
-                       return OPC_EMULATED;
-
-               case 0xFA: /* cli */
-                       TRACE((regs, regs->eip - eip, "cli"));
-                       regs->eflags &= ~EFLAGS_IF;
-                       return OPC_EMULATED;
-
-               case 0xFB: /* sti */
-                       TRACE((regs, regs->eip - eip, "sti"));
-                       regs->eflags |= EFLAGS_IF;
-                       return OPC_EMULATED;
-
-               default:
-                       goto invalid;
-               }
-       }
-
-invalid:
-       regs->eip = eip;
-       TRACE((regs, regs->eip - eip, "opc 0x%x", opc));
-       return OPC_INVALID;
-}
-
-void
-emulate(struct regs *regs)
-{
-       unsigned flteip;
-       int nemul = 0;
-       unsigned ip;
-
-       /* emulate as many instructions as possible */
-       while (opcode(regs) != OPC_INVALID)
-               nemul++;
-
-       /* detect the case where we are not making progress */
-       if (nemul == 0 && prev_eip == regs->eip) {
-               flteip = address(regs, MASK16(regs->cs), regs->eip);
-
-               printf("Undecoded sequence: \n");
-               for (ip=flteip; ip < flteip+16; ip++)
-                       printf("0x%02x ", read8(ip));
-               printf("\n");
-
-               panic("Unknown opcode at %04x:%04x=0x%x",
-                       MASK16(regs->cs), regs->eip, flteip);
-       } else
-               prev_eip = regs->eip;
-}
-
-void
-trap(int trapno, int errno, struct regs *regs)
-{
-       /* emulate device interrupts */
-       if (trapno >= NR_EXCEPTION_HANDLER) {
-               int irq = trapno - NR_EXCEPTION_HANDLER;
-               if (irq < 8) 
-                       interrupt(regs, irq + 8);
-               else
-                       interrupt(regs, 0x70 + (irq - 8));
-               return;
-       }
-
-       switch (trapno) {
-       case 1: /* Debug */
-               if (regs->eflags & EFLAGS_VM) {
-                       /* emulate any 8086 instructions  */
-                       if (mode == VM86_REAL)
-                               return;
-                       if (mode != VM86_REAL_TO_PROTECTED)
-                               panic("not in real-to-protected mode");
-                       emulate(regs);
-                       return;
-               }
-               goto invalid;
-
-       case 13: /* GPF */
-               if (regs->eflags & EFLAGS_VM) {
-                       /* emulate any 8086 instructions  */
-                       if (mode == VM86_PROTECTED)
-                               panic("unexpected protected mode");
-                       emulate(regs);
-                       return;
-               }
-               goto invalid;
-
-       default:
-       invalid:
-               printf("Trap (0x%x) while in %s mode\n",
-                       trapno, regs->eflags & EFLAGS_VM ? "real" : 
"protected");
-               if (trapno == 14)
-                       printf("Page fault address 0x%x\n", get_cr2());
-               dump_regs(regs);
-               halt();
-       }
-}
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 tools/firmware/vmxassist/vm86.h
--- a/tools/firmware/vmxassist/vm86.h   Tue Feb 05 23:27:12 2008 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +0,0 @@
-/*
- * vm86.h: vm86 emulator definitions.
- *
- * Leendert van Doorn, leendert@xxxxxxxxxxxxxx
- * Copyright (c) 2005, International Business Machines Corporation.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms and conditions of the GNU General Public License,
- * version 2, as published by the Free Software Foundation.
- *
- * This program is distributed in the hope it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
- * more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place - Suite 330, Boston, MA 02111-1307 USA.
- */
-#ifndef __VM86_H__
-#define __VM86_H__
-
-#ifndef __ASSEMBLY__
-#include <stdint.h>
-#endif
-
-#include <xen/hvm/vmx_assist.h>
-
-#ifndef __ASSEMBLY__
-
-struct regs {
-       unsigned        edi, esi, ebp, esp, ebx, edx, ecx, eax;
-       unsigned        trapno, errno;
-       unsigned        eip, cs, eflags, uesp, uss;
-       unsigned        ves, vds, vfs, vgs;
-};
-
-enum vm86_mode {
-       VM86_REAL = 0,
-       VM86_REAL_TO_PROTECTED,
-       VM86_PROTECTED_TO_REAL,
-       VM86_PROTECTED
-};
-
-#ifdef DEBUG
-#define TRACE(a)        trace a
-#else
-#define TRACE(a)
-#endif
-
-extern enum vm86_mode prevmode, mode;
-extern struct vmx_assist_context oldctx;
-
-extern void emulate(struct regs *);
-extern void dump_regs(struct regs *);
-extern void trace(struct regs *, int, char *, ...);
-
-extern void set_mode(struct regs *, enum vm86_mode);
-extern void switch_to_real_mode(void);
-extern void switch_to_protected_mode(void);
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* __VM86_H__ */
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 tools/firmware/vmxassist/vmxassist.ld
--- a/tools/firmware/vmxassist/vmxassist.ld     Tue Feb 05 23:27:12 2008 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-/*
- * vmxassist.ld
- */
-OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
-ENTRY(_start)
-
-SECTIONS
-{
-       _btext = .;
-       .text TEXTADDR : 
-       {
-               *(.text)
-               *(.rodata)
-               *(.rodata.*)
-       }
-       _etext = .;
-
-       _bdata = .;
-       .data :
-       {
-               *(.data)
-       }
-       _edata = .;
-
-       _bbss = .;
-       .bss :
-       {
-               *(.bss)
-       }
-       _ebss = .;
-}
-
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 xen/arch/x86/Rules.mk
--- a/xen/arch/x86/Rules.mk     Tue Feb 05 23:27:12 2008 +0000
+++ b/xen/arch/x86/Rules.mk     Wed Feb 06 12:07:55 2008 +0000
@@ -11,11 +11,6 @@ xenoprof := y
 #
 pae ?= n
 supervisor_mode_kernel ?= n
-vmxassist ?= n
-
-ifeq ($(vmxassist),y)
-CFLAGS += -DVMXASSIST
-endif
 
 # Solaris grabs stdarg.h and friends from the system include directory.
 ifneq ($(XEN_OS),SunOS)
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 xen/arch/x86/hvm/hvm.c
--- a/xen/arch/x86/hvm/hvm.c    Tue Feb 05 23:27:12 2008 +0000
+++ b/xen/arch/x86/hvm/hvm.c    Wed Feb 06 12:07:55 2008 +0000
@@ -1671,16 +1671,6 @@ int hvm_bringup_ap(int vcpuid, int tramp
     ctxt->flags = VGCF_online;
     ctxt->user_regs.eflags = 2;
 
-#ifdef VMXASSIST
-    if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL )
-    {
-        ctxt->user_regs.eip = VMXASSIST_BASE;
-        ctxt->user_regs.edx = vcpuid;
-        ctxt->user_regs.ebx = trampoline_vector;
-        goto done;
-    }
-#endif
-
     v->arch.hvm_vcpu.guest_cr[0] = X86_CR0_ET;
     hvm_update_guest_cr(v, 0);
 
@@ -1721,9 +1711,6 @@ int hvm_bringup_ap(int vcpuid, int tramp
     hvm_set_segment_register(v, x86_seg_gdtr, &reg);
     hvm_set_segment_register(v, x86_seg_idtr, &reg);
 
-#ifdef VMXASSIST
- done:
-#endif
     /* Sync AP's TSC with BSP's. */
     v->arch.hvm_vcpu.cache_tsc_offset =
         v->domain->vcpu[0]->arch.hvm_vcpu.cache_tsc_offset;
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 xen/arch/x86/hvm/vmx/Makefile
--- a/xen/arch/x86/hvm/vmx/Makefile     Tue Feb 05 23:27:12 2008 +0000
+++ b/xen/arch/x86/hvm/vmx/Makefile     Wed Feb 06 12:07:55 2008 +0000
@@ -4,9 +4,7 @@ subdir-$(x86_64) += x86_64
 subdir-$(x86_64) += x86_64
 
 obj-y += intr.o
-ifneq ($(vmxassist),y)
 obj-y += realmode.o
-endif
 obj-y += vmcs.o
 obj-y += vmx.o
 obj-y += vpmu.o
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 xen/arch/x86/hvm/vmx/vmx.c
--- a/xen/arch/x86/hvm/vmx/vmx.c        Tue Feb 05 23:27:12 2008 +0000
+++ b/xen/arch/x86/hvm/vmx/vmx.c        Wed Feb 06 12:07:55 2008 +0000
@@ -94,11 +94,10 @@ static int vmx_vcpu_initialise(struct vc
 
     vmx_install_vlapic_mapping(v);
 
-#ifndef VMXASSIST
+    /* %eax == 1 signals full real-mode support to the guest loader. */
     if ( v->vcpu_id == 0 )
         v->arch.guest_context.user_regs.eax = 1;
     v->arch.hvm_vcpu.io_complete = vmx_realmode_io_complete;
-#endif
 
     return 0;
 }
@@ -708,10 +707,6 @@ static void vmx_load_cpu_state(struct vc
 
     v->arch.hvm_vmx.cstar     = data->msr_cstar;
     v->arch.hvm_vmx.shadow_gs = data->shadow_gs;
-#endif
-
-#ifdef VMXASSIST
-    v->arch.hvm_vmx.vmxassist_enabled = !(data->cr0 & X86_CR0_PE);
 #endif
 
     hvm_set_guest_time(v, data->tsc);
@@ -1266,43 +1261,6 @@ void vmx_cpuid_intercept(
 {
     unsigned int input = *eax;
     unsigned int count = *ecx;
-
-#ifdef VMXASSIST
-    if ( input == 0x40000003 )
-    {
-        /*
-         * NB. Unsupported interface for private use of VMXASSIST only.
-         * Note that this leaf lives at <max-hypervisor-leaf> + 1.
-         */
-        u64 value = ((u64)*edx << 32) | (u32)*ecx;
-        p2m_type_t p2mt;
-        unsigned long mfn;
-        struct vcpu *v = current;
-        char *p;
-
-        mfn = mfn_x(gfn_to_mfn_current(value >> PAGE_SHIFT, &p2mt));
-
-        gdprintk(XENLOG_INFO, "Input address is 0x%"PRIx64".\n", value);
-
-        /* 8-byte aligned valid pseudophys address from vmxassist, please. */
-        if ( (value & 7) || !p2m_is_ram(p2mt) ||
-             !v->arch.hvm_vmx.vmxassist_enabled )
-        {
-            domain_crash(v->domain);
-            return;
-        }
-        ASSERT(mfn_valid(mfn));
-
-        p = map_domain_page(mfn);
-        value = *((uint64_t *)(p + (value & (PAGE_SIZE - 1))));
-        unmap_domain_page(p);
-
-        gdprintk(XENLOG_INFO, "Output value is 0x%"PRIx64".\n", value);
-        *ecx = (u32)value;
-        *edx = (u32)(value >> 32);
-        return;
-    }
-#endif
 
     hvm_cpuid(input, eax, ebx, ecx, edx);
 
@@ -1843,256 +1801,6 @@ static void vmx_io_instruction(unsigned 
     }
 }
 
-#ifdef VMXASSIST
-
-static void vmx_world_save(struct vcpu *v, struct vmx_assist_context *c)
-{
-    struct cpu_user_regs *regs = guest_cpu_user_regs();
-
-    c->eip  = regs->eip;
-    c->eip += __get_instruction_length(); /* Safe: MOV Cn, LMSW, CLTS */
-    c->esp = regs->esp;
-    c->eflags = regs->eflags & ~X86_EFLAGS_RF;
-
-    c->cr0 = v->arch.hvm_vcpu.guest_cr[0];
-    c->cr3 = v->arch.hvm_vcpu.guest_cr[3];
-    c->cr4 = v->arch.hvm_vcpu.guest_cr[4];
-
-    c->idtr_limit = __vmread(GUEST_IDTR_LIMIT);
-    c->idtr_base = __vmread(GUEST_IDTR_BASE);
-
-    c->gdtr_limit = __vmread(GUEST_GDTR_LIMIT);
-    c->gdtr_base = __vmread(GUEST_GDTR_BASE);
-
-    c->cs_sel = __vmread(GUEST_CS_SELECTOR);
-    c->cs_limit = __vmread(GUEST_CS_LIMIT);
-    c->cs_base = __vmread(GUEST_CS_BASE);
-    c->cs_arbytes.bytes = __vmread(GUEST_CS_AR_BYTES);
-
-    c->ds_sel = __vmread(GUEST_DS_SELECTOR);
-    c->ds_limit = __vmread(GUEST_DS_LIMIT);
-    c->ds_base = __vmread(GUEST_DS_BASE);
-    c->ds_arbytes.bytes = __vmread(GUEST_DS_AR_BYTES);
-
-    c->es_sel = __vmread(GUEST_ES_SELECTOR);
-    c->es_limit = __vmread(GUEST_ES_LIMIT);
-    c->es_base = __vmread(GUEST_ES_BASE);
-    c->es_arbytes.bytes = __vmread(GUEST_ES_AR_BYTES);
-
-    c->ss_sel = __vmread(GUEST_SS_SELECTOR);
-    c->ss_limit = __vmread(GUEST_SS_LIMIT);
-    c->ss_base = __vmread(GUEST_SS_BASE);
-    c->ss_arbytes.bytes = __vmread(GUEST_SS_AR_BYTES);
-
-    c->fs_sel = __vmread(GUEST_FS_SELECTOR);
-    c->fs_limit = __vmread(GUEST_FS_LIMIT);
-    c->fs_base = __vmread(GUEST_FS_BASE);
-    c->fs_arbytes.bytes = __vmread(GUEST_FS_AR_BYTES);
-
-    c->gs_sel = __vmread(GUEST_GS_SELECTOR);
-    c->gs_limit = __vmread(GUEST_GS_LIMIT);
-    c->gs_base = __vmread(GUEST_GS_BASE);
-    c->gs_arbytes.bytes = __vmread(GUEST_GS_AR_BYTES);
-
-    c->tr_sel = __vmread(GUEST_TR_SELECTOR);
-    c->tr_limit = __vmread(GUEST_TR_LIMIT);
-    c->tr_base = __vmread(GUEST_TR_BASE);
-    c->tr_arbytes.bytes = __vmread(GUEST_TR_AR_BYTES);
-
-    c->ldtr_sel = __vmread(GUEST_LDTR_SELECTOR);
-    c->ldtr_limit = __vmread(GUEST_LDTR_LIMIT);
-    c->ldtr_base = __vmread(GUEST_LDTR_BASE);
-    c->ldtr_arbytes.bytes = __vmread(GUEST_LDTR_AR_BYTES);
-}
-
-static int vmx_world_restore(struct vcpu *v, struct vmx_assist_context *c)
-{
-    struct cpu_user_regs *regs = guest_cpu_user_regs();
-    int rc;
-
-    rc = vmx_restore_cr0_cr3(v, c->cr0, c->cr3);
-    if ( rc )
-        return rc;
-
-    regs->eip = c->eip;
-    regs->esp = c->esp;
-    regs->eflags = c->eflags | 2;
-
-    v->arch.hvm_vcpu.guest_cr[4] = c->cr4;
-    vmx_update_guest_cr(v, 0);
-    vmx_update_guest_cr(v, 4);
-
-    __vmwrite(GUEST_IDTR_LIMIT, c->idtr_limit);
-    __vmwrite(GUEST_IDTR_BASE, c->idtr_base);
-
-    __vmwrite(GUEST_GDTR_LIMIT, c->gdtr_limit);
-    __vmwrite(GUEST_GDTR_BASE, c->gdtr_base);
-
-    __vmwrite(GUEST_CS_SELECTOR, c->cs_sel);
-    __vmwrite(GUEST_CS_LIMIT, c->cs_limit);
-    __vmwrite(GUEST_CS_BASE, c->cs_base);
-    __vmwrite(GUEST_CS_AR_BYTES, c->cs_arbytes.bytes);
-
-    __vmwrite(GUEST_DS_SELECTOR, c->ds_sel);
-    __vmwrite(GUEST_DS_LIMIT, c->ds_limit);
-    __vmwrite(GUEST_DS_BASE, c->ds_base);
-    __vmwrite(GUEST_DS_AR_BYTES, c->ds_arbytes.bytes);
-
-    __vmwrite(GUEST_ES_SELECTOR, c->es_sel);
-    __vmwrite(GUEST_ES_LIMIT, c->es_limit);
-    __vmwrite(GUEST_ES_BASE, c->es_base);
-    __vmwrite(GUEST_ES_AR_BYTES, c->es_arbytes.bytes);
-
-    __vmwrite(GUEST_SS_SELECTOR, c->ss_sel);
-    __vmwrite(GUEST_SS_LIMIT, c->ss_limit);
-    __vmwrite(GUEST_SS_BASE, c->ss_base);
-    __vmwrite(GUEST_SS_AR_BYTES, c->ss_arbytes.bytes);
-
-    __vmwrite(GUEST_FS_SELECTOR, c->fs_sel);
-    __vmwrite(GUEST_FS_LIMIT, c->fs_limit);
-    __vmwrite(GUEST_FS_BASE, c->fs_base);
-    __vmwrite(GUEST_FS_AR_BYTES, c->fs_arbytes.bytes);
-
-    __vmwrite(GUEST_GS_SELECTOR, c->gs_sel);
-    __vmwrite(GUEST_GS_LIMIT, c->gs_limit);
-    __vmwrite(GUEST_GS_BASE, c->gs_base);
-    __vmwrite(GUEST_GS_AR_BYTES, c->gs_arbytes.bytes);
-
-    __vmwrite(GUEST_TR_SELECTOR, c->tr_sel);
-    __vmwrite(GUEST_TR_LIMIT, c->tr_limit);
-    __vmwrite(GUEST_TR_BASE, c->tr_base);
-    __vmwrite(GUEST_TR_AR_BYTES, c->tr_arbytes.bytes);
-
-    __vmwrite(GUEST_LDTR_SELECTOR, c->ldtr_sel);
-    __vmwrite(GUEST_LDTR_LIMIT, c->ldtr_limit);
-    __vmwrite(GUEST_LDTR_BASE, c->ldtr_base);
-    __vmwrite(GUEST_LDTR_AR_BYTES, c->ldtr_arbytes.bytes);
-
-    paging_update_paging_modes(v);
-    return 0;
-}
-
-enum { VMX_ASSIST_INVOKE = 0, VMX_ASSIST_RESTORE };
-
-static int vmx_assist(struct vcpu *v, int mode)
-{
-    struct vmx_assist_context c;
-    struct hvm_hw_vpic *vpic = v->domain->arch.hvm_domain.vpic;
-    u32 magic, cp;
-
-    if ( hvm_copy_from_guest_phys(&magic, VMXASSIST_MAGIC_OFFSET,
-                                  sizeof(magic)) )
-    {
-        gdprintk(XENLOG_ERR, "No vmxassist: can't execute real mode code\n");
-        domain_crash(v->domain);
-        return 0;
-    }
-
-    if ( magic != VMXASSIST_MAGIC )
-    {
-        gdprintk(XENLOG_ERR, "vmxassist magic number not match\n");
-        domain_crash(v->domain);
-        return 0;
-    }
-
-    switch ( mode ) {
-        /*
-         * Transfer control to vmxassist.
-         * Store the current context in VMXASSIST_OLD_CONTEXT and load
-         * the new VMXASSIST_NEW_CONTEXT context. This context was created
-         * by vmxassist and will transfer control to it.
-         */
-    case VMX_ASSIST_INVOKE:
-        /* save the old context */
-        if ( hvm_copy_from_guest_phys(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp)) )
-            goto error;
-        if ( cp != 0 ) {
-            vmx_world_save(v, &c);
-            if ( hvm_copy_to_guest_phys(cp, &c, sizeof(c)) )
-                goto error;
-        }
-
-        /* restore the new context, this should activate vmxassist */
-        if ( hvm_copy_from_guest_phys(&cp, VMXASSIST_NEW_CONTEXT, sizeof(cp)) )
-            goto error;
-        if ( cp != 0 ) {
-            if ( hvm_copy_from_guest_phys(&c, cp, sizeof(c)) )
-                goto error;
-            if ( vmx_world_restore(v, &c) != 0 )
-                goto error;
-            v->arch.hvm_vmx.pm_irqbase[0] = vpic[0].irq_base;
-            v->arch.hvm_vmx.pm_irqbase[1] = vpic[1].irq_base;
-            vpic[0].irq_base = NR_EXCEPTION_HANDLER;
-            vpic[1].irq_base = NR_EXCEPTION_HANDLER + 8;
-            v->arch.hvm_vmx.vmxassist_enabled = 1;
-            return 1;
-        }
-        break;
-
-        /*
-         * Restore the VMXASSIST_OLD_CONTEXT that was saved by
-         * VMX_ASSIST_INVOKE above.
-         */
-    case VMX_ASSIST_RESTORE:
-        /* save the old context */
-        if ( hvm_copy_from_guest_phys(&cp, VMXASSIST_OLD_CONTEXT, sizeof(cp)) )
-            goto error;
-        if ( cp != 0 ) {
-            if ( hvm_copy_from_guest_phys(&c, cp, sizeof(c)) )
-                goto error;
-            if ( vmx_world_restore(v, &c) != 0 )
-                goto error;
-            if ( v->arch.hvm_vmx.irqbase_mode ) {
-                vpic[0].irq_base = c.rm_irqbase[0] & 0xf8;
-                vpic[1].irq_base = c.rm_irqbase[1] & 0xf8;
-            } else {
-                vpic[0].irq_base = v->arch.hvm_vmx.pm_irqbase[0];
-                vpic[1].irq_base = v->arch.hvm_vmx.pm_irqbase[1];
-            }
-            v->arch.hvm_vmx.vmxassist_enabled = 0;
-            return 1;
-        }
-        break;
-    }
-
- error:
-    gdprintk(XENLOG_ERR, "Failed to transfer to vmxassist\n");
-    domain_crash(v->domain);
-    return 0;
-}
-
-static int vmx_set_cr0(unsigned long value)
-{
-    struct vcpu *v = current;
-
-    if ( hvm_set_cr0(value) == 0 )
-        return 0;
-
-    /*
-     * VMX does not implement real-mode virtualization. We emulate
-     * real-mode by performing a world switch to VMXAssist whenever
-     * a partition disables the CR0.PE bit.
-     */
-    if ( !(value & X86_CR0_PE) )
-    {
-        if ( vmx_assist(v, VMX_ASSIST_INVOKE) )
-            return 0; /* do not update eip! */
-    }
-    else if ( v->arch.hvm_vmx.vmxassist_enabled )
-    {
-        if ( vmx_assist(v, VMX_ASSIST_RESTORE) )
-            return 0; /* do not update eip! */
-    }
-
-    return 1;
-}
-
-#else /* !defined(VMXASSIST) */
-
-#define vmx_set_cr0(v) hvm_set_cr0(v)
-
-#endif
-
 #define CASE_SET_REG(REG, reg)      \
     case REG_ ## REG: regs->reg = value; break
 #define CASE_GET_REG(REG, reg)      \
@@ -2146,7 +1854,7 @@ static int mov_to_cr(int gp, int cr, str
     switch ( cr )
     {
     case 0:
-        return vmx_set_cr0(value);
+        return hvm_set_cr0(value);
 
     case 3:
         return hvm_set_cr3(value);
@@ -2243,7 +1951,7 @@ static int vmx_cr_access(unsigned long e
         value = (value & ~0xF) |
             (((exit_qualification & LMSW_SOURCE_DATA) >> 16) & 0xF);
         HVMTRACE_1D(LMSW, current, value);
-        return vmx_set_cr0(value);
+        return hvm_set_cr0(value);
     default:
         BUG();
     }
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 xen/arch/x86/hvm/vmx/x86_32/exits.S
--- a/xen/arch/x86/hvm/vmx/x86_32/exits.S       Tue Feb 05 23:27:12 2008 +0000
+++ b/xen/arch/x86/hvm/vmx/x86_32/exits.S       Wed Feb 06 12:07:55 2008 +0000
@@ -115,10 +115,8 @@ ENTRY(vmx_asm_do_vmentry)
         movl $GUEST_RFLAGS,%eax
         VMWRITE(UREGS_eflags)
 
-#ifndef VMXASSIST
         testb $0xff,VCPU_vmx_emul(%ebx)
         jnz  vmx_goto_realmode
-#endif
 
         cmpb $0,VCPU_vmx_launched(%ebx)
         je   vmx_launch
@@ -138,7 +136,6 @@ vmx_launch:
         call vm_launch_fail
         ud2
 
-#ifndef VMXASSIST
 vmx_goto_realmode:
         sti
         movl %esp,%eax
@@ -146,4 +143,3 @@ vmx_goto_realmode:
         call vmx_realmode
         addl $4,%esp
         jmp vmx_asm_do_vmentry
-#endif
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 xen/arch/x86/hvm/vmx/x86_64/exits.S
--- a/xen/arch/x86/hvm/vmx/x86_64/exits.S       Tue Feb 05 23:27:12 2008 +0000
+++ b/xen/arch/x86/hvm/vmx/x86_64/exits.S       Wed Feb 06 12:07:55 2008 +0000
@@ -134,10 +134,8 @@ ENTRY(vmx_asm_do_vmentry)
         movl $GUEST_RFLAGS,%eax
         VMWRITE(UREGS_eflags)
 
-#ifndef VMXASSIST
         testb $0xff,VCPU_vmx_emul(%rbx)
         jnz  vmx_goto_realmode
-#endif
 
         cmpb $0,VCPU_vmx_launched(%rbx)
         je   vmx_launch
@@ -157,10 +155,8 @@ vmx_launch:
         call vm_launch_fail
         ud2
 
-#ifndef VMXASSIST
 vmx_goto_realmode:
         sti
         movq %rsp,%rdi
         call vmx_realmode
         jmp vmx_asm_do_vmentry
-#endif
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 xen/arch/x86/hvm/vpic.c
--- a/xen/arch/x86/hvm/vpic.c   Tue Feb 05 23:27:12 2008 +0000
+++ b/xen/arch/x86/hvm/vpic.c   Wed Feb 06 12:07:55 2008 +0000
@@ -271,11 +271,6 @@ static void vpic_ioport_write(
             vpic->imr = val;
             break;
         case 1:
-#ifdef VMXASSIST
-            /* Which mode is irqbase programmed in? */
-            current->arch.hvm_vmx.irqbase_mode =
-                current->arch.hvm_vmx.vmxassist_enabled;
-#endif
             /* ICW2 */
             vpic->irq_base = val & 0xf8;
             vpic->init_state++;
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 xen/include/asm-x86/hvm/vmx/vmcs.h
--- a/xen/include/asm-x86/hvm/vmx/vmcs.h        Tue Feb 05 23:27:12 2008 +0000
+++ b/xen/include/asm-x86/hvm/vmx/vmcs.h        Wed Feb 06 12:07:55 2008 +0000
@@ -23,10 +23,6 @@
 #include <asm/hvm/io.h>
 #include <asm/hvm/vmx/cpu.h>
 #include <asm/hvm/vmx/vpmu.h>
-
-#ifdef VMXASSIST
-#include <public/hvm/vmx_assist.h>
-#endif
 
 extern void start_vmx(void);
 extern void vmcs_dump_vcpu(struct vcpu *v);
@@ -94,14 +90,6 @@ struct arch_vmx_struct {
 
     unsigned long        host_cr0;
 
-#ifdef VMXASSIST
-
-    unsigned long        vmxassist_enabled:1;
-    unsigned long        irqbase_mode:1;
-    unsigned char        pm_irqbase[2];
-
-#else
-
     /* Are we emulating rather than VMENTERing? */
 #define VMXEMUL_REALMODE 1  /* Yes, because CR0.PE == 0   */
 #define VMXEMUL_BAD_CS   2  /* Yes, because CS.RPL != CPL */
@@ -112,7 +100,6 @@ struct arch_vmx_struct {
     bool_t               real_mode_io_in_progress;
     bool_t               real_mode_io_completed;
     unsigned long        real_mode_io_data;
-#endif
 };
 
 int vmx_create_vmcs(struct vcpu *v);
diff -r f8db1c6baad9 -r 9d0e86d8c1d1 xen/include/public/hvm/vmx_assist.h
--- a/xen/include/public/hvm/vmx_assist.h       Tue Feb 05 23:27:12 2008 +0000
+++ /dev/null   Thu Jan 01 00:00:00 1970 +0000
@@ -1,122 +0,0 @@
-/*
- * vmx_assist.h: Context definitions for the VMXASSIST world switch.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- *
- * Leendert van Doorn, leendert@xxxxxxxxxxxxxx
- * Copyright (c) 2005, International Business Machines Corporation.
- */
-
-#ifndef _VMX_ASSIST_H_
-#define _VMX_ASSIST_H_
-
-#define VMXASSIST_BASE         0xD0000
-#define VMXASSIST_MAGIC        0x17101966
-#define VMXASSIST_MAGIC_OFFSET (VMXASSIST_BASE+8)
-
-#define VMXASSIST_NEW_CONTEXT (VMXASSIST_BASE + 12)
-#define VMXASSIST_OLD_CONTEXT (VMXASSIST_NEW_CONTEXT + 4)
-
-#ifndef __ASSEMBLY__
-
-#define NR_EXCEPTION_HANDLER    32
-#define NR_INTERRUPT_HANDLERS   16
-#define NR_TRAPS        (NR_EXCEPTION_HANDLER+NR_INTERRUPT_HANDLERS)
-
-union vmcs_arbytes {
-    struct arbyte_fields {
-        unsigned int seg_type : 4,
-            s         : 1,
-            dpl       : 2,
-            p         : 1,
-            reserved0 : 4,
-            avl       : 1,
-            reserved1 : 1,
-            default_ops_size: 1,
-            g         : 1,
-            null_bit  : 1,
-            reserved2 : 15;
-    } fields;
-    unsigned int bytes;
-};
-
-/*
- * World switch state
- */
-struct vmx_assist_context {
-    uint32_t  eip;        /* execution pointer */
-    uint32_t  esp;        /* stack pointer */
-    uint32_t  eflags;     /* flags register */
-    uint32_t  cr0;
-    uint32_t  cr3;        /* page table directory */
-    uint32_t  cr4;
-    uint32_t  idtr_limit; /* idt */
-    uint32_t  idtr_base;
-    uint32_t  gdtr_limit; /* gdt */
-    uint32_t  gdtr_base;
-    uint32_t  cs_sel;     /* cs selector */
-    uint32_t  cs_limit;
-    uint32_t  cs_base;
-    union vmcs_arbytes cs_arbytes;
-    uint32_t  ds_sel;     /* ds selector */
-    uint32_t  ds_limit;
-    uint32_t  ds_base;
-    union vmcs_arbytes ds_arbytes;
-    uint32_t  es_sel;     /* es selector */
-    uint32_t  es_limit;
-    uint32_t  es_base;
-    union vmcs_arbytes es_arbytes;
-    uint32_t  ss_sel;     /* ss selector */
-    uint32_t  ss_limit;
-    uint32_t  ss_base;
-    union vmcs_arbytes ss_arbytes;
-    uint32_t  fs_sel;     /* fs selector */
-    uint32_t  fs_limit;
-    uint32_t  fs_base;
-    union vmcs_arbytes fs_arbytes;
-    uint32_t  gs_sel;     /* gs selector */
-    uint32_t  gs_limit;
-    uint32_t  gs_base;
-    union vmcs_arbytes gs_arbytes;
-    uint32_t  tr_sel;     /* task selector */
-    uint32_t  tr_limit;
-    uint32_t  tr_base;
-    union vmcs_arbytes tr_arbytes;
-    uint32_t  ldtr_sel;   /* ldtr selector */
-    uint32_t  ldtr_limit;
-    uint32_t  ldtr_base;
-    union vmcs_arbytes ldtr_arbytes;
-
-    unsigned char rm_irqbase[2];
-};
-typedef struct vmx_assist_context vmx_assist_context_t;
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* _VMX_ASSIST_H_ */
-
-/*
- * Local variables:
- * mode: C
- * c-set-style: "BSD"
- * c-basic-offset: 4
- * tab-width: 4
- * indent-tabs-mode: nil
- * End:
- */

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.