VirtualBox

Changeset 40357 in vbox


Ignore:
Timestamp:
Mar 5, 2012 1:55:06 PM (13 years ago)
Author:
vboxsync
Message:

EM: Moving functions around a bit.

File:
1 edited

Legend:

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

    r40356 r40357  
    105105
    106106/**
     107 * Sets the PC for which interrupts should be inhibited.
     108 *
     109 * @param   pVCpu       The VMCPU handle.
     110 * @param   PC          The PC.
     111 */
     112VMMDECL(void) EMSetInhibitInterruptsPC(PVMCPU pVCpu, RTGCUINTPTR PC)
     113{
     114    pVCpu->em.s.GCPtrInhibitInterrupts = PC;
     115    VMCPU_FF_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS);
     116}
     117
     118
     119/**
     120 * Gets the PC for which interrupts should be inhibited.
     121 *
     122 * There are a few instructions which inhibits or delays interrupts
     123 * for the instruction following them. These instructions are:
     124 *      - STI
     125 *      - MOV SS, r/m16
     126 *      - POP SS
     127 *
     128 * @returns The PC for which interrupts should be inhibited.
     129 * @param   pVCpu       The VMCPU handle.
     130 *
     131 */
     132VMMDECL(RTGCUINTPTR) EMGetInhibitInterruptsPC(PVMCPU pVCpu)
     133{
     134    return pVCpu->em.s.GCPtrInhibitInterrupts;
     135}
     136
     137
     138/**
     139 * Prepare an MWAIT - essentials of the MONITOR instruction.
     140 *
     141 * @returns VINF_SUCCESS
     142 * @param   pVCpu               The current CPU.
     143 * @param   rax                 The content of RAX.
     144 * @param   rcx                 The content of RCX.
     145 * @param   rdx                 The content of RDX.
     146 */
     147VMM_INT_DECL(int) EMMonitorWaitPrepare(PVMCPU pVCpu, uint64_t rax, uint64_t rcx, uint64_t rdx)
     148{
     149    pVCpu->em.s.MWait.uMonitorRAX = rax;
     150    pVCpu->em.s.MWait.uMonitorRCX = rcx;
     151    pVCpu->em.s.MWait.uMonitorRDX = rdx;
     152    pVCpu->em.s.MWait.fWait |= EMMWAIT_FLAG_MONITOR_ACTIVE;
     153    /** @todo Complete MONITOR implementation.  */
     154    return VINF_SUCCESS;
     155}
     156
     157
     158/**
     159 * Performs an MWAIT.
     160 *
     161 * @returns VINF_SUCCESS
     162 * @param   pVCpu               The current CPU.
     163 * @param   rax                 The content of RAX.
     164 * @param   rcx                 The content of RCX.
     165 */
     166VMM_INT_DECL(int) EMMonitorWaitPerform(PVMCPU pVCpu, uint64_t rax, uint64_t rcx)
     167{
     168    pVCpu->em.s.MWait.uMWaitRAX = rax;
     169    pVCpu->em.s.MWait.uMWaitRCX = rcx;
     170    pVCpu->em.s.MWait.fWait |= EMMWAIT_FLAG_ACTIVE;
     171    if (rcx)
     172        pVCpu->em.s.MWait.fWait |= EMMWAIT_FLAG_BREAKIRQIF0;
     173    else
     174        pVCpu->em.s.MWait.fWait &= ~EMMWAIT_FLAG_BREAKIRQIF0;
     175    /** @todo not completely correct?? */
     176    return VINF_EM_HALT;
     177}
     178
     179
     180
     181/**
     182 * Determine if we should continue after encountering a hlt or mwait
     183 * instruction.
     184 *
     185 * Clears MWAIT flags if returning @c true.
     186 *
     187 * @returns boolean
     188 * @param   pVCpu           The VMCPU to operate on.
     189 * @param   pCtx            Current CPU context.
     190 */
     191VMM_INT_DECL(bool) EMShouldContinueAfterHalt(PVMCPU pVCpu, PCPUMCTX pCtx)
     192{
     193    if (   pCtx->eflags.Bits.u1IF
     194        || (   (pVCpu->em.s.MWait.fWait & (EMMWAIT_FLAG_ACTIVE | EMMWAIT_FLAG_BREAKIRQIF0))
     195            ==                            (EMMWAIT_FLAG_ACTIVE | EMMWAIT_FLAG_BREAKIRQIF0)) )
     196    {
     197        pVCpu->em.s.MWait.fWait &= ~(EMMWAIT_FLAG_ACTIVE | EMMWAIT_FLAG_BREAKIRQIF0);
     198        return !!VMCPU_FF_ISPENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC));
     199    }
     200
     201    return false;
     202}
     203
     204
     205/**
     206 * Locks REM execution to a single VCpu
     207 *
     208 * @param   pVM         VM handle.
     209 */
     210VMMDECL(void) EMRemLock(PVM pVM)
     211{
     212#ifdef VBOX_WITH_REM
     213    if (!PDMCritSectIsInitialized(&pVM->em.s.CritSectREM))
     214        return;     /* early init */
     215
     216    Assert(!PGMIsLockOwner(pVM));
     217    Assert(!IOMIsLockOwner(pVM));
     218    int rc = PDMCritSectEnter(&pVM->em.s.CritSectREM, VERR_SEM_BUSY);
     219    AssertRCSuccess(rc);
     220#endif
     221}
     222
     223
     224/**
     225 * Unlocks REM execution
     226 *
     227 * @param   pVM         VM handle.
     228 */
     229VMMDECL(void) EMRemUnlock(PVM pVM)
     230{
     231#ifdef VBOX_WITH_REM
     232    if (!PDMCritSectIsInitialized(&pVM->em.s.CritSectREM))
     233        return;     /* early init */
     234
     235    PDMCritSectLeave(&pVM->em.s.CritSectREM);
     236#endif
     237}
     238
     239
     240/**
     241 * Check if this VCPU currently owns the REM lock.
     242 *
     243 * @returns bool owner/not owner
     244 * @param   pVM         The VM to operate on.
     245 */
     246VMMDECL(bool) EMRemIsLockOwner(PVM pVM)
     247{
     248#ifdef VBOX_WITH_REM
     249    if (!PDMCritSectIsInitialized(&pVM->em.s.CritSectREM))
     250        return true;   /* early init */
     251
     252    return PDMCritSectIsOwner(&pVM->em.s.CritSectREM);
     253#else
     254    return true;
     255#endif
     256}
     257
     258
     259/**
     260 * Try to acquire the REM lock.
     261 *
     262 * @returns VBox status code
     263 * @param   pVM         The VM to operate on.
     264 */
     265VMMDECL(int) EMRemTryLock(PVM pVM)
     266{
     267#ifdef VBOX_WITH_REM
     268    if (!PDMCritSectIsInitialized(&pVM->em.s.CritSectREM))
     269        return VINF_SUCCESS; /* early init */
     270
     271    return PDMCritSectTryEnter(&pVM->em.s.CritSectREM);
     272#else
     273    return VINF_SUCCESS;
     274#endif
     275}
     276
     277
     278/**
    107279 * Read callback for disassembly function; supports reading bytes that cross a page boundary
    108280 *
     
    114286 *
    115287 */
    116 DECLCALLBACK(int) EMReadBytes(RTUINTPTR pSrc, uint8_t *pDest, unsigned cb, void *pvUserdata)
     288static DECLCALLBACK(int) EMReadBytes(RTUINTPTR pSrc, uint8_t *pDest, unsigned cb, void *pvUserdata)
    117289{
    118290    PDISCPUSTATE  pDis   = (PDISCPUSTATE)pvUserdata;
     
    411583}
    412584
     585
     586#ifndef VBOX_WITH_IEM
    413587
    414588DECLINLINE(int) emRamRead(PVM pVM, PVMCPU pVCpu, PCPUMCTXCORE pCtxCore, void *pvDst, RTGCPTR GCPtrSrc, uint32_t cb)
     
    25762750    NOREF(pDis); NOREF(pvFault); NOREF(pcbSize);
    25772751    return EMInterpretRdpmc(pVM, pVCpu, pRegFrame);
    2578 }
    2579 
    2580 
    2581 /**
    2582  * Prepare an MWAIT - essentials of the MONITOR instruction.
    2583  *
    2584  * @returns VINF_SUCCESS
    2585  * @param   pVCpu               The current CPU.
    2586  * @param   rax                 The content of RAX.
    2587  * @param   rcx                 The content of RCX.
    2588  * @param   rdx                 The content of RDX.
    2589  */
    2590 VMM_INT_DECL(int) EMMonitorWaitPrepare(PVMCPU pVCpu, uint64_t rax, uint64_t rcx, uint64_t rdx)
    2591 {
    2592     pVCpu->em.s.MWait.uMonitorRAX = rax;
    2593     pVCpu->em.s.MWait.uMonitorRCX = rcx;
    2594     pVCpu->em.s.MWait.uMonitorRDX = rdx;
    2595     pVCpu->em.s.MWait.fWait |= EMMWAIT_FLAG_MONITOR_ACTIVE;
    2596     /** @todo Complete MONITOR implementation.  */
    2597     return VINF_SUCCESS;
    2598 }
    2599 
    2600 
    2601 /**
    2602  * Performs an MWAIT.
    2603  *
    2604  * @returns VINF_SUCCESS
    2605  * @param   pVCpu               The current CPU.
    2606  * @param   rax                 The content of RAX.
    2607  * @param   rcx                 The content of RCX.
    2608  */
    2609 VMM_INT_DECL(int) EMMonitorWaitPerform(PVMCPU pVCpu, uint64_t rax, uint64_t rcx)
    2610 {
    2611     pVCpu->em.s.MWait.uMWaitRAX = rax;
    2612     pVCpu->em.s.MWait.uMWaitRCX = rcx;
    2613     pVCpu->em.s.MWait.fWait |= EMMWAIT_FLAG_ACTIVE;
    2614     if (rcx)
    2615         pVCpu->em.s.MWait.fWait |= EMMWAIT_FLAG_BREAKIRQIF0;
    2616     else
    2617         pVCpu->em.s.MWait.fWait &= ~EMMWAIT_FLAG_BREAKIRQIF0;
    2618     /** @todo not completely correct?? */
    2619     return VINF_EM_HALT;
    26202752}
    26212753
     
    31463278}
    31473279
    3148 
    3149 /**
    3150  * Sets the PC for which interrupts should be inhibited.
    3151  *
    3152  * @param   pVCpu       The VMCPU handle.
    3153  * @param   PC          The PC.
    3154  */
    3155 VMMDECL(void) EMSetInhibitInterruptsPC(PVMCPU pVCpu, RTGCUINTPTR PC)
    3156 {
    3157     pVCpu->em.s.GCPtrInhibitInterrupts = PC;
    3158     VMCPU_FF_SET(pVCpu, VMCPU_FF_INHIBIT_INTERRUPTS);
    3159 }
    3160 
    3161 
    3162 /**
    3163  * Gets the PC for which interrupts should be inhibited.
    3164  *
    3165  * There are a few instructions which inhibits or delays interrupts
    3166  * for the instruction following them. These instructions are:
    3167  *      - STI
    3168  *      - MOV SS, r/m16
    3169  *      - POP SS
    3170  *
    3171  * @returns The PC for which interrupts should be inhibited.
    3172  * @param   pVCpu       The VMCPU handle.
    3173  *
    3174  */
    3175 VMMDECL(RTGCUINTPTR) EMGetInhibitInterruptsPC(PVMCPU pVCpu)
    3176 {
    3177     return pVCpu->em.s.GCPtrInhibitInterrupts;
    3178 }
    3179 
    3180 /**
    3181  * Locks REM execution to a single VCpu
    3182  *
    3183  * @param   pVM         VM handle.
    3184  */
    3185 VMMDECL(void) EMRemLock(PVM pVM)
    3186 {
    3187 #ifdef VBOX_WITH_REM
    3188     if (!PDMCritSectIsInitialized(&pVM->em.s.CritSectREM))
    3189         return;     /* early init */
    3190 
    3191     Assert(!PGMIsLockOwner(pVM));
    3192     Assert(!IOMIsLockOwner(pVM));
    3193     int rc = PDMCritSectEnter(&pVM->em.s.CritSectREM, VERR_SEM_BUSY);
    3194     AssertRCSuccess(rc);
    3195 #endif
    3196 }
    3197 
    3198 /**
    3199  * Unlocks REM execution
    3200  *
    3201  * @param   pVM         VM handle.
    3202  */
    3203 VMMDECL(void) EMRemUnlock(PVM pVM)
    3204 {
    3205 #ifdef VBOX_WITH_REM
    3206     if (!PDMCritSectIsInitialized(&pVM->em.s.CritSectREM))
    3207         return;     /* early init */
    3208 
    3209     PDMCritSectLeave(&pVM->em.s.CritSectREM);
    3210 #endif
    3211 }
    3212 
    3213 /**
    3214  * Check if this VCPU currently owns the REM lock.
    3215  *
    3216  * @returns bool owner/not owner
    3217  * @param   pVM         The VM to operate on.
    3218  */
    3219 VMMDECL(bool) EMRemIsLockOwner(PVM pVM)
    3220 {
    3221 #ifdef VBOX_WITH_REM
    3222     if (!PDMCritSectIsInitialized(&pVM->em.s.CritSectREM))
    3223         return true;   /* early init */
    3224 
    3225     return PDMCritSectIsOwner(&pVM->em.s.CritSectREM);
    3226 #else
    3227     return true;
    3228 #endif
    3229 }
    3230 
    3231 /**
    3232  * Try to acquire the REM lock.
    3233  *
    3234  * @returns VBox status code
    3235  * @param   pVM         The VM to operate on.
    3236  */
    3237 VMMDECL(int) EMRemTryLock(PVM pVM)
    3238 {
    3239 #ifdef VBOX_WITH_REM
    3240     if (!PDMCritSectIsInitialized(&pVM->em.s.CritSectREM))
    3241         return VINF_SUCCESS; /* early init */
    3242 
    3243     return PDMCritSectTryEnter(&pVM->em.s.CritSectREM);
    3244 #else
    3245     return VINF_SUCCESS;
    3246 #endif
    3247 }
    3248 
    3249 /**
    3250  * Determine if we should continue after encountering a hlt or mwait
    3251  * instruction.
    3252  *
    3253  * Clears MWAIT flags if returning @c true.
    3254  *
    3255  * @returns boolean
    3256  * @param   pVCpu           The VMCPU to operate on.
    3257  * @param   pCtx            Current CPU context.
    3258  */
    3259 VMM_INT_DECL(bool) EMShouldContinueAfterHalt(PVMCPU pVCpu, PCPUMCTX pCtx)
    3260 {
    3261     if (   pCtx->eflags.Bits.u1IF
    3262         || (   (pVCpu->em.s.MWait.fWait & (EMMWAIT_FLAG_ACTIVE | EMMWAIT_FLAG_BREAKIRQIF0))
    3263             ==                            (EMMWAIT_FLAG_ACTIVE | EMMWAIT_FLAG_BREAKIRQIF0)) )
    3264     {
    3265         pVCpu->em.s.MWait.fWait &= ~(EMMWAIT_FLAG_ACTIVE | EMMWAIT_FLAG_BREAKIRQIF0);
    3266         return !!VMCPU_FF_ISPENDING(pVCpu, (VMCPU_FF_INTERRUPT_APIC | VMCPU_FF_INTERRUPT_PIC));
    3267     }
    3268 
    3269     return false;
    3270 }
    3271 
     3280#endif /* !VBOX_WITH_IEM */
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