コード例 #1
0
/**
 * Get the timestamp frequency.
 *
 * @returns Number of ticks per second.
 * @param   pVM     The cross context VM structure.
 */
VMMDECL(uint64_t) TMCpuTicksPerSecond(PVM pVM)
{
    if (   pVM->tm.s.enmTSCMode == TMTSCMODE_REAL_TSC_OFFSET
        && g_pSUPGlobalInfoPage->u32Mode != SUPGIPMODE_INVARIANT_TSC)
    {
#ifdef IN_RING3
        uint64_t cTSCTicksPerSecond = SUPGetCpuHzFromGip(g_pSUPGlobalInfoPage);
#elif defined(IN_RING0)
        uint64_t cTSCTicksPerSecond = SUPGetCpuHzFromGipBySetIndex(g_pSUPGlobalInfoPage, RTMpCpuIdToSetIndex(RTMpCpuId()));
#else
        uint64_t cTSCTicksPerSecond = SUPGetCpuHzFromGipBySetIndex(g_pSUPGlobalInfoPage, VMMGetCpu(pVM)->iHostCpuSet);
#endif
        if (RT_LIKELY(cTSCTicksPerSecond != ~(uint64_t)0))
            return cTSCTicksPerSecond;
    }
    return pVM->tm.s.cTSCTicksPerSecond;
}
コード例 #2
0
ファイル: TMAllCpu.cpp プロジェクト: miguelinux/vbox
/**
 * Calculates the number of host CPU ticks till the next virtual sync deadline.
 *
 * @note    To save work, this function will not bother calculating the accurate
 *          tick count for deadlines that are more than a second ahead.
 *
 * @returns The number of host cpu ticks to the next deadline.  Max one second.
 * @param   pVCpu           The cross context virtual CPU structure of the calling EMT.
 * @param   cNsToDeadline   The number of nano seconds to the next virtual
 *                          sync deadline.
 */
DECLINLINE(uint64_t) tmCpuCalcTicksToDeadline(PVMCPU pVCpu, uint64_t cNsToDeadline)
{
    AssertCompile(TMCLOCK_FREQ_VIRTUAL <= _4G);
#ifdef IN_RING3
    uint64_t uCpuHz = SUPGetCpuHzFromGip(g_pSUPGlobalInfoPage);
#else
    uint64_t uCpuHz = SUPGetCpuHzFromGipBySetIndex(g_pSUPGlobalInfoPage, pVCpu->iHostCpuSet);
#endif
    if (RT_UNLIKELY(cNsToDeadline >= TMCLOCK_FREQ_VIRTUAL))
        return uCpuHz;
    uint64_t cTicks = ASMMultU64ByU32DivByU32(uCpuHz, cNsToDeadline, TMCLOCK_FREQ_VIRTUAL);
    if (cTicks > 4000)
        cTicks -= 4000; /* fudge to account for overhead */
    else
        cTicks >>= 1;
    return cTicks;
}
コード例 #3
0
/**
 * The GC entry point.
 *
 * @returns VBox status code.
 * @param   pVM         The cross context VM structure.
 * @param   uOperation  Which operation to execute (VMMRCOPERATION).
 * @param   uArg        Argument to that operation.
 */
VMMRCDECL(int) VMMRCEntry(PVM pVM, unsigned uOperation, unsigned uArg, ...)
{
    /** @todo */
    switch (uOperation)
    {
        /*
         * Init RC modules.
         */
        case VMMRC_DO_VMMRC_INIT:
        {
            /*
             * Validate the svn revision (uArg) and build type (ellipsis).
             */
            if (uArg != VMMGetSvnRev())
                return VERR_VMM_RC_VERSION_MISMATCH;

            va_list va;
            va_start(va, uArg);

            uint32_t uBuildType = va_arg(va, uint32_t);
            if (uBuildType != vmmGetBuildType())
            {
                va_end(va);
                return VERR_VMM_RC_VERSION_MISMATCH;
            }

            /*
             * Initialize the runtime.
             */
            uint64_t u64TS = va_arg(va, uint64_t);

            va_end(va);

            int rc = RTRCInit(u64TS);
            Log(("VMMRCEntry: VMMRC_DO_VMMRC_INIT - uArg=%u (svn revision) u64TS=%RX64; rc=%Rrc\n", uArg, u64TS, rc));
            AssertRCReturn(rc, rc);

            rc = PGMRegisterStringFormatTypes();
            AssertRCReturn(rc, rc);

            rc = PGMRCDynMapInit(pVM);
            AssertRCReturn(rc, rc);
            return VINF_SUCCESS;
        }

        /*
         * Testcase which is used to test interrupt forwarding.
         * It spins for a while with interrupts enabled.
         */
        case VMMRC_DO_TESTCASE_HYPER_INTERRUPT:
        {
            uint32_t volatile i = 0;
            ASMIntEnable();
            while (i < _2G32)
                i++;
            ASMIntDisable();
            return 0;
        }

        /*
         * Testcase which simply returns, this is used for
         * profiling of the switcher.
         */
        case VMMRC_DO_TESTCASE_NOP:
            return 0;

        /*
         * Testcase executes a privileged instruction to force a world switch. (in both SVM & VMX)
         */
        case VMMRC_DO_TESTCASE_HM_NOP:
            ASMRdMsr_Low(MSR_IA32_SYSENTER_CS);
            return 0;

        /*
         * Delay for ~100us.
         */
        case VMMRC_DO_TESTCASE_INTERRUPT_MASKING:
        {
            uint64_t u64MaxTicks = (SUPGetCpuHzFromGip(g_pSUPGlobalInfoPage) != ~(uint64_t)0
                                    ? SUPGetCpuHzFromGip(g_pSUPGlobalInfoPage)
                                    : _2G)
                                   / 10000;
            uint64_t u64StartTSC = ASMReadTSC();
            uint64_t u64TicksNow;
            uint32_t volatile i = 0;

            do
            {
                /* waste some time and protect against getting stuck. */
                for (uint32_t volatile j = 0; j < 1000; j++, i++)
                    if (i > _2G32)
                        return VERR_GENERAL_FAILURE;

                /* check if we're done.*/
                u64TicksNow = ASMReadTSC() - u64StartTSC;
            } while (u64TicksNow < u64MaxTicks);

            return VINF_SUCCESS;
        }

        /*
         * Trap testcases and unknown operations.
         */
        default:
            if (    uOperation >= VMMRC_DO_TESTCASE_TRAP_FIRST
                &&  uOperation < VMMRC_DO_TESTCASE_TRAP_LAST)
                return vmmGCTest(pVM, uOperation, uArg);
            return VERR_INVALID_PARAMETER;
    }
}