- Timestamp:
- Apr 4, 2007 4:00:01 PM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/VMMAll/EMAll.cpp
r1929 r1939 54 54 DECLINLINE(int) emInterpretInstructionCPU(PVM pVM, PDISCPUSTATE pCpu, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, uint32_t *pcbSize); 55 55 56 /* Enable to allow segment prefix support */ 57 #define EM_ALLOW_SEG_PREFIX 56 58 57 59 /** … … 107 109 inline int emDisCoreOne(PVM pVM, DISCPUSTATE *pCpu, RTGCUINTPTR InstrGC, uint32_t *pOpsize) 108 110 { 109 return DISCoreOneEx(InstrGC, pCpu->mode, EMReadBytes, pVM, pCpu, pOpsize);111 return DISCoreOneEx(InstrGC, pCpu->mode, EMReadBytes, pVM, pCpu, pOpsize); 110 112 } 111 113 … … 282 284 283 285 284 inline int emRamRead(PVM pVM, void *pDest, RTGCPTR GCSrc, uint32_t cb)286 inline int emRamRead(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu, void *pDest, RTGCPTR GCSrc, uint32_t cb) 285 287 { 286 288 #ifdef IN_GC … … 300 302 } 301 303 302 inline int emRamWrite(PVM pVM, RTGCPTR GCDest, void *pSrc, uint32_t cb)304 inline int emRamWrite(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu, RTGCPTR GCDest, void *pSrc, uint32_t cb) 303 305 { 304 306 #ifdef IN_GC … … 317 319 } 318 320 321 /* Convert sel:addr to a flat GC address */ 322 static RTGCPTR emConvertToFlatAddr(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu, POP_PARAMETER pParam, RTGCPTR pvAddr) 323 { 324 #ifdef EM_ALLOW_SEG_PREFIX 325 int prefix_seg; 326 RTSEL sel = 0; 327 CPUMSELREGHID *pSelHidReg; 328 329 prefix_seg = DISDetectSegReg(pCpu, pParam); 330 DISFetchRegSegEx(pRegFrame, prefix_seg, &sel, &pSelHidReg); 331 return SELMToFlat(pVM, pRegFrame->eflags, sel, pSelHidReg, pvAddr); 332 #else 333 return pvAddr; 334 #endif 335 } 336 319 337 /** 320 338 * XCHG instruction emulation. … … 351 369 case PARMTYPE_ADDRESS: 352 370 pParam1 = (RTGCPTR)param1.val.val32; 371 pParam1 = emConvertToFlatAddr(pVM, pRegFrame, pCpu, &pCpu->param1, pParam1); 353 372 #ifdef IN_GC 354 373 /* Safety check (in theory it could cross a page boundary and fault there though) */ 355 AssertReturn(pParam1 == (RTGCPTR)pvFault, VERR_EM_INTERPRETER);356 #endif 357 rc = emRamRead(pVM, &valpar1, pParam1, param1.size);374 AssertReturn(pParam1 == pvFault, VERR_EM_INTERPRETER); 375 #endif 376 rc = emRamRead(pVM, pRegFrame, pCpu, &valpar1, pParam1, param1.size); 358 377 if (VBOX_FAILURE(rc)) 359 378 { … … 372 391 case PARMTYPE_ADDRESS: 373 392 pParam2 = (RTGCPTR)param2.val.val32; 393 pParam2 = emConvertToFlatAddr(pVM, pRegFrame, pCpu, &pCpu->param2, pParam2); 374 394 #ifdef IN_GC 375 395 /* Safety check (in theory it could cross a page boundary and fault there though) */ 376 AssertReturn(pParam2 == (RTGCPTR)pvFault, VERR_EM_INTERPRETER);377 #endif 378 rc = emRamRead(pVM, &valpar2, pParam2, param2.size);396 AssertReturn(pParam2 == pvFault, VERR_EM_INTERPRETER); 397 #endif 398 rc = emRamRead(pVM, pRegFrame, pCpu, &valpar2, pParam2, param2.size); 379 399 if (VBOX_FAILURE(rc)) 380 400 { … … 409 429 else 410 430 { 411 rc = emRamWrite(pVM, p Param1, &valpar2, param1.size);431 rc = emRamWrite(pVM, pRegFrame, pCpu, pParam1, &valpar2, param1.size); 412 432 if (VBOX_FAILURE(rc)) 413 433 { … … 434 454 else 435 455 { 436 rc = emRamWrite(pVM, p Param2, &valpar1, param2.size);456 rc = emRamWrite(pVM, pRegFrame, pCpu, pParam2, &valpar1, param2.size); 437 457 if (VBOX_FAILURE(rc)) 438 458 { … … 475 495 { 476 496 pParam1 = (RTGCPTR)param1.val.val32; 497 pParam1 = emConvertToFlatAddr(pVM, pRegFrame, pCpu, &pCpu->param1, pParam1); 477 498 #ifdef IN_GC 478 499 /* Safety check (in theory it could cross a page boundary and fault there though) */ 479 AssertReturn(pParam1 == (RTGCPTR)pvFault, VERR_EM_INTERPRETER);480 #endif 481 rc = emRamRead(pVM, &valpar1, pParam1, param1.size);500 AssertReturn(pParam1 == pvFault, VERR_EM_INTERPRETER); 501 #endif 502 rc = emRamRead(pVM, pRegFrame, pCpu, &valpar1, pParam1, param1.size); 482 503 if (VBOX_FAILURE(rc)) 483 504 { … … 500 521 501 522 /* Write result back */ 502 rc = emRamWrite(pVM, p Param1, &valpar1, param1.size);523 rc = emRamWrite(pVM, pRegFrame, pCpu, pParam1, &valpar1, param1.size); 503 524 if (VBOX_FAILURE(rc)) 504 525 { … … 550 571 return VERR_EM_INTERPRETER; 551 572 552 rc = emRamRead(pVM, &valpar1, pStackVal, param1.size);573 rc = emRamRead(pVM, pRegFrame, pCpu, &valpar1, pStackVal, param1.size); 553 574 if (VBOX_FAILURE(rc)) 554 575 { … … 568 589 ) 569 590 pParam1 = (RTGCPTR)((RTGCUINTPTR)pParam1 + param1.size); 591 592 pParam1 = emConvertToFlatAddr(pVM, pRegFrame, pCpu, &pCpu->param1, pParam1); 570 593 571 594 #ifdef IN_GC 572 595 /* Safety check (in theory it could cross a page boundary and fault there though) */ 573 AssertMsgReturn(pParam1 == (RTGCPTR)pvFault, ("%VGv != %VGv\n", pParam1, pvFault), VERR_EM_INTERPRETER);574 #endif 575 rc = emRamWrite(pVM, p Param1, &valpar1, param1.size);596 AssertMsgReturn(pParam1 == pvFault || (RTGCPTR)pRegFrame->esp == pvFault, ("%VGv != %VGv ss:esp=%04X:%VGv\n", pParam1, pvFault, pRegFrame->ss, pRegFrame->esp), VERR_EM_INTERPRETER); 597 #endif 598 rc = emRamWrite(pVM, pRegFrame, pCpu, pParam1, &valpar1, param1.size); 576 599 if (VBOX_FAILURE(rc)) 577 600 { … … 640 663 { 641 664 pParam1 = (RTGCPTR)param1.val.val32; 665 pParam1 = emConvertToFlatAddr(pVM, pRegFrame, pCpu, &pCpu->param1, pParam1); 642 666 643 667 #ifdef IN_GC 644 668 /* Safety check (in theory it could cross a page boundary and fault there though) */ 645 AssertReturn(pParam1 == (RTGCPTR)pvFault, VERR_EM_INTERPRETER);646 #endif 647 rc = emRamRead(pVM, &valpar1, pParam1, param1.size);669 AssertReturn(pParam1 == pvFault, VERR_EM_INTERPRETER); 670 #endif 671 rc = emRamRead(pVM, pRegFrame, pCpu, &valpar1, pParam1, param1.size); 648 672 if (VBOX_FAILURE(rc)) 649 673 { … … 678 702 679 703 /* And write it back */ 680 rc = emRamWrite(pVM, p Param1, &valpar1, param1.size);704 rc = emRamWrite(pVM, pRegFrame, pCpu, pParam1, &valpar1, param1.size); 681 705 if (VBOX_SUCCESS(rc)) 682 706 { … … 731 755 { 732 756 pParam1 = (RTGCPTR)param1.val.val32; 757 pParam1 = emConvertToFlatAddr(pVM, pRegFrame, pCpu, &pCpu->param1, pParam1); 733 758 734 759 #ifdef IN_GC 735 760 /* Safety check (in theory it could cross a page boundary and fault there though) */ 736 AssertReturn(pParam1 == (RTGCPTR)pvFault, VERR_EM_INTERPRETER);737 #endif 738 rc = emRamRead(pVM, &valpar1, pParam1, param1.size);761 AssertReturn(pParam1 == pvFault, VERR_EM_INTERPRETER); 762 #endif 763 rc = emRamRead(pVM, pRegFrame, pCpu, &valpar1, pParam1, param1.size); 739 764 if (VBOX_FAILURE(rc)) 740 765 { … … 769 794 770 795 /* And write it back */ 771 rc = emRamWrite(pVM, p Param1, &valpar1, param1.size);796 rc = emRamWrite(pVM, pRegFrame, pCpu, pParam1, &valpar1, param1.size); 772 797 if (VBOX_SUCCESS(rc)) 773 798 { … … 822 847 { 823 848 pParam1 = (RTGCPTR)param1.val.val32; 849 pParam1 = emConvertToFlatAddr(pVM, pRegFrame, pCpu, &pCpu->param1, pParam1); 824 850 825 851 #ifdef IN_GC … … 827 853 AssertMsgReturn(pParam1 == pvFault, ("pParam1 = %VGv pvFault = %VGv\n", pParam1, pvFault), VERR_EM_INTERPRETER); 828 854 #endif 829 rc = emRamRead(pVM, &valpar1, pParam1, param1.size);855 rc = emRamRead(pVM, pRegFrame, pCpu, &valpar1, pParam1, param1.size); 830 856 if (VBOX_FAILURE(rc)) 831 857 { … … 862 888 863 889 /* And write it back */ 864 rc = emRamWrite(pVM, p Param1, &valpar1, param1.size);890 rc = emRamWrite(pVM, pRegFrame, pCpu, pParam1, &valpar1, param1.size); 865 891 if (VBOX_SUCCESS(rc)) 866 892 { … … 915 941 { 916 942 pParam1 = (RTGCPTR)param1.val.val32; 943 pParam1 = emConvertToFlatAddr(pVM, pRegFrame, pCpu, &pCpu->param1, pParam1); 917 944 918 945 #ifdef IN_GC 919 946 /* Safety check (in theory it could cross a page boundary and fault there though) */ 920 AssertReturn(pParam1 == (RTGCPTR)pvFault, VERR_EM_INTERPRETER);921 #endif 922 rc = emRamRead(pVM, &valpar1, pParam1, param1.size);947 AssertReturn(pParam1 == pvFault, VERR_EM_INTERPRETER); 948 #endif 949 rc = emRamRead(pVM, pRegFrame, pCpu, &valpar1, pParam1, param1.size); 923 950 if (VBOX_FAILURE(rc)) 924 951 { … … 955 982 956 983 /* And write it back */ 957 rc = emRamWrite(pVM, p Param1, &valpar1, param1.size);984 rc = emRamWrite(pVM, pRegFrame, pCpu, pParam1, &valpar1, param1.size); 958 985 if (VBOX_SUCCESS(rc)) 959 986 { … … 1009 1036 { 1010 1037 pParam1 = (RTGCPTR)param1.val.val32; 1038 pParam1 = emConvertToFlatAddr(pVM, pRegFrame, pCpu, &pCpu->param1, pParam1); 1011 1039 1012 1040 #ifdef IN_GC 1013 1041 /* Safety check (in theory it could cross a page boundary and fault there though) */ 1014 AssertReturn(pParam1 == (RTGCPTR)pvFault, VERR_EM_INTERPRETER);1015 #endif 1016 rc = emRamRead(pVM, &valpar1, pParam1, param1.size);1042 AssertReturn(pParam1 == pvFault, VERR_EM_INTERPRETER); 1043 #endif 1044 rc = emRamRead(pVM, pRegFrame, pCpu, &valpar1, pParam1, param1.size); 1017 1045 if (VBOX_FAILURE(rc)) 1018 1046 { … … 1054 1082 1055 1083 /* And write it back */ 1056 rc = emRamWrite(pVM, p Param1, &valpar1, param1.size);1084 rc = emRamWrite(pVM, pRegFrame, pCpu, pParam1, &valpar1, param1.size); 1057 1085 if (VBOX_SUCCESS(rc)) 1058 1086 { … … 1107 1135 { 1108 1136 pParam1 = (RTGCPTR)param1.val.val32; 1137 pParam1 = emConvertToFlatAddr(pVM, pRegFrame, pCpu, &pCpu->param1, pParam1); 1109 1138 1110 1139 #ifdef IN_GC 1111 1140 /* Safety check (in theory it could cross a page boundary and fault there though) */ 1112 AssertReturn(pParam1 == (RTGCPTR)pvFault, VERR_EM_INTERPRETER);1113 #endif 1114 rc = emRamRead(pVM, &valpar1, pParam1, param1.size);1141 AssertReturn(pParam1 == pvFault, VERR_EM_INTERPRETER); 1142 #endif 1143 rc = emRamRead(pVM, pRegFrame, pCpu, &valpar1, pParam1, param1.size); 1115 1144 if (VBOX_FAILURE(rc)) 1116 1145 { … … 1147 1176 1148 1177 /* And write it back */ 1149 rc = emRamWrite(pVM, p Param1, &valpar1, param1.size);1178 rc = emRamWrite(pVM, pRegFrame, pCpu, pParam1, &valpar1, param1.size); 1150 1179 if (VBOX_SUCCESS(rc)) 1151 1180 { … … 1197 1226 case PARMTYPE_ADDRESS: 1198 1227 pDest = (RTGCPTR)param1.val.val32; 1228 pDest = emConvertToFlatAddr(pVM, pRegFrame, pCpu, &pCpu->param1, pDest); 1199 1229 break; 1200 1230 … … 1218 1248 Assert(param2.size <= 4 && param2.size > 0); 1219 1249 1220 rc = emRamWrite(pVM, pDest, &val32, param2.size); 1250 #ifdef IN_GC 1251 /* Safety check (in theory it could cross a page boundary and fault there though) */ 1252 AssertReturn(pDest == pvFault, VERR_EM_INTERPRETER); 1253 #endif 1254 rc = emRamWrite(pVM, pRegFrame, pCpu, pDest, &val32, param2.size); 1221 1255 if (VBOX_FAILURE(rc)) 1222 1256 return VERR_EM_INTERPRETER; … … 1239 1273 case PARMTYPE_ADDRESS: 1240 1274 pSrc = (RTGCPTR)param2.val.val32; 1275 pSrc = emConvertToFlatAddr(pVM, pRegFrame, pCpu, &pCpu->param2, pSrc); 1241 1276 break; 1242 1277 … … 1246 1281 1247 1282 Assert(param1.size <= 4 && param1.size > 0); 1248 rc = emRamRead(pVM, &val32, pSrc, param1.size); 1283 #ifdef IN_GC 1284 /* Safety check (in theory it could cross a page boundary and fault there though) */ 1285 AssertReturn(pSrc == pvFault, VERR_EM_INTERPRETER); 1286 #endif 1287 rc = emRamRead(pVM, pRegFrame, pCpu, &val32, pSrc, param1.size); 1249 1288 if (VBOX_FAILURE(rc)) 1250 1289 return VERR_EM_INTERPRETER; … … 1293 1332 int rc; 1294 1333 1295 rc = emRamRead(pVM, &eip, (RTGCPTR)pIretStack, 4);1296 rc |= emRamRead(pVM, &cs, (RTGCPTR)(pIretStack + 4), 4);1297 rc |= emRamRead(pVM, &eflags, (RTGCPTR)(pIretStack + 8), 4);1334 rc = emRamRead(pVM, NULL, NULL, &eip, (RTGCPTR)pIretStack , 4); 1335 rc |= emRamRead(pVM, NULL, NULL, &cs, (RTGCPTR)(pIretStack + 4), 4); 1336 rc |= emRamRead(pVM, NULL, NULL, &eflags, (RTGCPTR)(pIretStack + 8), 4); 1298 1337 AssertRCReturn(rc, VERR_EM_INTERPRETER); 1299 1338 AssertReturn(eflags & X86_EFL_VM, VERR_EM_INTERPRETER); 1300 1339 1301 rc |= emRamRead(pVM, &esp, (RTGCPTR)(pIretStack + 12), 4);1302 rc |= emRamRead(pVM, &ss, (RTGCPTR)(pIretStack + 16), 4);1303 rc |= emRamRead(pVM, &es, (RTGCPTR)(pIretStack + 20), 4);1304 rc |= emRamRead(pVM, &ds, (RTGCPTR)(pIretStack + 24), 4);1305 rc |= emRamRead(pVM, &fs, (RTGCPTR)(pIretStack + 28), 4);1306 rc |= emRamRead(pVM, &gs, (RTGCPTR)(pIretStack + 32), 4);1340 rc |= emRamRead(pVM, NULL, NULL, &esp, (RTGCPTR)(pIretStack + 12), 4); 1341 rc |= emRamRead(pVM, NULL, NULL, &ss, (RTGCPTR)(pIretStack + 16), 4); 1342 rc |= emRamRead(pVM, NULL, NULL, &es, (RTGCPTR)(pIretStack + 20), 4); 1343 rc |= emRamRead(pVM, NULL, NULL, &ds, (RTGCPTR)(pIretStack + 24), 4); 1344 rc |= emRamRead(pVM, NULL, NULL, &fs, (RTGCPTR)(pIretStack + 28), 4); 1345 rc |= emRamRead(pVM, NULL, NULL, &gs, (RTGCPTR)(pIretStack + 32), 4); 1307 1346 AssertRCReturn(rc, VERR_EM_INTERPRETER); 1308 1347 … … 1853 1892 } 1854 1893 1894 #ifdef EM_ALLOW_SEG_PREFIX 1895 if (pCpu->prefix & (PREFIX_REPNE | PREFIX_REP | PREFIX_LOCK)) 1896 #else 1855 1897 /* Out emulation above can't cope with 16 bits code yet. */ 1856 1898 if (!SELMIsSelector32Bit(pVM, pRegFrame->eflags, pRegFrame->cs, &pRegFrame->csHid)) 1857 1899 return VERR_EM_INTERPRETER; 1858 1900 1859 /** @note we could ignore PREFIX_LOCK here. Need to take special precautions when/if we support SMP in the guest.1860 */1861 1901 if (pCpu->prefix & (PREFIX_REPNE | PREFIX_REP | PREFIX_SEG | PREFIX_LOCK)) 1902 #endif 1862 1903 { 1863 1904 //Log(("EMInterpretInstruction: wrong prefix!!\n"));
Note:
See TracChangeset
for help on using the changeset viewer.