VirtualBox

Changeset 64655 in vbox for trunk/src/VBox/VMM/VMMAll


Ignore:
Timestamp:
Nov 14, 2016 10:46:07 AM (8 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
111904
Message:

VMM,recompiler: Get rid of PDM APIC interfaces reducing one level of indirection, cleaned up some unused stuff in recompiler.

Location:
trunk/src/VBox/VMM/VMMAll
Files:
8 edited

Legend:

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

    r64596 r64655  
    228228        /* 7 */     { "write reserved bits of MSR",    "",                            VINF_CPUM_R3_MSR_WRITE },
    229229        /* 8 */     { "write an invalid value to MSR", "",                            VINF_CPUM_R3_MSR_WRITE },
    230         /* 9 */     { "write MSR",                     "disallowed by configuration", VINF_CPUM_R3_MSR_WRITE }
     230        /* 9 */     { "write MSR",                     "disallowed by configuration", VINF_CPUM_R3_MSR_WRITE },
     231        /* 10 */    { "read MSR",                      "disallowed by configuration", VINF_CPUM_R3_MSR_READ }
    231232    };
    232233    AssertCompile(RT_ELEMENTS(s_aAccess) == APICMSRACCESS_COUNT);
     
    18581859
    18591860/**
    1860  * @interface_method_impl{PDMAPICREG,pfnReadMsrR3}
    1861  */
    1862 APICBOTHCBDECL(VBOXSTRICTRC) apicReadMsr(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t u32Reg, uint64_t *pu64Value)
     1861 * Reads an APIC MSR.
     1862 *
     1863 * @returns Strict VBox status code.
     1864 * @param   pVCpu           The cross context virtual CPU structure.
     1865 * @param   u32Reg          The MSR being read.
     1866 * @param   pu64Value       Where to store the read value.
     1867 */
     1868VMM_INT_DECL(VBOXSTRICTRC) APICReadMsr(PVMCPU pVCpu, uint32_t u32Reg, uint64_t *pu64Value)
    18631869{
    18641870    /*
     
    18681874    Assert(u32Reg >= MSR_IA32_X2APIC_ID && u32Reg <= MSR_IA32_X2APIC_SELF_IPI);
    18691875    Assert(pu64Value);
    1870     RT_NOREF_PV(pDevIns);
    1871 
     1876
     1877    /*
     1878     * Is the APIC enabled?
     1879     */
    18721880    PCAPIC pApic = VM_TO_APIC(pVCpu->CTX_SUFF(pVM));
     1881    if (apicIsEnabled(pVCpu))
     1882    { /* likely */ }
     1883    else
     1884    {
     1885        return apicMsrAccessError(pVCpu, u32Reg, pApic->enmMaxMode == PDMAPICMODE_NONE ?
     1886                                                 APICMSRACCESS_READ_DISALLOWED_CONFIG : APICMSRACCESS_READ_RSVD_OR_UNKNOWN);
     1887    }
     1888
    18731889#ifndef IN_RING3
    18741890    if (pApic->fRZEnabled)
     
    19621978
    19631979/**
    1964  * @interface_method_impl{PDMAPICREG,pfnWriteMsrR3}
    1965  */
    1966 APICBOTHCBDECL(VBOXSTRICTRC) apicWriteMsr(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint32_t u32Reg, uint64_t u64Value)
     1980 * Writes an APIC MSR.
     1981 *
     1982 * @returns Strict VBox status code.
     1983 * @param   pVCpu           The cross context virtual CPU structure.
     1984 * @param   u32Reg          The MSR being written.
     1985 * @param   pu64Value       The value to write.
     1986 */
     1987VMM_INT_DECL(VBOXSTRICTRC) APICWriteMsr(PVMCPU pVCpu, uint32_t u32Reg, uint64_t u64Value)
    19671988{
    19681989    /*
     
    19711992    VMCPU_ASSERT_EMT(pVCpu);
    19721993    Assert(u32Reg >= MSR_IA32_X2APIC_ID && u32Reg <= MSR_IA32_X2APIC_SELF_IPI);
    1973     RT_NOREF_PV(pDevIns);
    1974 
     1994
     1995    /*
     1996     * Is the APIC enabled?
     1997     */
    19751998    PCAPIC pApic = VM_TO_APIC(pVCpu->CTX_SUFF(pVM));
     1999    if (apicIsEnabled(pVCpu))
     2000    { /* likely */ }
     2001    else
     2002    {
     2003        return apicMsrAccessError(pVCpu, u32Reg, pApic->enmMaxMode == PDMAPICMODE_NONE ?
     2004                                                 APICMSRACCESS_WRITE_DISALLOWED_CONFIG : APICMSRACCESS_WRITE_RSVD_OR_UNKNOWN);
     2005    }
     2006
    19762007#ifndef IN_RING3
    19772008    if (pApic->fRZEnabled)
     
    21232154
    21242155/**
    2125  * @interface_method_impl{PDMAPICREG,pfnSetBaseMsrR3}
    2126  */
    2127 APICBOTHCBDECL(VBOXSTRICTRC) apicSetBaseMsr(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint64_t u64BaseMsr)
     2156 * Sets the APIC base MSR.
     2157 *
     2158 * @returns Strict VBox status code.
     2159 * @param   pVCpu       The cross context virtual CPU structure.
     2160 * @param   u64BaseMsr  The value to set.
     2161 */
     2162VMM_INT_DECL(VBOXSTRICTRC) APICSetBaseMsr(PVMCPU pVCpu, uint64_t u64BaseMsr)
    21282163{
    21292164    Assert(pVCpu);
    2130     NOREF(pDevIns);
    21312165
    21322166#ifdef IN_RING3
     
    22552289
    22562290#else  /* !IN_RING3 */
    2257     RT_NOREF_PV(pDevIns);
    22582291    RT_NOREF_PV(pVCpu);
    22592292    RT_NOREF_PV(u64BaseMsr);
     
    22642297
    22652298/**
    2266  * @interface_method_impl{PDMAPICREG,pfnGetBaseMsrR3}
    2267  */
    2268 APICBOTHCBDECL(uint64_t) apicGetBaseMsr(PPDMDEVINS pDevIns, PVMCPU pVCpu)
    2269 {
    2270     RT_NOREF_PV(pDevIns);
     2299 * Gets the APIC base MSR (no checks are performed wrt APIC hardware or its
     2300 * state).
     2301 *
     2302 * @returns The base MSR value.
     2303 * @param   pVCpu       The cross context virtual CPU structure.
     2304 */
     2305VMM_INT_DECL(uint64_t) APICGetBaseMsrNoCheck(PVMCPU pVCpu)
     2306{
    22712307    VMCPU_ASSERT_EMT_OR_NOT_RUNNING(pVCpu);
    2272 
    22732308    PCAPICCPU pApicCpu = VMCPU_TO_APICCPU(pVCpu);
    22742309    return pApicCpu->uApicBaseMsr;
     
    22772312
    22782313/**
    2279  * @interface_method_impl{PDMAPICREG,pfnSetTprR3}
    2280  */
    2281 APICBOTHCBDECL(void) apicSetTpr(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t u8Tpr)
    2282 {
    2283     RT_NOREF_PV(pDevIns);
    2284     apicSetTprEx(pVCpu, u8Tpr, false /* fForceX2ApicBehaviour */);
     2314 * Gets the APIC base MSR.
     2315 *
     2316 * @returns Strict VBox status code.
     2317 * @param   pVCpu       The cross context virtual CPU structure.
     2318 * @param   pu64Value   Where to store the MSR value.
     2319 */
     2320VMM_INT_DECL(VBOXSTRICTRC) APICGetBaseMsr(PVMCPU pVCpu, uint64_t *pu64Value)
     2321{
     2322    VMCPU_ASSERT_EMT_OR_NOT_RUNNING(pVCpu);
     2323
     2324    PCAPIC pApic = VM_TO_APIC(pVCpu->CTX_SUFF(pVM));
     2325    if (pApic->enmMaxMode != PDMAPICMODE_NONE)
     2326    {
     2327        *pu64Value = APICGetBaseMsrNoCheck(pVCpu);
     2328        return VINF_SUCCESS;
     2329    }
     2330
     2331#ifdef IN_RING3
     2332    LogRelMax(5, ("APIC%u: Reading APIC base MSR (%#x) when there is no APIC -> #GP(0)\n", pVCpu->idCpu, MSR_IA32_APICBASE));
     2333    return VERR_CPUM_RAISE_GP_0;
     2334#else
     2335    return VINF_CPUM_R3_MSR_WRITE;
     2336#endif
     2337}
     2338
     2339
     2340/**
     2341 * Sets the TPR (Task Priority Register).
     2342 *
     2343 * @returns VBox status code.
     2344 * @param   pVCpu       The cross context virtual CPU structure.
     2345 * @param   u8Tpr       The TPR value to set.
     2346 */
     2347VMMDECL(int) APICSetTpr(PVMCPU pVCpu, uint8_t u8Tpr)
     2348{
     2349    if (apicIsEnabled(pVCpu))
     2350        return VBOXSTRICTRC_VAL(apicSetTprEx(pVCpu, u8Tpr, false /* fForceX2ApicBehaviour */));
     2351    return VERR_PDM_NO_APIC_INSTANCE;
    22852352}
    22862353
     
    23102377
    23112378/**
    2312  * @interface_method_impl{PDMAPICREG,pfnGetTprR3}
    2313  */
    2314 APICBOTHCBDECL(uint8_t) apicGetTpr(PPDMDEVINS pDevIns, PVMCPU pVCpu, bool *pfPending, uint8_t *pu8PendingIntr)
    2315 {
    2316     RT_NOREF_PV(pDevIns);
     2379 * Gets the APIC TPR (Task Priority Register).
     2380 *
     2381 * @returns VBox status code.
     2382 * @param   pVCpu           The cross context virtual CPU structure.
     2383 * @param   pu8Tpr          Where to store the TPR.
     2384 * @param   pfPending       Where to store whether there is a pending interrupt
     2385 *                          (optional, can be NULL).
     2386 * @param   pu8PendingIntr  Where to store the highest-priority pending
     2387 *                          interrupt (optional, can be NULL).
     2388 */
     2389VMMDECL(int) APICGetTpr(PVMCPU pVCpu, uint8_t *pu8Tpr, bool *pfPending, uint8_t *pu8PendingIntr)
     2390{
    23172391    VMCPU_ASSERT_EMT(pVCpu);
    2318     PCXAPICPAGE pXApicPage = VMCPU_TO_CXAPICPAGE(pVCpu);
    2319 
    2320     if (pfPending)
    2321     {
    2322         /*
    2323          * Just return whatever the highest pending interrupt is in the IRR.
    2324          * The caller is responsible for figuring out if it's masked by the TPR etc.
    2325          */
    2326         *pfPending = apicGetHighestPendingInterrupt(pVCpu, pu8PendingIntr);
    2327     }
    2328 
    2329     return pXApicPage->tpr.u8Tpr;
    2330 }
    2331 
    2332 
    2333 /**
    2334  * @interface_method_impl{PDMAPICREG,pfnGetTimerFreqR3}
    2335  */
    2336 APICBOTHCBDECL(uint64_t) apicGetTimerFreq(PPDMDEVINS pDevIns)
    2337 {
    2338     PVM      pVM      = PDMDevHlpGetVM(pDevIns);
    2339     PVMCPU   pVCpu    = &pVM->aCpus[0];
    2340     PAPICCPU pApicCpu = VMCPU_TO_APICCPU(pVCpu);
    2341     uint64_t uTimer   = TMTimerGetFreq(pApicCpu->CTX_SUFF(pTimer));
    2342     return uTimer;
    2343 }
    2344 
    2345 
    2346 /**
    2347  * @interface_method_impl{PDMAPICREG,pfnBusDeliverR3}
    2348  * @remarks This is a private interface between the IOAPIC and the APIC.
    2349  */
    2350 APICBOTHCBDECL(int) apicBusDeliver(PPDMDEVINS pDevIns, uint8_t uDest, uint8_t uDestMode, uint8_t uDeliveryMode, uint8_t uVector,
    2351                             uint8_t uPolarity, uint8_t uTriggerMode, uint32_t uTagSrc)
     2392    if (apicIsEnabled(pVCpu))
     2393    {
     2394        PCXAPICPAGE pXApicPage = VMCPU_TO_CXAPICPAGE(pVCpu);
     2395        if (pfPending)
     2396        {
     2397            /*
     2398             * Just return whatever the highest pending interrupt is in the IRR.
     2399             * The caller is responsible for figuring out if it's masked by the TPR etc.
     2400             */
     2401            *pfPending = apicGetHighestPendingInterrupt(pVCpu, pu8PendingIntr);
     2402        }
     2403
     2404        *pu8Tpr = pXApicPage->tpr.u8Tpr;
     2405        return VINF_SUCCESS;
     2406    }
     2407
     2408    *pu8Tpr = 0;
     2409    return VERR_PDM_NO_APIC_INSTANCE;
     2410}
     2411
     2412
     2413/**
     2414 * Gets the APIC timer frequency.
     2415 *
     2416 * @returns Strict VBox status code.
     2417 * @param
     2418 */
     2419VMM_INT_DECL(int) APICGetTimerFreq(PVM pVM, uint64_t *pu64Value)
     2420{
     2421    /*
     2422     * Validate.
     2423     */
     2424    Assert(pVM);
     2425    AssertPtrReturn(pu64Value, VERR_INVALID_PARAMETER);
     2426
     2427    PVMCPU pVCpu = &pVM->aCpus[0];
     2428    if (apicIsEnabled(pVCpu))
     2429    {
     2430        PCAPICCPU pApicCpu = VMCPU_TO_APICCPU(pVCpu);
     2431        *pu64Value = TMTimerGetFreq(pApicCpu->CTX_SUFF(pTimer));
     2432        return VINF_SUCCESS;
     2433    }
     2434    return VERR_PDM_NO_APIC_INSTANCE;
     2435}
     2436
     2437
     2438/**
     2439 * Delivers an interrupt message via the system bus.
     2440 *
     2441 * @returns VBox status code.
     2442 * @param   pVM             The cross context VM structure.
     2443 * @param   uDest           The destination mask.
     2444 * @param   uDestMode       The destination mode.
     2445 * @param   uDeliveryMode   The delivery mode.
     2446 * @param   uVector         The interrupt vector.
     2447 * @param   uPolarity       The interrupt line polarity.
     2448 * @param   uTriggerMode    The trigger mode.
     2449 * @param   uTagSrc         The interrupt tag (debugging).
     2450 */
     2451VMM_INT_DECL(int) APICBusDeliver(PVM pVM, uint8_t uDest, uint8_t uDestMode, uint8_t uDeliveryMode, uint8_t uVector,
     2452                                 uint8_t uPolarity, uint8_t uTriggerMode, uint32_t uTagSrc)
    23522453{
    23532454    NOREF(uPolarity);
    23542455    NOREF(uTagSrc);
    2355     PVM pVM = PDMDevHlpGetVM(pDevIns);
     2456
     2457    /*
     2458     * If the APIC isn't enabled, do nothing and pretend success.
     2459     */
     2460    if (apicIsEnabled(&pVM->aCpus[0]))
     2461    { /* likely */ }
     2462    else
     2463        return VINF_SUCCESS;
    23562464
    23572465    /*
     
    23822490
    23832491/**
    2384  * @interface_method_impl{PDMAPICREG,pfnLocalInterruptR3}
    2385  * @remarks This is a private interface between the PIC and the APIC.
    2386  */
    2387 APICBOTHCBDECL(VBOXSTRICTRC) apicLocalInterrupt(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t u8Pin, uint8_t u8Level, int rcRZ)
    2388 {
    2389     NOREF(pDevIns);
     2492 * Assert/de-assert the local APIC's LINT0/LINT1 interrupt pins.
     2493 *
     2494 * @returns Strict VBox status code.
     2495 * @param   pVCpu       The cross context virtual CPU structure.
     2496 * @param   u8Pin       The interrupt pin (0 for LINT0 or 1 for LINT1).
     2497 * @param   u8Level     The level (0 for low or 1 for high).
     2498 * @param   rcRZ        The return code if the operation cannot be performed in
     2499 *                      the current context.
     2500 */
     2501VMM_INT_DECL(VBOXSTRICTRC) APICLocalInterrupt(PVMCPU pVCpu, uint8_t u8Pin, uint8_t u8Level, int rcRZ)
     2502{
    23902503    AssertReturn(u8Pin <= 1, VERR_INVALID_PARAMETER);
    23912504    AssertReturn(u8Level <= 1, VERR_INVALID_PARAMETER);
     
    25442657
    25452658/**
    2546  * @interface_method_impl{PDMAPICREG,pfnGetInterruptR3}
    2547  */
    2548 APICBOTHCBDECL(int) apicGetInterrupt(PPDMDEVINS pDevIns, PVMCPU pVCpu, uint8_t *pu8Vector, uint32_t *pu32TagSrc)
    2549 {
    2550     RT_NOREF_PV(pDevIns);
     2659 * Gets the next highest-priority interrupt from the APIC, marking it as an
     2660 * "in-service" interrupt.
     2661 *
     2662 * @returns VBox status code.
     2663 * @param   pVCpu       The cross context virtual CPU structure.
     2664 * @param   pu8Vector   Where to store the vector.
     2665 * @param   pu32TagSrc  The source tag (debugging).
     2666 */
     2667VMM_INT_DECL(int) APICGetInterrupt(PVMCPU pVCpu, uint8_t *pu8Vector, uint32_t *pu32TagSrc)
     2668{
    25512669    VMCPU_ASSERT_EMT(pVCpu);
    25522670    Assert(pu8Vector);
     
    29053023 *          interrupt shadow etc.)
    29063024 */
    2907 VMMDECL(bool) APICQueueInterruptToService(PVMCPU pVCpu, uint8_t u8PendingIntr)
     3025VMM_INT_DECL(bool) APICQueueInterruptToService(PVMCPU pVCpu, uint8_t u8PendingIntr)
    29083026{
    29093027    VMCPU_ASSERT_EMT(pVCpu);
     
    29373055 *                              in-service.
    29383056 */
    2939 VMMDECL(void) APICDequeueInterruptFromService(PVMCPU pVCpu, uint8_t u8PendingIntr)
     3057VMM_INT_DECL(void) APICDequeueInterruptFromService(PVMCPU pVCpu, uint8_t u8PendingIntr)
    29403058{
    29413059    VMCPU_ASSERT_EMT(pVCpu);
     
    30443162 *                              interrupt is pending.
    30453163 */
    3046 VMMDECL(bool) APICGetHighestPendingInterrupt(PVMCPU pVCpu, uint8_t *pu8PendingIntr)
     3164VMM_INT_DECL(bool) APICGetHighestPendingInterrupt(PVMCPU pVCpu, uint8_t *pu8PendingIntr)
    30473165{
    30483166    VMCPU_ASSERT_EMT(pVCpu);
  • trunk/src/VBox/VMM/VMMAll/CPUMAllMsrs.cpp

    r62606 r64655  
    2222#define LOG_GROUP LOG_GROUP_CPUM
    2323#include <VBox/vmm/cpum.h>
    24 #include <VBox/vmm/pdmapi.h>
     24#include <VBox/vmm/apic.h>
    2525#include <VBox/vmm/hm.h>
    2626#include <VBox/vmm/tm.h>
     
    217217{
    218218    RT_NOREF_PV(idMsr); RT_NOREF_PV(pRange);
    219     return PDMApicGetBaseMsr(pVCpu, puValue, false /* fIgnoreErrors */);
     219    return APICGetBaseMsr(pVCpu, puValue);
    220220}
    221221
     
    225225{
    226226    RT_NOREF_PV(pVCpu); RT_NOREF_PV(idMsr); RT_NOREF_PV(pRange); RT_NOREF_PV(uValue); RT_NOREF_PV(uRawValue);
    227     return PDMApicSetBaseMsr(pVCpu, uValue);
     227    return APICSetBaseMsr(pVCpu, uValue);
    228228}
    229229
     
    12151215{
    12161216    RT_NOREF_PV(pRange);
    1217     return PDMApicReadMsr(pVCpu, idMsr, puValue);
     1217    return APICReadMsr(pVCpu, idMsr, puValue);
    12181218}
    12191219
     
    12231223{
    12241224    RT_NOREF_PV(pRange); RT_NOREF_PV(uRawValue);
    1225     return PDMApicWriteMsr(pVCpu, idMsr, uValue);
     1225    return APICWriteMsr(pVCpu, idMsr, uValue);
    12261226}
    12271227
  • trunk/src/VBox/VMM/VMMAll/CPUMAllRegs.cpp

    r62601 r64655  
    2424#include <VBox/vmm/patm.h>
    2525#include <VBox/vmm/dbgf.h>
    26 #include <VBox/vmm/pdm.h>
     26#include <VBox/vmm/apic.h>
    2727#include <VBox/vmm/pgm.h>
    2828#include <VBox/vmm/mm.h>
     
    10591059        {
    10601060            uint8_t u8Tpr;
    1061             int rc = PDMApicGetTPR(pVCpu, &u8Tpr, NULL /* pfPending */, NULL /* pu8PendingIrq */);
     1061            int rc = APICGetTpr(pVCpu, &u8Tpr, NULL /* pfPending */, NULL /* pu8PendingIrq */);
    10621062            if (RT_FAILURE(rc))
    10631063            {
     
    10661066                return rc;
    10671067            }
    1068             *pValue = u8Tpr >> 4; /* bits 7-4 contain the task priority that go in cr8, bits 3-0*/
     1068            *pValue = u8Tpr >> 4; /* bits 7-4 contain the task priority that go in cr8, bits 3-0 */
    10691069            break;
    10701070        }
  • trunk/src/VBox/VMM/VMMAll/EMAll.cpp

    r63560 r64655  
    32503250
    32513251    case DISCREG_CR8:
    3252         return PDMApicSetTPR(pVCpu, val << 4);  /* cr8 bits 3-0 correspond to bits 7-4 of the task priority mmio register. */
     3252        return APICSetTpr(pVCpu, val << 4);  /* cr8 bits 3-0 correspond to bits 7-4 of the task priority mmio register. */
    32533253
    32543254    default:
  • trunk/src/VBox/VMM/VMMAll/GIMAllHv.cpp

    r63651 r64655  
    560560        case MSR_GIM_HV_APIC_FREQ:
    561561        {
    562             int rc = PDMApicGetTimerFreq(pVM, puValue);
     562            int rc = APICGetTimerFreq(pVM, puValue);
    563563            if (RT_FAILURE(rc))
    564564                return VERR_CPUM_RAISE_GP_0;
  • trunk/src/VBox/VMM/VMMAll/IEMAll.cpp

    r64545 r64655  
    9696#include <VBox/vmm/iem.h>
    9797#include <VBox/vmm/cpum.h>
     98#include <VBox/vmm/apic.h>
    9899#include <VBox/vmm/pdm.h>
    99100#include <VBox/vmm/pgm.h>
  • trunk/src/VBox/VMM/VMMAll/IEMAllCImpl.cpp.h

    r64033 r64655  
    49584958        {
    49594959            uint8_t uTpr;
    4960             int rc = PDMApicGetTPR(pVCpu, &uTpr, NULL, NULL);
     4960            int rc = APICGetTpr(pVCpu, &uTpr, NULL, NULL);
    49614961            if (RT_SUCCESS(rc))
    49624962                crX = uTpr >> 4;
     
    52715271
    52725272            if (!IEM_FULL_VERIFICATION_ENABLED(pVCpu))
    5273                 PDMApicSetTPR(pVCpu, (uint8_t)uNewCrX << 4);
     5273                APICSetTpr(pVCpu, (uint8_t)uNewCrX << 4);
    52745274            rcStrict = VINF_SUCCESS;
    52755275            break;
  • trunk/src/VBox/VMM/VMMAll/PDMAll.cpp

    r64626 r64655  
    6262    {
    6363        VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_APIC);
    64         Assert(pVM->pdm.s.Apic.CTX_SUFF(pDevIns));
    65         Assert(pVM->pdm.s.Apic.CTX_SUFF(pfnGetInterrupt));
    6664        uint32_t uTagSrc;
    6765        uint8_t  uVector;
    68         rc = pVM->pdm.s.Apic.CTX_SUFF(pfnGetInterrupt)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), pVCpu, &uVector, &uTagSrc);
     66        rc = APICGetInterrupt(pVCpu, &uVector, &uTagSrc);
    6967        if (RT_SUCCESS(rc))
    7068        {
     
    260258
    261259/**
    262  * Returns the presence of a Local APIC.
    263  *
    264  * @returns VBox true if a Local APIC is present.
    265  * @param   pVM         The cross context VM structure.
    266  */
    267 VMM_INT_DECL(bool) PDMHasApic(PVM pVM)
    268 {
    269     return pVM->pdm.s.Apic.CTX_SUFF(pDevIns) != NULL;
    270 }
    271 
    272 
    273 /**
    274  * Set the APIC base.
    275  *
    276  * @returns Strict VBox status code.
    277  * @param   pVCpu       The cross context virtual CPU structure.
    278  * @param   u64Base     The new base.
    279  */
    280 VMMDECL(VBOXSTRICTRC) PDMApicSetBaseMsr(PVMCPU pVCpu, uint64_t u64Base)
    281 {
    282     PVM pVM = pVCpu->CTX_SUFF(pVM);
    283     if (pVM->pdm.s.Apic.CTX_SUFF(pDevIns))
    284     {
    285         Assert(pVM->pdm.s.Apic.CTX_SUFF(pfnSetBaseMsr));
    286         VBOXSTRICTRC rcStrict = pVM->pdm.s.Apic.CTX_SUFF(pfnSetBaseMsr)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), pVCpu, u64Base);
    287 
    288         /* Update CPUM's copy of the APIC base. */
    289         PCPUMCTX pCtx = CPUMQueryGuestCtxPtr(pVCpu);
    290         Assert(pCtx);
    291         pCtx->msrApicBase = pVM->pdm.s.Apic.CTX_SUFF(pfnGetBaseMsr)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), pVCpu);
    292 
    293         return rcStrict;
    294     }
    295 
    296 #ifdef IN_RING3
    297     LogRelMax(5, ("PDM: APIC%U: Writing APIC base MSR (%#x) invalid since there isn't an APIC -> #GP(0)\n", pVCpu->idCpu,
    298                   MSR_IA32_APICBASE));
    299     return VERR_CPUM_RAISE_GP_0;
    300 #else
    301     return VINF_CPUM_R3_MSR_WRITE;
    302 #endif
    303 }
    304 
    305 
    306 /**
    307  * Get the APIC base MSR from the APIC device.
    308  *
    309  * @returns Strict VBox status code.
    310  * @param   pVCpu           The cross context virtual CPU structure.
    311  * @param   pu64Base        Where to store the APIC base.
    312  * @param   fIgnoreErrors   Whether to ignore errors (i.e. not a real guest MSR
    313  *                          access).
    314  */
    315 VMMDECL(VBOXSTRICTRC) PDMApicGetBaseMsr(PVMCPU pVCpu, uint64_t *pu64Base, bool fIgnoreErrors)
    316 {
    317     PVM pVM = pVCpu->CTX_SUFF(pVM);
    318     if (pVM->pdm.s.Apic.CTX_SUFF(pDevIns))
    319     {
    320         Assert(pVM->pdm.s.Apic.CTX_SUFF(pfnGetBaseMsr));
    321         VMCPU_ASSERT_EMT_OR_NOT_RUNNING(pVCpu);
    322         *pu64Base = pVM->pdm.s.Apic.CTX_SUFF(pfnGetBaseMsr)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), pVCpu);
    323         return VINF_SUCCESS;
    324     }
    325 
    326     *pu64Base = 0;
    327     if (fIgnoreErrors)
    328         return VINF_SUCCESS;
    329 
    330 #ifdef IN_RING3
    331     LogRelMax(5, ("PDM: APIC%u: Reading APIC base MSR (%#x) invalid without an APIC instance -> #GP(0)\n", pVCpu->idCpu,
    332                   MSR_IA32_APICBASE));
    333     return VERR_CPUM_RAISE_GP_0;
    334 #else
    335     return VINF_CPUM_R3_MSR_WRITE;
    336 #endif
    337 }
    338 
    339 
    340 /**
    341  * Set the TPR (Task Priority Register).
    342  *
    343  * @returns VBox status code.
    344  * @param   pVCpu           The cross context virtual CPU structure.
    345  * @param   u8TPR           The new TPR.
    346  */
    347 VMMDECL(int) PDMApicSetTPR(PVMCPU pVCpu, uint8_t u8TPR)
    348 {
    349     PVM pVM = pVCpu->CTX_SUFF(pVM);
    350     if (pVM->pdm.s.Apic.CTX_SUFF(pDevIns))
    351     {
    352         Assert(pVM->pdm.s.Apic.CTX_SUFF(pfnSetTpr));
    353         pVM->pdm.s.Apic.CTX_SUFF(pfnSetTpr)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), pVCpu, u8TPR);
    354         return VINF_SUCCESS;
    355     }
    356     return VERR_PDM_NO_APIC_INSTANCE;
    357 }
    358 
    359 
    360 /**
    361  * Get the TPR (Task Priority Register).
    362  *
    363  * @returns VINF_SUCCESS or VERR_PDM_NO_APIC_INSTANCE.
    364  * @param   pVCpu           The cross context virtual CPU structure.
    365  * @param   pu8TPR          Where to store the TRP.
    366  * @param   pfPending       Where to store whether there is a pending interrupt
    367  *                          (out, optional).
    368  * @param   pu8PendingIntr  Where to store the highest-priority pending
    369  *                          interrupt (out, optional).
    370  *
    371  * @remarks No-long-jump zone!!!
    372  */
    373 VMMDECL(int) PDMApicGetTPR(PVMCPU pVCpu, uint8_t *pu8TPR, bool *pfPending, uint8_t *pu8PendingIntr)
    374 {
    375     PVM        pVM      = pVCpu->CTX_SUFF(pVM);
    376     PPDMDEVINS pApicIns = pVM->pdm.s.Apic.CTX_SUFF(pDevIns);
    377     if (pApicIns)
    378     {
    379         /*
    380          * Note! We don't acquire the PDM lock here as we're just reading
    381          *       information. Doing so causes massive contention as this
    382          *       function is called very often by each and every VCPU.
    383          */
    384         Assert(pVM->pdm.s.Apic.CTX_SUFF(pfnGetTpr));
    385         *pu8TPR = pVM->pdm.s.Apic.CTX_SUFF(pfnGetTpr)(pApicIns, pVCpu, pfPending, pu8PendingIntr);
    386         return VINF_SUCCESS;
    387     }
    388     *pu8TPR = 0;
    389     return VERR_PDM_NO_APIC_INSTANCE;
    390 }
    391 
    392 
    393 /**
    394  * Write a MSR in APIC range.
    395  *
    396  * @returns Strict VBox status code.
    397  * @param   pVCpu           The cross context virtual CPU structure.
    398  * @param   u32Reg          MSR to write.
    399  * @param   u64Value        Value to write.
    400  */
    401 VMM_INT_DECL(VBOXSTRICTRC) PDMApicWriteMsr(PVMCPU pVCpu, uint32_t u32Reg, uint64_t u64Value)
    402 {
    403     PVM pVM = pVCpu->CTX_SUFF(pVM);
    404     if (pVM->pdm.s.Apic.CTX_SUFF(pDevIns))
    405     {
    406         AssertPtr(pVM->pdm.s.Apic.CTX_SUFF(pfnWriteMsr));
    407         return pVM->pdm.s.Apic.CTX_SUFF(pfnWriteMsr)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), pVCpu, u32Reg, u64Value);
    408     }
    409     return VERR_CPUM_RAISE_GP_0;
    410 }
    411 
    412 
    413 /**
    414  * Read a MSR in APIC range.
    415  *
    416  * @returns Strict VBox status code.
    417  * @param   pVCpu           The cross context virtual CPU structure.
    418  * @param   u32Reg          MSR to read.
    419  * @param   pu64Value       Where to store the value read.
    420  */
    421 VMM_INT_DECL(VBOXSTRICTRC) PDMApicReadMsr(PVMCPU pVCpu, uint32_t u32Reg, uint64_t *pu64Value)
    422 {
    423     PVM pVM = pVCpu->CTX_SUFF(pVM);
    424     if (pVM->pdm.s.Apic.CTX_SUFF(pDevIns))
    425     {
    426         AssertPtr(pVM->pdm.s.Apic.CTX_SUFF(pfnReadMsr));
    427         return pVM->pdm.s.Apic.CTX_SUFF(pfnReadMsr)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), pVCpu, u32Reg, pu64Value);
    428     }
    429     return VERR_CPUM_RAISE_GP_0;
    430 }
    431 
    432 
    433 /**
    434  * Gets the frequency of the APIC timer.
    435  *
    436  * @returns VBox status code.
    437  * @param   pVM             The cross context VM structure.
    438  * @param   pu64Value       Where to store the frequency.
    439  */
    440 VMM_INT_DECL(int) PDMApicGetTimerFreq(PVM pVM, uint64_t *pu64Value)
    441 {
    442     if (pVM->pdm.s.Apic.CTX_SUFF(pDevIns))
    443     {
    444         AssertPtr(pVM->pdm.s.Apic.CTX_SUFF(pfnGetTimerFreq));
    445         *pu64Value = pVM->pdm.s.Apic.CTX_SUFF(pfnGetTimerFreq)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns));
    446         return VINF_SUCCESS;
    447     }
    448     return VERR_PDM_NO_APIC_INSTANCE;
    449 }
    450 
    451 
    452 /**
    453260 * Locks PDM.
    454261 * This might call back to Ring-3 in order to deal with lock contention in GC and R3.
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette