VirtualBox

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


Ignore:
Timestamp:
Apr 18, 2007 12:25:41 PM (18 years ago)
Author:
vboxsync
Message:

Added single stepping in hardware accelerated mode (debug feature)

File:
1 edited

Legend:

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

    r2135 r2160  
    965965}
    966966
     967/**
     968 * Steps hardware accelerated mode.
     969 *
     970 * @returns VBox status code.
     971 * @param   pVM     The VM handle.
     972 */
     973static int emR3HwAccStep(PVM pVM)
     974{
     975    Assert(pVM->em.s.enmState == EMSTATE_DEBUG_GUEST_HWACC);
     976
     977    int         rc;
     978    PCPUMCTX    pCtx   = pVM->em.s.pCtx;
     979    bool        fGuest = pVM->em.s.enmState != EMSTATE_DEBUG_HYPER;
     980    if (fGuest)
     981    {
     982        VM_FF_CLEAR(pVM, (VM_FF_SELM_SYNC_GDT | VM_FF_SELM_SYNC_LDT | VM_FF_TRPM_SYNC_IDT | VM_FF_SELM_SYNC_TSS));
     983
     984        /*
     985         * Check vital forced actions, but ignore pending interrupts and timers.
     986         */
     987        if (VM_FF_ISPENDING(pVM, VM_FF_HIGH_PRIORITY_PRE_RAW_MASK))
     988        {
     989            rc = emR3RawForcedActions(pVM, pCtx);
     990            if (VBOX_FAILURE(rc))
     991                return rc;
     992        }
     993
     994        /*
     995         * Set flags for single stepping.
     996         */
     997        CPUMSetGuestEFlags(pVM, CPUMGetGuestEFlags(pVM) | X86_EFL_TF | X86_EFL_RF);
     998    }
     999    else
     1000        CPUMSetHyperEFlags(pVM, CPUMGetHyperEFlags(pVM) | X86_EFL_TF | X86_EFL_RF);
     1001
     1002    /*
     1003     * Single step.
     1004     * We do not start time or anything, if anything we should just do a few nanoseconds.
     1005     */
     1006    do
     1007    {
     1008        if (pVM->em.s.enmState == EMSTATE_DEBUG_HYPER)
     1009            rc = VMMR3ResumeHyper(pVM);
     1010        else
     1011            rc = VMMR3RawRunGC(pVM);
     1012    } while (   rc == VINF_SUCCESS
     1013             || rc == VINF_EM_RAW_INTERRUPT);
     1014    VM_FF_CLEAR(pVM, VM_FF_RESUME_GUEST_MASK);
     1015
     1016    /*
     1017     * Make sure the trap flag is cleared.
     1018     * (Too bad if the guest is trying to single step too.)
     1019     */
     1020    if (fGuest)
     1021        CPUMSetGuestEFlags(pVM, CPUMGetGuestEFlags(pVM) & ~X86_EFL_TF);
     1022    else
     1023        CPUMSetHyperEFlags(pVM, CPUMGetHyperEFlags(pVM) & ~X86_EFL_TF);
     1024
     1025    /*
     1026     * Deal with the return codes.
     1027     */
     1028    rc = emR3HighPriorityPostForcedActions(pVM, rc);
     1029    rc = emR3RawHandleRC(pVM, pCtx, rc);
     1030    rc = emR3RawUpdateForceFlag(pVM, pCtx, rc);
     1031    return rc;
     1032}
     1033
    9671034#ifdef DEBUG_sandervl
    9681035void emR3SingleStepExecRaw(PVM pVM, uint32_t cIterations)
     
    9791046        DBGFR3DisasInstrCurrentLog(pVM, "RSS: ");
    9801047        emR3RawStep(pVM);
     1048    }
     1049    Log(("Single step END:\n"));
     1050    CPUMSetGuestEFlags(pVM, CPUMGetGuestEFlags(pVM) & ~X86_EFL_TF);
     1051    pVM->em.s.enmState = enmOldState;
     1052}
     1053
     1054void emR3SingleStepExecHwAcc(PVM pVM, uint32_t cIterations)
     1055{
     1056    EMSTATE  enmOldState = pVM->em.s.enmState;
     1057    PCPUMCTX pCtx        = pVM->em.s.pCtx;
     1058
     1059    pVM->em.s.enmState = EMSTATE_DEBUG_GUEST_HWACC;
     1060
     1061    Log(("Single step BEGIN:\n"));
     1062    for(uint32_t i=0;i<cIterations;i++)
     1063    {
     1064        DBGFR3PrgStep(pVM);
     1065        DBGFR3DisasInstrCurrentLog(pVM, "RSS: ");
     1066        emR3HwAccStep(pVM);
    9811067    }
    9821068    Log(("Single step END:\n"));
     
    27952881         * Check various preconditions.
    27962882         */
    2797         Assert(!(pCtx->cr4 & X86_CR4_PAE));
    2798 
    27992883        VM_FF_CLEAR(pVM, (VM_FF_SELM_SYNC_GDT | VM_FF_SELM_SYNC_LDT | VM_FF_TRPM_SYNC_IDT | VM_FF_SELM_SYNC_TSS));
    28002884
    28012885        /*
    2802          * Sync page directory.
    2803          */
    2804         if (VM_FF_ISPENDING(pVM, (VM_FF_PGM_SYNC_CR3 | VM_FF_PGM_SYNC_CR3_NON_GLOBAL)))
    2805         {
    2806             rc = PGMSyncCR3(pVM, pCtx->cr0, pCtx->cr3, pCtx->cr4, VM_FF_ISSET(pVM, VM_FF_PGM_SYNC_CR3));
     2886         * Process high priority pre-execution raw-mode FFs.
     2887         */
     2888        if (VM_FF_ISPENDING(pVM, VM_FF_HIGH_PRIORITY_PRE_RAW_MASK))
     2889        {
     2890            rc = emR3RawForcedActions(pVM, pCtx);
    28072891            if (VBOX_FAILURE(rc))
    2808                 return rc;
    2809 
    2810             Assert(!VM_FF_ISPENDING(pVM, VM_FF_SELM_SYNC_GDT | VM_FF_SELM_SYNC_LDT));
    2811 
    2812             /* Prefetch pages for EIP and ESP */
    2813             rc = PGMPrefetchPage(pVM, SELMToFlat(pVM, pCtx->eflags, pCtx->cs, &pCtx->csHid, pCtx->eip));
    2814             if (rc == VINF_SUCCESS)
    2815                 rc = PGMPrefetchPage(pVM, SELMToFlat(pVM, pCtx->eflags, pCtx->ss, &pCtx->ssHid, pCtx->esp));
    2816             if (rc != VINF_SUCCESS)
    2817             {
    2818                 if (rc != VINF_PGM_SYNC_CR3)
    2819                     return rc;
    2820                 rc = PGMSyncCR3(pVM, pCtx->cr0, pCtx->cr3, pCtx->cr4, VM_FF_ISSET(pVM, VM_FF_PGM_SYNC_CR3));
    2821                 if (VBOX_FAILURE(rc))
    2822                     return rc;
    2823             }
    2824 
    2825             /** @todo maybe prefetch the supervisor stack page as well */
     2892                break;
    28262893        }
    28272894
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