VirtualBox

Changeset 36794 in vbox


Ignore:
Timestamp:
Apr 21, 2011 3:02:34 PM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
71349
Message:

IEM: Verify I/O port read and writes as well as MMIO accesses. Implemented some more instructions, getting thru the BIOS now.

Location:
trunk
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/iem.h

    r36768 r36794  
    4040VMMDECL(VBOXSTRICTRC) IEMExecOne(PVMCPU pVCpu);
    4141
     42#if defined(IEM_VERIFICATION_MODE) && defined(IN_RING3)
     43VMM_INT_DECL(void)   IEMNotifyMMIORead(PVM pVM, RTGCPHYS GCPhys, size_t cbValue);
     44VMM_INT_DECL(void)   IEMNotifyMMIOWrite(PVM pVM, RTGCPHYS GCPhys, uint32_t u32Value, size_t cbValue);
     45VMM_INT_DECL(void)   IEMNotifyIOPortRead(PVM pVM, RTIOPORT Port, size_t cbValue);
     46VMM_INT_DECL(void)   IEMNotifyIOPortWrite(PVM pVM, RTIOPORT Port, uint32_t u32Value, size_t cbValue);
     47VMM_INT_DECL(void)   IEMNotifyIOPortReadString(PVM pVM, RTIOPORT Port, RTGCPTR GCPtrDst, RTGCUINTREG cTransfers, size_t cbValue);
     48VMM_INT_DECL(void)   IEMNotifyIOPortWriteString(PVM pVM, RTIOPORT Port, RTGCPTR GCPtrSrc, RTGCUINTREG cTransfers, size_t cbValue);
     49#endif
    4250
    4351
  • trunk/src/VBox/VMM/VMMAll/IEMAll.cpp

    r36780 r36794  
    5353#ifdef IEM_VERIFICATION_MODE
    5454# include <VBox/vmm/rem.h>
     55# include <VBox/vmm/mm.h>
    5556#endif
    5657#include "IEMInternal.h"
     
    187188*   Defined Constants And Macros                                               *
    188189*******************************************************************************/
     190/** Temporary hack to disable the double execution.  Will be removed in favor
     191 * of a dedicated execution mode in EM. */
     192//#define IEM_VERIFICATION_MODE_NO_REM
     193
    189194/** Used to shut up GCC warnings about variables that 'may be used uninitialized'
    190195 * due to GCC lacking knowledge about the value range of a switch. */
     
    500505static VBOXSTRICTRC     iemRaiseSelectorNotPresent(PIEMCPU pIemCpu, uint32_t iSegReg, uint32_t fAccess);
    501506static VBOXSTRICTRC     iemRaisePageFault(PIEMCPU pIemCpu, RTGCPTR GCPtrWhere, uint32_t fAccess, int rc);
     507#if defined(IEM_VERIFICATION_MODE) && !defined(IEM_VERIFICATION_MODE_NO_REM)
     508static PIEMVERIFYEVTREC iemVerifyAllocRecord(PIEMCPU pIemCpu);
     509static VBOXSTRICTRC     iemVerifyFakeIOPortRead(PIEMCPU pIemCpu, RTIOPORT Port, uint32_t *pu32Value, size_t cbValue);
     510static VBOXSTRICTRC     iemVerifyFakeIOPortWrite(PIEMCPU pIemCpu, RTIOPORT Port, uint32_t u32Value, size_t cbValue);
     511#endif
    502512
    503513
     
    20782088static int iemMemPageMap(PIEMCPU pIemCpu, RTGCPHYS GCPhysMem, uint32_t fAccess, void **ppvMem)
    20792089{
    2080 #ifdef IEM_VERIFICATION_MODE
     2090#if defined(IEM_VERIFICATION_MODE) && !defined(IEM_VERIFICATION_MODE_NO_REM)
    20812091    /* Force the alternative path so we can ignore writes. */
    20822092    if (fAccess & IEM_ACCESS_TYPE_WRITE)
     
    21622172     */
    21632173    int rc;
    2164 #ifndef IEM_VERIFICATION_MODE /* No memory changes in verification mode. */
     2174#if !defined(IEM_VERIFICATION_MODE) || defined(IEM_VERIFICATION_MODE_NO_REM) /* No memory changes in verification mode. */
    21652175    if (!pIemCpu->aMemBbMappings[iMemMap].fUnassigned)
    21662176    {
     
    21972207        rc = VINF_SUCCESS;
    21982208
     2209#if defined(IEM_VERIFICATION_MODE) && !defined(IEM_VERIFICATION_MODE_NO_REM)
     2210    /*
     2211     * Record the write(s).
     2212     */
     2213    PIEMVERIFYEVTREC pEvtRec = iemVerifyAllocRecord(pIemCpu);
     2214    if (pEvtRec)
     2215    {
     2216        pEvtRec->enmEvent = IEMVERIFYEVENT_RAM_WRITE;
     2217        pEvtRec->u.RamWrite.GCPhys  = pIemCpu->aMemBbMappings[iMemMap].GCPhysFirst;
     2218        pEvtRec->u.RamWrite.cb      = pIemCpu->aMemBbMappings[iMemMap].cbFirst;
     2219        memcpy(pEvtRec->u.RamWrite.ab, &pIemCpu->aBounceBuffers[iMemMap].ab[0], pIemCpu->aMemBbMappings[iMemMap].cbFirst);
     2220        pEvtRec->pNext = *pIemCpu->ppIemEvtRecNext;
     2221        *pIemCpu->ppIemEvtRecNext = pEvtRec;
     2222    }
     2223    if (pIemCpu->aMemBbMappings[iMemMap].cbSecond)
     2224    {
     2225        pEvtRec = iemVerifyAllocRecord(pIemCpu);
     2226        if (pEvtRec)
     2227        {
     2228            pEvtRec->enmEvent = IEMVERIFYEVENT_RAM_WRITE;
     2229            pEvtRec->u.RamWrite.GCPhys  = pIemCpu->aMemBbMappings[iMemMap].GCPhysSecond;
     2230            pEvtRec->u.RamWrite.cb      = pIemCpu->aMemBbMappings[iMemMap].cbSecond;
     2231            memcpy(pEvtRec->u.RamWrite.ab,
     2232                   &pIemCpu->aBounceBuffers[iMemMap].ab[pIemCpu->aMemBbMappings[iMemMap].cbFirst],
     2233                   pIemCpu->aMemBbMappings[iMemMap].cbSecond);
     2234            pEvtRec->pNext = *pIemCpu->ppIemEvtRecNext;
     2235            *pIemCpu->ppIemEvtRecNext = pEvtRec;
     2236        }
     2237    }
     2238#endif
     2239
    21992240    /*
    22002241     * Free the mapping entry.
     
    22552296                return rc;
    22562297        }
     2298
     2299#if defined(IEM_VERIFICATION_MODE) && !defined(IEM_VERIFICATION_MODE_NO_REM)
     2300        /*
     2301         * Record the reads.
     2302         */
     2303        PIEMVERIFYEVTREC pEvtRec = iemVerifyAllocRecord(pIemCpu);
     2304        if (pEvtRec)
     2305        {
     2306            pEvtRec->enmEvent = IEMVERIFYEVENT_RAM_READ;
     2307            pEvtRec->u.RamRead.GCPhys  = GCPhysFirst;
     2308            pEvtRec->u.RamRead.cb      = cbFirstPage;
     2309            pEvtRec->pNext = *pIemCpu->ppIemEvtRecNext;
     2310            *pIemCpu->ppIemEvtRecNext = pEvtRec;
     2311        }
     2312        pEvtRec = iemVerifyAllocRecord(pIemCpu);
     2313        if (pEvtRec)
     2314        {
     2315            pEvtRec->enmEvent = IEMVERIFYEVENT_RAM_READ;
     2316            pEvtRec->u.RamRead.GCPhys  = GCPhysSecond;
     2317            pEvtRec->u.RamRead.cb      = cbSecondPage;
     2318            pEvtRec->pNext = *pIemCpu->ppIemEvtRecNext;
     2319            *pIemCpu->ppIemEvtRecNext = pEvtRec;
     2320        }
     2321#endif
    22572322    }
    22582323#ifdef VBOX_STRICT
     
    23182383                return rc;
    23192384        }
     2385
     2386#if defined(IEM_VERIFICATION_MODE) && !defined(IEM_VERIFICATION_MODE_NO_REM)
     2387        /*
     2388         * Record the read.
     2389         */
     2390        PIEMVERIFYEVTREC pEvtRec = iemVerifyAllocRecord(pIemCpu);
     2391        if (pEvtRec)
     2392        {
     2393            pEvtRec->enmEvent = IEMVERIFYEVENT_RAM_READ;
     2394            pEvtRec->u.RamRead.GCPhys  = GCPhysFirst;
     2395            pEvtRec->u.RamRead.cb      = cbMem;
     2396            pEvtRec->pNext = *pIemCpu->ppIemEvtRecNext;
     2397            *pIemCpu->ppIemEvtRecNext = pEvtRec;
     2398        }
     2399#endif
    23202400    }
    23212401#ifdef VBOX_STRICT
     
    23622442 *                              memory.
    23632443 * @param   cbMem               The number of bytes to map.  This is usually 1,
    2364  *                              2, 4, 6, 8, 12 or 16.  When used by string
     2444 *                              2, 4, 6, 8, 12, 16 or 32.  When used by string
    23652445 *                              operations it can be up to a page.
    23662446 * @param   iSegReg             The index of the segment register to use for
     
    23802460     * Check the input and figure out which mapping entry to use.
    23812461     */
    2382     Assert(cbMem <= 16);
     2462    Assert(cbMem <= 32);
    23832463    Assert(~(fAccess & ~(IEM_ACCESS_TYPE_MASK | IEM_ACCESS_WHAT_MASK)));
    23842464
     
    37963876     * Commit the flags.
    37973877     */
     3878    Assert(fEflNew & RT_BIT_32(1));
    37983879    pCtx->eflags.u = fEflNew;
    37993880    iemRegAddToRip(pIemCpu, cbInstr);
     
    43574438                       | X86_EFL_RF /*| X86_EFL_VM*/ | X86_EFL_AC /*|X86_EFL_VIF*/ /*|X86_EFL_VIP*/
    43584439                       | X86_EFL_ID;
    4359             uNewFlags |= pCtx->eflags.u & (X86_EFL_VM | X86_EFL_VIF | X86_EFL_VIP);
     4440            uNewFlags |= pCtx->eflags.u & (X86_EFL_VM | X86_EFL_VIF | X86_EFL_VIP | X86_EFL_1);
    43604441        }
    43614442        else
     
    43694450            uNewFlags &= X86_EFL_CF | X86_EFL_PF | X86_EFL_AF | X86_EFL_ZF | X86_EFL_SF
    43704451                       | X86_EFL_TF | X86_EFL_IF | X86_EFL_DF | X86_EFL_OF | X86_EFL_IOPL | X86_EFL_NT;
    4371             uNewFlags |= pCtx->eflags.u & UINT16_C(0xffff0000);
     4452            uNewFlags |= pCtx->eflags.u & (UINT16_C(0xffff0000) | X86_EFL_1);
    43724453            /** @todo The intel pseudo code does not indicate what happens to
    43734454             *        reserved flags. We just ignore them. */
     
    44134494        pCtx->csHid.u64Base = (uint32_t)uNewCs << 4;
    44144495        /** @todo do we load attribs and limit as well? */
     4496        Assert(uNewFlags & X86_EFL_1);
    44154497        pCtx->eflags.u      = uNewFlags;
    44164498
     
    44924574
    44934575        *pSel = uSel;   /* Not RPL, remember :-) */
    4494         if (pIemCpu->enmCpuMode == IEMMODE_64BIT)
     4576        if (   pIemCpu->enmCpuMode == IEMMODE_64BIT
     4577            && iSegReg != X86_SREG_FS
     4578            && iSegReg != X86_SREG_GS)
    44954579        {
    44964580            /** @todo figure out what this actually does, it works. Needs
     
    46344718
    46354719/**
     4720 * Implements lgs, lfs, les, lds & lss.
     4721 */
     4722IEM_CIMPL_DEF_5(iemCImpl_load_SReg_Greg,
     4723                uint16_t, uSel,
     4724                uint64_t, offSeg,
     4725                uint8_t,  iSegReg,
     4726                uint8_t,  iGReg,
     4727                IEMMODE,  enmEffOpSize)
     4728{
     4729    PCPUMCTX        pCtx = pIemCpu->CTX_SUFF(pCtx);
     4730    VBOXSTRICTRC    rcStrict;
     4731
     4732    /*
     4733     * Use iemCImpl_LoadSReg to do the tricky segment register loading.
     4734     */
     4735    /** @todo verify and test that mov, pop and lXs works the segment
     4736     *        register loading in the exact same way. */
     4737    rcStrict = IEM_CIMPL_CALL_2(iemCImpl_LoadSReg, iSegReg, uSel);
     4738    if (rcStrict == VINF_SUCCESS)
     4739    {
     4740        switch (enmEffOpSize)
     4741        {
     4742            case IEMMODE_16BIT:
     4743                *(uint16_t *)iemGRegRef(pIemCpu, iGReg) = offSeg;
     4744                break;
     4745            case IEMMODE_32BIT:
     4746                *(uint64_t *)iemGRegRef(pIemCpu, iGReg) = offSeg;
     4747                break;
     4748            case IEMMODE_64BIT:
     4749                *(uint64_t *)iemGRegRef(pIemCpu, iGReg) = offSeg;
     4750                break;
     4751            IEM_NOT_REACHED_DEFAULT_CASE_RET();
     4752        }
     4753    }
     4754
     4755    return rcStrict;
     4756}
     4757
     4758
     4759/**
    46364760 * Implements 'pop SReg'.
    46374761 *
     
    47104834    if (rcStrict == VINF_SUCCESS)
    47114835    {
    4712 #ifndef IEM_VERIFICATION_MODE
     4836#if !defined(IEM_VERIFICATION_MODE) || defined(IEM_VERIFICATION_MODE_NO_REM)
    47134837        rcStrict = CPUMSetGuestGDTR(IEMCPU_TO_VMCPU(pIemCpu), GCPtrBase, cbLimit);
    47144838#else
     
    47454869    if (rcStrict == VINF_SUCCESS)
    47464870    {
    4747 #ifndef IEM_VERIFICATION_MODE
     4871#if !defined(IEM_VERIFICATION_MODE) || defined(IEM_VERIFICATION_MODE_NO_REM)
    47484872        rcStrict = CPUMSetGuestIDTR(IEMCPU_TO_VMCPU(pIemCpu), GCPtrBase, cbLimit);
    47494873#else
     
    47814905        case 4: crX = pCtx->cr4; break;
    47824906        case 8:
    4783 #ifndef IEM_VERIFICATION_MODE
     4907#if !defined(IEM_VERIFICATION_MODE) || defined(IEM_VERIFICATION_MODE_NO_REM)
    47844908            AssertFailedReturn(VERR_NOT_IMPLEMENTED); /** @todo implement CR8 reading and writing. */
    47854909#else
     
    48885012             * Change CR0.
    48895013             */
    4890 #ifndef IEM_VERIFICATION_MODE
     5014#if !defined(IEM_VERIFICATION_MODE) || defined(IEM_VERIFICATION_MODE_NO_REM)
    48915015            rc = CPUMSetGuestCR0(pVCpu, NewCrX);
    48925016            AssertRCSuccessReturn(rc, RT_FAILURE_NP(rc) ? rc : VERR_INTERNAL_ERROR_3);
     
    49085032                    NewEFER &= ~MSR_K6_EFER_LME;
    49095033
    4910 #ifndef IEM_VERIFICATION_MODE
     5034#if !defined(IEM_VERIFICATION_MODE) || defined(IEM_VERIFICATION_MODE_NO_REM)
    49115035                CPUMSetGuestEFER(pVCpu, NewEFER);
    49125036#else
     
    49165040            }
    49175041
    4918 #ifndef IEM_VERIFICATION_MODE
     5042#if !defined(IEM_VERIFICATION_MODE) || defined(IEM_VERIFICATION_MODE_NO_REM)
    49195043            /*
    49205044             * Inform PGM.
     
    49785102
    49795103            /* Make the change. */
    4980 #ifndef IEM_VERIFICATION_MODE
     5104#if !defined(IEM_VERIFICATION_MODE) || defined(IEM_VERIFICATION_MODE_NO_REM)
    49815105            rc = CPUMSetGuestCR3(pVCpu, NewCrX);
    49825106            AssertRCSuccessReturn(rc, rc);
     
    49855109#endif
    49865110
    4987 #ifndef IEM_VERIFICATION_MODE
     5111#if !defined(IEM_VERIFICATION_MODE) || defined(IEM_VERIFICATION_MODE_NO_REM)
    49885112            /* Inform PGM. */
    49895113            if (pCtx->cr0 & X86_CR0_PG)
     
    50375161             * Change it.
    50385162             */
    5039 #ifndef IEM_VERIFICATION_MODE
     5163#if !defined(IEM_VERIFICATION_MODE) || defined(IEM_VERIFICATION_MODE_NO_REM)
    50405164            rc = CPUMSetGuestCR4(pVCpu, NewCrX);
    50415165            AssertRCSuccessReturn(rc, rc);
     
    50485172             * Notify SELM and PGM.
    50495173             */
    5050 #ifndef IEM_VERIFICATION_MODE
     5174#if !defined(IEM_VERIFICATION_MODE) || defined(IEM_VERIFICATION_MODE_NO_REM)
    50515175            /* SELM - VME may change things wrt to the TSS shadowing. */
    50525176            if ((NewCrX ^ OldCrX) & X86_CR4_VME)
     
    50735197         */
    50745198        case 8:
    5075 #ifndef IEM_VERIFICATION_MODE
     5199#if !defined(IEM_VERIFICATION_MODE) || defined(IEM_VERIFICATION_MODE_NO_REM)
    50765200            AssertFailedReturn(VERR_NOT_IMPLEMENTED); /** @todo implement CR8 reading and writing. */
    50775201#else
     
    51145238     */
    51155239    uint32_t u32Value;
    5116 #ifndef IEM_VERIFICATION_MODE
     5240#if !defined(IEM_VERIFICATION_MODE) || defined(IEM_VERIFICATION_MODE_NO_REM)
    51175241    rcStrict = IOMIOPortRead(IEMCPU_TO_VM(pIemCpu), u16Port, &u32Value, cbReg);
    51185242#else
    5119     u32Value = 0xffffffff;
    5120     rcStrict = VINF_SUCCESS;
    5121     pIemCpu->cIOReads++;
     5243    rcStrict = iemVerifyFakeIOPortRead(pIemCpu, u16Port, &u32Value, cbReg);
    51225244#endif
    51235245    if (IOM_SUCCESS(rcStrict))
     
    51815303        default: AssertFailedReturn(VERR_INTERNAL_ERROR_3);
    51825304    }
    5183 #ifndef IEM_VERIFICATION_MODE
     5305# if !defined(IEM_VERIFICATION_MODE) || defined(IEM_VERIFICATION_MODE_NO_REM)
    51845306    VBOXSTRICTRC rc = IOMIOPortWrite(IEMCPU_TO_VM(pIemCpu), u16Port, u32Value, cbReg);
    5185 #else
    5186     VBOXSTRICTRC rc = VINF_SUCCESS;
    5187     pIemCpu->cIOWrites++;
    5188 #endif
     5307# else
     5308    VBOXSTRICTRC rc = iemVerifyFakeIOPortWrite(pIemCpu, u16Port, u32Value, cbReg);
     5309# endif
    51895310    if (IOM_SUCCESS(rc))
    51905311    {
     
    53695490    uint32_t a_Name; \
    53705491    uint32_t *a_pName = &a_Name
    5371 #define IEM_MC_COMMIT_EFLAGS(a_EFlags)                  (pIemCpu)->CTX_SUFF(pCtx)->eflags.u = (a_EFlags)
     5492#define IEM_MC_COMMIT_EFLAGS(a_EFlags) \
     5493   do { (pIemCpu)->CTX_SUFF(pCtx)->eflags.u = (a_EFlags); Assert((pIemCpu)->CTX_SUFF(pCtx)->eflags.u & X86_EFL_1); } while (0)
    53725494
    53735495#define IEM_MC_ASSIGN(a_VarOrArg, a_CVariableOrConst)   (a_VarOrArg) = (a_CVariableOrConst)
     
    55655687
    55665688/**
     5689 * Defers the rest of the instruction emulation to a C implementation routine
     5690 * and returns, taking two arguments in addition to the standard ones.
     5691 *
     5692 * @param   a_pfnCImpl      The pointer to the C routine.
     5693 * @param   a0              The first extra argument.
     5694 * @param   a1              The second extra argument.
     5695 * @param   a2              The third extra argument.
     5696 * @param   a3              The fourth extra argument.
     5697 * @param   a4              The fifth extra argument.
     5698 */
     5699#define IEM_MC_CALL_CIMPL_5(a_pfnCImpl, a0, a1, a2, a3, a4) return (a_pfnCImpl)(pIemCpu, pIemCpu->offOpcode, a0, a1, a2, a3, a4)
     5700
     5701/**
    55675702 * Defers the entire instruction emulation to a C implementation routine and
    55685703 * returns, only taking the standard parameters.
     
    56295764            && !(pIemCpu->CTX_SUFF(pCtx)->eflags.u & a_fBit)) {
    56305765#define IEM_MC_IF_LOCAL_IS_Z(a_Local)                   if ((a_Local) == 0) {
     5766#define IEM_MC_IF_GREG_BIT_SET(a_iGReg, a_iBitNo)       if (*(uint64_t *)iemGRegRef(pIemCpu, (a_iGReg)) & RT_BIT_64(a_iBitNo)) {
    56315767#define IEM_MC_ELSE()                                   } else {
    56325768#define IEM_MC_ENDIF()                                  } do {} while (0)
     
    59986134static void iemExecVerificationModeSetup(PIEMCPU pIemCpu)
    59996135{
     6136    PCPUMCTX pOrgCtx = pIemCpu->CTX_SUFF(pCtx);
     6137
     6138# ifndef IEM_VERIFICATION_MODE_NO_REM
    60006139    /*
    60016140     * Switch state.
     
    60036142    static CPUMCTX  s_DebugCtx; /* Ugly! */
    60046143
    6005     PCPUMCTX pOrgCtx = pIemCpu->CTX_SUFF(pCtx);
    60066144    s_DebugCtx = *pOrgCtx;
    60076145    pIemCpu->CTX_SUFF(pCtx) = &s_DebugCtx;
     6146# endif
    60086147
    60096148    /*
     
    60276166    pIemCpu->fMulDivHack = false;
    60286167    pIemCpu->fShlHack    = false;
    6029 }
     6168
     6169    /*
     6170     * Free all verification records.
     6171     */
     6172    PIEMVERIFYEVTREC pEvtRec = pIemCpu->pIemEvtRecHead;
     6173    pIemCpu->pIemEvtRecHead = NULL;
     6174    pIemCpu->ppIemEvtRecNext = &pIemCpu->pIemEvtRecHead;
     6175    do
     6176    {
     6177        while (pEvtRec)
     6178        {
     6179            PIEMVERIFYEVTREC pNext = pEvtRec->pNext;
     6180            pEvtRec->pNext = pIemCpu->pFreeEvtRec;
     6181            pIemCpu->pFreeEvtRec = pEvtRec;
     6182            pEvtRec = pNext;
     6183        }
     6184        pEvtRec = pIemCpu->pOtherEvtRecHead;
     6185        pIemCpu->pOtherEvtRecHead = NULL;
     6186        pIemCpu->ppOtherEvtRecNext = &pIemCpu->pOtherEvtRecHead;
     6187    } while (pEvtRec);
     6188}
     6189
     6190/**
     6191 * Allocate an event record.
     6192 * @returns Poitner to a record.
     6193 */
     6194static PIEMVERIFYEVTREC iemVerifyAllocRecord(PIEMCPU pIemCpu)
     6195{
     6196    PIEMVERIFYEVTREC pEvtRec = pIemCpu->pFreeEvtRec;
     6197    if (pEvtRec)
     6198        pIemCpu->pFreeEvtRec = pEvtRec->pNext;
     6199    else
     6200    {
     6201        if (!pIemCpu->ppIemEvtRecNext)
     6202            return NULL; /* Too early (fake PCIBIOS), ignore notification. */
     6203
     6204        pEvtRec = (PIEMVERIFYEVTREC)MMR3HeapAlloc(IEMCPU_TO_VM(pIemCpu), MM_TAG_EM /* lazy bird*/, sizeof(*pEvtRec));
     6205        if (!pEvtRec)
     6206            return NULL;
     6207    }
     6208    pEvtRec->enmEvent = IEMVERIFYEVENT_INVALID;
     6209    pEvtRec->pNext    = NULL;
     6210    return pEvtRec;
     6211}
     6212
     6213
     6214/**
     6215 * IOMMMIORead notification.
     6216 */
     6217VMM_INT_DECL(void)   IEMNotifyMMIORead(PVM pVM, RTGCPHYS GCPhys, size_t cbValue)
     6218{
     6219# ifndef IEM_VERIFICATION_MODE_NO_REM
     6220    PVMCPU              pVCpu = VMMGetCpu(pVM);
     6221    if (!pVCpu)
     6222        return;
     6223    PIEMCPU             pIemCpu = &pVCpu->iem.s;
     6224    PIEMVERIFYEVTREC    pEvtRec = iemVerifyAllocRecord(pIemCpu);
     6225    if (!pEvtRec)
     6226        return;
     6227    pEvtRec->enmEvent = IEMVERIFYEVENT_RAM_READ;
     6228    pEvtRec->u.RamRead.GCPhys  = GCPhys;
     6229    pEvtRec->u.RamRead.cb      = cbValue;
     6230    pEvtRec->pNext = *pIemCpu->ppOtherEvtRecNext;
     6231    *pIemCpu->ppOtherEvtRecNext = pEvtRec;
     6232# endif
     6233}
     6234
     6235
     6236/**
     6237 * IOMMMIOWrite notification.
     6238 */
     6239VMM_INT_DECL(void)   IEMNotifyMMIOWrite(PVM pVM, RTGCPHYS GCPhys, uint32_t u32Value, size_t cbValue)
     6240{
     6241# ifndef IEM_VERIFICATION_MODE_NO_REM
     6242    PVMCPU              pVCpu = VMMGetCpu(pVM);
     6243    if (!pVCpu)
     6244        return;
     6245    PIEMCPU             pIemCpu = &pVCpu->iem.s;
     6246    PIEMVERIFYEVTREC    pEvtRec = iemVerifyAllocRecord(pIemCpu);
     6247    if (!pEvtRec)
     6248        return;
     6249    pEvtRec->enmEvent = IEMVERIFYEVENT_RAM_WRITE;
     6250    pEvtRec->u.RamWrite.GCPhys   = GCPhys;
     6251    pEvtRec->u.RamWrite.cb       = cbValue;
     6252    pEvtRec->u.RamWrite.ab[0]    = RT_BYTE1(u32Value);
     6253    pEvtRec->u.RamWrite.ab[1]    = RT_BYTE2(u32Value);
     6254    pEvtRec->u.RamWrite.ab[2]    = RT_BYTE3(u32Value);
     6255    pEvtRec->u.RamWrite.ab[3]    = RT_BYTE4(u32Value);
     6256    pEvtRec->pNext = *pIemCpu->ppOtherEvtRecNext;
     6257    *pIemCpu->ppOtherEvtRecNext = pEvtRec;
     6258# endif
     6259}
     6260
     6261
     6262/**
     6263 * IOMIOPortRead notification.
     6264 */
     6265VMM_INT_DECL(void)   IEMNotifyIOPortRead(PVM pVM, RTIOPORT Port, size_t cbValue)
     6266{
     6267# ifndef IEM_VERIFICATION_MODE_NO_REM
     6268    PVMCPU              pVCpu = VMMGetCpu(pVM);
     6269    if (!pVCpu)
     6270        return;
     6271    PIEMCPU             pIemCpu = &pVCpu->iem.s;
     6272    PIEMVERIFYEVTREC    pEvtRec = iemVerifyAllocRecord(pIemCpu);
     6273    if (!pEvtRec)
     6274        return;
     6275    pEvtRec->enmEvent = IEMVERIFYEVENT_IOPORT_READ;
     6276    pEvtRec->u.IOPortRead.Port    = Port;
     6277    pEvtRec->u.IOPortRead.cbValue = cbValue;
     6278    pEvtRec->pNext = *pIemCpu->ppOtherEvtRecNext;
     6279    *pIemCpu->ppOtherEvtRecNext = pEvtRec;
     6280# endif
     6281}
     6282
     6283/**
     6284 * IOMIOPortWrite notification.
     6285 */
     6286VMM_INT_DECL(void)   IEMNotifyIOPortWrite(PVM pVM, RTIOPORT Port, uint32_t u32Value, size_t cbValue)
     6287{
     6288# ifndef IEM_VERIFICATION_MODE_NO_REM
     6289    PVMCPU              pVCpu = VMMGetCpu(pVM);
     6290    if (!pVCpu)
     6291        return;
     6292    PIEMCPU             pIemCpu = &pVCpu->iem.s;
     6293    PIEMVERIFYEVTREC    pEvtRec = iemVerifyAllocRecord(pIemCpu);
     6294    if (!pEvtRec)
     6295        return;
     6296    pEvtRec->enmEvent = IEMVERIFYEVENT_IOPORT_WRITE;
     6297    pEvtRec->u.IOPortWrite.Port     = Port;
     6298    pEvtRec->u.IOPortWrite.cbValue  = cbValue;
     6299    pEvtRec->u.IOPortWrite.u32Value = u32Value;
     6300    pEvtRec->pNext = *pIemCpu->ppOtherEvtRecNext;
     6301    *pIemCpu->ppOtherEvtRecNext = pEvtRec;
     6302# endif
     6303}
     6304
     6305
     6306VMM_INT_DECL(void)   IEMNotifyIOPortReadString(PVM pVM, RTIOPORT Port, RTGCPTR GCPtrDst, RTGCUINTREG cTransfers, size_t cbValue)
     6307{
     6308    AssertFailed();
     6309}
     6310
     6311
     6312VMM_INT_DECL(void)   IEMNotifyIOPortWriteString(PVM pVM, RTIOPORT Port, RTGCPTR GCPtrSrc, RTGCUINTREG cTransfers, size_t cbValue)
     6313{
     6314    AssertFailed();
     6315}
     6316
     6317
     6318/**
     6319 * Fakes and records an I/O port read.
     6320 *
     6321 * @returns VINF_SUCCESS.
     6322 * @param   pIemCpu             The IEM per CPU data.
     6323 * @param   Port                The I/O port.
     6324 * @param   pu32Value           Where to store the fake value.
     6325 * @param   cbValue             The size of the access.
     6326 */
     6327static VBOXSTRICTRC iemVerifyFakeIOPortRead(PIEMCPU pIemCpu, RTIOPORT Port, uint32_t *pu32Value, size_t cbValue)
     6328{
     6329    PIEMVERIFYEVTREC pEvtRec = iemVerifyAllocRecord(pIemCpu);
     6330    if (pEvtRec)
     6331    {
     6332        pEvtRec->enmEvent = IEMVERIFYEVENT_IOPORT_READ;
     6333        pEvtRec->u.IOPortRead.Port    = Port;
     6334        pEvtRec->u.IOPortRead.cbValue = cbValue;
     6335        pEvtRec->pNext = *pIemCpu->ppIemEvtRecNext;
     6336        *pIemCpu->ppIemEvtRecNext = pEvtRec;
     6337    }
     6338    pIemCpu->cIOReads++;
     6339    *pu32Value = 0xffffffff;
     6340    return VINF_SUCCESS;
     6341}
     6342
     6343
     6344/**
     6345 * Fakes and records an I/O port write.
     6346 *
     6347 * @returns VINF_SUCCESS.
     6348 * @param   pIemCpu             The IEM per CPU data.
     6349 * @param   Port                The I/O port.
     6350 * @param   u32Value            The value being written.
     6351 * @param   cbValue             The size of the access.
     6352 */
     6353static VBOXSTRICTRC iemVerifyFakeIOPortWrite(PIEMCPU pIemCpu, RTIOPORT Port, uint32_t u32Value, size_t cbValue)
     6354{
     6355    PIEMVERIFYEVTREC pEvtRec = iemVerifyAllocRecord(pIemCpu);
     6356    if (pEvtRec)
     6357    {
     6358        pEvtRec->enmEvent = IEMVERIFYEVENT_IOPORT_WRITE;
     6359        pEvtRec->u.IOPortWrite.Port     = Port;
     6360        pEvtRec->u.IOPortWrite.cbValue  = cbValue;
     6361        pEvtRec->u.IOPortWrite.u32Value = u32Value;
     6362        pEvtRec->pNext = *pIemCpu->ppIemEvtRecNext;
     6363        *pIemCpu->ppIemEvtRecNext = pEvtRec;
     6364    }
     6365    pIemCpu->cIOWrites++;
     6366    return VINF_SUCCESS;
     6367}
     6368
     6369
     6370/**
     6371 * Used by iemVerifyAssertRecord and iemVerifyAssertRecords to add a record
     6372 * dump to the assertion info.
     6373 *
     6374 * @param   pEvtRec         The record to dump.
     6375 */
     6376static void iemVerifyAssertAddRecordDump(PIEMVERIFYEVTREC pEvtRec)
     6377{
     6378    switch (pEvtRec->enmEvent)
     6379    {
     6380        case IEMVERIFYEVENT_IOPORT_READ:
     6381            RTAssertMsg2Add("I/O PORT READ from %#6x, %d bytes\n",
     6382                            pEvtRec->u.IOPortWrite.Port,
     6383                            pEvtRec->u.IOPortWrite.cbValue);
     6384            break;
     6385        case IEMVERIFYEVENT_IOPORT_WRITE:
     6386            RTAssertMsg2Add("I/O PORT WRITE  to %#6x, %d bytes, value %#x\n",
     6387                            pEvtRec->u.IOPortWrite.Port,
     6388                            pEvtRec->u.IOPortWrite.cbValue,
     6389                            pEvtRec->u.IOPortWrite.u32Value);
     6390            break;
     6391        case IEMVERIFYEVENT_RAM_READ:
     6392            RTAssertMsg2Add("RAM READ  at %RGp, %#4zx bytes\n",
     6393                            pEvtRec->u.RamRead.GCPhys,
     6394                            pEvtRec->u.RamRead.cb);
     6395            break;
     6396        case IEMVERIFYEVENT_RAM_WRITE:
     6397            RTAssertMsg2Add("RAM WRITE at %RGp, %#4zx bytes: %.*RHxs\n",
     6398                            pEvtRec->u.RamWrite.GCPhys,
     6399                            pEvtRec->u.RamWrite.cb,
     6400                            (int)pEvtRec->u.RamWrite.cb,
     6401                            pEvtRec->u.RamWrite.ab);
     6402            break;
     6403        default:
     6404            AssertMsgFailed(("Invalid event type %d\n", pEvtRec->enmEvent));
     6405            break;
     6406    }
     6407}
     6408
     6409
     6410/**
     6411 * Raises an assertion on the specified record, showing the given message with
     6412 * a record dump attached.
     6413 *
     6414 * @param   pEvtRec1        The first record.
     6415 * @param   pEvtRec2        The second record.
     6416 * @param   pszMsg          The message explaining why we're asserting.
     6417 */
     6418static void iemVerifyAssertRecords(PIEMVERIFYEVTREC pEvtRec1, PIEMVERIFYEVTREC pEvtRec2, const char *pszMsg)
     6419{
     6420    RTAssertMsg1(pszMsg, __LINE__, __FILE__, __PRETTY_FUNCTION__);
     6421    iemVerifyAssertAddRecordDump(pEvtRec1);
     6422    iemVerifyAssertAddRecordDump(pEvtRec2);
     6423    RTAssertPanic();
     6424}
     6425
     6426
     6427/**
     6428 * Raises an assertion on the specified record, showing the given message with
     6429 * a record dump attached.
     6430 *
     6431 * @param   pEvtRec1        The first record.
     6432 * @param   pszMsg          The message explaining why we're asserting.
     6433 */
     6434static void iemVerifyAssertRecord(PIEMVERIFYEVTREC pEvtRec, const char *pszMsg)
     6435{
     6436    RTAssertMsg1(pszMsg, __LINE__, __FILE__, __PRETTY_FUNCTION__);
     6437    iemVerifyAssertAddRecordDump(pEvtRec);
     6438    RTAssertPanic();
     6439}
     6440
    60306441
    60316442/**
     
    60346445static void iemExecVerificationModeCheck(PIEMCPU pIemCpu)
    60356446{
     6447# if defined(IEM_VERIFICATION_MODE) && !defined(IEM_VERIFICATION_MODE_NO_REM)
     6448    /*
     6449     * Switch back the state.
     6450     */
    60366451    PCPUMCTX    pOrgCtx   = CPUMQueryGuestCtxPtr(IEMCPU_TO_VMCPU(pIemCpu));
    60376452    PCPUMCTX    pDebugCtx = pIemCpu->CTX_SUFF(pCtx);
     
    60396454    pIemCpu->CTX_SUFF(pCtx) = pOrgCtx;
    60406455
     6456    /*
     6457     * Execute the instruction in REM.
     6458     */
    60416459    int rc = REMR3EmulateInstruction(IEMCPU_TO_VM(pIemCpu), IEMCPU_TO_VMCPU(pIemCpu));
    60426460    AssertRC(rc);
    6043 
     6461#if 0
     6462    if (pIemCpu->fPrefixes & (IEM_OP_PRF_REPNZ | IEM_OP_PRF_REPZ))
     6463    {
     6464        while (    pOrgCtx->rip == pDebugCtx->rip - pIemCpu->offOpcode
     6465               &&  pOrgCtx->rcx != pDebugCtx->rcx
     6466               &&  pOrgCtx->rsi != pDebugCtx->rsi
     6467               &&  pOrgCtx->rdi != pDebugCtx->rdi)
     6468        {
     6469            rc = REMR3EmulateInstruction(IEMCPU_TO_VM(pIemCpu), IEMCPU_TO_VMCPU(pIemCpu));
     6470            AssertRC(rc);
     6471        }
     6472    }
     6473#endif
     6474
     6475    /*
     6476     * Compare the register states.
     6477     */
     6478    unsigned cDiffs = 0;
    60446479    if (memcmp(pOrgCtx, pDebugCtx, sizeof(*pDebugCtx)))
    60456480    {
    60466481        Log(("REM and IEM ends up with different registers!\n"));
    6047         unsigned cDiffs = 0;
    6048 
    6049 # define CHECK_FIELD(a_Field) \
     6482
     6483#  define CHECK_FIELD(a_Field) \
    60506484        do \
    60516485        { \
     
    60646498        } while (0)
    60656499
    6066 # define CHECK_BIT_FIELD(a_Field) \
     6500#  define CHECK_BIT_FIELD(a_Field) \
    60676501        do \
    60686502        { \
     
    60876521        uint32_t fFlagsMask = UINT32_MAX;
    60886522        if (pIemCpu->fMulDivHack)
    6089             fFlagsMask &= ~(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF);
     6523            fFlagsMask &= ~(X86_EFL_SF | X86_EFL_ZF | X86_EFL_AF | X86_EFL_PF | X86_EFL_CF);
    60906524        if (pIemCpu->fShlHack)
    60916525            fFlagsMask &= ~(X86_EFL_OF);
     
    60946528            RTAssertMsg2Weak("  rflags differs - iem=%08llx rem=%08llx\n", pDebugCtx->rflags.u, pOrgCtx->rflags.u);
    60956529            CHECK_BIT_FIELD(rflags.Bits.u1CF);
    6096             /*CHECK_BIT_FIELD(rflags.Bits.u1Reserved0); */ /** @todo why does REM set this? */
     6530            CHECK_BIT_FIELD(rflags.Bits.u1Reserved0);
    60976531            CHECK_BIT_FIELD(rflags.Bits.u1PF);
    60986532            CHECK_BIT_FIELD(rflags.Bits.u1Reserved1);
     
    61906624        if (cDiffs != 0)
    61916625            AssertFailed();
    6192 # undef CHECK_FIELD
     6626#  undef CHECK_FIELD
     6627#  undef CHECK_BIT_FIELD
     6628    }
     6629
     6630    /*
     6631     * If the register state compared fine, check the verification event
     6632     * records.
     6633     */
     6634    if (cDiffs == 0)
     6635    {
     6636        /*
     6637         * Compare verficiation event records.
     6638         *  - I/O port accesses should be a 1:1 match.
     6639         */
     6640        PIEMVERIFYEVTREC pIemRec   = pIemCpu->pIemEvtRecHead;
     6641        PIEMVERIFYEVTREC pOtherRec = pIemCpu->pOtherEvtRecHead;
     6642        while (pIemRec && pOtherRec)
     6643        {
     6644            /* Since we might miss RAM writes and reads, ignore extra ones
     6645               made by IEM.  */
     6646            while (   IEMVERIFYEVENT_IS_RAM(pIemRec->enmEvent)
     6647                   && !IEMVERIFYEVENT_IS_RAM(pOtherRec->enmEvent)
     6648                   && pIemRec->pNext)
     6649                pIemRec = pIemRec->pNext;
     6650
     6651            /* Do the compare. */
     6652            if (pIemRec->enmEvent != pOtherRec->enmEvent)
     6653            {
     6654                iemVerifyAssertRecords(pIemRec, pOtherRec, "Type mismatches");
     6655                break;
     6656            }
     6657            bool fEquals;
     6658            switch (pIemRec->enmEvent)
     6659            {
     6660                case IEMVERIFYEVENT_IOPORT_READ:
     6661                    fEquals = pIemRec->u.IOPortRead.Port        == pOtherRec->u.IOPortRead.Port
     6662                           && pIemRec->u.IOPortRead.cbValue     == pOtherRec->u.IOPortRead.cbValue;
     6663                    break;
     6664                case IEMVERIFYEVENT_IOPORT_WRITE:
     6665                    fEquals = pIemRec->u.IOPortWrite.Port       == pOtherRec->u.IOPortWrite.Port
     6666                           && pIemRec->u.IOPortWrite.cbValue    == pOtherRec->u.IOPortWrite.cbValue
     6667                           && pIemRec->u.IOPortWrite.u32Value   == pOtherRec->u.IOPortWrite.u32Value;
     6668                    break;
     6669                case IEMVERIFYEVENT_RAM_READ:
     6670                    fEquals = pIemRec->u.RamRead.GCPhys         == pOtherRec->u.RamRead.GCPhys
     6671                           && pIemRec->u.RamRead.cb             == pOtherRec->u.RamRead.cb;
     6672                    break;
     6673                case IEMVERIFYEVENT_RAM_WRITE:
     6674                    fEquals = pIemRec->u.RamWrite.GCPhys        == pOtherRec->u.RamWrite.GCPhys
     6675                           && pIemRec->u.RamWrite.cb            == pOtherRec->u.RamWrite.cb
     6676                           && !memcmp(pIemRec->u.RamWrite.ab, pOtherRec->u.RamWrite.ab, pIemRec->u.RamWrite.cb);
     6677                    break;
     6678                default:
     6679                    fEquals = false;
     6680                    break;
     6681            }
     6682            if (!fEquals)
     6683            {
     6684                iemVerifyAssertRecords(pIemRec, pOtherRec, "Mismatch");
     6685                break;
     6686            }
     6687
     6688            /* advance */
     6689            pIemRec   = pIemRec->pNext;
     6690            pOtherRec = pOtherRec->pNext;
     6691        }
     6692
     6693        /* Ignore extra writes and reads. */
     6694        while (pIemRec && IEMVERIFYEVENT_IS_RAM(pIemRec->enmEvent))
     6695            pIemRec = pIemRec->pNext;
     6696        if (pIemRec != NULL)
     6697            iemVerifyAssertRecord(pIemRec, "Extra IEM record!");
     6698        else if (pOtherRec != NULL)
     6699            iemVerifyAssertRecord(pIemRec, "Extra Other record!");
    61936700    }
    61946701    pIemCpu->CTX_SUFF(pCtx) = pOrgCtx;
     6702# endif
    61956703}
    61966704
     
    62616769                pIemCpu->cInstructions++;
    62626770        }
     6771        EMSetInhibitInterruptsPC(pVCpu, UINT64_C(0x7777555533331111));
    62636772    }
    62646773
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImplStrInstr.cpp.h

    r36768 r36794  
    297297
    298298
     299/**
     300 * Implements 'REP LODS'.
     301 */
     302IEM_CIMPL_DEF_1(RT_CONCAT4(iemCImpl_lods_,OP_rAX,_m,ADDR_SIZE), int8_t, iEffSeg)
     303{
     304    PCPUMCTX pCtx = pIemCpu->CTX_SUFF(pCtx);
     305
     306    /*
     307     * Setup.
     308     */
     309    ADDR_TYPE       uCounterReg = pCtx->ADDR_rCX;
     310    if (uCounterReg == 0)
     311        return VINF_SUCCESS;
     312
     313    PCCPUMSELREGHID pSrcHid = iemSRegGetHid(pIemCpu, iEffSeg);
     314    VBOXSTRICTRC rcStrict = iemMemSegCheckReadAccessEx(pIemCpu, pSrcHid, iEffSeg);
     315    if (rcStrict != VINF_SUCCESS)
     316        return rcStrict;
     317
     318    int8_t const    cbIncr      = pCtx->eflags.Bits.u1DF ? -(OP_SIZE / 8) : (OP_SIZE / 8);
     319    OP_TYPE         uValueReg   = pCtx->OP_rAX;
     320    ADDR_TYPE       uAddrReg    = pCtx->ADDR_rSI;
     321
     322    /*
     323     * The loop.
     324     */
     325    do
     326    {
     327        /*
     328         * Do segmentation and virtual page stuff.
     329         */
     330#if ADDR_SIZE != 64
     331        ADDR2_TYPE  uVirtAddr = (uint32_t)pSrcHid->u64Base + uAddrReg;
     332#else
     333        uint64_t    uVirtAddr = uAddrReg;
     334#endif
     335        uint32_t    cLeftPage = (PAGE_SIZE - (uVirtAddr & PAGE_OFFSET_MASK)) / (OP_SIZE / 8);
     336        if (cLeftPage > uCounterReg)
     337            cLeftPage = uCounterReg;
     338        if (   cLeftPage > 0 /* can be null if unaligned, do one fallback round. */
     339            && cbIncr > 0    /** @todo Implement reverse direction string ops. */
     340#if ADDR_SIZE != 64
     341            && uAddrReg < pSrcHid->u32Limit
     342            && uAddrReg + (cLeftPage * (OP_SIZE / 8)) <= pSrcHid->u32Limit
     343#endif
     344           )
     345        {
     346            RTGCPHYS GCPhysMem;
     347            rcStrict = iemMemPageTranslateAndCheckAccess(pIemCpu, uVirtAddr, IEM_ACCESS_DATA_R, &GCPhysMem);
     348            if (rcStrict != VINF_SUCCESS)
     349                break;
     350
     351            /*
     352             * If we can map the page without trouble, we can get away with
     353             * just reading the last value on the page.
     354             */
     355            OP_TYPE const *puMem;
     356            rcStrict = iemMemPageMap(pIemCpu, GCPhysMem, IEM_ACCESS_DATA_R, (void **)&puMem);
     357            if (rcStrict == VINF_SUCCESS)
     358            {
     359                /* Only get the last byte, the rest doesn't matter in direct access mode. */
     360                uValueReg = puMem[cLeftPage - 1];
     361
     362                /* Update the regs. */
     363                uCounterReg -= cLeftPage;
     364                uAddrReg    += cLeftPage * cbIncr;
     365
     366                /* If unaligned, we drop thru and do the page crossing access
     367                   below. Otherwise, do the next page. */
     368                if (!(uVirtAddr & (OP_SIZE - 1)))
     369                    continue;
     370                if (uCounterReg == 0)
     371                    break;
     372                cLeftPage = 0;
     373            }
     374        }
     375
     376        /*
     377         * Fallback - slow processing till the end of the current page.
     378         * In the cross page boundrary case we will end up here with cLeftPage
     379         * as 0, we execute one loop then.
     380         */
     381        do
     382        {
     383            OP_TYPE uTmpValue;
     384            rcStrict = RT_CONCAT(iemMemFetchDataU,OP_SIZE)(pIemCpu, &uTmpValue, iEffSeg, uAddrReg);
     385            if (rcStrict != VINF_SUCCESS)
     386                break;
     387            uValueReg = uTmpValue;
     388            uAddrReg += cbIncr;
     389            uCounterReg--;
     390            cLeftPage--;
     391        } while ((int32_t)cLeftPage > 0);
     392        if (rcStrict != VINF_SUCCESS)
     393            break;
     394    } while (uCounterReg != 0);
     395
     396    /*
     397     * Update the registers.
     398     */
     399    pCtx->ADDR_rCX = uCounterReg;
     400    pCtx->ADDR_rDI = uAddrReg;
     401#if OP_SIZE == 32
     402    pCtx->rax     = uValueReg;
     403#else
     404    pCtx->OP_rAX  = uValueReg;
     405#endif
     406    if (rcStrict == VINF_SUCCESS)
     407        iemRegAddToRip(pIemCpu, cbInstr);
     408
     409    return rcStrict;
     410}
     411
     412
    299413#if OP_SIZE != 64
    300414
     
    323437
    324438    uint32_t        u32Value;
     439# if !defined(IEM_VERIFICATION_MODE) || defined(IEM_VERIFICATION_MODE_NO_REM)
    325440    rcStrict = IOMIOPortRead(pVM, pCtx->dx, &u32Value, OP_SIZE / 8);
     441# else
     442    iemVerifyFakeIOPortRead(pIemCpu, pCtx->dx, &u32Value, OP_SIZE / 8);
     443# endif
    326444    if (IOM_SUCCESS(rcStrict))
    327445    {
     
    344462    return rcStrict;
    345463}
     464
    346465
    347466/**
     
    417536                {
    418537                    uint32_t u32Value;
     538# if !defined(IEM_VERIFICATION_MODE) || defined(IEM_VERIFICATION_MODE_NO_REM)
    419539                    rcStrict = IOMIOPortRead(pVM, u16Port, &u32Value, OP_SIZE / 8);
     540# else
     541                    rcStrict = iemVerifyFakeIOPortRead(pIemCpu, u16Port, &u32Value, OP_SIZE / 8);
     542# endif
    420543                    if (!IOM_SUCCESS(rcStrict))
    421544                        break;
     
    461584
    462585            uint32_t u32Value;
     586# if !defined(IEM_VERIFICATION_MODE) || defined(IEM_VERIFICATION_MODE_NO_REM)
    463587            rcStrict = IOMIOPortRead(pVM, u16Port, &u32Value, OP_SIZE / 8);
     588# else
     589            rcStrict = iemVerifyFakeIOPortRead(pIemCpu, u16Port, &u32Value, OP_SIZE / 8);
     590# endif
    464591            if (!IOM_SUCCESS(rcStrict))
    465592                break;
     
    496623 * Implements 'OUTS' (no rep)
    497624 */
    498 IEM_CIMPL_DEF_0(RT_CONCAT4(iemCImpl_outs_op,OP_SIZE,_addr,ADDR_SIZE))
     625IEM_CIMPL_DEF_1(RT_CONCAT4(iemCImpl_outs_op,OP_SIZE,_addr,ADDR_SIZE), uint8_t, iEffSeg)
    499626{
    500627    PVM             pVM  = IEMCPU_TO_VM(pIemCpu);
     
    512639
    513640    OP_TYPE uValue;
    514     rcStrict = RT_CONCAT(iemMemFetchDataU,OP_SIZE)(pIemCpu, &uValue, X86_SREG_ES, pCtx->ADDR_rDI);
     641    rcStrict = RT_CONCAT(iemMemFetchDataU,OP_SIZE)(pIemCpu, &uValue, iEffSeg, pCtx->ADDR_rSI);
    515642    if (rcStrict == VINF_SUCCESS)
    516643    {
     644# if !defined(IEM_VERIFICATION_MODE) || defined(IEM_VERIFICATION_MODE_NO_REM)
    517645        rcStrict = IOMIOPortWrite(pVM, pCtx->dx, uValue, OP_SIZE / 8);
     646# else
     647        rcStrict = iemVerifyFakeIOPortWrite(pIemCpu, pCtx->dx, uValue, OP_SIZE / 8);
     648# endif
    518649        if (IOM_SUCCESS(rcStrict))
    519650        {
    520651            if (!pCtx->eflags.Bits.u1DF)
    521                 pCtx->ADDR_rDI += OP_SIZE / 8;
     652                pCtx->ADDR_rSI += OP_SIZE / 8;
    522653            else
    523                 pCtx->ADDR_rDI -= OP_SIZE / 8;
     654                pCtx->ADDR_rSI -= OP_SIZE / 8;
    524655            iemRegAddToRip(pIemCpu, cbInstr);
    525656            /** @todo massage IOM status codes. */
     
    529660}
    530661
     662
    531663/**
    532664 * Implements 'REP OUTS'.
    533665 */
    534 IEM_CIMPL_DEF_0(RT_CONCAT4(iemCImpl_rep_outs_op,OP_SIZE,_addr,ADDR_SIZE))
     666IEM_CIMPL_DEF_1(RT_CONCAT4(iemCImpl_rep_outs_op,OP_SIZE,_addr,ADDR_SIZE), uint8_t, iEffSeg)
    535667{
    536668    PVM         pVM  = IEMCPU_TO_VM(pIemCpu);
     
    549681        return VINF_SUCCESS;
    550682
    551     rcStrict = iemMemSegCheckReadAccessEx(pIemCpu, &pCtx->esHid, X86_SREG_ES);
     683    PCCPUMSELREGHID pHid = iemSRegGetHid(pIemCpu, iEffSeg);
     684    rcStrict = iemMemSegCheckReadAccessEx(pIemCpu, pHid, iEffSeg);
    552685    if (rcStrict != VINF_SUCCESS)
    553686        return rcStrict;
    554687
    555688    int8_t const    cbIncr      = pCtx->eflags.Bits.u1DF ? -(OP_SIZE / 8) : (OP_SIZE / 8);
    556     ADDR_TYPE       uAddrReg    = pCtx->ADDR_rDI;
     689    ADDR_TYPE       uAddrReg    = pCtx->ADDR_rSI;
    557690
    558691    /*
     
    565698         */
    566699#if ADDR_SIZE != 64
    567         ADDR2_TYPE  uVirtAddr = (uint32_t)pCtx->esHid.u64Base + uAddrReg;
     700        ADDR2_TYPE  uVirtAddr = (uint32_t)pHid->u64Base + uAddrReg;
    568701#else
    569702        uint64_t    uVirtAddr = uAddrReg;
     
    575708            && cbIncr > 0    /** @todo Implement reverse direction string ops. */
    576709#if ADDR_SIZE != 64
    577             && uAddrReg < pCtx->esHid.u32Limit
    578             && uAddrReg + (cLeftPage * (OP_SIZE / 8)) <= pCtx->esHid.u32Limit
     710            && uAddrReg < pHid->u32Limit
     711            && uAddrReg + (cLeftPage * (OP_SIZE / 8)) <= pHid->u32Limit
    579712#endif
    580713           )
     
    601734                {
    602735                    uint32_t u32Value = *puMem++;
     736# if !defined(IEM_VERIFICATION_MODE) || defined(IEM_VERIFICATION_MODE_NO_REM)
    603737                    rcStrict = IOMIOPortWrite(pVM, u16Port, u32Value, OP_SIZE / 8);
     738# else
     739                    rcStrict = iemVerifyFakeIOPortWrite(pIemCpu, u16Port, u32Value, OP_SIZE / 8);
     740# endif
    604741                    if (!IOM_SUCCESS(rcStrict))
    605742                        break;
     
    639776        {
    640777            OP_TYPE uValue;
    641             rcStrict = RT_CONCAT(iemMemFetchDataU,OP_SIZE)(pIemCpu, &uValue, X86_SREG_ES, uAddrReg);
    642             if (rcStrict != VINF_SUCCESS)
    643                 break;
    644 
     778            rcStrict = RT_CONCAT(iemMemFetchDataU,OP_SIZE)(pIemCpu, &uValue, iEffSeg, uAddrReg);
     779            if (rcStrict != VINF_SUCCESS)
     780                break;
     781
     782# if !defined(IEM_VERIFICATION_MODE) || defined(IEM_VERIFICATION_MODE_NO_REM)
    645783            rcStrict = IOMIOPortWrite(pVM, u16Port, uValue, OP_SIZE / 8);
     784# else
     785            rcStrict = iemVerifyFakeIOPortWrite(pIemCpu, u16Port, uValue, OP_SIZE / 8);
     786# endif
    646787            if (!IOM_SUCCESS(rcStrict))
    647788                break;
     
    664805     */
    665806    pCtx->ADDR_rCX = uCounterReg;
    666     pCtx->ADDR_rDI = uAddrReg;
     807    pCtx->ADDR_rSI = uAddrReg;
    667808    if (rcStrict == VINF_SUCCESS)
    668809        iemRegAddToRip(pIemCpu, cbInstr);
  • trunk/src/VBox/VMM/VMMAll/IEMAllInstructions.cpp.h

    r36780 r36794  
    17101710/** Opcode 0x0f 0xb1. */
    17111711FNIEMOP_STUB(iemOp_cmpxchg_Ev_Gv);
     1712
     1713
     1714FNIEMOP_DEF_1(iemOpCommonLoadSRegAndGreg, uint8_t, iSegReg)
     1715{
     1716    uint8_t bRm; IEM_OPCODE_GET_NEXT_BYTE(pIemCpu, &bRm);
     1717    IEMOP_HLP_NO_LOCK_PREFIX(); /** @todo should probably not be raised until we've fetched all the opcode bytes? */
     1718
     1719    /* The source cannot be a register. */
     1720    if ((bRm & X86_MODRM_MOD_MASK) == (3 << X86_MODRM_MOD_SHIFT))
     1721        return IEMOP_RAISE_INVALID_LOCK_PREFIX();
     1722    uint8_t const iGReg = ((bRm >> X86_MODRM_REG_SHIFT) & bRm & X86_MODRM_REG_SMASK) | pIemCpu->uRexReg;
     1723
     1724    switch (pIemCpu->enmEffOpSize)
     1725    {
     1726        case IEMMODE_16BIT:
     1727            IEM_MC_BEGIN(5, 1);
     1728            IEM_MC_ARG(uint16_t,        uSel,                                    0);
     1729            IEM_MC_ARG(uint16_t,        offSeg,                                  1);
     1730            IEM_MC_ARG_CONST(uint8_t,   iSegRegArg,/*=*/iSegReg,                 2);
     1731            IEM_MC_ARG_CONST(uint8_t,   iGRegArg,  /*=*/iGReg,                   3);
     1732            IEM_MC_ARG_CONST(IEMMODE,   enmEffOpSize,/*=*/pIemCpu->enmEffOpSize, 4);
     1733            IEM_MC_LOCAL(RTGCPTR,       GCPtrEff);
     1734            IEM_MC_CALC_RM_EFF_ADDR(GCPtrEff, bRm);
     1735            IEM_MC_FETCH_MEM_U16(offSeg, pIemCpu->iEffSeg, GCPtrEff);
     1736            IEM_MC_FETCH_MEM_U16(uSel,   pIemCpu->iEffSeg, GCPtrEff + 2);
     1737            IEM_MC_CALL_CIMPL_5(iemCImpl_load_SReg_Greg, uSel, offSeg, iSegRegArg, iGRegArg, enmEffOpSize);
     1738            IEM_MC_END();
     1739            return VINF_SUCCESS;
     1740
     1741        case IEMMODE_32BIT:
     1742            IEM_MC_BEGIN(5, 1);
     1743            IEM_MC_ARG(uint16_t,        uSel,                                    0);
     1744            IEM_MC_ARG(uint32_t,        offSeg,                                  1);
     1745            IEM_MC_ARG_CONST(uint8_t,   iSegRegArg,/*=*/iSegReg,                 2);
     1746            IEM_MC_ARG_CONST(uint8_t,   iGRegArg,  /*=*/iGReg,                   3);
     1747            IEM_MC_ARG_CONST(IEMMODE,   enmEffOpSize,/*=*/pIemCpu->enmEffOpSize, 4);
     1748            IEM_MC_LOCAL(RTGCPTR,       GCPtrEff);
     1749            IEM_MC_CALC_RM_EFF_ADDR(GCPtrEff, bRm);
     1750            IEM_MC_FETCH_MEM_U32(offSeg, pIemCpu->iEffSeg, GCPtrEff);
     1751            IEM_MC_FETCH_MEM_U16(uSel,   pIemCpu->iEffSeg, GCPtrEff + 4);
     1752            IEM_MC_CALL_CIMPL_5(iemCImpl_load_SReg_Greg, uSel, offSeg, iSegRegArg, iGRegArg, enmEffOpSize);
     1753            IEM_MC_END();
     1754            return VINF_SUCCESS;
     1755
     1756        case IEMMODE_64BIT:
     1757            IEM_MC_BEGIN(5, 1);
     1758            IEM_MC_ARG(uint16_t,        uSel,                                    0);
     1759            IEM_MC_ARG(uint64_t,        offSeg,                                  1);
     1760            IEM_MC_ARG_CONST(uint8_t,   iSegRegArg,/*=*/iSegReg,                 2);
     1761            IEM_MC_ARG_CONST(uint8_t,   iGRegArg,  /*=*/iGReg,                   3);
     1762            IEM_MC_ARG_CONST(IEMMODE,   enmEffOpSize,/*=*/pIemCpu->enmEffOpSize, 4);
     1763            IEM_MC_LOCAL(RTGCPTR,       GCPtrEff);
     1764            IEM_MC_CALC_RM_EFF_ADDR(GCPtrEff, bRm);
     1765            IEM_MC_FETCH_MEM_U64(offSeg, pIemCpu->iEffSeg, GCPtrEff);
     1766            IEM_MC_FETCH_MEM_U16(uSel,   pIemCpu->iEffSeg, GCPtrEff + 8);
     1767            IEM_MC_CALL_CIMPL_5(iemCImpl_load_SReg_Greg, uSel, offSeg, iSegRegArg, iGRegArg, enmEffOpSize);
     1768            IEM_MC_END();
     1769            return VINF_SUCCESS;
     1770
     1771        IEM_NOT_REACHED_DEFAULT_CASE_RET();
     1772    }
     1773}
     1774
     1775
    17121776/** Opcode 0x0f 0xb2. */
    1713 FNIEMOP_STUB(iemOp_lss_Gv_Mp);
     1777FNIEMOP_DEF(iemOp_lss_Gv_Mp)
     1778{
     1779    IEMOP_MNEMONIC("lss Gv,Mp");
     1780    return FNIEMOP_CALL_1(iemOpCommonLoadSRegAndGreg, X86_SREG_SS);
     1781}
     1782
     1783
    17141784/** Opcode 0x0f 0xb3. */
    17151785FNIEMOP_STUB(iemOp_btr_Ev_Gv);
     1786
     1787
    17161788/** Opcode 0x0f 0xb4. */
    1717 FNIEMOP_STUB(iemOp_lfs_Gv_Mp);
     1789FNIEMOP_DEF(iemOp_lfs_Gv_Mp)
     1790{
     1791    IEMOP_MNEMONIC("lfs Gv,Mp");
     1792    return FNIEMOP_CALL_1(iemOpCommonLoadSRegAndGreg, X86_SREG_FS);
     1793}
     1794
     1795
    17181796/** Opcode 0x0f 0xb5. */
    1719 FNIEMOP_STUB(iemOp_lgs_Gv_Mp);
     1797FNIEMOP_DEF(iemOp_lgs_Gv_Mp)
     1798{
     1799    IEMOP_MNEMONIC("lgs Gv,Mp");
     1800    return FNIEMOP_CALL_1(iemOpCommonLoadSRegAndGreg, X86_SREG_GS);
     1801}
    17201802
    17211803
     
    38173899        switch (pIemCpu->enmEffAddrMode)
    38183900        {
    3819             case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_rep_outs_op8_addr16);
    3820             case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_rep_outs_op8_addr32);
    3821             case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_rep_outs_op8_addr64);
     3901            case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_outs_op8_addr16, pIemCpu->iEffSeg);
     3902            case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_outs_op8_addr32, pIemCpu->iEffSeg);
     3903            case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_outs_op8_addr64, pIemCpu->iEffSeg);
    38223904            IEM_NOT_REACHED_DEFAULT_CASE_RET();
    38233905        }
     
    38283910        switch (pIemCpu->enmEffAddrMode)
    38293911        {
    3830             case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_outs_op8_addr16);
    3831             case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_outs_op8_addr32);
    3832             case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_outs_op8_addr64);
     3912            case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_outs_op8_addr16, pIemCpu->iEffSeg);
     3913            case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_outs_op8_addr32, pIemCpu->iEffSeg);
     3914            case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_outs_op8_addr64, pIemCpu->iEffSeg);
    38333915            IEM_NOT_REACHED_DEFAULT_CASE_RET();
    38343916        }
     
    38493931                switch (pIemCpu->enmEffAddrMode)
    38503932                {
    3851                     case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_rep_outs_op16_addr16);
    3852                     case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_rep_outs_op16_addr32);
    3853                     case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_rep_outs_op16_addr64);
     3933                    case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_outs_op16_addr16, pIemCpu->iEffSeg);
     3934                    case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_outs_op16_addr32, pIemCpu->iEffSeg);
     3935                    case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_outs_op16_addr64, pIemCpu->iEffSeg);
    38543936                    IEM_NOT_REACHED_DEFAULT_CASE_RET();
    38553937                }
     
    38593941                switch (pIemCpu->enmEffAddrMode)
    38603942                {
    3861                     case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_rep_outs_op32_addr16);
    3862                     case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_rep_outs_op32_addr32);
    3863                     case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_rep_outs_op32_addr64);
     3943                    case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_outs_op32_addr16, pIemCpu->iEffSeg);
     3944                    case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_outs_op32_addr32, pIemCpu->iEffSeg);
     3945                    case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_rep_outs_op32_addr64, pIemCpu->iEffSeg);
    38643946                    IEM_NOT_REACHED_DEFAULT_CASE_RET();
    38653947                }
     
    38763958                switch (pIemCpu->enmEffAddrMode)
    38773959                {
    3878                     case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_outs_op16_addr16);
    3879                     case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_outs_op16_addr32);
    3880                     case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_outs_op16_addr64);
     3960                    case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_outs_op16_addr16, pIemCpu->iEffSeg);
     3961                    case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_outs_op16_addr32, pIemCpu->iEffSeg);
     3962                    case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_outs_op16_addr64, pIemCpu->iEffSeg);
    38813963                    IEM_NOT_REACHED_DEFAULT_CASE_RET();
    38823964                }
     
    38863968                switch (pIemCpu->enmEffAddrMode)
    38873969                {
    3888                     case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_outs_op32_addr16);
    3889                     case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_outs_op32_addr32);
    3890                     case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_0(iemCImpl_outs_op32_addr64);
     3970                    case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_outs_op32_addr16, pIemCpu->iEffSeg);
     3971                    case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_outs_op32_addr32, pIemCpu->iEffSeg);
     3972                    case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_outs_op32_addr64, pIemCpu->iEffSeg);
    38913973                    IEM_NOT_REACHED_DEFAULT_CASE_RET();
    38923974                }
     
    51945276/** Opcode 0x98. */
    51955277FNIEMOP_STUB(iemOp_cbw);
     5278
     5279
    51965280/** Opcode 0x99. */
    5197 FNIEMOP_STUB(iemOp_cwd);
     5281FNIEMOP_DEF(iemOp_cwd)
     5282{
     5283    IEMOP_HLP_NO_LOCK_PREFIX();
     5284    switch (pIemCpu->enmEffOpSize)
     5285    {
     5286        case IEMMODE_16BIT:
     5287            IEMOP_MNEMONIC("cwd");
     5288            IEM_MC_BEGIN(0, 1);
     5289            IEM_MC_IF_GREG_BIT_SET(X86_GREG_xAX, 15) {
     5290                IEM_MC_STORE_GREG_U16(X86_GREG_xDX, UINT16_C(0xffff));
     5291            } IEM_MC_ELSE() {
     5292                IEM_MC_STORE_GREG_U16(X86_GREG_xDX, 0);
     5293            } IEM_MC_ENDIF();
     5294            IEM_MC_ADVANCE_RIP();
     5295            IEM_MC_END();
     5296            return VINF_SUCCESS;
     5297
     5298        case IEMMODE_32BIT:
     5299            IEMOP_MNEMONIC("cwq");
     5300            IEM_MC_BEGIN(0, 1);
     5301            IEM_MC_IF_GREG_BIT_SET(X86_GREG_xAX, 31) {
     5302                IEM_MC_STORE_GREG_U32(X86_GREG_xDX, UINT32_C(0xffffffff));
     5303            } IEM_MC_ELSE() {
     5304                IEM_MC_STORE_GREG_U32(X86_GREG_xDX, 0);
     5305            } IEM_MC_ENDIF();
     5306            IEM_MC_ADVANCE_RIP();
     5307            IEM_MC_END();
     5308            return VINF_SUCCESS;
     5309
     5310        case IEMMODE_64BIT:
     5311            IEMOP_MNEMONIC("cqo");
     5312            IEM_MC_BEGIN(0, 1);
     5313            IEM_MC_IF_GREG_BIT_SET(X86_GREG_xAX, 63) {
     5314                IEM_MC_STORE_GREG_U64(X86_GREG_xDX, UINT64_C(0xffffffffffffffff));
     5315            } IEM_MC_ELSE() {
     5316                IEM_MC_STORE_GREG_U64(X86_GREG_xDX, 0);
     5317            } IEM_MC_ENDIF();
     5318            IEM_MC_ADVANCE_RIP();
     5319            IEM_MC_END();
     5320            return VINF_SUCCESS;
     5321
     5322        IEM_NOT_REACHED_DEFAULT_CASE_RET();
     5323    }
     5324}
     5325
     5326
    51985327/** Opcode 0x9a. */
    51995328FNIEMOP_STUB(iemOp_call_Ap);
     
    56895818#undef IEM_STOS_CASE
    56905819
     5820/** Macro used by iemOp_lodsb_AL_Xb and iemOp_lodswd_eAX_Xv */
     5821#define IEM_LODS_CASE(ValBits, AddrBits) \
     5822        IEM_MC_BEGIN(0, 2); \
     5823        IEM_MC_LOCAL(uint##ValBits##_t, uValue); \
     5824        IEM_MC_LOCAL(uint##AddrBits##_t, uAddr); \
     5825        IEM_MC_FETCH_GREG_U##AddrBits(uAddr, X86_GREG_xSI); \
     5826        IEM_MC_FETCH_MEM_U##ValBits(uValue, pIemCpu->iEffSeg, uAddr); \
     5827        IEM_MC_STORE_GREG_U##ValBits(X86_GREG_xAX, uValue); \
     5828        IEM_MC_IF_EFL_BIT_SET(X86_EFL_DF) { \
     5829            IEM_MC_SUB_GREG_U##AddrBits(X86_GREG_xSI, ValBits / 8); \
     5830        } IEM_MC_ELSE() { \
     5831            IEM_MC_ADD_GREG_U##AddrBits(X86_GREG_xSI, ValBits / 8); \
     5832        } IEM_MC_ENDIF(); \
     5833        IEM_MC_ADVANCE_RIP(); \
     5834        IEM_MC_END();
     5835
    56915836/** Opcode 0xac. */
    5692 FNIEMOP_STUB(iemOp_lodsb_AL_Xb);
     5837FNIEMOP_DEF(iemOp_lodsb_AL_Xb)
     5838{
     5839    IEMOP_HLP_NO_LOCK_PREFIX();
     5840
     5841    /*
     5842     * Use the C implementation if a repeate prefix is encountered.
     5843     */
     5844    if (pIemCpu->fPrefixes & (IEM_OP_PRF_REPNZ | IEM_OP_PRF_REPZ))
     5845    {
     5846        IEMOP_MNEMONIC("rep lodsb al,Xb");
     5847        switch (pIemCpu->enmEffAddrMode)
     5848        {
     5849            case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_lods_al_m16, pIemCpu->iEffSeg);
     5850            case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_lods_al_m32, pIemCpu->iEffSeg);
     5851            case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_lods_al_m64, pIemCpu->iEffSeg);
     5852            IEM_NOT_REACHED_DEFAULT_CASE_RET();
     5853        }
     5854    }
     5855    IEMOP_MNEMONIC("lodsb al,Xb");
     5856
     5857    /*
     5858     * Sharing case implementation with stos[wdq] below.
     5859     */
     5860    switch (pIemCpu->enmEffAddrMode)
     5861    {
     5862        case IEMMODE_16BIT: IEM_LODS_CASE(8, 16); break;
     5863        case IEMMODE_32BIT: IEM_LODS_CASE(8, 32); break;
     5864        case IEMMODE_64BIT: IEM_LODS_CASE(8, 64); break;
     5865        IEM_NOT_REACHED_DEFAULT_CASE_RET();
     5866    }
     5867    return VINF_SUCCESS;
     5868}
     5869
     5870
    56935871/** Opcode 0xad. */
    5694 FNIEMOP_STUB(iemOp_lodswd_eAX_Xv);
     5872FNIEMOP_DEF(iemOp_lodswd_eAX_Xv)
     5873{
     5874    IEMOP_HLP_NO_LOCK_PREFIX();
     5875
     5876    /*
     5877     * Use the C implementation if a repeate prefix is encountered.
     5878     */
     5879    if (pIemCpu->fPrefixes & (IEM_OP_PRF_REPNZ | IEM_OP_PRF_REPZ))
     5880    {
     5881        IEMOP_MNEMONIC("rep lods rAX,Xv");
     5882        switch (pIemCpu->enmEffOpSize)
     5883        {
     5884            case IEMMODE_16BIT:
     5885                switch (pIemCpu->enmEffAddrMode)
     5886                {
     5887                    case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_lods_ax_m16, pIemCpu->iEffSeg);
     5888                    case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_lods_ax_m32, pIemCpu->iEffSeg);
     5889                    case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_lods_ax_m64, pIemCpu->iEffSeg);
     5890                    IEM_NOT_REACHED_DEFAULT_CASE_RET();
     5891                }
     5892                break;
     5893            case IEMMODE_32BIT:
     5894                switch (pIemCpu->enmEffAddrMode)
     5895                {
     5896                    case IEMMODE_16BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_lods_eax_m16, pIemCpu->iEffSeg);
     5897                    case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_lods_eax_m32, pIemCpu->iEffSeg);
     5898                    case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_lods_eax_m64, pIemCpu->iEffSeg);
     5899                    IEM_NOT_REACHED_DEFAULT_CASE_RET();
     5900                }
     5901            case IEMMODE_64BIT:
     5902                switch (pIemCpu->enmEffAddrMode)
     5903                {
     5904                    case IEMMODE_16BIT: AssertFailedReturn(VERR_INTERNAL_ERROR_3);
     5905                    case IEMMODE_32BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_lods_rax_m32, pIemCpu->iEffSeg);
     5906                    case IEMMODE_64BIT: return IEM_MC_DEFER_TO_CIMPL_1(iemCImpl_lods_rax_m64, pIemCpu->iEffSeg);
     5907                    IEM_NOT_REACHED_DEFAULT_CASE_RET();
     5908                }
     5909            IEM_NOT_REACHED_DEFAULT_CASE_RET();
     5910        }
     5911    }
     5912    IEMOP_MNEMONIC("lods rAX,Xv");
     5913
     5914    /*
     5915     * Annoying double switch here.
     5916     * Using ugly macro for implementing the cases, sharing it with lodsb.
     5917     */
     5918    switch (pIemCpu->enmEffOpSize)
     5919    {
     5920        case IEMMODE_16BIT:
     5921            switch (pIemCpu->enmEffAddrMode)
     5922            {
     5923                case IEMMODE_16BIT: IEM_LODS_CASE(16, 16); break;
     5924                case IEMMODE_32BIT: IEM_LODS_CASE(16, 32); break;
     5925                case IEMMODE_64BIT: IEM_LODS_CASE(16, 64); break;
     5926                IEM_NOT_REACHED_DEFAULT_CASE_RET();
     5927            }
     5928            break;
     5929
     5930        case IEMMODE_32BIT:
     5931            switch (pIemCpu->enmEffAddrMode)
     5932            {
     5933                case IEMMODE_16BIT: IEM_LODS_CASE(32, 16); break;
     5934                case IEMMODE_32BIT: IEM_LODS_CASE(32, 32); break;
     5935                case IEMMODE_64BIT: IEM_LODS_CASE(32, 64); break;
     5936                IEM_NOT_REACHED_DEFAULT_CASE_RET();
     5937            }
     5938            break;
     5939
     5940        case IEMMODE_64BIT:
     5941            switch (pIemCpu->enmEffAddrMode)
     5942            {
     5943                case IEMMODE_16BIT: AssertFailedReturn(VERR_INTERNAL_ERROR_4); /* cannot be encoded */ break;
     5944                case IEMMODE_32BIT: IEM_LODS_CASE(64, 32); break;
     5945                case IEMMODE_64BIT: IEM_LODS_CASE(64, 64); break;
     5946                IEM_NOT_REACHED_DEFAULT_CASE_RET();
     5947            }
     5948            break;
     5949        IEM_NOT_REACHED_DEFAULT_CASE_RET();
     5950    }
     5951    return VINF_SUCCESS;
     5952}
     5953
     5954#undef IEM_LODS_CASE
     5955
    56955956/** Opcode 0xae. */
    56965957FNIEMOP_STUB(iemOp_scasb_AL_Xb);
     
    61176378
    61186379/** Opcode 0xc4. */
    6119 FNIEMOP_STUB(iemOp_les_Gv_Mp);
     6380FNIEMOP_DEF(iemOp_les_Gv_Mp)
     6381{
     6382    IEMOP_MNEMONIC("les Gv,Mp");
     6383    return FNIEMOP_CALL_1(iemOpCommonLoadSRegAndGreg, X86_SREG_ES);
     6384}
     6385
     6386
    61206387/** Opcode 0xc5. */
    6121 FNIEMOP_STUB(iemOp_lds_Gv_Mp);
     6388FNIEMOP_DEF(iemOp_lds_Gv_Mp)
     6389{
     6390    IEMOP_MNEMONIC("lds Gv,Mp");
     6391    return FNIEMOP_CALL_1(iemOpCommonLoadSRegAndGreg, X86_SREG_DS);
     6392}
    61226393
    61236394
     
    68747145            IEM_MC_BEGIN(0,0);
    68757146            IEM_MC_IF_CX_IS_NZ() {
     7147                IEM_MC_ADVANCE_RIP();
     7148            } IEM_MC_ELSE() {
    68767149                IEM_MC_REL_JMP_S8(i8Imm);
    6877             } IEM_MC_ELSE() {
    6878                 IEM_MC_ADVANCE_RIP();
    68797150            } IEM_MC_ENDIF();
    68807151            IEM_MC_END();
     
    68847155            IEM_MC_BEGIN(0,0);
    68857156            IEM_MC_IF_ECX_IS_NZ() {
     7157                IEM_MC_ADVANCE_RIP();
     7158            } IEM_MC_ELSE() {
    68867159                IEM_MC_REL_JMP_S8(i8Imm);
    6887             } IEM_MC_ELSE() {
    6888                 IEM_MC_ADVANCE_RIP();
    68897160            } IEM_MC_ENDIF();
    68907161            IEM_MC_END();
     
    68947165            IEM_MC_BEGIN(0,0);
    68957166            IEM_MC_IF_RCX_IS_NZ() {
     7167                IEM_MC_ADVANCE_RIP();
     7168            } IEM_MC_ELSE() {
    68967169                IEM_MC_REL_JMP_S8(i8Imm);
    6897             } IEM_MC_ELSE() {
    6898                 IEM_MC_ADVANCE_RIP();
    68997170            } IEM_MC_ENDIF();
    69007171            IEM_MC_END();
  • trunk/src/VBox/VMM/VMMAll/IOMAll.cpp

    r35346 r36794  
    2222#include <VBox/vmm/iom.h>
    2323#include <VBox/vmm/mm.h>
     24#if defined(IEM_VERIFICATION_MODE) && defined(IN_RING3)
     25# include <VBox/vmm/iem.h>
     26#endif
    2427#include <VBox/param.h>
    2528#include "IOMInternal.h"
     
    265268#endif
    266269    AssertRC(rc2);
     270#if defined(IEM_VERIFICATION_MODE) && defined(IN_RING3)
     271    IEMNotifyIOPortRead(pVM, Port, cbValue);
     272#endif
    267273
    268274#ifdef VBOX_WITH_STATISTICS
     
    455461#endif
    456462    AssertRC(rc2);
     463#if defined(IEM_VERIFICATION_MODE) && defined(IN_RING3)
     464    IEMNotifyIOPortReadString(pVM, Port, *pGCPtrDst, *pcTransfers, cb);
     465#endif
    457466
    458467#ifdef LOG_ENABLED
     
    623632#endif
    624633    AssertRC(rc2);
     634#if defined(IEM_VERIFICATION_MODE) && defined(IN_RING3)
     635    IEMNotifyIOPortWrite(pVM, Port, u32Value, cbValue);
     636#endif
    625637
    626638/** @todo bird: When I get time, I'll remove the RC/R0 trees and link the RC/R0
     
    789801#endif
    790802    AssertRC(rc2);
     803#if defined(IEM_VERIFICATION_MODE) && defined(IN_RING3)
     804    IEMNotifyIOPortWriteString(pVM, Port, *pGCPtrSrc, *pcTransfers, cb);
     805#endif
    791806
    792807#ifdef LOG_ENABLED
  • trunk/src/VBox/VMM/VMMAll/IOMAllMMIO.cpp

    r35346 r36794  
    2929#include <VBox/vmm/pgm.h>
    3030#include <VBox/vmm/trpm.h>
     31#if defined(IEM_VERIFICATION_MODE) && defined(IN_RING3)
     32# include <VBox/vmm/iem.h>
     33#endif
    3134#include "IOMInternal.h"
    3235#include <VBox/vmm/vm.h>
     
    13741377#endif
    13751378    AssertRC(rc);
     1379#if defined(IEM_VERIFICATION_MODE) && defined(IN_RING3)
     1380    IEMNotifyMMIORead(pVM, GCPhys, cbValue);
     1381#endif
    13761382
    13771383    /*
     
    15001506#endif
    15011507    AssertRC(rc);
     1508#if defined(IEM_VERIFICATION_MODE) && defined(IN_RING3)
     1509    IEMNotifyMMIOWrite(pVM, GCPhys, u32Value, cbValue);
     1510#endif
    15021511
    15031512    /*
  • trunk/src/VBox/VMM/include/IEMInternal.h

    r36768 r36794  
    6060AssertCompileSize(IEMMODEX, 4);
    6161
     62
     63#ifdef IEM_VERIFICATION_MODE
     64
     65/**
     66 * Verification event type.
     67 */
     68typedef enum IEMVERIFYEVENT
     69{
     70    IEMVERIFYEVENT_INVALID = 0,
     71    IEMVERIFYEVENT_IOPORT_READ,
     72    IEMVERIFYEVENT_IOPORT_WRITE,
     73    IEMVERIFYEVENT_RAM_WRITE,
     74    IEMVERIFYEVENT_RAM_READ
     75} IEMVERIFYEVENT;
     76
     77/** Checks if the event type is a RAM read or write. */
     78# define IEMVERIFYEVENT_IS_RAM(a_enmType)    ((a_enmType) == IEMVERIFYEVENT_RAM_WRITE || (a_enmType) == IEMVERIFYEVENT_RAM_READ)
     79
     80/**
     81 * Verification event record.
     82 */
     83typedef struct IEMVERIFYEVTREC
     84{
     85    /** Pointer to the next record in the list. */
     86    struct IEMVERIFYEVTREC *pNext;
     87    /** The event type. */
     88    IEMVERIFYEVENT          enmEvent;
     89    /** The event data. */
     90    union
     91    {
     92        /** IEMVERIFYEVENT_IOPORT_READ */
     93        struct
     94        {
     95            RTIOPORT    Port;
     96            uint32_t    cbValue;
     97        } IOPortRead;
     98
     99        /** IEMVERIFYEVENT_IOPORT_WRITE */
     100        struct
     101        {
     102            RTIOPORT    Port;
     103            uint32_t    cbValue;
     104            uint32_t    u32Value;
     105        } IOPortWrite;
     106
     107        /** IEMVERIFYEVENT_RAM_READ */
     108        struct
     109        {
     110            RTGCPHYS    GCPhys;
     111            uint32_t    cb;
     112        } RamRead;
     113
     114        /** IEMVERIFYEVENT_RAM_WRITE */
     115        struct
     116        {
     117            RTGCPHYS    GCPhys;
     118            uint32_t    cb;
     119            uint8_t     ab[32];
     120        } RamWrite;
     121    } u;
     122} IEMVERIFYEVTREC;
     123/** Pointer to an IEM event verification records. */
     124typedef IEMVERIFYEVTREC *PIEMVERIFYEVTREC;
     125
     126#endif /* IEM_VERIFICATION_MODE */
    62127
    63128
     
    188253    struct
    189254    {
    190         uint8_t             ab[/*PAGE_SIZE*/16];
     255        uint8_t             ab[64];
    191256    } aBounceBuffers[3];
    192257
     258#ifdef IEM_VERIFICATION_MODE
     259    /** The event verification records for what IEM did (LIFO). */
     260    R3PTRTYPE(PIEMVERIFYEVTREC)     pIemEvtRecHead;
     261    /** Insertion point for pIemEvtRecHead. */
     262    R3PTRTYPE(PIEMVERIFYEVTREC *)   ppIemEvtRecNext;
     263    /** The event verification records for what the other party did (FIFO). */
     264    R3PTRTYPE(PIEMVERIFYEVTREC)     pOtherEvtRecHead;
     265    /** Insertion point for pOtherEvtRecHead. */
     266    R3PTRTYPE(PIEMVERIFYEVTREC *)   ppOtherEvtRecNext;
     267    /** List of free event records. */
     268    R3PTRTYPE(PIEMVERIFYEVTREC)     pFreeEvtRec;
     269#endif
    193270} IEMCPU;
    194271/** Pointer to the per-CPU IEM state. */
     
    630707 * @param   a2                  The name of the 3rd argument.
    631708 */
    632 # define IEM_CIMPL_CALL_3(a_fn, a0, a1, a2) a_fn(pIemCpu, cbInstr, (a0), (a1))
     709# define IEM_CIMPL_CALL_3(a_fn, a0, a1, a2) a_fn(pIemCpu, cbInstr, (a0), (a1), (a2))
     710
     711
     712/**
     713 * For typedef'ing or declaring a C instruction implementation function taking
     714 * four extra arguments.
     715 *
     716 * @param   a_Name              The name of the type.
     717 * @param   a_Type0             The type of the 1st argument
     718 * @param   a_Arg0              The name of the 1st argument.
     719 * @param   a_Type1             The type of the 2nd argument.
     720 * @param   a_Arg1              The name of the 2nd argument.
     721 * @param   a_Type2             The type of the 3rd argument.
     722 * @param   a_Arg2              The name of the 3rd argument.
     723 * @param   a_Type3             The type of the 4th argument.
     724 * @param   a_Arg3              The name of the 4th argument.
     725 */
     726# define IEM_CIMPL_DECL_TYPE_4(a_Name, a_Type0, a_Arg0, a_Type1, a_Arg1, a_Type2, a_Arg2, a_Type3, a_Arg3) \
     727    IEM_DECL_IMPL_TYPE(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr, a_Type0 a_Arg0, a_Type1 a_Arg1, a_Type2 a_Arg2, a_Type3 a_Arg3))
     728/**
     729 * For defining a C instruction implementation function taking four extra
     730 * arguments.
     731 *
     732 * @param   a_Name              The name of the function.
     733 * @param   a_Type0             The type of the 1st argument
     734 * @param   a_Arg0              The name of the 1st argument.
     735 * @param   a_Type1             The type of the 2nd argument.
     736 * @param   a_Arg1              The name of the 2nd argument.
     737 * @param   a_Type2             The type of the 3rd argument.
     738 * @param   a_Arg2              The name of the 3rd argument.
     739 * @param   a_Type3             The type of the 4th argument.
     740 * @param   a_Arg3              The name of the 4th argument.
     741 */
     742# define IEM_CIMPL_DEF_4(a_Name, a_Type0, a_Arg0, a_Type1, a_Arg1, a_Type2, a_Arg2, a_Type3, aArg3) \
     743    IEM_DECL_IMPL_DEF(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr, a_Type0 a_Arg0, a_Type1 a_Arg1, a_Type2 a_Arg2, a_Type3 a_Arg3))
     744/**
     745 * For calling a C instruction implementation function taking four extra
     746 * arguments.
     747 *
     748 * This special call macro adds default arguments to the call and allow us to
     749 * change these later.
     750 *
     751 * @param   a_fn                The name of the function.
     752 * @param   a0                  The name of the 1st argument.
     753 * @param   a1                  The name of the 2nd argument.
     754 * @param   a2                  The name of the 3rd argument.
     755 * @param   a3                  The name of the 4th argument.
     756 */
     757# define IEM_CIMPL_CALL_4(a_fn, a0, a1, a2, a3) a_fn(pIemCpu, cbInstr, (a0), (a1), (a2), (a3))
     758
     759
     760/**
     761 * For typedef'ing or declaring a C instruction implementation function taking
     762 * five extra arguments.
     763 *
     764 * @param   a_Name              The name of the type.
     765 * @param   a_Type0             The type of the 1st argument
     766 * @param   a_Arg0              The name of the 1st argument.
     767 * @param   a_Type1             The type of the 2nd argument.
     768 * @param   a_Arg1              The name of the 2nd argument.
     769 * @param   a_Type2             The type of the 3rd argument.
     770 * @param   a_Arg2              The name of the 3rd argument.
     771 * @param   a_Type3             The type of the 4th argument.
     772 * @param   a_Arg3              The name of the 4th argument.
     773 * @param   a_Type4             The type of the 5th argument.
     774 * @param   a_Arg4              The name of the 5th argument.
     775 */
     776# define IEM_CIMPL_DECL_TYPE_5(a_Name, a_Type0, a_Arg0, a_Type1, a_Arg1, a_Type2, a_Arg2, a_Type3, a_Arg3, a_Type4, a_Arg4) \
     777    IEM_DECL_IMPL_TYPE(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr, \
     778                                               a_Type0 a_Arg0, a_Type1 a_Arg1, a_Type2 a_Arg2, \
     779                                               a_Type3 a_Arg3, a_Type4 a_Arg4))
     780/**
     781 * For defining a C instruction implementation function taking five extra
     782 * arguments.
     783 *
     784 * @param   a_Name              The name of the function.
     785 * @param   a_Type0             The type of the 1st argument
     786 * @param   a_Arg0              The name of the 1st argument.
     787 * @param   a_Type1             The type of the 2nd argument.
     788 * @param   a_Arg1              The name of the 2nd argument.
     789 * @param   a_Type2             The type of the 3rd argument.
     790 * @param   a_Arg2              The name of the 3rd argument.
     791 * @param   a_Type3             The type of the 4th argument.
     792 * @param   a_Arg3              The name of the 4th argument.
     793 * @param   a_Type4             The type of the 5th argument.
     794 * @param   a_Arg4              The name of the 5th argument.
     795 */
     796# define IEM_CIMPL_DEF_5(a_Name, a_Type0, a_Arg0, a_Type1, a_Arg1, a_Type2, a_Arg2, a_Type3, a_Arg3, a_Type4, a_Arg4) \
     797    IEM_DECL_IMPL_DEF(VBOXSTRICTRC, a_Name, (PIEMCPU pIemCpu, uint8_t cbInstr, \
     798                                             a_Type0 a_Arg0, a_Type1 a_Arg1, a_Type2 a_Arg2, \
     799                                             a_Type3 a_Arg3, a_Type4 a_Arg4))
     800/**
     801 * For calling a C instruction implementation function taking five extra
     802 * arguments.
     803 *
     804 * This special call macro adds default arguments to the call and allow us to
     805 * change these later.
     806 *
     807 * @param   a_fn                The name of the function.
     808 * @param   a0                  The name of the 1st argument.
     809 * @param   a1                  The name of the 2nd argument.
     810 * @param   a2                  The name of the 3rd argument.
     811 * @param   a3                  The name of the 4th argument.
     812 * @param   a4                  The name of the 5th argument.
     813 */
     814# define IEM_CIMPL_CALL_5(a_fn, a0, a1, a2, a3, a4) a_fn(pIemCpu, cbInstr, (a0), (a1), (a2), (a3), (a4))
    633815
    634816/** @}  */
  • trunk/src/recompiler/VBoxRecompiler.c

    r36490 r36794  
    14071407    uint32_t u32CR0;
    14081408
     1409#ifdef IEM_VERIFICATION_MODE
     1410    return false;
     1411#endif
     1412
    14091413    /* Update counter. */
    14101414    env->pVM->rem.s.cCanExecuteRaw++;
     
    41714175REMR3DECL(void) REMR3NotifyInterruptSet(PVM pVM, PVMCPU pVCpu)
    41724176{
     4177#ifndef IEM_VERIFICATION_MODE
    41734178    LogFlow(("REMR3NotifyInterruptSet: fInRem=%d interrupts %s\n", pVM->rem.s.fInREM,
    41744179             (pVM->rem.s.Env.eflags & IF_MASK) && !(pVM->rem.s.Env.hflags & HF_INHIBIT_IRQ_MASK) ? "enabled" : "disabled"));
     
    41784183                       CPU_INTERRUPT_EXTERNAL_HARD);
    41794184    }
     4185#endif
    41804186}
    41814187
     
    42084214REMR3DECL(void) REMR3NotifyTimerPending(PVM pVM, PVMCPU pVCpuDst)
    42094215{
     4216#ifndef IEM_VERIFICATION_MODE
    42104217#ifndef DEBUG_bird
    42114218    LogFlow(("REMR3NotifyTimerPending: fInRem=%d\n", pVM->rem.s.fInREM));
     
    42244231    else
    42254232        LogIt(LOG_INSTANCE, RTLOGGRPFLAGS_LEVEL_5, LOG_GROUP_TM, ("REMR3NotifyTimerPending: !fInREM; cpu state=%d\n", VMCPU_GET_STATE(pVCpuDst)));
     4233#endif
    42264234}
    42274235
     
    42354243REMR3DECL(void) REMR3NotifyDmaPending(PVM pVM)
    42364244{
     4245#ifndef IEM_VERIFICATION_MODE
    42374246    LogFlow(("REMR3NotifyDmaPending: fInRem=%d\n", pVM->rem.s.fInREM));
    42384247    if (pVM->rem.s.fInREM)
     
    42414250                       CPU_INTERRUPT_EXTERNAL_DMA);
    42424251    }
     4252#endif
    42434253}
    42444254
     
    42524262REMR3DECL(void) REMR3NotifyQueuePending(PVM pVM)
    42534263{
     4264#ifndef IEM_VERIFICATION_MODE
    42544265    LogFlow(("REMR3NotifyQueuePending: fInRem=%d\n", pVM->rem.s.fInREM));
    42554266    if (pVM->rem.s.fInREM)
     
    42584269                       CPU_INTERRUPT_EXTERNAL_EXIT);
    42594270    }
     4271#endif
    42604272}
    42614273
     
    42694281REMR3DECL(void) REMR3NotifyFF(PVM pVM)
    42704282{
     4283#ifndef IEM_VERIFICATION_MODE
    42714284    LogFlow(("REMR3NotifyFF: fInRem=%d\n", pVM->rem.s.fInREM));
    42724285    if (pVM->rem.s.fInREM)
     
    42754288                       CPU_INTERRUPT_EXTERNAL_EXIT);
    42764289    }
     4290#endif
    42774291}
    42784292
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