VirtualBox

Changeset 41829 in vbox


Ignore:
Timestamp:
Jun 19, 2012 2:39:48 PM (12 years ago)
Author:
vboxsync
Message:

IEM: Implemented IEMExecOneWithPrefetchedByPC and IEMExecOneEx.

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

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/VMM/VMMAll/IEMAll.cpp

    r41803 r41829  
    48434843    pIemCpu->cActiveMappings++;
    48444844
     4845    if (   (fAccess & (IEM_ACCESS_WHAT_MASK | IEM_ACCESS_TYPE_WRITE)) == (IEM_ACCESS_WHAT_STACK | IEM_ACCESS_TYPE_WRITE)
     4846        || (fAccess & (IEM_ACCESS_WHAT_MASK | IEM_ACCESS_TYPE_WRITE)) == (IEM_ACCESS_WHAT_DATA | IEM_ACCESS_TYPE_WRITE) )
     4847        pIemCpu->cbWritten += cbMem;
    48454848    *ppvMem = pvMem;
    48464849    return VINF_SUCCESS;
     
    77497752
    77507753/**
     7754 * Updates the real CPU context structure with the context core (from the trap
     7755 * stack frame) before interpreting any instructions.
     7756 *
     7757 * @param   pCtx        The real CPU context.
     7758 * @param   pCtxCore    The trap stack CPU core context.
     7759 */
     7760DECLINLINE(void) iemCtxCoreToCtx(PCPUMCTX pCtx, PCCPUMCTXCORE pCtxCore)
     7761{
     7762    PCPUMCTXCORE pDst = CPUMCTX2CORE(pCtx);
     7763    if (pDst != pCtxCore)
     7764        *pDst = *pCtxCore;
     7765}
     7766
     7767
     7768/**
     7769 * Updates the context core (from the trap stack frame) with the updated values
     7770 * from the real CPU context structure after instruction emulation.
     7771 *
     7772 * @param   pCtx        The real CPU context.
     7773 * @param   pCtxCore    The trap stack CPU core context.
     7774 */
     7775DECLINLINE(void) iemCtxToCtxCore(PCPUMCTXCORE pCtxCore, PCCPUMCTX pCtx)
     7776{
     7777    PCCPUMCTXCORE pSrc = CPUMCTX2CORE(pCtx);
     7778    if (pSrc != pCtxCore)
     7779        *pCtxCore = *pSrc;
     7780}
     7781
     7782
     7783/**
     7784 * The actual code execution bits of IEMExecOne, IEMExecOneEx, and
     7785 * IEMExecOneWithPrefetchedByPC.
     7786 *
     7787 * @return  Strict VBox status code.
     7788 * @param   pVCpu       The current virtual CPU.
     7789 * @param   pIemCpu     The IEM per CPU data.
     7790 */
     7791DECL_FORCE_INLINE(VBOXSTRICTRC) iemExecOneInner(PVMCPU pVCpu, PIEMCPU pIemCpu)
     7792{
     7793    uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
     7794    VBOXSTRICTRC rcStrict = FNIEMOP_CALL(g_apfnOneByteMap[b]);
     7795    if (rcStrict == VINF_SUCCESS)
     7796        pIemCpu->cInstructions++;
     7797//#ifdef DEBUG
     7798//    AssertMsg(pIemCpu->offOpcode == cbInstr || rcStrict != VINF_SUCCESS, ("%u %u\n", pIemCpu->offOpcode, cbInstr));
     7799//#endif
     7800
     7801    /* Execute the next instruction as well if a cli, pop ss or
     7802       mov ss, Gr has just completed successfully. */
     7803    if (   rcStrict == VINF_SUCCESS
     7804        && VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS)
     7805        && EMGetInhibitInterruptsPC(pVCpu) == pIemCpu->CTX_SUFF(pCtx)->rip )
     7806    {
     7807        rcStrict = iemInitDecoderAndPrefetchOpcodes(pIemCpu);
     7808        if (rcStrict == VINF_SUCCESS)
     7809        {
     7810            b; IEM_OPCODE_GET_NEXT_U8(&b);
     7811            rcStrict = FNIEMOP_CALL(g_apfnOneByteMap[b]);
     7812            if (rcStrict == VINF_SUCCESS)
     7813                pIemCpu->cInstructions++;
     7814        }
     7815        EMSetInhibitInterruptsPC(pVCpu, UINT64_C(0x7777555533331111));
     7816    }
     7817
     7818    return rcStrict;
     7819}
     7820
     7821
     7822/**
    77517823 * Execute one instruction.
    77527824 *
     
    77977869     */
    77987870    VBOXSTRICTRC rcStrict = iemInitDecoderAndPrefetchOpcodes(pIemCpu);
    7799     if (rcStrict != VINF_SUCCESS)
    7800     {
    7801 #if defined(IEM_VERIFICATION_MODE) && defined(IN_RING3)
    7802         iemExecVerificationModeCheck(pIemCpu);
    7803 #endif
    7804         return rcStrict;
    7805     }
    7806 
    7807     uint8_t b; IEM_OPCODE_GET_NEXT_U8(&b);
    7808     rcStrict = FNIEMOP_CALL(g_apfnOneByteMap[b]);
    78097871    if (rcStrict == VINF_SUCCESS)
    7810         pIemCpu->cInstructions++;
    7811 //#ifdef DEBUG
    7812 //    AssertMsg(pIemCpu->offOpcode == cbInstr || rcStrict != VINF_SUCCESS, ("%u %u\n", pIemCpu->offOpcode, cbInstr));
    7813 //#endif
    7814 
    7815     /* Execute the next instruction as well if a cli, pop ss or
    7816        mov ss, Gr has just completed successfully. */
    7817     if (   rcStrict == VINF_SUCCESS
    7818         && VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS)
    7819         && EMGetInhibitInterruptsPC(pVCpu) == pIemCpu->CTX_SUFF(pCtx)->rip )
    7820     {
    7821         rcStrict = iemInitDecoderAndPrefetchOpcodes(pIemCpu);
    7822         if (rcStrict == VINF_SUCCESS)
    7823         {
    7824             b; IEM_OPCODE_GET_NEXT_U8(&b);
    7825             rcStrict = FNIEMOP_CALL(g_apfnOneByteMap[b]);
    7826             if (rcStrict == VINF_SUCCESS)
    7827                 pIemCpu->cInstructions++;
    7828         }
    7829         EMSetInhibitInterruptsPC(pVCpu, UINT64_C(0x7777555533331111));
    7830     }
     7872        rcStrict = iemExecOneInner(pVCpu, pIemCpu);
    78317873
    78327874#if defined(IEM_VERIFICATION_MODE) && defined(IN_RING3)
     
    78397881        LogFlow(("IEMExecOne: cs:rip=%04x:%08RX64 ss:rsp=%04x:%08RX64 EFL=%06x - rcStrict=%Rrc\n",
    78407882                 pCtx->cs, pCtx->rip, pCtx->ss, pCtx->rsp, pCtx->eflags.u, VBOXSTRICTRC_VAL(rcStrict)));
     7883    return rcStrict;
     7884}
     7885
     7886
     7887VMMDECL(VBOXSTRICTRC)       IEMExecOneEx(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, uint32_t *pcbWritten)
     7888{
     7889    PIEMCPU  pIemCpu = &pVCpu->iem.s;
     7890    PCPUMCTX pCtx    = pVCpu->iem.s.CTX_SUFF(pCtx);
     7891
     7892    iemCtxCoreToCtx(pCtx, pCtxCore);
     7893    iemInitDecoder(pIemCpu);
     7894    uint32_t const cbOldWritten = pIemCpu->cbWritten;
     7895
     7896    VBOXSTRICTRC rcStrict = iemInitDecoderAndPrefetchOpcodes(pIemCpu);
     7897    if (rcStrict == VINF_SUCCESS)
     7898    {
     7899        rcStrict = iemExecOneInner(pVCpu, pIemCpu);
     7900        if (rcStrict == VINF_SUCCESS)
     7901            iemCtxToCtxCore(pCtxCore, pCtx);
     7902        if (pcbWritten)
     7903            *pcbWritten = pIemCpu->cbWritten - cbOldWritten;
     7904    }
     7905    return rcStrict;
     7906}
     7907
     7908
     7909VMMDECL(VBOXSTRICTRC)       IEMExecOneWithPrefetchedByPC(PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, uint64_t OpcodeBytesPC,
     7910                                                         const void *pvOpcodeBytes, size_t cbOpcodeBytes)
     7911{
     7912    PIEMCPU  pIemCpu = &pVCpu->iem.s;
     7913    PCPUMCTX pCtx    = pVCpu->iem.s.CTX_SUFF(pCtx);
     7914
     7915    iemCtxCoreToCtx(pCtx, pCtxCore);
     7916
     7917    VBOXSTRICTRC rcStrict;
     7918    if (cbOpcodeBytes)
     7919    {
     7920        iemInitDecoder(pIemCpu);
     7921        pIemCpu->cbOpcode = RT_MIN(cbOpcodeBytes, sizeof(pIemCpu->abOpcode));
     7922        memcpy(pIemCpu->abOpcode, pvOpcodeBytes, pIemCpu->cbOpcode);
     7923        rcStrict = VINF_SUCCESS;
     7924    }
     7925    else
     7926        rcStrict = iemInitDecoderAndPrefetchOpcodes(pIemCpu);
     7927    if (rcStrict == VINF_SUCCESS)
     7928    {
     7929        rcStrict = iemExecOneInner(pVCpu, pIemCpu);
     7930        if (rcStrict == VINF_SUCCESS)
     7931            iemCtxToCtxCore(pCtxCore, pCtx);
     7932    }
    78417933    return rcStrict;
    78427934}
     
    79198011
    79208012
    7921 /**
    7922  * Updates the real CPU context structure with the context core (from the trap
    7923  * stack frame) before interpreting any instructions.
    7924  *
    7925  * @param   pCtx        The real CPU context.
    7926  * @param   pCtxCore    The trap stack CPU core context.
    7927  */
    7928 DECLINLINE(void) iemCtxCoreToCtx(PCPUMCTX pCtx, PCCPUMCTXCORE pCtxCore)
    7929 {
    7930     PCPUMCTXCORE pDst = CPUMCTX2CORE(pCtx);
    7931     if (pDst != pCtxCore)
    7932         *pDst = *pCtxCore;
    7933 }
    7934 
    7935 
    7936 /**
    7937  * Updates the context core (from the trap stack frame) with the updated values
    7938  * from the real CPU context structure after instruction emulation.
    7939  *
    7940  * @param   pCtx        The real CPU context.
    7941  * @param   pCtxCore    The trap stack CPU core context.
    7942  */
    7943 DECLINLINE(void) iemCtxToCtxCore(PCPUMCTXCORE pCtxCore, PCCPUMCTX pCtx)
    7944 {
    7945     PCCPUMCTXCORE pSrc = CPUMCTX2CORE(pCtx);
    7946     if (pSrc != pCtxCore)
    7947         *pCtxCore = *pSrc;
    7948 }
    7949 
    7950 
    79518013#if 0 /* The IRET-to-v8086 mode in PATM is very optimistic, so I don't dare do this yet. */
    79528014/**
  • trunk/src/VBox/VMM/include/IEMInternal.h

    r40252 r41829  
    216216    int8_t                  cXcptRecursions;
    217217    /** Explicit alignment padding. */
    218     bool                    afAlignment1[5];
     218    bool                    afAlignment1[1];
    219219    /** The CPL. */
    220220    uint8_t                 uCpl;
     
    228228    /** The number of potential exits. */
    229229    uint32_t                cPotentialExits;
     230    /** The number of bytes data or stack written (mostly for IEMExecOneEx).
     231     * This may contain uncommitted writes.  */
     232    uint32_t                cbWritten;
    230233#ifdef IEM_VERIFICATION_MODE
    231234    /** The Number of I/O port reads that has been performed. */
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