direct-io.hg

changeset 15447:a836f4bc86fd

vmxassist: Decode mov instruction in protected to real mode in vmxassist.
Also some clean up.
Signed-off-by: Xin Li <xin.b.li@intel.com>
author kfraser@localhost.localdomain
date Tue Jul 03 10:08:34 2007 +0100 (2007-07-03)
parents f85252ce203e
children 356bd2f3b9d8
files tools/firmware/vmxassist/vm86.c
line diff
     1.1 --- a/tools/firmware/vmxassist/vm86.c	Tue Jul 03 10:06:48 2007 +0100
     1.2 +++ b/tools/firmware/vmxassist/vm86.c	Tue Jul 03 10:08:34 2007 +0100
     1.3 @@ -594,16 +594,24 @@ movr(struct regs *regs, unsigned prefix,
     1.4  		TRACE((regs, regs->eip - eip,
     1.5  			"movb %%e%s, *0x%x", rnames[r], addr));
     1.6  		write8(addr, val);
     1.7 -		break;
     1.8 +		return 1;
     1.9  
    1.10  	case 0x8A: /* addr32 mov r/m8, r8 */
    1.11  		TRACE((regs, regs->eip - eip,
    1.12  			"movb *0x%x, %%%s", addr, rnames[r]));
    1.13  		setreg8(regs, r, read8(addr));
    1.14 -		break;
    1.15 +		return 1;
    1.16  
    1.17  	case 0x89: /* addr32 mov r16, r/m16 */
    1.18  		val = getreg32(regs, r);
    1.19 +		if ((modrm & 0xC0) == 0xC0) {
    1.20 +			if (prefix & DATA32)
    1.21 +				setreg32(regs, modrm & 7, val);
    1.22 +			else
    1.23 +				setreg16(regs, modrm & 7, MASK16(val));
    1.24 +			return 1;
    1.25 +		}
    1.26 +
    1.27  		if (prefix & DATA32) {
    1.28  			TRACE((regs, regs->eip - eip,
    1.29  				"movl %%e%s, *0x%x", rnames[r], addr));
    1.30 @@ -613,9 +621,17 @@ movr(struct regs *regs, unsigned prefix,
    1.31  				"movw %%%s, *0x%x", rnames[r], addr));
    1.32  			write16(addr, MASK16(val));
    1.33  		}
    1.34 -		break;
    1.35 +		return 1;
    1.36  
    1.37 -	case 0x8B: /* addr32 mov r/m16, r16 */
    1.38 +	case 0x8B: /* mov r/m16, r16 */
    1.39 +		if ((modrm & 0xC0) == 0xC0) {
    1.40 +			if (prefix & DATA32)
    1.41 +				setreg32(regs, r, addr);
    1.42 +			else
    1.43 +				setreg16(regs, r, MASK16(addr));
    1.44 +			return 1;
    1.45 +		}
    1.46 +
    1.47  		if (prefix & DATA32) {
    1.48  			TRACE((regs, regs->eip - eip,
    1.49  				"movl *0x%x, %%e%s", addr, rnames[r]));
    1.50 @@ -625,7 +641,7 @@ movr(struct regs *regs, unsigned prefix,
    1.51  				"movw *0x%x, %%%s", addr, rnames[r]));
    1.52  			setreg16(regs, r, read16(addr));
    1.53  		}
    1.54 -		break;
    1.55 +		return 1;
    1.56  
    1.57  	case 0xC6: /* addr32 movb $imm, r/m8 */
    1.58  		if ((modrm >> 3) & 7)
    1.59 @@ -634,9 +650,9 @@ movr(struct regs *regs, unsigned prefix,
    1.60  		write8(addr, val);
    1.61  		TRACE((regs, regs->eip - eip, "movb $0x%x, *0x%x",
    1.62  							val, addr));
    1.63 -		break;
    1.64 +		return 1;
    1.65  	}
    1.66 -	return 1;
    1.67 +	return 0;
    1.68  }
    1.69  
    1.70  /*
    1.71 @@ -816,8 +832,8 @@ mov_to_seg(struct regs *regs, unsigned p
    1.72  	 * 1) real->protected mode.
    1.73  	 * 2) protected->real mode.
    1.74  	 */
    1.75 -	if ((mode != VM86_REAL_TO_PROTECTED) &&
    1.76 -	    (mode != VM86_PROTECTED_TO_REAL))
    1.77 +	if (mode != VM86_REAL_TO_PROTECTED &&
    1.78 +	    mode != VM86_PROTECTED_TO_REAL)
    1.79  		return 0;
    1.80  
    1.81  	/* Register source only. */
    1.82 @@ -1037,8 +1053,8 @@ set_mode(struct regs *regs, enum vm86_mo
    1.83  {
    1.84  	switch (newmode) {
    1.85  	case VM86_REAL:
    1.86 -		if ((mode == VM86_PROTECTED_TO_REAL) ||
    1.87 -		    (mode == VM86_REAL_TO_PROTECTED)) {
    1.88 +		if (mode == VM86_PROTECTED_TO_REAL ||
    1.89 +		    mode == VM86_REAL_TO_PROTECTED) {
    1.90  			regs->eflags &= ~EFLAGS_TF;
    1.91  			real_mode(regs);
    1.92  		} else if (mode != VM86_REAL)
    1.93 @@ -1121,7 +1137,7 @@ jmpl_indirect(struct regs *regs, int pre
    1.94  
    1.95  	if (mode == VM86_REAL_TO_PROTECTED)		/* jump to protected mode */
    1.96  		set_mode(regs, VM86_PROTECTED);
    1.97 -	else if (mode == VM86_PROTECTED_TO_REAL)/* jump to real mode */
    1.98 +	else if (mode == VM86_PROTECTED_TO_REAL)	/* jump to real mode */
    1.99  		set_mode(regs, VM86_REAL);
   1.100  	else
   1.101  		panic("jmpl");
   1.102 @@ -1147,7 +1163,7 @@ retl(struct regs *regs, int prefix)
   1.103  
   1.104  	if (mode == VM86_REAL_TO_PROTECTED)		/* jump to protected mode */
   1.105  		set_mode(regs, VM86_PROTECTED);
   1.106 -	else if (mode == VM86_PROTECTED_TO_REAL)/* jump to real mode */
   1.107 +	else if (mode == VM86_PROTECTED_TO_REAL)	/* jump to real mode */
   1.108  		set_mode(regs, VM86_REAL);
   1.109  	else
   1.110  		panic("retl");
   1.111 @@ -1382,9 +1398,7 @@ opcode(struct regs *regs)
   1.112  
   1.113  		case 0x39: /* addr32 cmp r16, r/m16 */
   1.114  		case 0x3B: /* addr32 cmp r/m16, r16 */
   1.115 -			if (mode != VM86_REAL && mode != VM86_REAL_TO_PROTECTED)
   1.116 -				goto invalid;
   1.117 -			if ((prefix & ADDR32) == 0)
   1.118 +			if (mode == VM86_PROTECTED_TO_REAL || !(prefix & ADDR32))
   1.119  				goto invalid;
   1.120  			if (!cmp(regs, prefix, opc))
   1.121  				goto invalid;
   1.122 @@ -1427,37 +1441,17 @@ opcode(struct regs *regs)
   1.123  			}
   1.124  			continue;
   1.125  
   1.126 -		case 0x88: /* mov r8, r/m8 */
   1.127 -		case 0x8A: /* mov r/m8, r8 */
   1.128 -			if (mode != VM86_REAL && mode != VM86_REAL_TO_PROTECTED)
   1.129 -				goto invalid;
   1.130 -			if ((prefix & ADDR32) == 0)
   1.131 +		case 0x88: /* addr32 mov r8, r/m8 */
   1.132 +		case 0x8A: /* addr32 mov r/m8, r8 */
   1.133 +			if (mode == VM86_PROTECTED_TO_REAL || !(prefix & ADDR32))
   1.134  				goto invalid;
   1.135  			if (!movr(regs, prefix, opc))
   1.136  				goto invalid;
   1.137  			return OPC_EMULATED;
   1.138  
   1.139 -		case 0x89: /* addr32 mov r16, r/m16 */
   1.140 -			if (mode == VM86_PROTECTED_TO_REAL) {
   1.141 -				unsigned modrm = fetch8(regs);
   1.142 -				unsigned addr = operand(prefix, regs, modrm);
   1.143 -				unsigned val, r = (modrm >> 3) & 7;
   1.144 -
   1.145 -				if (prefix & DATA32) {
   1.146 -					val = getreg16(regs, r);
   1.147 -					write32(addr, val);
   1.148 -				} else {
   1.149 -					val = getreg32(regs, r);
   1.150 -					write16(addr, MASK16(val));
   1.151 -				}
   1.152 -				TRACE((regs, regs->eip - eip,
   1.153 -					"mov %%%s, *0x%x", rnames[r], addr));
   1.154 -				return OPC_EMULATED;
   1.155 -			}
   1.156 -		case 0x8B: /* addr32 mov r/m16, r16 */
   1.157 -			if (mode != VM86_REAL && mode != VM86_REAL_TO_PROTECTED)
   1.158 -				goto invalid;
   1.159 -			if ((prefix & ADDR32) == 0)
   1.160 +		case 0x89: /* mov r16, r/m16 */
   1.161 +		case 0x8B: /* mov r/m16, r16 */
   1.162 +			if (mode != VM86_PROTECTED_TO_REAL && !(prefix & ADDR32))
   1.163  				goto invalid;
   1.164  			if (!movr(regs, prefix, opc))
   1.165  				goto invalid;
   1.166 @@ -1469,7 +1463,7 @@ opcode(struct regs *regs)
   1.167  			return OPC_EMULATED;
   1.168  
   1.169  		case 0x8F: /* addr32 pop r/m16 */
   1.170 -			if ((prefix & ADDR32) == 0)
   1.171 +			if (!(prefix & ADDR32))
   1.172  				goto invalid;
   1.173  			if (!pop(regs, prefix, opc))
   1.174  				goto invalid;
   1.175 @@ -1498,48 +1492,48 @@ opcode(struct regs *regs)
   1.176  			return OPC_EMULATED;
   1.177  
   1.178  		case 0xA1: /* mov ax, r/m16 */
   1.179 -			{
   1.180 -				int addr, data;
   1.181 -				int seg = segment(prefix, regs, regs->vds);
   1.182 -				int offset = prefix & ADDR32? fetch32(regs) : fetch16(regs);
   1.183 +		{
   1.184 +			int addr, data;
   1.185 +			int seg = segment(prefix, regs, regs->vds);
   1.186 +			int offset = prefix & ADDR32 ? fetch32(regs) : fetch16(regs);
   1.187  
   1.188 -				if (prefix & DATA32) {
   1.189 -					addr = address(regs, seg, offset);
   1.190 -					data = read32(addr);
   1.191 -					setreg32(regs, 0, data);
   1.192 -				} else {
   1.193 -					addr = address(regs, seg, offset);
   1.194 -					data = read16(addr);
   1.195 -					setreg16(regs, 0, data);
   1.196 -				}
   1.197 -				TRACE((regs, regs->eip - eip, "mov *0x%x, %%ax", addr));
   1.198 +			if (prefix & DATA32) {
   1.199 +				addr = address(regs, seg, offset);
   1.200 +				data = read32(addr);
   1.201 +				setreg32(regs, 0, data);
   1.202 +			} else {
   1.203 +				addr = address(regs, seg, offset);
   1.204 +				data = read16(addr);
   1.205 +				setreg16(regs, 0, data);
   1.206  			}
   1.207 +			TRACE((regs, regs->eip - eip, "mov *0x%x, %%ax", addr));
   1.208  			return OPC_EMULATED;
   1.209 +		}
   1.210  
   1.211  		case 0xBB: /* mov bx, imm16 */
   1.212 -			{
   1.213 -				int data;
   1.214 -				if (prefix & DATA32) {
   1.215 -					data = fetch32(regs);
   1.216 -					setreg32(regs, 3, data);
   1.217 -				} else {
   1.218 -					data = fetch16(regs);
   1.219 -					setreg16(regs, 3, data);
   1.220 -				}
   1.221 -				TRACE((regs, regs->eip - eip, "mov $0x%x, %%bx", data));
   1.222 +		{
   1.223 +			int data;
   1.224 +			if (prefix & DATA32) {
   1.225 +				data = fetch32(regs);
   1.226 +				setreg32(regs, 3, data);
   1.227 +			} else {
   1.228 +				data = fetch16(regs);
   1.229 +				setreg16(regs, 3, data);
   1.230  			}
   1.231 +			TRACE((regs, regs->eip - eip, "mov $0x%x, %%bx", data));
   1.232  			return OPC_EMULATED;
   1.233 +		}
   1.234  
   1.235  		case 0xC6: /* addr32 movb $imm, r/m8 */
   1.236 -			if ((prefix & ADDR32) == 0)
   1.237 +			if (!(prefix & ADDR32))
   1.238  				goto invalid;
   1.239  			if (!movr(regs, prefix, opc))
   1.240  				goto invalid;
   1.241  			return OPC_EMULATED;
   1.242  
   1.243  		case 0xCB: /* retl */
   1.244 -			if ((mode == VM86_REAL_TO_PROTECTED) ||
   1.245 -				(mode == VM86_PROTECTED_TO_REAL)) {
   1.246 +			if (mode == VM86_REAL_TO_PROTECTED ||
   1.247 +				mode == VM86_PROTECTED_TO_REAL) {
   1.248  				retl(regs, prefix);
   1.249  				return OPC_INVALID;
   1.250  			}
   1.251 @@ -1576,37 +1570,37 @@ opcode(struct regs *regs)
   1.252  			return OPC_EMULATED;
   1.253  
   1.254  		case 0xEA: /* jmpl */
   1.255 -			if ((mode == VM86_REAL_TO_PROTECTED) ||
   1.256 -				(mode == VM86_PROTECTED_TO_REAL)) {
   1.257 +			if (mode == VM86_REAL_TO_PROTECTED ||
   1.258 +				mode == VM86_PROTECTED_TO_REAL) {
   1.259  				jmpl(regs, prefix);
   1.260  				return OPC_INVALID;
   1.261  			}
   1.262  			goto invalid;
   1.263  
   1.264 -		case 0xFF: /* jmpl (indirect) */
   1.265 -			{
   1.266 -				unsigned modrm = fetch8(regs);
   1.267 -				switch((modrm >> 3) & 7) {
   1.268 -				case 5: /* jmpl (indirect) */
   1.269 -					if ((mode == VM86_REAL_TO_PROTECTED) ||
   1.270 -						(mode == VM86_PROTECTED_TO_REAL)) {
   1.271 -						jmpl_indirect(regs, prefix, modrm);
   1.272 -						return OPC_INVALID;
   1.273 -					}
   1.274 -					goto invalid;
   1.275 +		case 0xFF:
   1.276 +		{
   1.277 +			unsigned modrm = fetch8(regs);
   1.278 +			switch((modrm >> 3) & 7) {
   1.279 +			case 5: /* jmpl (indirect) */
   1.280 +				if (mode == VM86_REAL_TO_PROTECTED ||
   1.281 +					mode == VM86_PROTECTED_TO_REAL) {
   1.282 +					jmpl_indirect(regs, prefix, modrm);
   1.283 +					return OPC_INVALID;
   1.284 +				}
   1.285 +				goto invalid;
   1.286  
   1.287 -				case 6: /* push r/m16 */
   1.288 -					pushrm(regs, prefix, modrm);
   1.289 -					return OPC_EMULATED;
   1.290 +			case 6: /* push r/m16 */
   1.291 +				pushrm(regs, prefix, modrm);
   1.292 +				return OPC_EMULATED;
   1.293  
   1.294 -				default:
   1.295 -					goto invalid;
   1.296 -				}
   1.297 +			default:
   1.298 +				goto invalid;
   1.299  			}
   1.300 +		}
   1.301  
   1.302  		case 0xEB: /* short jump */
   1.303 -			if ((mode == VM86_REAL_TO_PROTECTED) ||
   1.304 -				(mode == VM86_PROTECTED_TO_REAL)) {
   1.305 +			if (mode == VM86_REAL_TO_PROTECTED ||
   1.306 +				mode == VM86_PROTECTED_TO_REAL) {
   1.307  				disp = (char) fetch8(regs);
   1.308  				TRACE((regs, 2, "jmp 0x%x", regs->eip + disp));
   1.309  				regs->eip += disp;
   1.310 @@ -1629,7 +1623,7 @@ opcode(struct regs *regs)
   1.311  			continue;
   1.312  
   1.313  		case 0xF6: /* addr32 testb $imm, r/m8 */
   1.314 -			if ((prefix & ADDR32) == 0)
   1.315 +			if (!(prefix & ADDR32))
   1.316  				goto invalid;
   1.317  			if (!test(regs, prefix, opc))
   1.318  				goto invalid;