diff options
author | kaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk> | 2006-04-01 14:59:12 +0100 |
---|---|---|
committer | kaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk> | 2006-04-01 14:59:12 +0100 |
commit | 9cf21925de2dee4365e83fd0c18b13aef621ae41 (patch) | |
tree | 6ce3bda800c5108b9fd6c377e630d778145d75c9 | |
parent | 97c44fa2f3486940b29b07f854855b18906fe69c (diff) | |
download | xen-9cf21925de2dee4365e83fd0c18b13aef621ae41.tar.gz xen-9cf21925de2dee4365e83fd0c18b13aef621ae41.tar.bz2 xen-9cf21925de2dee4365e83fd0c18b13aef621ae41.zip |
This patch fixes several issues related to vmxassist:
1) AP bring up;
2) RHEL4 IA32e installation;
3) SLES10 IA32e installation;
Signed-off-by: Xin Li <xin.b.li@intel.com>
-rw-r--r-- | tools/firmware/vmxassist/Makefile | 12 | ||||
-rw-r--r-- | tools/firmware/vmxassist/trap.S | 1 | ||||
-rw-r--r-- | tools/firmware/vmxassist/util.c | 1 | ||||
-rw-r--r-- | tools/firmware/vmxassist/vm86.c | 94 | ||||
-rw-r--r-- | tools/firmware/vmxassist/vm86.h | 1 |
5 files changed, 63 insertions, 46 deletions
diff --git a/tools/firmware/vmxassist/Makefile b/tools/firmware/vmxassist/Makefile index 85c9fff581..17b13b2be2 100644 --- a/tools/firmware/vmxassist/Makefile +++ b/tools/firmware/vmxassist/Makefile @@ -53,25 +53,25 @@ vmxassist.bin: vmxassist.ld $(OBJECTS) dd if=vmxassist.tmp of=vmxassist.bin ibs=512 conv=sync rm -f vmxassist.tmp -head.o: machine.h head.S +head.o: machine.h vm86.h head.S $(CC) $(CFLAGS) -D__ASSEMBLY__ $(DEFINES) -c head.S -trap.o: machine.h offsets.h trap.S +trap.o: machine.h vm86.h offsets.h trap.S $(CC) $(CFLAGS) -D__ASSEMBLY__ $(DEFINES) -c trap.S -vm86.o: machine.h vm86.c +vm86.o: machine.h vm86.h vm86.c $(CC) $(CFLAGS) -c vm86.c -setup.o: machine.h setup.c +setup.o: machine.h vm86.h setup.c $(CC) $(CFLAGS) -c setup.c -util.o: machine.h util.c +util.o: machine.h vm86.h util.c $(CC) $(CFLAGS) -c util.c offsets.h: gen ./gen > offsets.h -gen: gen.c +gen: vm86.h gen.c $(HOSTCC) $(HOSTCFLAGS) -I. $(XENINC) -o gen gen.c clean: diff --git a/tools/firmware/vmxassist/trap.S b/tools/firmware/vmxassist/trap.S index e4294e88c2..468da0a5db 100644 --- a/tools/firmware/vmxassist/trap.S +++ b/tools/firmware/vmxassist/trap.S @@ -18,6 +18,7 @@ * Place - Suite 330, Boston, MA 02111-1307 USA. */ #include "machine.h" +#include "vm86.h" #include "offsets.h" /* diff --git a/tools/firmware/vmxassist/util.c b/tools/firmware/vmxassist/util.c index 9e9f86cb12..0181fe702c 100644 --- a/tools/firmware/vmxassist/util.c +++ b/tools/firmware/vmxassist/util.c @@ -18,7 +18,6 @@ * Place - Suite 330, Boston, MA 02111-1307 USA. */ #include <stdarg.h> -#include <vm86.h> #include "util.h" #include "machine.h" diff --git a/tools/firmware/vmxassist/vm86.c b/tools/firmware/vmxassist/vm86.c index f9e8ae3753..e18efc1c64 100644 --- a/tools/firmware/vmxassist/vm86.c +++ b/tools/firmware/vmxassist/vm86.c @@ -34,7 +34,7 @@ #define SEG_FS 0x0040 #define SEG_GS 0x0080 -unsigned prev_eip = 0; +static unsigned prev_eip = 0; enum vm86_mode mode = 0; #ifdef DEBUG @@ -50,23 +50,41 @@ char *states[] = { static char *rnames[] = { "ax", "cx", "dx", "bx", "sp", "bp", "si", "di" }; #endif /* DEBUG */ -unsigned +static unsigned address(struct regs *regs, unsigned seg, unsigned off) { unsigned long long entry; - unsigned addr; + unsigned seg_base, seg_limit; + unsigned entry_low, entry_high; - if (seg == 0) - return off; + 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 (seg > oldctx.gdtr_limit) + if (mode == VM86_REAL || seg > oldctx.gdtr_limit || + (mode == VM86_REAL_TO_PROTECTED && regs->cs == seg)) return ((seg & 0xFFFF) << 4) + off; entry = ((unsigned long long *) oldctx.gdtr_base)[seg >> 3]; - addr = (((entry >> (56-24)) & 0xFF000000) | - ((entry >> (32-16)) & 0x00FF0000) | - ((entry >> ( 16)) & 0x0000FFFF)) + off; - return addr; + 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 @@ -194,7 +212,7 @@ fetch8(struct regs *regs) return read8(addr); } -unsigned +static unsigned getreg32(struct regs *regs, int r) { switch (r & 7) { @@ -210,13 +228,13 @@ getreg32(struct regs *regs, int r) return ~0; } -unsigned +static unsigned getreg16(struct regs *regs, int r) { return MASK16(getreg32(regs, r)); } -unsigned +static unsigned getreg8(struct regs *regs, int r) { switch (r & 7) { @@ -232,7 +250,7 @@ getreg8(struct regs *regs, int r) return ~0; } -void +static void setreg32(struct regs *regs, int r, unsigned v) { switch (r & 7) { @@ -247,13 +265,13 @@ setreg32(struct regs *regs, int r, unsigned v) } } -void +static void setreg16(struct regs *regs, int r, unsigned v) { setreg32(regs, r, (getreg32(regs, r) & ~0xFFFF) | MASK16(v)); } -void +static void setreg8(struct regs *regs, int r, unsigned v) { v &= 0xFF; @@ -269,7 +287,7 @@ setreg8(struct regs *regs, int r, unsigned v) } } -unsigned +static unsigned segment(unsigned prefix, struct regs *regs, unsigned seg) { if (prefix & SEG_ES) @@ -287,7 +305,7 @@ segment(unsigned prefix, struct regs *regs, unsigned seg) return seg; } -unsigned +static unsigned sib(struct regs *regs, int mod, unsigned byte) { unsigned scale = (byte >> 6) & 3; @@ -319,7 +337,7 @@ sib(struct regs *regs, int mod, unsigned byte) /* * Operand (modrm) decode */ -unsigned +static unsigned operand(unsigned prefix, struct regs *regs, unsigned modrm) { int mod, disp = 0, seg; @@ -418,7 +436,7 @@ operand(unsigned prefix, struct regs *regs, unsigned modrm) /* * Load new IDT */ -int +static int lidt(struct regs *regs, unsigned prefix, unsigned modrm) { unsigned eip = regs->eip - 3; @@ -438,7 +456,7 @@ lidt(struct regs *regs, unsigned prefix, unsigned modrm) /* * Load new GDT */ -int +static int lgdt(struct regs *regs, unsigned prefix, unsigned modrm) { unsigned eip = regs->eip - 3; @@ -458,7 +476,7 @@ lgdt(struct regs *regs, unsigned prefix, unsigned modrm) /* * Modify CR0 either through an lmsw instruction. */ -int +static int lmsw(struct regs *regs, unsigned prefix, unsigned modrm) { unsigned eip = regs->eip - 3; @@ -481,7 +499,7 @@ lmsw(struct regs *regs, unsigned prefix, unsigned modrm) * We need to handle moves that address memory beyond the 64KB segment * limit that VM8086 mode enforces. */ -int +static int movr(struct regs *regs, unsigned prefix, unsigned opc) { unsigned eip = regs->eip - 1; @@ -546,7 +564,7 @@ movr(struct regs *regs, unsigned prefix, unsigned opc) /* * Move to and from a control register. */ -int +static int movcr(struct regs *regs, unsigned prefix, unsigned opc) { unsigned eip = regs->eip - 2; @@ -618,7 +636,7 @@ static inline void set_eflags_ZF(unsigned mask, unsigned v1, struct regs *regs) * We need to handle cmp opcodes that address memory beyond the 64KB * segment limit that VM8086 mode enforces. */ -int +static int cmp(struct regs *regs, unsigned prefix, unsigned opc) { unsigned eip = regs->eip - 1; @@ -658,7 +676,7 @@ cmp(struct regs *regs, unsigned prefix, unsigned opc) * We need to handle test opcodes that address memory beyond the 64KB * segment limit that VM8086 mode enforces. */ -int +static int test(struct regs *regs, unsigned prefix, unsigned opc) { unsigned eip = regs->eip - 1; @@ -691,7 +709,7 @@ test(struct regs *regs, unsigned prefix, unsigned opc) * We need to handle pop opcodes that address memory beyond the 64KB * segment limit that VM8086 mode enforces. */ -int +static int pop(struct regs *regs, unsigned prefix, unsigned opc) { unsigned eip = regs->eip - 1; @@ -721,7 +739,7 @@ pop(struct regs *regs, unsigned prefix, unsigned opc) /* * Emulate a segment load in protected mode */ -int +static int load_seg(unsigned long sel, uint32_t *base, uint32_t *limit, union vmcs_arbytes *arbytes) { unsigned long long entry; @@ -768,7 +786,7 @@ load_seg(unsigned long sel, uint32_t *base, uint32_t *limit, union vmcs_arbytes /* * Transition to protected mode */ -void +static void protected_mode(struct regs *regs) { regs->eflags &= ~(EFLAGS_TF|EFLAGS_VM); @@ -842,7 +860,7 @@ protected_mode(struct regs *regs) /* * Start real-mode emulation */ -void +static void real_mode(struct regs *regs) { regs->eflags |= EFLAGS_VM | 0x02; @@ -935,7 +953,7 @@ set_mode(struct regs *regs, enum vm86_mode newmode) TRACE((regs, 0, states[mode])); } -void +static void jmpl(struct regs *regs, int prefix) { unsigned n = regs->eip; @@ -963,7 +981,7 @@ jmpl(struct regs *regs, int prefix) panic("jmpl"); } -void +static void retl(struct regs *regs, int prefix) { unsigned cs, eip; @@ -990,7 +1008,7 @@ retl(struct regs *regs, int prefix) panic("retl"); } -void +static void interrupt(struct regs *regs, int n) { TRACE((regs, 0, "external interrupt %d", n)); @@ -1008,7 +1026,7 @@ interrupt(struct regs *regs, int n) * interrupt vectors. The following simple state machine catches * these attempts and rewrites them. */ -int +static int outbyte(struct regs *regs, unsigned prefix, unsigned opc) { static char icw2[2] = { 0 }; @@ -1059,7 +1077,7 @@ outbyte(struct regs *regs, unsigned prefix, unsigned opc) return 1; } -int +static int inbyte(struct regs *regs, unsigned prefix, unsigned opc) { int port; @@ -1086,7 +1104,7 @@ enum { OPC_INVALID, OPC_EMULATED }; * a small subset of the opcodes, and not all opcodes are implemented for each * of the four modes we can operate in. */ -int +static int opcode(struct regs *regs) { unsigned eip = regs->eip; @@ -1246,7 +1264,7 @@ opcode(struct regs *regs) if ((mode == VM86_REAL_TO_PROTECTED) || (mode == VM86_PROTECTED_TO_REAL)) { retl(regs, prefix); - return OPC_EMULATED; + return OPC_INVALID; } goto invalid; @@ -1284,7 +1302,7 @@ opcode(struct regs *regs) if ((mode == VM86_REAL_TO_PROTECTED) || (mode == VM86_PROTECTED_TO_REAL)) { jmpl(regs, prefix); - return OPC_EMULATED; + return OPC_INVALID; } goto invalid; diff --git a/tools/firmware/vmxassist/vm86.h b/tools/firmware/vmxassist/vm86.h index d9798bce7e..0c04dc6e73 100644 --- a/tools/firmware/vmxassist/vm86.h +++ b/tools/firmware/vmxassist/vm86.h @@ -58,7 +58,6 @@ extern struct vmx_assist_context oldctx; extern struct vmx_assist_context newctx; extern void emulate(struct regs *); -extern void interrupt(struct regs *, int); extern void dump_regs(struct regs *); extern void trace(struct regs *, int, char *, ...); |