VirtualBox

Changeset 2228 in vbox for trunk/src/VBox/VMM


Ignore:
Timestamp:
Apr 19, 2007 1:52:53 PM (18 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
20578
Message:

backed out 20576 due to regressions

Location:
trunk/src/VBox/VMM
Files:
8 edited

Legend:

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

    r23 r2228  
    235235    RTStrmPrintf(g_pStdErr, "DBGF: No debugger attached, waiting 15 seconds for one to attach (event=%d)\n", enmEvent);
    236236    RTStrmFlush(g_pStdErr);
    237 #ifdef DEBUG_sandervl
     237#if 1 //def DEBUG_sandervl
    238238    int cWait = 10;
    239239#else
  • trunk/src/VBox/VMM/EM.cpp

    r2226 r2228  
    988988            return rc;
    989989    }
    990 
    991990    /*
    992991     * Set flags for single stepping.
     
    10201019}
    10211020
    1022 #ifdef DEBUG_sandervl
     1021#if 1 //def DEBUG_sandervl
    10231022void emR3SingleStepExecRaw(PVM pVM, uint32_t cIterations)
    10241023{
     
    12711270    if (VBOX_SUCCESS(rc))
    12721271    {
     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
    12731289        if (!(Cpu.prefix & (PREFIX_REP | PREFIX_REPNE)))
    12741290        {
     1291            OP_PARAMVAL ParmVal;
     1292            int         rc;
    12751293            switch (Cpu.pCurInstr->opcode)
    12761294            {
    12771295                case OP_IN:
    12781296                {
    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)
    12831308                    {
    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
    12931312                        return rc;
    12941313                    }
    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                    }
    12961364                    break;
    12971365                }
     
    12991367                case OP_OUT:
    13001368                {
    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)
    13051383                    {
    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
    13151387                        return rc;
    13161388                    }
    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                    }
    13181433                    break;
    13191434                }
     
    13301445                case OP_INSWD:
    13311446                {
    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)
    13351472                    {
    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
    13381486                        return rc;
    13391487                    }
    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)
    13421497                    {
    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--;
    13461505                    }
    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;
    13491512                }
    13501513                case OP_OUTSB:
    13511514                case OP_OUTSWD:
    13521515                {
    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)
    13561540                    {
    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
    13591554                        return rc;
    13601555                    }
    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)
    13631565                    {
    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--;
    13671573                    }
    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;
    13701580                }
    13711581            }
     
    26892899#endif
    26902900
     2901//        DBGFR3InfoLog(pVM, "cpumguest", "PRE");
     2902//        DBGFR3DisasInstrCurrentLog(pVM, "PRE");
    26912903
    26922904        /*
     
    26992911        VMMR3Lock(pVM);
    27002912        STAM_PROFILE_STOP(&pVM->em.s.StatHwAccExec, x);
     2913
     2914//        DBGFR3InfoLog(pVM, "cpumguest", "POST");
     2915//        DBGFR3DisasInstrCurrentLog(pVM, "POST");
    27012916
    27022917        /*
  • trunk/src/VBox/VMM/HWACCM.cpp

    r2213 r2228  
    457457    Assert(pVM->fHWACCMEnabled);
    458458
    459 #if 0
     459#if 1
    460460    /* AMD SVM supports real & protected mode with or without paging. */
    461461    if (pVM->hwaccm.s.svm.fEnabled)
  • trunk/src/VBox/VMM/VMM.cpp

    r2124 r2228  
    433433 * to not stub all the log functions.
    434434 */
    435 # ifdef DEBUG_sandervl
     435# if 1 //def DEBUG_sandervl
    436436                    rc = MMHyperAlloc(pVM, RT_OFFSETOF(VMMR0LOGGER, Logger.afGroups[pLogger->cGroups]),
    437437                                      0, MM_TAG_VMM, (void **)&pVM->vmm.s.pR0Logger);
  • trunk/src/VBox/VMM/VMMAll/IOMAll.cpp

    r2226 r2228  
    3737#include <iprt/assert.h>
    3838
    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 by
    169  * 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_STATISTICS
    218     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 #else
    235     NOREF(pVM); NOREF(cb);
    236 #endif
    237 }
    23839
    23940/**
     
    12931094    return VINF_SUCCESS;
    12941095}
    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_GC
    1308     STAM_COUNTER_INC(&pVM->iom.s.StatGCInstIn);
    1309 #endif
    1310 
    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_GC
    1355     STAM_COUNTER_INC(&pVM->iom.s.StatGCInstOut);
    1356 #endif
    1357 
    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  
    26782678        while (iPage-- > 0)
    26792679        {
    2680             Assert(pRam->aHCPhys[iPage] & X86_PTE_PAE_PG_MASK);
     2680            AssertMsg(pRam->aHCPhys[iPage] & X86_PTE_PAE_PG_MASK, ("GCPhysHint=%VGp\n", GCPhysHint));
    26812681            if ((pRam->aHCPhys[iPage] & X86_PTE_PAE_PG_MASK) == HCPhys)
    26822682            {
  • trunk/src/VBox/VMM/VMMGC/IOMGC.cpp

    r2226 r2228  
    4646
    4747
     48/*******************************************************************************
     49*   Internal Functions                                                         *
     50*******************************************************************************/
     51static unsigned iomGCGetRegSize(PDISCPUSTATE pCpu, PCOP_PARAMETER pParam);
     52static bool iomGCGetRegImmData(PDISCPUSTATE pCpu, PCOP_PARAMETER pParam, PCPUMCTXCORE pRegFrame, uint32_t *pu32Data, unsigned *pcbSize);
     53static 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 */
     63static 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 */
     89static 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 */
     119static 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 */
     193static 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 */
     232inline 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 */
     266IOMDECL(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 */
     313IOMDECL(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}
    48342
    49343/**
  • trunk/src/VBox/VMM/VMMR0/VMMR0.cpp

    r2108 r2228  
    727727
    728728#ifdef DEBUG_NO_RING0_ASSERTIONS
     729#undef LOG_GROUP
     730#define LOG_GROUP LOG_GROUP_EM
     731
    729732/**
    730733 * Check if we really want to hit a breakpoint.
     
    747750
    748751
    749 #undef LOG_GROUP
    750 #define LOG_GROUP LOG_GROUP_EM
    751752
    752753/** Runtime assert implementation for Native Win32 Ring-0. */
Note: See TracChangeset for help on using the changeset viewer.

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