Changeset 2228 in vbox for trunk/src/VBox/VMM
- Timestamp:
- Apr 19, 2007 1:52:53 PM (18 years ago)
- svn:sync-xref-src-repo-rev:
- 20578
- Location:
- trunk/src/VBox/VMM
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/VMM/DBGF.cpp
r23 r2228 235 235 RTStrmPrintf(g_pStdErr, "DBGF: No debugger attached, waiting 15 seconds for one to attach (event=%d)\n", enmEvent); 236 236 RTStrmFlush(g_pStdErr); 237 #if def DEBUG_sandervl237 #if 1 //def DEBUG_sandervl 238 238 int cWait = 10; 239 239 #else -
trunk/src/VBox/VMM/EM.cpp
r2226 r2228 988 988 return rc; 989 989 } 990 991 990 /* 992 991 * Set flags for single stepping. … … 1020 1019 } 1021 1020 1022 #if def DEBUG_sandervl1021 #if 1 //def DEBUG_sandervl 1023 1022 void emR3SingleStepExecRaw(PVM pVM, uint32_t cIterations) 1024 1023 { … … 1271 1270 if (VBOX_SUCCESS(rc)) 1272 1271 { 1272 #ifdef VBOX_WITH_STATISTICS 1273 switch (Cpu.pCurInstr->opcode) 1274 { 1275 case OP_INSB: 1276 case OP_INSWD: 1277 case OP_IN: 1278 STAM_COUNTER_INC(&pVM->em.s.CTXSUFF(pStats)->StatIn); 1279 break; 1280 1281 case OP_OUTSB: 1282 case OP_OUTSWD: 1283 case OP_OUT: 1284 STAM_COUNTER_INC(&pVM->em.s.CTXSUFF(pStats)->StatOut); 1285 break; 1286 } 1287 #endif 1288 1273 1289 if (!(Cpu.prefix & (PREFIX_REP | PREFIX_REPNE))) 1274 1290 { 1291 OP_PARAMVAL ParmVal; 1292 int rc; 1275 1293 switch (Cpu.pCurInstr->opcode) 1276 1294 { 1277 1295 case OP_IN: 1278 1296 { 1279 STAM_COUNTER_INC(&pVM->em.s.CTXSUFF(pStats)->StatIn); 1280 1281 rc = IOMInterpretIN(pVM, CPUMCTX2CORE(pCtx), &Cpu); 1282 if (rc == VINF_SUCCESS) 1297 rc = DISQueryParamVal(CPUMCTX2CORE(pCtx), &Cpu, &Cpu.param2, &ParmVal, PARAM_SOURCE); 1298 if ( VBOX_FAILURE(rc) 1299 || ParmVal.type != PARMTYPE_IMMEDIATE) 1300 break; 1301 1302 if (!(Cpu.param1.flags & (USE_REG_GEN8 | USE_REG_GEN16 | USE_REG_GEN32))) 1303 break; 1304 1305 /* Make sure port access is allowed */ 1306 rc = IOMInterpretCheckPortIOAccess(pVM, CPUMCTX2CORE(pCtx), ParmVal.val.val16, Cpu.param1.size); 1307 if (rc != VINF_SUCCESS) 1283 1308 { 1284 pCtx->eip += Cpu.opsize; 1285 STAM_PROFILE_STOP(&pVM->em.s.StatIOEmu, a); 1286 return VINF_SUCCESS; 1287 } 1288 else 1289 if (rc == VINF_EM_RAW_GUEST_TRAP) 1290 { 1291 STAM_PROFILE_STOP(&pVM->em.s.StatIOEmu, a); 1292 rc = emR3RawGuestTrap(pVM); 1309 if (rc == VINF_EM_RAW_GUEST_TRAP) 1310 rc = emR3RawGuestTrap(pVM); 1311 1293 1312 return rc; 1294 1313 } 1295 /* emulate in the recompiler */ 1314 1315 uint32_t u32Value = 0; 1316 switch (Cpu.param1.size) 1317 { 1318 case 1: 1319 Assert(Cpu.param1.base.reg_gen8 == USE_REG_AL); 1320 rc = IOMIOPortRead(pVM, ParmVal.val.val16, &u32Value, sizeof(uint8_t)); 1321 if (VBOX_SUCCESS(rc)) 1322 { 1323 pCtx->eax = (pCtx->eax & ~0xFF) | (uint8_t)u32Value; 1324 Log(("EMU: in8 %x, %x\n", ParmVal.val.val16, pCtx->eax & 0xFF)); 1325 pCtx->eip += Cpu.opsize; 1326 STAM_PROFILE_STOP(&pVM->em.s.StatIOEmu, a); 1327 return rc; 1328 } 1329 AssertRC(rc); 1330 break; 1331 1332 case 2: 1333 Assert(Cpu.param1.base.reg_gen16 == USE_REG_AX); 1334 rc = IOMIOPortRead(pVM, ParmVal.val.val16, &u32Value, sizeof(uint16_t)); 1335 if (VBOX_SUCCESS(rc)) 1336 { 1337 pCtx->eax = (pCtx->eax & ~0xFFFF) | (uint16_t)u32Value; 1338 Log(("EMU: in16 %x, %x\n", ParmVal.val.val16, pCtx->eax & 0xFFFF)); 1339 pCtx->eip += Cpu.opsize; 1340 STAM_PROFILE_STOP(&pVM->em.s.StatIOEmu, a); 1341 return rc; 1342 } 1343 AssertRC(rc); 1344 break; 1345 1346 case 4: 1347 Assert(Cpu.param1.base.reg_gen32 == USE_REG_EAX); 1348 rc = IOMIOPortRead(pVM, ParmVal.val.val16, &u32Value, sizeof(uint32_t)); 1349 if (VBOX_SUCCESS(rc)) 1350 { 1351 pCtx->eax = u32Value; 1352 Log(("EMU: in32 %x, %x\n", ParmVal.val.val16, pCtx->eax)); 1353 pCtx->eip += Cpu.opsize; 1354 STAM_PROFILE_STOP(&pVM->em.s.StatIOEmu, a); 1355 return rc; 1356 } 1357 AssertRC(rc); 1358 break; 1359 1360 default: 1361 AssertMsgFailed(("Unexpected port size %d\n", ParmVal.size)); 1362 break; 1363 } 1296 1364 break; 1297 1365 } … … 1299 1367 case OP_OUT: 1300 1368 { 1301 STAM_COUNTER_INC(&pVM->em.s.CTXSUFF(pStats)->StatOut); 1302 1303 rc = IOMInterpretOUT(pVM, CPUMCTX2CORE(pCtx), &Cpu); 1304 if (rc == VINF_SUCCESS) 1369 // it really is the destination, but we're interested in the destination value. hence we specify PARAM_SOURCE (bit of a hack) 1370 rc = DISQueryParamVal(CPUMCTX2CORE(pCtx), &Cpu, &Cpu.param1, &ParmVal, PARAM_SOURCE); 1371 if ( VBOX_FAILURE(rc) 1372 || ParmVal.type != PARMTYPE_IMMEDIATE) 1373 break; 1374 OP_PARAMVAL ParmVal2; 1375 rc = DISQueryParamVal(CPUMCTX2CORE(pCtx), &Cpu, &Cpu.param2, &ParmVal2, PARAM_SOURCE); 1376 if ( VBOX_FAILURE(rc) 1377 || ParmVal2.type != PARMTYPE_IMMEDIATE) 1378 break; 1379 1380 /* Make sure port access is allowed */ 1381 rc = IOMInterpretCheckPortIOAccess(pVM, CPUMCTX2CORE(pCtx), ParmVal.val.val16, Cpu.param1.size); 1382 if (rc != VINF_SUCCESS) 1305 1383 { 1306 pCtx->eip += Cpu.opsize; 1307 STAM_PROFILE_STOP(&pVM->em.s.StatIOEmu, a); 1308 return VINF_SUCCESS; 1309 } 1310 else 1311 if (rc == VINF_EM_RAW_GUEST_TRAP) 1312 { 1313 STAM_PROFILE_STOP(&pVM->em.s.StatIOEmu, a); 1314 rc = emR3RawGuestTrap(pVM); 1384 if (rc == VINF_EM_RAW_GUEST_TRAP) 1385 rc = emR3RawGuestTrap(pVM); 1386 1315 1387 return rc; 1316 1388 } 1317 /* emulate in the recompiler */ 1389 1390 AssertMsg(Cpu.param2.size == ParmVal2.size, ("size %d vs %d\n", Cpu.param2.size, ParmVal2.size)); 1391 switch (ParmVal2.size) 1392 { 1393 case 1: 1394 Log(("EMU: out8 %x, %x\n", ParmVal.val.val16, ParmVal2.val.val8)); 1395 rc = IOMIOPortWrite(pVM, ParmVal.val.val16, ParmVal2.val.val8, sizeof(ParmVal2.val.val8)); 1396 if (VBOX_SUCCESS(rc)) 1397 { 1398 pCtx->eip += Cpu.opsize; 1399 STAM_PROFILE_STOP(&pVM->em.s.StatIOEmu, a); 1400 return rc; 1401 } 1402 AssertRC(rc); 1403 break; 1404 1405 case 2: 1406 Log(("EMU: out16 %x, %x\n", ParmVal.val.val16, ParmVal2.val.val16)); 1407 rc = IOMIOPortWrite(pVM, ParmVal.val.val16, ParmVal2.val.val16, sizeof(ParmVal2.val.val16)); 1408 if (VBOX_SUCCESS(rc)) 1409 { 1410 pCtx->eip += Cpu.opsize; 1411 STAM_PROFILE_STOP(&pVM->em.s.StatIOEmu, a); 1412 return rc; 1413 } 1414 AssertRC(rc); 1415 break; 1416 1417 case 4: 1418 Log(("EMU: out32 %x, %x\n", ParmVal.val.val16, ParmVal2.val.val32)); 1419 rc = IOMIOPortWrite(pVM, ParmVal.val.val16, ParmVal2.val.val32, sizeof(ParmVal2.val.val32)); 1420 if (VBOX_SUCCESS(rc)) 1421 { 1422 pCtx->eip += Cpu.opsize; 1423 STAM_PROFILE_STOP(&pVM->em.s.StatIOEmu, a); 1424 return rc; 1425 } 1426 AssertRC(rc); 1427 break; 1428 1429 default: 1430 AssertMsgFailed(("Unexpected port size %d\n", ParmVal2.size)); 1431 break; 1432 } 1318 1433 break; 1319 1434 } … … 1330 1445 case OP_INSWD: 1331 1446 { 1332 STAM_COUNTER_INC(&pVM->em.s.CTXSUFF(pStats)->StatIn); 1333 rc = IOMInterpretINS(pVM, CPUMCTX2CORE(pCtx), &Cpu); 1334 if (rc == VINF_SUCCESS) 1447 /* 1448 * Do not optimize the destination address decrement case (not worth the effort) 1449 * and likewise for 16 bit address size (would need to use and update only cx/di). 1450 */ 1451 if (pCtx->eflags.Bits.u1DF || Cpu.addrmode != CPUMODE_32BIT) 1452 break; 1453 /* 1454 * Get port number and transfer count directly from the registers (no need to bother the 1455 * disassembler). And get the I/O register size from the opcode / prefix. 1456 */ 1457 uint32_t uPort = pCtx->edx & 0xffff; 1458 RTGCUINTREG cTransfers = pCtx->ecx; 1459 unsigned cbUnit; 1460 if (Cpu.pCurInstr->opcode == OP_INSB) 1461 cbUnit = 1; 1462 else 1463 cbUnit = Cpu.opmode == CPUMODE_32BIT ? 4 : 2; 1464 1465 RTGCPTR GCPtrDst = pCtx->edi; 1466 uint32_t cpl = (pCtx->eflags.Bits.u1VM) ? 3 : (pCtx->ss & X86_SEL_RPL); 1467 1468 /* Access verification first; we can't recover from traps inside this instruction, as the port read cannot be repeated. */ 1469 rc = PGMVerifyAccess(pVM, GCPtrDst, cTransfers * cbUnit, 1470 X86_PTE_RW | ((cpl == 3) ? X86_PTE_US : 0)); 1471 if (rc != VINF_SUCCESS) 1335 1472 { 1336 STAM_PROFILE_STOP(&pVM->em.s.StatIOEmu, a); 1337 pCtx->eip += Cpu.opsize; 1473 Log(("EMU: rep ins%d will generate a trap -> fallback, rc=%d\n", cbUnit * 8, rc)); 1474 break; 1475 } 1476 1477 Log(("EMU: rep ins%d port %#x count %d\n", cbUnit * 8, uPort, cTransfers)); 1478 1479 /* Make sure port access is allowed */ 1480 rc = IOMInterpretCheckPortIOAccess(pVM, CPUMCTX2CORE(pCtx), uPort, cbUnit); 1481 if (rc != VINF_SUCCESS) 1482 { 1483 if (rc == VINF_EM_RAW_GUEST_TRAP) 1484 rc = emR3RawGuestTrap(pVM); 1485 1338 1486 return rc; 1339 1487 } 1340 else 1341 if (rc == VINF_EM_RAW_GUEST_TRAP) 1488 1489 /* 1490 * If the device supports string transfers, ask it to do as 1491 * much as it wants. The rest is done with single-word transfers. 1492 */ 1493 rc = IOMIOPortReadString(pVM, uPort, &GCPtrDst, &cTransfers, cbUnit); 1494 AssertRC(rc); Assert(cTransfers <= pCtx->ecx); 1495 1496 while (cTransfers && rc == VINF_SUCCESS) 1342 1497 { 1343 STAM_PROFILE_STOP(&pVM->em.s.StatIOEmu, a); 1344 rc = emR3RawGuestTrap(pVM); 1345 return rc; 1498 uint32_t u32Value; 1499 rc = IOMIOPortRead(pVM, uPort, &u32Value, cbUnit); 1500 AssertRC(rc); 1501 int rc2 = PGMPhysWriteGCPtrDirty(pVM, GCPtrDst, &u32Value, cbUnit); 1502 AssertRC(rc2); 1503 GCPtrDst += cbUnit; 1504 cTransfers--; 1346 1505 } 1347 /* emulate in the recompiler */ 1348 break; 1506 pCtx->edi += (pCtx->ecx - cTransfers) * cbUnit; 1507 pCtx->ecx = cTransfers; 1508 if (!cTransfers && VBOX_SUCCESS(rc)) 1509 pCtx->eip += Cpu.opsize; 1510 STAM_PROFILE_STOP(&pVM->em.s.StatIOEmu, a); 1511 return rc; 1349 1512 } 1350 1513 case OP_OUTSB: 1351 1514 case OP_OUTSWD: 1352 1515 { 1353 STAM_COUNTER_INC(&pVM->em.s.CTXSUFF(pStats)->StatOut); 1354 rc = IOMInterpretOUTS(pVM, CPUMCTX2CORE(pCtx), &Cpu); 1355 if (rc == VINF_SUCCESS) 1516 /* 1517 * Do not optimize the source address decrement case (not worth the effort) 1518 * and likewise for 16 bit address size (would need to use and update only cx/si). 1519 */ 1520 if (pCtx->eflags.Bits.u1DF || Cpu.addrmode != CPUMODE_32BIT) 1521 break; 1522 /* 1523 * Get port number and transfer count directly from the registers (no need to bother the 1524 * disassembler). And get the I/O register size from the opcode / prefix. 1525 */ 1526 uint32_t uPort = pCtx->edx & 0xffff; 1527 RTGCUINTREG cTransfers = pCtx->ecx; 1528 unsigned cbUnit; 1529 if (Cpu.pCurInstr->opcode == OP_OUTSB) 1530 cbUnit = 1; 1531 else 1532 cbUnit = Cpu.opmode == CPUMODE_32BIT ? 4 : 2; 1533 1534 RTGCPTR GCPtrSrc = pCtx->esi; 1535 uint32_t cpl = (pCtx->eflags.Bits.u1VM) ? 3 : (pCtx->ss & X86_SEL_RPL); 1536 1537 /* Access verification first; we currently can't recover properly from traps inside this instruction */ 1538 rc = PGMVerifyAccess(pVM, GCPtrSrc, cTransfers * cbUnit, ((cpl == 3) ? X86_PTE_US : 0)); 1539 if (rc != VINF_SUCCESS) 1356 1540 { 1357 STAM_PROFILE_STOP(&pVM->em.s.StatIOEmu, a); 1358 pCtx->eip += Cpu.opsize; 1541 Log(("EMU: rep outs%d will generate a trap -> fallback, rc=%d\n", cbUnit * 8, rc)); 1542 break; 1543 } 1544 1545 Log(("EMU: rep outs%d port %#x count %d\n", cbUnit * 8, uPort, cTransfers)); 1546 1547 /* Make sure port access is allowed */ 1548 rc = IOMInterpretCheckPortIOAccess(pVM, CPUMCTX2CORE(pCtx), uPort, cbUnit); 1549 if (rc != VINF_SUCCESS) 1550 { 1551 if (rc == VINF_EM_RAW_GUEST_TRAP) 1552 rc = emR3RawGuestTrap(pVM); 1553 1359 1554 return rc; 1360 1555 } 1361 else 1362 if (rc == VINF_EM_RAW_GUEST_TRAP) 1556 1557 /* 1558 * If the device supports string transfers, ask it to do as 1559 * much as it wants. The rest is done with single-word transfers. 1560 */ 1561 rc = IOMIOPortWriteString(pVM, uPort, &GCPtrSrc, &cTransfers, cbUnit); 1562 AssertRC(rc); Assert(cTransfers <= pCtx->ecx); 1563 1564 while (cTransfers && rc == VINF_SUCCESS) 1363 1565 { 1364 STAM_PROFILE_STOP(&pVM->em.s.StatIOEmu, a); 1365 rc = emR3RawGuestTrap(pVM); 1366 return rc; 1566 uint32_t u32Value; 1567 rc = PGMPhysReadGCPtr(pVM, &u32Value, GCPtrSrc, cbUnit); 1568 Assert(rc == VINF_SUCCESS); 1569 rc = IOMIOPortWrite(pVM, uPort, u32Value, cbUnit); 1570 AssertRC(rc); 1571 GCPtrSrc += cbUnit; 1572 cTransfers--; 1367 1573 } 1368 /* emulate in the recompiler */ 1369 break; 1574 pCtx->esi += (pCtx->ecx - cTransfers) * cbUnit; 1575 pCtx->ecx = cTransfers; 1576 if (!cTransfers && VBOX_SUCCESS(rc)) 1577 pCtx->eip += Cpu.opsize; 1578 STAM_PROFILE_STOP(&pVM->em.s.StatIOEmu, a); 1579 return rc; 1370 1580 } 1371 1581 } … … 2689 2899 #endif 2690 2900 2901 // DBGFR3InfoLog(pVM, "cpumguest", "PRE"); 2902 // DBGFR3DisasInstrCurrentLog(pVM, "PRE"); 2691 2903 2692 2904 /* … … 2699 2911 VMMR3Lock(pVM); 2700 2912 STAM_PROFILE_STOP(&pVM->em.s.StatHwAccExec, x); 2913 2914 // DBGFR3InfoLog(pVM, "cpumguest", "POST"); 2915 // DBGFR3DisasInstrCurrentLog(pVM, "POST"); 2701 2916 2702 2917 /* -
trunk/src/VBox/VMM/HWACCM.cpp
r2213 r2228 457 457 Assert(pVM->fHWACCMEnabled); 458 458 459 #if 0459 #if 1 460 460 /* AMD SVM supports real & protected mode with or without paging. */ 461 461 if (pVM->hwaccm.s.svm.fEnabled) -
trunk/src/VBox/VMM/VMM.cpp
r2124 r2228 433 433 * to not stub all the log functions. 434 434 */ 435 # if def DEBUG_sandervl435 # if 1 //def DEBUG_sandervl 436 436 rc = MMHyperAlloc(pVM, RT_OFFSETOF(VMMR0LOGGER, Logger.afGroups[pLogger->cGroups]), 437 437 0, MM_TAG_VMM, (void **)&pVM->vmm.s.pR0Logger); -
trunk/src/VBox/VMM/VMMAll/IOMAll.cpp
r2226 r2228 37 37 #include <iprt/assert.h> 38 38 39 40 /*******************************************************************************41 * Global Variables *42 *******************************************************************************/43 44 /**45 * Array for fast recode of the operand size (1/2/4/8 bytes) to bit shift value.46 */47 static const unsigned g_aSize2Shift[] =48 {49 ~0, /* 0 - invalid */50 0, /* *1 == 2^0 */51 1, /* *2 == 2^1 */52 ~0, /* 3 - invalid */53 2, /* *4 == 2^2 */54 ~0, /* 5 - invalid */55 ~0, /* 6 - invalid */56 ~0, /* 7 - invalid */57 3 /* *8 == 2^3 */58 };59 60 /**61 * Macro for fast recode of the operand size (1/2/4/8 bytes) to bit shift value.62 */63 #define SIZE2SHIFT(cb) (g_aSize2Shift[cb])64 65 /**66 * Calculates the size of register parameter.67 *68 * @returns 1, 2, 4 on success.69 * @returns 0 if non-register parameter.70 * @param pCpu Pointer to current disassembler context.71 * @param pParam Pointer to parameter of instruction to proccess.72 */73 static unsigned iomGCGetRegSize(PDISCPUSTATE pCpu, PCOP_PARAMETER pParam)74 {75 if (pParam->flags & (USE_BASE | USE_INDEX | USE_SCALE | USE_DISPLACEMENT8 | USE_DISPLACEMENT16 | USE_DISPLACEMENT32 | USE_IMMEDIATE8 | USE_IMMEDIATE16 | USE_IMMEDIATE32 | USE_IMMEDIATE16_SX8 | USE_IMMEDIATE32_SX8))76 return 0;77 78 if (pParam->flags & USE_REG_GEN32)79 return 4;80 81 if (pParam->flags & USE_REG_GEN16)82 return 2;83 84 if (pParam->flags & USE_REG_GEN8)85 return 1;86 87 if (pParam->flags & USE_REG_SEG)88 return 2;89 return 0;90 }91 92 /**93 * Returns the contents of register or immediate data of instruction's parameter.94 *95 * @returns true on success.96 *97 * @param pCpu Pointer to current disassembler context.98 * @param pParam Pointer to parameter of instruction to proccess.99 * @param pRegFrame Pointer to CPUMCTXCORE guest structure.100 * @param pu32Data Where to store retrieved data.101 * @param pcbSize Where to store the size of data (1, 2, 4).102 */103 static bool iomGCGetRegImmData(PDISCPUSTATE pCpu, PCOP_PARAMETER pParam, PCPUMCTXCORE pRegFrame, uint32_t *pu32Data, unsigned *pcbSize)104 {105 if (pParam->flags & (USE_BASE | USE_INDEX | USE_SCALE | USE_DISPLACEMENT8 | USE_DISPLACEMENT16 | USE_DISPLACEMENT32))106 {107 *pcbSize = 0;108 *pu32Data = 0;109 return false;110 }111 112 if (pParam->flags & USE_REG_GEN32)113 {114 *pcbSize = 4;115 DISFetchReg32(pRegFrame, pParam->base.reg_gen32, pu32Data);116 return true;117 }118 119 if (pParam->flags & USE_REG_GEN16)120 {121 *pcbSize = 2;122 DISFetchReg16(pRegFrame, pParam->base.reg_gen16, (uint16_t *)pu32Data);123 return true;124 }125 126 if (pParam->flags & USE_REG_GEN8)127 {128 *pcbSize = 1;129 DISFetchReg8(pRegFrame, pParam->base.reg_gen8, (uint8_t *)pu32Data);130 return true;131 }132 133 if (pParam->flags & (USE_IMMEDIATE32|USE_IMMEDIATE32_SX8))134 {135 *pcbSize = 4;136 *pu32Data = (uint32_t)pParam->parval;137 return true;138 }139 140 if (pParam->flags & (USE_IMMEDIATE16|USE_IMMEDIATE16_SX8))141 {142 *pcbSize = 2;143 *pu32Data = (uint16_t)pParam->parval;144 return true;145 }146 147 if (pParam->flags & USE_IMMEDIATE8)148 {149 *pcbSize = 1;150 *pu32Data = (uint8_t)pParam->parval;151 return true;152 }153 154 if (pParam->flags & USE_REG_SEG)155 {156 *pcbSize = 2;157 DISFetchRegSeg(pRegFrame, pParam->base.reg_seg, (RTSEL *)pu32Data);158 return true;159 } /* Else - error. */160 161 *pcbSize = 0;162 *pu32Data = 0;163 return false;164 }165 166 167 /**168 * Saves data to 8/16/32 general purpose or segment register defined by169 * instruction's parameter.170 *171 * @returns true on success.172 * @param pCpu Pointer to current disassembler context.173 * @param pParam Pointer to parameter of instruction to proccess.174 * @param pRegFrame Pointer to CPUMCTXCORE guest structure.175 * @param u32Data 8/16/32 bit data to store.176 */177 static bool iomGCSaveDataToReg(PDISCPUSTATE pCpu, PCOP_PARAMETER pParam, PCPUMCTXCORE pRegFrame, unsigned u32Data)178 {179 if (pParam->flags & (USE_BASE | USE_INDEX | USE_SCALE | USE_DISPLACEMENT8 | USE_DISPLACEMENT16 | USE_DISPLACEMENT32 | USE_IMMEDIATE8 | USE_IMMEDIATE16 | USE_IMMEDIATE32 | USE_IMMEDIATE32_SX8 | USE_IMMEDIATE16_SX8))180 {181 return false;182 }183 184 if (pParam->flags & USE_REG_GEN32)185 {186 DISWriteReg32(pRegFrame, pParam->base.reg_gen32, u32Data);187 return true;188 }189 190 if (pParam->flags & USE_REG_GEN16)191 {192 DISWriteReg16(pRegFrame, pParam->base.reg_gen16, (uint16_t)u32Data);193 return true;194 }195 196 if (pParam->flags & USE_REG_GEN8)197 {198 DISWriteReg8(pRegFrame, pParam->base.reg_gen8, (uint8_t)u32Data);199 return true;200 }201 202 if (pParam->flags & USE_REG_SEG)203 {204 DISWriteRegSeg(pRegFrame, pParam->base.reg_seg, (RTSEL)u32Data);205 return true;206 }207 208 /* Else - error. */209 return false;210 }211 212 /*213 * Internal - statistics only.214 */215 inline void iomGCMMIOStatLength(PVM pVM, unsigned cb)216 {217 #ifdef VBOX_WITH_STATISTICS218 switch (cb)219 {220 case 1:221 STAM_COUNTER_INC(&pVM->iom.s.StatGCMMIO1Byte);222 break;223 case 2:224 STAM_COUNTER_INC(&pVM->iom.s.StatGCMMIO2Bytes);225 break;226 case 4:227 STAM_COUNTER_INC(&pVM->iom.s.StatGCMMIO4Bytes);228 break;229 default:230 /* No way. */231 AssertMsgFailed(("Invalid data length %d\n", cb));232 break;233 }234 #else235 NOREF(pVM); NOREF(cb);236 #endif237 }238 39 239 40 /** … … 1293 1094 return VINF_SUCCESS; 1294 1095 } 1295 1296 /**1297 * IN <AL|AX|EAX>, <DX|imm16>1298 *1299 * @returns VBox status code.1300 *1301 * @param pVM The virtual machine (GC pointer ofcourse).1302 * @param pRegFrame Pointer to CPUMCTXCORE guest registers structure.1303 * @param pCpu Disassembler CPU state.1304 */1305 IOMDECL(int) IOMInterpretIN(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu)1306 {1307 #ifdef IN_GC1308 STAM_COUNTER_INC(&pVM->iom.s.StatGCInstIn);1309 #endif1310 1311 /*1312 * Get port number from second parameter.1313 * And get the register size from the first parameter.1314 */1315 uint32_t uPort = 0;1316 unsigned cbSize = 0;1317 bool fRc = iomGCGetRegImmData(pCpu, &pCpu->param2, pRegFrame, &uPort, &cbSize);1318 AssertMsg(fRc, ("Failed to get reg/imm port number!\n")); NOREF(fRc);1319 1320 cbSize = iomGCGetRegSize(pCpu, &pCpu->param1);1321 Assert(cbSize > 0);1322 int rc = IOMInterpretCheckPortIOAccess(pVM, pRegFrame, uPort, cbSize);1323 if (rc == VINF_SUCCESS)1324 {1325 /*1326 * Attemp to read the port.1327 */1328 uint32_t u32Data = ~0U;1329 rc = IOMIOPortRead(pVM, uPort, &u32Data, cbSize);1330 if (rc == VINF_SUCCESS)1331 {1332 /*1333 * Store the result in the AL|AX|EAX register.1334 */1335 fRc = iomGCSaveDataToReg(pCpu, &pCpu->param1, pRegFrame, u32Data);1336 AssertMsg(fRc, ("Failed to store register value!\n")); NOREF(fRc);1337 }1338 }1339 return rc;1340 }1341 1342 1343 /**1344 * OUT <DX|imm16>, <AL|AX|EAX>1345 *1346 * @returns VBox status code.1347 *1348 * @param pVM The virtual machine (GC pointer ofcourse).1349 * @param pRegFrame Pointer to CPUMCTXCORE guest registers structure.1350 * @param pCpu Disassembler CPU state.1351 */1352 IOMDECL(int) IOMInterpretOUT(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu)1353 {1354 #ifdef IN_GC1355 STAM_COUNTER_INC(&pVM->iom.s.StatGCInstOut);1356 #endif1357 1358 /*1359 * Get port number from first parameter.1360 * And get the register size and value from the second parameter.1361 */1362 uint32_t uPort = 0;1363 unsigned cbSize = 0;1364 bool fRc = iomGCGetRegImmData(pCpu, &pCpu->param1, pRegFrame, &uPort, &cbSize);1365 AssertMsg(fRc, ("Failed to get reg/imm port number!\n")); NOREF(fRc);1366 1367 int rc = IOMInterpretCheckPortIOAccess(pVM, pRegFrame, uPort, cbSize);1368 if (rc == VINF_SUCCESS)1369 {1370 uint32_t u32Data = 0;1371 fRc = iomGCGetRegImmData(pCpu, &pCpu->param2, pRegFrame, &u32Data, &cbSize);1372 AssertMsg(fRc, ("Failed to get reg value!\n")); NOREF(fRc);1373 1374 /*1375 * Attemp to write to the port.1376 */1377 rc = IOMIOPortWrite(pVM, uPort, u32Data, cbSize);1378 }1379 return rc;1380 } -
trunk/src/VBox/VMM/VMMAll/PGMAllPool.cpp
r2153 r2228 2678 2678 while (iPage-- > 0) 2679 2679 { 2680 Assert (pRam->aHCPhys[iPage] & X86_PTE_PAE_PG_MASK);2680 AssertMsg(pRam->aHCPhys[iPage] & X86_PTE_PAE_PG_MASK, ("GCPhysHint=%VGp\n", GCPhysHint)); 2681 2681 if ((pRam->aHCPhys[iPage] & X86_PTE_PAE_PG_MASK) == HCPhys) 2682 2682 { -
trunk/src/VBox/VMM/VMMGC/IOMGC.cpp
r2226 r2228 46 46 47 47 48 /******************************************************************************* 49 * Internal Functions * 50 *******************************************************************************/ 51 static unsigned iomGCGetRegSize(PDISCPUSTATE pCpu, PCOP_PARAMETER pParam); 52 static bool iomGCGetRegImmData(PDISCPUSTATE pCpu, PCOP_PARAMETER pParam, PCPUMCTXCORE pRegFrame, uint32_t *pu32Data, unsigned *pcbSize); 53 static bool iomGCSaveDataToReg(PDISCPUSTATE pCpu, PCOP_PARAMETER pParam, PCPUMCTXCORE pRegFrame, uint32_t u32Data); 54 55 56 /******************************************************************************* 57 * Global Variables * 58 *******************************************************************************/ 59 60 /** 61 * Array for fast recode of the operand size (1/2/4/8 bytes) to bit shift value. 62 */ 63 static const unsigned g_aSize2Shift[] = 64 { 65 ~0, /* 0 - invalid */ 66 0, /* *1 == 2^0 */ 67 1, /* *2 == 2^1 */ 68 ~0, /* 3 - invalid */ 69 2, /* *4 == 2^2 */ 70 ~0, /* 5 - invalid */ 71 ~0, /* 6 - invalid */ 72 ~0, /* 7 - invalid */ 73 3 /* *8 == 2^3 */ 74 }; 75 76 /** 77 * Macro for fast recode of the operand size (1/2/4/8 bytes) to bit shift value. 78 */ 79 #define SIZE2SHIFT(cb) (g_aSize2Shift[cb]) 80 81 /** 82 * Calculates the size of register parameter. 83 * 84 * @returns 1, 2, 4 on success. 85 * @returns 0 if non-register parameter. 86 * @param pCpu Pointer to current disassembler context. 87 * @param pParam Pointer to parameter of instruction to proccess. 88 */ 89 static unsigned iomGCGetRegSize(PDISCPUSTATE pCpu, PCOP_PARAMETER pParam) 90 { 91 if (pParam->flags & (USE_BASE | USE_INDEX | USE_SCALE | USE_DISPLACEMENT8 | USE_DISPLACEMENT16 | USE_DISPLACEMENT32 | USE_IMMEDIATE8 | USE_IMMEDIATE16 | USE_IMMEDIATE32 | USE_IMMEDIATE16_SX8 | USE_IMMEDIATE32_SX8)) 92 return 0; 93 94 if (pParam->flags & USE_REG_GEN32) 95 return 4; 96 97 if (pParam->flags & USE_REG_GEN16) 98 return 2; 99 100 if (pParam->flags & USE_REG_GEN8) 101 return 1; 102 103 if (pParam->flags & USE_REG_SEG) 104 return 2; 105 return 0; 106 } 107 108 /** 109 * Returns the contents of register or immediate data of instruction's parameter. 110 * 111 * @returns true on success. 112 * 113 * @param pCpu Pointer to current disassembler context. 114 * @param pParam Pointer to parameter of instruction to proccess. 115 * @param pRegFrame Pointer to CPUMCTXCORE guest structure. 116 * @param pu32Data Where to store retrieved data. 117 * @param pcbSize Where to store the size of data (1, 2, 4). 118 */ 119 static bool iomGCGetRegImmData(PDISCPUSTATE pCpu, PCOP_PARAMETER pParam, PCPUMCTXCORE pRegFrame, uint32_t *pu32Data, unsigned *pcbSize) 120 { 121 if (pParam->flags & (USE_BASE | USE_INDEX | USE_SCALE | USE_DISPLACEMENT8 | USE_DISPLACEMENT16 | USE_DISPLACEMENT32)) 122 { 123 *pcbSize = 0; 124 *pu32Data = 0; 125 return false; 126 } 127 128 if (pParam->flags & USE_REG_GEN32) 129 { 130 *pcbSize = 4; 131 DISFetchReg32(pRegFrame, pParam->base.reg_gen32, pu32Data); 132 return true; 133 } 134 135 if (pParam->flags & USE_REG_GEN16) 136 { 137 *pcbSize = 2; 138 DISFetchReg16(pRegFrame, pParam->base.reg_gen16, (uint16_t *)pu32Data); 139 return true; 140 } 141 142 if (pParam->flags & USE_REG_GEN8) 143 { 144 *pcbSize = 1; 145 DISFetchReg8(pRegFrame, pParam->base.reg_gen8, (uint8_t *)pu32Data); 146 return true; 147 } 148 149 if (pParam->flags & (USE_IMMEDIATE32|USE_IMMEDIATE32_SX8)) 150 { 151 *pcbSize = 4; 152 *pu32Data = (uint32_t)pParam->parval; 153 return true; 154 } 155 156 if (pParam->flags & (USE_IMMEDIATE16|USE_IMMEDIATE16_SX8)) 157 { 158 *pcbSize = 2; 159 *pu32Data = (uint16_t)pParam->parval; 160 return true; 161 } 162 163 if (pParam->flags & USE_IMMEDIATE8) 164 { 165 *pcbSize = 1; 166 *pu32Data = (uint8_t)pParam->parval; 167 return true; 168 } 169 170 if (pParam->flags & USE_REG_SEG) 171 { 172 *pcbSize = 2; 173 DISFetchRegSeg(pRegFrame, pParam->base.reg_seg, (RTSEL *)pu32Data); 174 return true; 175 } /* Else - error. */ 176 177 *pcbSize = 0; 178 *pu32Data = 0; 179 return false; 180 } 181 182 183 /** 184 * Saves data to 8/16/32 general purpose or segment register defined by 185 * instruction's parameter. 186 * 187 * @returns true on success. 188 * @param pCpu Pointer to current disassembler context. 189 * @param pParam Pointer to parameter of instruction to proccess. 190 * @param pRegFrame Pointer to CPUMCTXCORE guest structure. 191 * @param u32Data 8/16/32 bit data to store. 192 */ 193 static bool iomGCSaveDataToReg(PDISCPUSTATE pCpu, PCOP_PARAMETER pParam, PCPUMCTXCORE pRegFrame, unsigned u32Data) 194 { 195 if (pParam->flags & (USE_BASE | USE_INDEX | USE_SCALE | USE_DISPLACEMENT8 | USE_DISPLACEMENT16 | USE_DISPLACEMENT32 | USE_IMMEDIATE8 | USE_IMMEDIATE16 | USE_IMMEDIATE32 | USE_IMMEDIATE32_SX8 | USE_IMMEDIATE16_SX8)) 196 { 197 return false; 198 } 199 200 if (pParam->flags & USE_REG_GEN32) 201 { 202 DISWriteReg32(pRegFrame, pParam->base.reg_gen32, u32Data); 203 return true; 204 } 205 206 if (pParam->flags & USE_REG_GEN16) 207 { 208 DISWriteReg16(pRegFrame, pParam->base.reg_gen16, (uint16_t)u32Data); 209 return true; 210 } 211 212 if (pParam->flags & USE_REG_GEN8) 213 { 214 DISWriteReg8(pRegFrame, pParam->base.reg_gen8, (uint8_t)u32Data); 215 return true; 216 } 217 218 if (pParam->flags & USE_REG_SEG) 219 { 220 DISWriteRegSeg(pRegFrame, pParam->base.reg_seg, (RTSEL)u32Data); 221 return true; 222 } 223 224 /* Else - error. */ 225 return false; 226 } 227 228 229 /* 230 * Internal - statistics only. 231 */ 232 inline void iomGCMMIOStatLength(PVM pVM, unsigned cb) 233 { 234 #ifdef VBOX_WITH_STATISTICS 235 switch (cb) 236 { 237 case 1: 238 STAM_COUNTER_INC(&pVM->iom.s.StatGCMMIO1Byte); 239 break; 240 case 2: 241 STAM_COUNTER_INC(&pVM->iom.s.StatGCMMIO2Bytes); 242 break; 243 case 4: 244 STAM_COUNTER_INC(&pVM->iom.s.StatGCMMIO4Bytes); 245 break; 246 default: 247 /* No way. */ 248 AssertMsgFailed(("Invalid data length %d\n", cb)); 249 break; 250 } 251 #else 252 NOREF(pVM); NOREF(cb); 253 #endif 254 } 255 256 257 /** 258 * IN <AL|AX|EAX>, <DX|imm16> 259 * 260 * @returns VBox status code. 261 * 262 * @param pVM The virtual machine (GC pointer ofcourse). 263 * @param pRegFrame Pointer to CPUMCTXCORE guest registers structure. 264 * @param pCpu Disassembler CPU state. 265 */ 266 IOMDECL(int) IOMInterpretIN(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu) 267 { 268 #ifdef VBOX_WITH_STATISTICS 269 STAM_COUNTER_INC(&pVM->iom.s.StatGCInstIn); 270 #endif 271 272 /* 273 * Get port number from second parameter. 274 * And get the register size from the first parameter. 275 */ 276 uint32_t uPort = 0; 277 unsigned cbSize = 0; 278 bool fRc = iomGCGetRegImmData(pCpu, &pCpu->param2, pRegFrame, &uPort, &cbSize); 279 AssertMsg(fRc, ("Failed to get reg/imm port number!\n")); NOREF(fRc); 280 281 cbSize = iomGCGetRegSize(pCpu, &pCpu->param1); 282 Assert(cbSize > 0); 283 int rc = IOMInterpretCheckPortIOAccess(pVM, pRegFrame, uPort, cbSize); 284 if (rc == VINF_SUCCESS) 285 { 286 /* 287 * Attemp to read the port. 288 */ 289 uint32_t u32Data = ~0U; 290 rc = IOMIOPortRead(pVM, uPort, &u32Data, cbSize); 291 if (rc == VINF_SUCCESS) 292 { 293 /* 294 * Store the result in the AL|AX|EAX register. 295 */ 296 fRc = iomGCSaveDataToReg(pCpu, &pCpu->param1, pRegFrame, u32Data); 297 AssertMsg(fRc, ("Failed to store register value!\n")); NOREF(fRc); 298 } 299 } 300 return rc; 301 } 302 303 304 /** 305 * OUT <DX|imm16>, <AL|AX|EAX> 306 * 307 * @returns VBox status code. 308 * 309 * @param pVM The virtual machine (GC pointer ofcourse). 310 * @param pRegFrame Pointer to CPUMCTXCORE guest registers structure. 311 * @param pCpu Disassembler CPU state. 312 */ 313 IOMDECL(int) IOMInterpretOUT(PVM pVM, PCPUMCTXCORE pRegFrame, PDISCPUSTATE pCpu) 314 { 315 #ifdef VBOX_WITH_STATISTICS 316 STAM_COUNTER_INC(&pVM->iom.s.StatGCInstOut); 317 #endif 318 319 /* 320 * Get port number from first parameter. 321 * And get the register size and value from the second parameter. 322 */ 323 uint32_t uPort = 0; 324 unsigned cbSize = 0; 325 bool fRc = iomGCGetRegImmData(pCpu, &pCpu->param1, pRegFrame, &uPort, &cbSize); 326 AssertMsg(fRc, ("Failed to get reg/imm port number!\n")); NOREF(fRc); 327 328 int rc = IOMInterpretCheckPortIOAccess(pVM, pRegFrame, uPort, cbSize); 329 if (rc == VINF_SUCCESS) 330 { 331 uint32_t u32Data = 0; 332 fRc = iomGCGetRegImmData(pCpu, &pCpu->param2, pRegFrame, &u32Data, &cbSize); 333 AssertMsg(fRc, ("Failed to get reg value!\n")); NOREF(fRc); 334 335 /* 336 * Attemp to write to the port. 337 */ 338 rc = IOMIOPortWrite(pVM, uPort, u32Data, cbSize); 339 } 340 return rc; 341 } 48 342 49 343 /** -
trunk/src/VBox/VMM/VMMR0/VMMR0.cpp
r2108 r2228 727 727 728 728 #ifdef DEBUG_NO_RING0_ASSERTIONS 729 #undef LOG_GROUP 730 #define LOG_GROUP LOG_GROUP_EM 731 729 732 /** 730 733 * Check if we really want to hit a breakpoint. … … 747 750 748 751 749 #undef LOG_GROUP750 #define LOG_GROUP LOG_GROUP_EM751 752 752 753 /** Runtime assert implementation for Native Win32 Ring-0. */
Note:
See TracChangeset
for help on using the changeset viewer.