VirtualBox

Changeset 2232 in vbox for trunk


Ignore:
Timestamp:
Apr 19, 2007 2:19:16 PM (18 years ago)
Author:
vboxsync
Message:

Put back 20576. Not sure what went wrong before.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/EM.cpp

    r2229 r2232  
    12701270    if (VBOX_SUCCESS(rc))
    12711271    {
    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 
    12891272        if (!(Cpu.prefix & (PREFIX_REP | PREFIX_REPNE)))
    12901273        {
    1291             OP_PARAMVAL ParmVal;
    1292             int         rc;
    12931274            switch (Cpu.pCurInstr->opcode)
    12941275            {
    12951276                case OP_IN:
    12961277                {
    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)
     1278                    STAM_COUNTER_INC(&pVM->em.s.CTXSUFF(pStats)->StatIn);
     1279
     1280                    rc = IOMInterpretIN(pVM, CPUMCTX2CORE(pCtx), &Cpu);
     1281                    if (rc == VINF_SUCCESS)
    13081282                    {
    1309                         if (rc == VINF_EM_RAW_GUEST_TRAP)
    1310                             rc = emR3RawGuestTrap(pVM);
    1311 
     1283                        pCtx->eip += Cpu.opsize;
     1284                        STAM_PROFILE_STOP(&pVM->em.s.StatIOEmu, a);
     1285                        return VINF_SUCCESS;
     1286                    }
     1287                    else
     1288                    if (rc == VINF_EM_RAW_GUEST_TRAP)
     1289                    {
     1290                        STAM_PROFILE_STOP(&pVM->em.s.StatIOEmu, a);
     1291                        rc = emR3RawGuestTrap(pVM);
    13121292                        return rc;
    13131293                    }
    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                     }
     1294                    /* emulate in the recompiler */
    13641295                    break;
    13651296                }
     
    13671298                case OP_OUT:
    13681299                {
    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)
     1300                    STAM_COUNTER_INC(&pVM->em.s.CTXSUFF(pStats)->StatOut);
     1301
     1302                    rc = IOMInterpretOUT(pVM, CPUMCTX2CORE(pCtx), &Cpu);
     1303                    if (rc == VINF_SUCCESS)
    13831304                    {
    1384                         if (rc == VINF_EM_RAW_GUEST_TRAP)
    1385                             rc = emR3RawGuestTrap(pVM);
    1386 
     1305                        pCtx->eip += Cpu.opsize;
     1306                        STAM_PROFILE_STOP(&pVM->em.s.StatIOEmu, a);
     1307                        return VINF_SUCCESS;
     1308                    }
     1309                    else
     1310                    if (rc == VINF_EM_RAW_GUEST_TRAP)
     1311                    {
     1312                        STAM_PROFILE_STOP(&pVM->em.s.StatIOEmu, a);
     1313                        rc = emR3RawGuestTrap(pVM);
    13871314                        return rc;
    13881315                    }
    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                     }
     1316                    /* emulate in the recompiler */
    14331317                    break;
    14341318                }
     
    14451329                case OP_INSWD:
    14461330                {
    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)
     1331                    STAM_COUNTER_INC(&pVM->em.s.CTXSUFF(pStats)->StatIn);
     1332                    rc = IOMInterpretINS(pVM, CPUMCTX2CORE(pCtx), &Cpu);
     1333                    if (rc == VINF_SUCCESS)
    14721334                    {
    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 
     1335                        STAM_PROFILE_STOP(&pVM->em.s.StatIOEmu, a);
     1336                        pCtx->eip += Cpu.opsize;
    14861337                        return rc;
    14871338                    }
    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)
     1339                    else
     1340                    if (rc == VINF_EM_RAW_GUEST_TRAP)
    14971341                    {
    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--;
     1342                        STAM_PROFILE_STOP(&pVM->em.s.StatIOEmu, a);
     1343                        rc = emR3RawGuestTrap(pVM);
     1344                        return rc;
    15051345                    }
    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;
     1346                    /* emulate in the recompiler */
     1347                    break;
    15121348                }
    15131349                case OP_OUTSB:
    15141350                case OP_OUTSWD:
    15151351                {
    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)
     1352                    STAM_COUNTER_INC(&pVM->em.s.CTXSUFF(pStats)->StatOut);
     1353                    rc = IOMInterpretOUTS(pVM, CPUMCTX2CORE(pCtx), &Cpu);
     1354                    if (rc == VINF_SUCCESS)
    15401355                    {
    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 
     1356                        STAM_PROFILE_STOP(&pVM->em.s.StatIOEmu, a);
     1357                        pCtx->eip += Cpu.opsize;
    15541358                        return rc;
    15551359                    }
    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)
     1360                    else
     1361                    if (rc == VINF_EM_RAW_GUEST_TRAP)
    15651362                    {
    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--;
     1363                        STAM_PROFILE_STOP(&pVM->em.s.StatIOEmu, a);
     1364                        rc = emR3RawGuestTrap(pVM);
     1365                        return rc;
    15731366                    }
    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;
     1367                    /* emulate in the recompiler */
     1368                    break;
    15801369                }
    15811370            }
     
    28992688#endif
    29002689
    2901 //        DBGFR3InfoLog(pVM, "cpumguest", "PRE");
    2902 //        DBGFR3DisasInstrCurrentLog(pVM, "PRE");
    2903 
    29042690        /*
    29052691         * Execute the code.
     
    29112697        VMMR3Lock(pVM);
    29122698        STAM_PROFILE_STOP(&pVM->em.s.StatHwAccExec, x);
    2913 
    2914 //        DBGFR3InfoLog(pVM, "cpumguest", "POST");
    2915 //        DBGFR3DisasInstrCurrentLog(pVM, "POST");
    29162699
    29172700        /*
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette