direct-io.hg

changeset 12365:ca75b51d69c7

[VMXASSIST] Emulate pop %ds and mov reg->{ds,es}.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Fri Nov 10 17:21:54 2006 +0000 (2006-11-10)
parents d19deb173503
children f6b7ae6ed504
files tools/firmware/vmxassist/vm86.c
line diff
     1.1 --- a/tools/firmware/vmxassist/vm86.c	Fri Nov 10 15:27:22 2006 +0000
     1.2 +++ b/tools/firmware/vmxassist/vm86.c	Fri Nov 10 17:21:54 2006 +0000
     1.3 @@ -813,6 +813,40 @@ pop(struct regs *regs, unsigned prefix, 
     1.4  	return 1;
     1.5  }
     1.6  
     1.7 +static int
     1.8 +mov_to_seg(struct regs *regs, unsigned prefix, unsigned opc)
     1.9 +{
    1.10 +	unsigned eip = regs->eip - 1;
    1.11 +	unsigned modrm = fetch8(regs);
    1.12 +	unsigned addr = operand(prefix, regs, modrm);
    1.13 +
    1.14 +	/* Only need to emulate segment loads in real->protected mode. */
    1.15 +	if (mode != VM86_REAL_TO_PROTECTED)
    1.16 +		return 0;
    1.17 +
    1.18 +	/* Register source only. */
    1.19 +	if ((modrm & 0xC0) != 0xC0)
    1.20 +		goto fail;
    1.21 +
    1.22 +	switch ((modrm & 0x38) >> 3) {
    1.23 +	case 3: /* ds */
    1.24 +		regs->vds = getreg16(regs, modrm);
    1.25 +		saved_rm_regs.vds = 0;
    1.26 +		oldctx.ds_sel = regs->vds;
    1.27 +		return 1;
    1.28 +	case 0: /* es */
    1.29 +		regs->ves = getreg16(regs, modrm);
    1.30 +		saved_rm_regs.ves = 0;
    1.31 +		oldctx.es_sel = regs->ves;
    1.32 +		return 1;
    1.33 +	}
    1.34 +
    1.35 + fail:
    1.36 +	printf("%s:%d: missed opcode %02x %02x\n",
    1.37 +	       __FUNCTION__, __LINE__, opc, modrm);
    1.38 +	return 0;
    1.39 +}
    1.40 +
    1.41  /*
    1.42   * Emulate a segment load in protected mode
    1.43   */
    1.44 @@ -1257,11 +1291,9 @@ opcode(struct regs *regs)
    1.45  
    1.46  	for (;;) {
    1.47  		switch ((opc = fetch8(regs))) {
    1.48 -		case 0x07:
    1.49 -			if (prefix & DATA32)
    1.50 -				regs->ves = pop32(regs);
    1.51 -			else
    1.52 -				regs->ves = pop16(regs);
    1.53 +		case 0x07: /* pop %es */
    1.54 +			regs->ves = (prefix & DATA32) ?
    1.55 +				pop32(regs) : pop16(regs);
    1.56  			TRACE((regs, regs->eip - eip, "pop %%es"));
    1.57  			if (mode == VM86_REAL_TO_PROTECTED) {
    1.58  				saved_rm_regs.ves = 0;
    1.59 @@ -1316,6 +1348,16 @@ opcode(struct regs *regs)
    1.60  			}
    1.61  			goto invalid;
    1.62  
    1.63 +		case 0x1F: /* pop %ds */
    1.64 +			regs->vds = (prefix & DATA32) ?
    1.65 +				pop32(regs) : pop16(regs);
    1.66 +			TRACE((regs, regs->eip - eip, "pop %%ds"));
    1.67 +			if (mode == VM86_REAL_TO_PROTECTED) {
    1.68 +				saved_rm_regs.vds = 0;
    1.69 +				oldctx.ds_sel = regs->vds;
    1.70 +			}
    1.71 +			return OPC_EMULATED;
    1.72 +
    1.73  		case 0x26:
    1.74  			TRACE((regs, regs->eip - eip, "%%es:"));
    1.75  			prefix |= SEG_ES;
    1.76 @@ -1402,6 +1444,11 @@ opcode(struct regs *regs)
    1.77                                  goto invalid;
    1.78                          return OPC_EMULATED;
    1.79  
    1.80 +		case 0x8E: /* mov r16, sreg */
    1.81 +			if (!mov_to_seg(regs, prefix, opc))
    1.82 +				goto invalid;
    1.83 +			return OPC_EMULATED;
    1.84 +
    1.85  		case 0x8F: /* addr32 pop r/m16 */
    1.86                          if ((prefix & ADDR32) == 0)
    1.87                                  goto invalid;