direct-io.hg

changeset 15444:93b9161fc920

Use 32bit operand and address during VMXAssist protected to real.
Signed-off-by: Xin Li <xin.b.li@intel.com>
author Keir Fraser <keir@xensource.com>
date Mon Jul 02 00:24:59 2007 +0100 (2007-07-02)
parents 5d7160564381
children 182446677b6b
files tools/firmware/vmxassist/setup.c tools/firmware/vmxassist/vm86.c
line diff
     1.1 --- a/tools/firmware/vmxassist/setup.c	Sun Jul 01 22:25:27 2007 +0100
     1.2 +++ b/tools/firmware/vmxassist/setup.c	Mon Jul 02 00:24:59 2007 +0100
     1.3 @@ -198,9 +198,10 @@ enter_real_mode(struct regs *regs)
     1.4  	}
     1.5  
     1.6  	/* go from protected to real mode */
     1.7 -	regs->eflags |= EFLAGS_VM;
     1.8  	set_mode(regs, VM86_PROTECTED_TO_REAL);
     1.9  	emulate(regs);
    1.10 +	if (mode != VM86_REAL)
    1.11 +		panic("failed to emulate between clear PE and long jump.\n");
    1.12  }
    1.13  
    1.14  /*
     2.1 --- a/tools/firmware/vmxassist/vm86.c	Sun Jul 01 22:25:27 2007 +0100
     2.2 +++ b/tools/firmware/vmxassist/vm86.c	Mon Jul 02 00:24:59 2007 +0100
     2.3 @@ -580,8 +580,13 @@ movr(struct regs *regs, unsigned prefix,
     2.4  	unsigned addr = operand(prefix, regs, modrm);
     2.5  	unsigned val, r = (modrm >> 3) & 7;
     2.6  
     2.7 -	if ((modrm & 0xC0) == 0xC0) /* no registers */
     2.8 -		return 0;
     2.9 +	if ((modrm & 0xC0) == 0xC0) {
    2.10 +		/*
    2.11 +		 * Emulate all guest instructions in protected to real mode.
    2.12 +		 */
    2.13 +		if (mode != VM86_PROTECTED_TO_REAL)
    2.14 +			return 0;
    2.15 +	}
    2.16  
    2.17  	switch (opc) {
    2.18  	case 0x88: /* addr32 mov r8, r/m8 */
    2.19 @@ -806,8 +811,13 @@ mov_to_seg(struct regs *regs, unsigned p
    2.20  {
    2.21  	unsigned modrm = fetch8(regs);
    2.22  
    2.23 -	/* Only need to emulate segment loads in real->protected mode. */
    2.24 -	if (mode != VM86_REAL_TO_PROTECTED)
    2.25 +	/*
    2.26 +	 * Emulate segment loads in:
    2.27 +	 * 1) real->protected mode.
    2.28 +	 * 2) protected->real mode.
    2.29 +	 */
    2.30 +	if ((mode != VM86_REAL_TO_PROTECTED) &&
    2.31 +	    (mode != VM86_PROTECTED_TO_REAL))
    2.32  		return 0;
    2.33  
    2.34  	/* Register source only. */
    2.35 @@ -817,6 +827,8 @@ mov_to_seg(struct regs *regs, unsigned p
    2.36  	switch ((modrm & 0x38) >> 3) {
    2.37  	case 0: /* es */
    2.38  		regs->ves = getreg16(regs, modrm);
    2.39 +		if (mode == VM86_PROTECTED_TO_REAL)
    2.40 +			return 1;
    2.41  		saved_rm_regs.ves = 0;
    2.42  		oldctx.es_sel = regs->ves;
    2.43  		return 1;
    2.44 @@ -825,21 +837,29 @@ mov_to_seg(struct regs *regs, unsigned p
    2.45  
    2.46  	case 2: /* ss */
    2.47  		regs->uss = getreg16(regs, modrm);
    2.48 +		if (mode == VM86_PROTECTED_TO_REAL)
    2.49 +			return 1;
    2.50  		saved_rm_regs.uss = 0;
    2.51  		oldctx.ss_sel = regs->uss;
    2.52  		return 1;
    2.53  	case 3: /* ds */
    2.54  		regs->vds = getreg16(regs, modrm);
    2.55 +		if (mode == VM86_PROTECTED_TO_REAL)
    2.56 +			return 1;
    2.57  		saved_rm_regs.vds = 0;
    2.58  		oldctx.ds_sel = regs->vds;
    2.59  		return 1;
    2.60  	case 4: /* fs */
    2.61  		regs->vfs = getreg16(regs, modrm);
    2.62 +		if (mode == VM86_PROTECTED_TO_REAL)
    2.63 +			return 1;
    2.64  		saved_rm_regs.vfs = 0;
    2.65  		oldctx.fs_sel = regs->vfs;
    2.66  		return 1;
    2.67  	case 5: /* gs */
    2.68  		regs->vgs = getreg16(regs, modrm);
    2.69 +		if (mode == VM86_PROTECTED_TO_REAL)
    2.70 +			return 1;
    2.71  		saved_rm_regs.vgs = 0;
    2.72  		oldctx.gs_sel = regs->vgs;
    2.73  		return 1;
    2.74 @@ -1055,7 +1075,8 @@ set_mode(struct regs *regs, enum vm86_mo
    2.75  	}
    2.76  
    2.77  	mode = newmode;
    2.78 -	TRACE((regs, 0, states[mode]));
    2.79 +	if (mode != VM86_PROTECTED)
    2.80 +		TRACE((regs, 0, states[mode]));
    2.81  }
    2.82  
    2.83  static void
    2.84 @@ -1269,6 +1290,12 @@ opcode(struct regs *regs)
    2.85  	unsigned opc, modrm, disp;
    2.86  	unsigned prefix = 0;
    2.87  
    2.88 +	if (mode == VM86_PROTECTED_TO_REAL &&
    2.89 +		oldctx.cs_arbytes.fields.default_ops_size) {
    2.90 +		prefix |= DATA32;
    2.91 +		prefix |= ADDR32;
    2.92 +	}
    2.93 +
    2.94  	for (;;) {
    2.95  		switch ((opc = fetch8(regs))) {
    2.96  		case 0x07: /* pop %es */
    2.97 @@ -1379,17 +1406,29 @@ opcode(struct regs *regs)
    2.98  			continue;
    2.99  
   2.100  		case 0x66:
   2.101 -			TRACE((regs, regs->eip - eip, "data32"));
   2.102 -			prefix |= DATA32;
   2.103 +			if (mode == VM86_PROTECTED_TO_REAL &&
   2.104 +				oldctx.cs_arbytes.fields.default_ops_size) {
   2.105 +				TRACE((regs, regs->eip - eip, "data16"));
   2.106 +				prefix &= ~DATA32;
   2.107 +			} else {
   2.108 +				TRACE((regs, regs->eip - eip, "data32"));
   2.109 +				prefix |= DATA32;
   2.110 +			}
   2.111  			continue;
   2.112  
   2.113  		case 0x67:
   2.114 -			TRACE((regs, regs->eip - eip, "addr32"));
   2.115 -			prefix |= ADDR32;
   2.116 +			if (mode == VM86_PROTECTED_TO_REAL &&
   2.117 +				oldctx.cs_arbytes.fields.default_ops_size) {
   2.118 +				TRACE((regs, regs->eip - eip, "addr16"));
   2.119 +				prefix &= ~ADDR32;
   2.120 +			} else {
   2.121 +				TRACE((regs, regs->eip - eip, "addr32"));
   2.122 +				prefix |= ADDR32;
   2.123 +			}
   2.124  			continue;
   2.125  
   2.126 -		case 0x88: /* addr32 mov r8, r/m8 */
   2.127 -		case 0x8A: /* addr32 mov r/m8, r8 */
   2.128 +		case 0x88: /* mov r8, r/m8 */
   2.129 +		case 0x8A: /* mov r/m8, r8 */
   2.130  			if (mode != VM86_REAL && mode != VM86_REAL_TO_PROTECTED)
   2.131  				goto invalid;
   2.132  			if ((prefix & ADDR32) == 0)