VirtualBox

Changeset 39060 in vbox


Ignore:
Timestamp:
Oct 20, 2011 2:53:51 PM (13 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
74482
Message:

DevApic,PDM: Combine the two read functions (MSR/MMIO); renamed debug info handler from lapic -> apic so it matches the device name; misc cleanups.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/vmm/pdmdev.h

    r38847 r39060  
    7676 *
    7777 * @returns VBox status.
    78  * @param   pDevIns     The device instance data. 
    79  * 
    80  * @remarks The device critical section is not entered.  The routine may delete 
     78 * @param   pDevIns     The device instance data.
     79 *
     80 * @remarks The device critical section is not entered.  The routine may delete
    8181 *          the critical section, so the caller cannot exit it.
    8282 */
     
    100100 *
    101101 * @remarks A relocation CANNOT fail.
    102  * 
    103  * @remarks The device critical section is not entered.  The relocations should 
     102 *
     103 * @remarks The device critical section is not entered.  The relocations should
    104104 *          not normally require any locking.
    105105 */
     
    123123 * @param   cbOut       Size of output data.
    124124 * @param   pcbOut      Where to store the actual size of the output data.
    125  * 
     125 *
    126126 * @remarks Not used.
    127127 */
     
    137137 * @returns VBox status.
    138138 * @param   pDevIns     The device instance data.
    139  * 
     139 *
    140140 * @remarks Caller enters the device critical section.
    141141 */
     
    149149 * @returns VBox status.
    150150 * @param   pDevIns     The device instance data.
    151  * 
     151 *
    152152 * @remarks Caller enters the device critical section.
    153153 */
     
    162162 * @param   pDevIns     The device instance data.
    163163 * @thread  EMT(0)
    164  * 
     164 *
    165165 * @remarks Caller enters the device critical section.
    166166 */
     
    174174 * @returns VBox status.
    175175 * @param   pDevIns     The device instance data.
    176  * 
     176 *
    177177 * @remarks Caller enters the device critical section.
    178178 */
     
    190190 * @param   pDevIns     The device instance data.
    191191 * @thread  EMT(0)
    192  * 
     192 *
    193193 * @remarks Caller enters the device critical section.
    194194 */
     
    210210 * @param   iLUN        The logical unit which is being detached.
    211211 * @param   fFlags      Flags, combination of the PDM_TACH_FLAGS_* \#defines.
    212  * 
     212 *
    213213 * @remarks Caller enters the device critical section.
    214214 */
     
    229229 * @param   iLUN        The logical unit which is being detached.
    230230 * @param   fFlags      Flags, combination of the PDMDEVATT_FLAGS_* \#defines.
    231  * 
     231 *
    232232 * @remarks Caller enters the device critical section.
    233233 */
     
    243243 * @param   iLUN        The logicial unit to query.
    244244 * @param   ppBase      Where to store the pointer to the base interface of the LUN.
    245  * 
     245 *
    246246 * @remarks The device critical section is not entered.
    247247 */
     
    257257 * @returns VBOX status code.
    258258 * @param   pDevIns     The device instance.
    259  * 
     259 *
    260260 * @remarks Caller enters the device critical section.
    261261 */
     
    303303    PFNPDMDEVDESTRUCT   pfnDestruct;
    304304    /** Relocation command - optional.
    305      * Critical section NOT entered. */ 
     305     * Critical section NOT entered. */
    306306    PFNPDMDEVRELOCATE   pfnRelocate;
    307307    /** I/O Control interface - optional.
     
    309309    PFNPDMDEVIOCTL      pfnIOCtl;
    310310    /** Power on notification - optional.
    311      * Critical section is entered. */ 
     311     * Critical section is entered. */
    312312    PFNPDMDEVPOWERON    pfnPowerOn;
    313     /** Reset notification - optional. 
    314      * Critical section is entered. */ 
     313    /** Reset notification - optional.
     314     * Critical section is entered. */
    315315    PFNPDMDEVRESET      pfnReset;
    316     /** Suspend notification  - optional. 
    317      * Critical section is entered. */ 
     316    /** Suspend notification  - optional.
     317     * Critical section is entered. */
    318318    PFNPDMDEVSUSPEND    pfnSuspend;
    319     /** Resume notification - optional. 
    320      * Critical section is entered. */ 
     319    /** Resume notification - optional.
     320     * Critical section is entered. */
    321321    PFNPDMDEVRESUME     pfnResume;
    322     /** Attach command - optional. 
    323      * Critical section is entered. */ 
     322    /** Attach command - optional.
     323     * Critical section is entered. */
    324324    PFNPDMDEVATTACH     pfnAttach;
    325     /** Detach notification - optional. 
    326      * Critical section is entered. */ 
     325    /** Detach notification - optional.
     326     * Critical section is entered. */
    327327    PFNPDMDEVDETACH     pfnDetach;
    328328    /** Query a LUN base interface - optional.
    329      * Critical section is NOT entered. */ 
     329     * Critical section is NOT entered. */
    330330    PFNPDMDEVQUERYINTERFACE pfnQueryInterface;
    331     /** Init complete notification - optional. 
    332      * Critical section is entered. */ 
     331    /** Init complete notification - optional.
     332     * Critical section is entered. */
    333333    PFNPDMDEVINITCOMPLETE   pfnInitComplete;
    334     /** Power off notification - optional. 
    335      * Critical section is entered. */ 
     334    /** Power off notification - optional.
     335     * Critical section is entered. */
    336336    PFNPDMDEVPOWEROFF   pfnPowerOff;
    337337    /** @todo */
     
    11331133     * @param   u32Reg          MSR to read.
    11341134     * @param   pu64Value       Where to return the read value.
     1135     *
     1136     * @remarks Unlike the other callbacks, the PDM lock is not taken before
     1137     *          calling this method.
    11351138     */
    11361139    DECLR3CALLBACKMEMBER(int, pfnReadMSRR3, (PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t u32Reg, uint64_t *pu64Value));
     
    39013904    /** The critical section for the device.
    39023905     *
    3903      * TM and IOM will enter this critical section before calling into the device 
    3904      * code.  PDM will when doing power on, power off, reset, suspend and resume 
    3905      * notifications.  SSM will currently not, but this will be changed later on. 
     3906     * TM and IOM will enter this critical section before calling into the device
     3907     * code.  PDM will when doing power on, power off, reset, suspend and resume
     3908     * notifications.  SSM will currently not, but this will be changed later on.
    39063909     *
    39073910     * The device gets a critical section automatically assigned to it before
  • trunk/src/VBox/Devices/PC/DevAPIC.cpp

    r39053 r39060  
    552552}
    553553
     554
     555/**
     556 * apicWriteRegister helper for dealing with invalid register access.
     557 *
     558 * @returns Strict VBox status code.
     559 * @param   pDev                The PDM device instance.
     560 * @param   pApic               The APIC being written to.
     561 * @param   iReg                The APIC register index.
     562 * @param   u64Value            The value being written.
     563 * @param   rcBusy              The busy return code to employ.  See
     564 *                              PDMCritSectEnter for a description.
     565 * @param   fMsr                Set if called via MSR, clear if MMIO.
     566 */
     567static int apicWriteRegisterInvalid(APICDeviceInfo *pDev, APICState *pApic, uint32_t iReg, uint64_t u64Value,
     568                                    int rcBusy, bool fMsr)
     569{
     570    Log(("apicWriteRegisterInvalid/%u: iReg=%#x fMsr=%RTbool u64Value=%#llx\n", pApic->phys_id, iReg, fMsr, u64Value));
     571    int rc = PDMDevHlpDBGFStop(pDev->CTX_SUFF(pDevIns), RT_SRC_POS,
     572                               "iReg=%#x fMsr=%RTbool u64Value=%#llx id=%u\n", iReg, fMsr, u64Value, pApic->phys_id);
     573    APIC_LOCK(pDev, rcBusy);
     574    pApic->esr |= ESR_ILLEGAL_ADDRESS;
     575    APIC_UNLOCK(pDev);
     576    return rc;
     577}
     578
     579
     580
    554581/**
    555582 * Writes to an APIC register via MMIO or MSR.
     
    636663
    637664        case 0x31:
    638             APIC_LOCK(pDev, rcBusy);
    639665            if (!fMsr)
     666            {
     667                APIC_LOCK(pDev, rcBusy);
    640668                pApic->icr[1] = (uint64_t)u64Value;
     669                APIC_UNLOCK(pDev);
     670            }
    641671            else
    642                 pApic->esr |= ESR_ILLEGAL_ADDRESS;
    643             APIC_UNLOCK(pDev);
     672                rc = apicWriteRegisterInvalid(pDev, pApic, iReg, u64Value, rcBusy, fMsr);
    644673            break;
    645674
     
    693722            }
    694723            /* else: fall thru */
     724
    695725        default:
    696             Log(("apicWriteRegister/%u: unknown index %#x\n", pApic->phys_id, iReg));
    697             rc = PDMDevHlpDBGFStop(pDev->CTX_SUFF(pDevIns), RT_SRC_POS,
    698                                    "unknown index %#x (id=%u)\n", iReg, pApic->phys_id);
    699             pApic->esr |= ESR_ILLEGAL_ADDRESS;
     726            rc = apicWriteRegisterInvalid(pDev, pApic, iReg, u64Value, rcBusy, fMsr);
    700727            break;
    701728    }
     
    704731}
    705732
    706 /**
    707  * @interface_method_impl{PDMAPICREG,pfnWriteMSRR3}
    708  */
    709 PDMBOTHCBDECL(int) apicWriteMSR(PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t u32Reg, uint64_t u64Value)
    710 {
    711     APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
    712     if (pDev->enmVersion < PDMAPICVERSION_X2APIC)
    713         return VERR_EM_INTERPRETER; /** @todo tell the caller to raise hell (\#GP(0)).  */
    714 
    715     APICState      *pApic = getLapicById(pDev, idCpu);
    716     uint32_t        iReg = (u32Reg - MSR_IA32_APIC_START) & 0xff;
    717     return apicWriteRegister(pDev, pApic, iReg, u64Value, VINF_SUCCESS /*rcBusy*/, true /*fMsr*/);
    718 }
    719 
    720 
    721 /**
    722  * @interface_method_impl{PDMAPICREG,pfnReadMSRR3}
    723  */
    724 PDMBOTHCBDECL(int) apicReadMSR(PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t u32Reg, uint64_t *pu64Value)
    725 {
    726     APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
    727     Assert(PDMCritSectIsOwner(pDev->CTX_SUFF(pCritSect)));
    728 
    729     if (pDev->enmVersion < PDMAPICVERSION_X2APIC)
    730         return VERR_EM_INTERPRETER;
    731 
    732     uint32_t    index = (u32Reg - MSR_IA32_APIC_START) & 0xff;
    733     APICState  *apic = getLapicById(pDev, idCpu);
    734     uint64_t    val = 0;
    735     int         rc = VINF_SUCCESS;
    736 
    737     switch (index)
     733
     734/**
     735 * apicReadRegister helper for dealing with invalid register access.
     736 *
     737 * @returns Strict VBox status code.
     738 * @param   pDev                The PDM device instance.
     739 * @param   pApic               The APIC being read to.
     740 * @param   iReg                The APIC register index.
     741 * @param   pu64Value           Where to store the value we've read.
     742 * @param   rcBusy              The busy return code to employ.  See
     743 *                              PDMCritSectEnter for a description.
     744 * @param   fMsr                Set if called via MSR, clear if MMIO.
     745 */
     746static int apicReadRegisterInvalid(APICDeviceInfo *pDev, APICState *pApic, uint32_t iReg, uint64_t *pu64Value,
     747                                   int rcBusy, bool fMsr)
     748{
     749    Log(("apicReadRegisterInvalid/%u: iReg=%#x fMsr=%RTbool\n", pApic->phys_id, iReg, fMsr));
     750    int rc = PDMDevHlpDBGFStop(pDev->CTX_SUFF(pDevIns), RT_SRC_POS,
     751                               "iReg=%#x fMsr=%RTbool id=%u\n", iReg, fMsr, pApic->phys_id);
     752    APIC_LOCK(pDev, rcBusy);
     753    pApic->esr |= ESR_ILLEGAL_ADDRESS;
     754    APIC_UNLOCK(pDev);
     755    *pu64Value = 0;
     756    return rc;
     757}
     758
     759
     760/**
     761 * Read from an APIC register via MMIO or MSR.
     762 *
     763 * @returns Strict VBox status code.
     764 * @param   pDev                The PDM device instance.
     765 * @param   pApic               The APIC being read to.
     766 * @param   iReg                The APIC register index.
     767 * @param   pu64Value           Where to store the value we've read.
     768 * @param   rcBusy              The busy return code to employ.  See
     769 *                              PDMCritSectEnter for a description.
     770 * @param   fMsr                Set if called via MSR, clear if MMIO.
     771 */
     772static int apicReadRegister(APICDeviceInfo *pDev, APICState *pApic, uint32_t iReg, uint64_t *pu64Value,
     773                            int rcBusy, bool fMsr)
     774{
     775    Assert(!PDMCritSectIsOwner(pDev->CTX_SUFF(pCritSect)));
     776
     777    int rc = VINF_SUCCESS;
     778    switch (iReg)
    738779    {
    739780        case 0x02: /* id */
    740             val = apic->id << 24;
    741             break;
     781            APIC_LOCK(pDev, rcBusy);
     782            *pu64Value = pApic->id << 24;
     783            APIC_UNLOCK(pDev);
     784            break;
     785
    742786        case 0x03: /* version */
    743             val = APIC_HW_VERSION
    744                 | ((APIC_LVT_NB - 1) << 16) /* Max LVT index */
    745                 | (0 << 24) /* Support for EOI broadcast suppression */;
    746             break;
     787            APIC_LOCK(pDev, rcBusy);
     788            *pu64Value = APIC_HW_VERSION
     789                       | ((APIC_LVT_NB - 1) << 16) /* Max LVT index */
     790#if 0
     791                       | (0 << 24) /* Support for EOI broadcast suppression */
     792#endif
     793                       ;
     794            APIC_UNLOCK(pDev);
     795            break;
     796
    747797        case 0x08:
    748             val = apic->tpr;
    749             break;
     798            APIC_LOCK(pDev, rcBusy);
     799            *pu64Value = pApic->tpr;
     800            APIC_UNLOCK(pDev);
     801            break;
     802
    750803        case 0x09:
    751             val = apic_get_arb_pri(apic);
    752             break;
     804            *pu64Value = apic_get_arb_pri(pApic);
     805            break;
     806
    753807        case 0x0a:
    754808            /* ppr */
    755             val = apic_get_ppr(apic);
    756             break;
     809            APIC_LOCK(pDev, rcBusy);
     810            *pu64Value = apic_get_ppr(pApic);
     811            APIC_UNLOCK(pDev);
     812            break;
     813
    757814        case 0x0b:
    758             val = 0;
    759             break;
     815            Log(("apicReadRegister: %x -> write only returning 0\n", iReg));
     816            *pu64Value = 0;
     817            break;
     818
    760819        case 0x0d:
    761             val = (uint64_t)apic->log_dest << 24;
    762             break;
     820            APIC_LOCK(pDev, rcBusy);
     821            *pu64Value = (uint64_t)pApic->log_dest << 24;
     822            APIC_UNLOCK(pDev);
     823            break;
     824
    763825        case 0x0e:
    764826            /* Bottom 28 bits are always 1 */
    765             val = ((uint64_t)apic->dest_mode << 28) | 0xfffffff;
    766             break;
     827            APIC_LOCK(pDev, rcBusy);
     828            *pu64Value = ((uint64_t)pApic->dest_mode << 28) | UINT32_C(0xfffffff);
     829            APIC_UNLOCK(pDev);
     830            break;
     831
    767832        case 0x0f:
    768             val = apic->spurious_vec;
    769             break;
     833            APIC_LOCK(pDev, rcBusy);
     834            *pu64Value = pApic->spurious_vec;
     835            APIC_UNLOCK(pDev);
     836            break;
     837
    770838        case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
    771             val = apic->isr[index & 7];
    772             break;
     839            APIC_LOCK(pDev, rcBusy);
     840            *pu64Value = pApic->isr[iReg & 7];
     841            APIC_UNLOCK(pDev);
     842            break;
     843
    773844        case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
    774             val = apic->tmr[index & 7];
    775             break;
     845            APIC_LOCK(pDev, rcBusy);
     846            *pu64Value = pApic->tmr[iReg & 7];
     847            APIC_UNLOCK(pDev);
     848            break;
     849
    776850        case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
    777             val = apic->irr[index & 7];
    778             break;
     851            APIC_LOCK(pDev, rcBusy);
     852            *pu64Value = pApic->irr[iReg & 7];
     853            APIC_UNLOCK(pDev);
     854            break;
     855
    779856        case 0x28:
    780             val = apic->esr;
    781             break;
     857            APIC_LOCK(pDev, rcBusy);
     858            *pu64Value = pApic->esr;
     859            APIC_UNLOCK(pDev);
     860            break;
     861
    782862        case 0x30:
    783863            /* Here one of the differences with regular APIC: ICR is single 64-bit register */
    784             val = ((uint64_t)apic->icr[1] << 32) | apic->icr[0];
    785             break;
     864            APIC_LOCK(pDev, rcBusy);
     865            if (fMsr)
     866                *pu64Value = RT_MAKE_U64(pApic->icr[0], pApic->icr[1]);
     867            else
     868                *pu64Value = pApic->icr[0];
     869            APIC_UNLOCK(pDev);
     870            break;
     871
     872        case 0x31:
     873            if (fMsr)
     874                rc = apicReadRegisterInvalid(pDev, pApic, iReg, pu64Value, rcBusy, fMsr);
     875            else
     876            {
     877                APIC_LOCK(pDev, rcBusy);
     878                *pu64Value = pApic->icr[1];
     879                APIC_UNLOCK(pDev);
     880            }
     881            break;
     882
    786883        case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
    787             val = apic->lvt[index - 0x32];
    788             break;
     884            APIC_LOCK(pDev, rcBusy);
     885            *pu64Value = pApic->lvt[iReg - 0x32];
     886            APIC_UNLOCK(pDev);
     887            break;
     888
    789889        case 0x38:
    790             val = apic->initial_count;
    791             break;
     890            APIC_LOCK(pDev, rcBusy);
     891            *pu64Value = pApic->initial_count;
     892            APIC_UNLOCK(pDev);
     893            break;
     894
    792895        case 0x39:
    793             val = apic_get_current_count(pDev, apic);
    794             break;
     896            APIC_AND_TM_LOCK(pDev, pApic, rcBusy);
     897            *pu64Value = apic_get_current_count(pDev, pApic);
     898            APIC_AND_TM_UNLOCK(pDev, pApic);
     899            break;
     900
    795901        case 0x3e:
    796             val = apic->divide_conf;
    797             break;
     902            APIC_LOCK(pDev, rcBusy);
     903            *pu64Value = pApic->divide_conf;
     904            APIC_UNLOCK(pDev);
     905            break;
     906
    798907        case 0x3f:
    799             /* Self IPI register is write only */
    800             Log(("apicReadMSR: read from write-only register %d ignored\n", index));
    801             break;
    802         case 0x2f:
    803             /**
    804              * Correctable machine check exception vector, @todo: implement me!
    805              */
     908            if (fMsr)
     909            {
     910                /* Self IPI register is write only */
     911                Log(("apicReadMSR: read from write-only register %d ignored\n", iReg));
     912                *pu64Value = 0;
     913            }
     914            else
     915                rc = apicReadRegisterInvalid(pDev, pApic, iReg, pu64Value, rcBusy, fMsr);
     916            break;
     917        case 0x2f: /** @todo Correctable machine check exception vector,  implement me! */
    806918        default:
    807919            /**
     
    809921             *        i.e. LVT[5]
    810922             */
    811             Log(("apicReadMSR/%u: unknown index %#x\n", apic->phys_id, index));
    812             rc = PDMDevHlpDBGFStop(pDev->CTX_SUFF(pDevIns), RT_SRC_POS,
    813                                    "unknown index %#x (id=%u)\n", index, apic->phys_id);
    814             apic->esr |= ESR_ILLEGAL_ADDRESS;
    815             val = 0;
    816             break;
    817     }
    818     *pu64Value = val;
     923            rc = apicReadRegisterInvalid(pDev, pApic, iReg, pu64Value, rcBusy, fMsr);
     924            break;
     925    }
    819926    return rc;
     927}
     928
     929/**
     930 * @interface_method_impl{PDMAPICREG,pfnWriteMSRR3}
     931 */
     932PDMBOTHCBDECL(int) apicWriteMSR(PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t u32Reg, uint64_t u64Value)
     933{
     934    APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
     935    if (pDev->enmVersion < PDMAPICVERSION_X2APIC)
     936        return VERR_EM_INTERPRETER; /** @todo tell the caller to raise hell (\#GP(0)).  */
     937
     938    APICState      *pApic = getLapicById(pDev, idCpu);
     939    uint32_t        iReg = (u32Reg - MSR_IA32_APIC_START) & 0xff;
     940    return apicWriteRegister(pDev, pApic, iReg, u64Value, VINF_SUCCESS /*rcBusy*/, true /*fMsr*/);
     941}
     942
     943
     944/**
     945 * @interface_method_impl{PDMAPICREG,pfnReadMSRR3}
     946 */
     947PDMBOTHCBDECL(int) apicReadMSR(PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t u32Reg, uint64_t *pu64Value)
     948{
     949    APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
     950    Assert(PDMCritSectIsOwner(pDev->CTX_SUFF(pCritSect)));
     951
     952    if (pDev->enmVersion < PDMAPICVERSION_X2APIC)
     953        return VERR_EM_INTERPRETER;
     954
     955    APICState      *pApic = getLapicById(pDev, idCpu);
     956    uint32_t        iReg = (u32Reg - MSR_IA32_APIC_START) & 0xff;
     957    return apicReadRegister(pDev, pApic, iReg, pu64Value, VINF_SUCCESS /*rcBusy*/, true /*fMsr*/);
    820958}
    821959
     
    12341372
    12351373/**
    1236  * May return to ring-3 to acquire the TM and PDM lock.
    1237  */
    1238 static uint32_t apic_get_current_count(APICDeviceInfo const *pDev, APICState const *s)
    1239 {
    1240     int64_t d;
     1374 * @remarks Caller (apicReadRegister) takes both the TM and APIC locks before
     1375 *          calling this function.
     1376 */
     1377static uint32_t apic_get_current_count(APICDeviceInfo const *pDev, APICState const *pApic)
     1378{
     1379    int64_t d = (TMTimerGet(pApic->CTX_SUFF(pTimer)) - pApic->initial_count_load_time)
     1380             >> pApic->count_shift;
     1381
    12411382    uint32_t val;
    1242 
    1243     /* Acquire the timer lock w/ lock order kludge. */
    1244     PDMCritSectLeave(pDev->CTX_SUFF(pCritSect));
    1245     TMTimerLock(s->CTX_SUFF(pTimer), VINF_SUCCESS);
    1246     PDMCritSectEnter(pDev->CTX_SUFF(pCritSect), VINF_SUCCESS);
    1247 
    1248     d = (TMTimerGet(s->CTX_SUFF(pTimer)) - s->initial_count_load_time) >>
    1249         s->count_shift;
    1250 
    1251     if (s->lvt[APIC_LVT_TIMER] & APIC_LVT_TIMER_PERIODIC) {
     1383    if (pApic->lvt[APIC_LVT_TIMER] & APIC_LVT_TIMER_PERIODIC)
    12521384        /* periodic */
    1253         val = s->initial_count - (d % ((uint64_t)s->initial_count + 1));
    1254     } else {
    1255         if (d >= s->initial_count)
    1256             val = 0;
    1257         else
    1258             val = s->initial_count - d;
    1259     }
    1260 
    1261     TMTimerUnlock(s->CTX_SUFF(pTimer));
     1385        val = pApic->initial_count - (d % ((uint64_t)pApic->initial_count + 1));
     1386    else if (d >= pApic->initial_count)
     1387        val = 0;
     1388    else
     1389        val = pApic->initial_count - d;
    12621390
    12631391    return val;
     
    13871515         * We postpone stopping the timer when it's masked, this way we can
    13881516         * avoid some timer work when the guest temporarily masks the timer.
    1389          * (apicTimerCallback will stop it if still masked.)
     1517         * (apicR3TimerCallback will stop it if still masked.)
    13901518         */
    13911519        if (fNew & APIC_LVT_MASKED)
     
    14461574 * @param  pvUser       User argument pointing to the APIC instance.
    14471575 */
    1448 static DECLCALLBACK(void) apicTimerCallback(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
     1576static DECLCALLBACK(void) apicR3TimerCallback(PPDMDEVINS pDevIns, PTMTIMER pTimer, void *pvUser)
    14491577{
    14501578    APICDeviceInfo *pDev   = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
     
    14661594            pApic->fTimerArmed = true;
    14671595            apicDoFrequencyHinting(pApic);
    1468             Log2(("apicTimerCallback: ic=%#x sh=%#x nxt=%#llx\n", pApic->initial_count, pApic->count_shift, pApic->next_time));
     1596            Log2(("apicR3TimerCallback: ic=%#x sh=%#x nxt=%#llx\n", pApic->initial_count, pApic->count_shift, pApic->next_time));
    14691597        } else {
    14701598            /* single shot or disabled. */
     
    14781606    }
    14791607}
    1480 # endif /* IN_RING3 */
    1481 
    1482 static int apic_mem_readl(APICDeviceInfo *pDev, APICState *s, RTGCPHYS addr, uint32_t *pu32)
    1483 {
    1484     int         rc = VINF_SUCCESS;
    1485     int         index = (addr >> 4) & 0xff;
    1486     uint32_t    val;
    1487 
    1488     switch (index) {
    1489     case 0x02: /* id */
    1490         val = s->id << 24;
    1491         break;
    1492     case 0x03: /* version */
    1493         val = APIC_HW_VERSION | ((APIC_LVT_NB - 1) << 16);
    1494         break;
    1495     case 0x08:
    1496         val = s->tpr;
    1497         break;
    1498     case 0x09:
    1499         val = apic_get_arb_pri(s);
    1500         break;
    1501     case 0x0a:
    1502         /* ppr */
    1503         val = apic_get_ppr(s);
    1504         break;
    1505     case 0x0b:
    1506         Log(("apic_mem_readl %x %x -> write only returning 0\n", addr, index));
    1507         val = 0;
    1508         break;
    1509     case 0x0d:
    1510         val = s->log_dest << 24;
    1511         break;
    1512     case 0x0e:
    1513         /* Bottom 28 bits are always 1 */
    1514         val = (s->dest_mode << 28) | 0xfffffff;
    1515         break;
    1516     case 0x0f:
    1517         val = s->spurious_vec;
    1518         break;
    1519     case 0x10: case 0x11: case 0x12: case 0x13: case 0x14: case 0x15: case 0x16: case 0x17:
    1520         val = s->isr[index & 7];
    1521         break;
    1522     case 0x18: case 0x19: case 0x1a: case 0x1b: case 0x1c: case 0x1d: case 0x1e: case 0x1f:
    1523         val = s->tmr[index & 7];
    1524         break;
    1525     case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27:
    1526         val = s->irr[index & 7];
    1527         break;
    1528     case 0x28:
    1529         val = s->esr;
    1530         break;
    1531     case 0x30:
    1532     case 0x31:
    1533         val = s->icr[index & 1];
    1534         break;
    1535     case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37:
    1536         val = s->lvt[index - 0x32];
    1537         break;
    1538     case 0x38:
    1539         val = s->initial_count;
    1540         break;
    1541     case 0x39:
    1542         val = apic_get_current_count(pDev, s);
    1543         break;
    1544     case 0x3e:
    1545         val = s->divide_conf;
    1546         break;
    1547     case 0x2f:
    1548         /** @todo
    1549          * Correctable machine check exception vector, implement me!
    1550          */
    1551     default:
    1552         s->esr |= ESR_ILLEGAL_ADDRESS;
    1553         *pu32 = 0;
    1554         Log(("APIC/%u: unknown index %#x (%RGp)\n", s->phys_id, index, addr));
    1555         return PDMDevHlpDBGFStop(pDev->CTX_SUFF(pDevIns), RT_SRC_POS,
    1556                                  "unknown index %#x (%RGp) (id=%u)\n", index, addr, s->phys_id);
    1557     }
    1558 #ifdef DEBUG_APIC
    1559     Log(("CPU%d: APIC read: %08x = %08x\n", s->phys_id, (uint32_t)addr, val));
    1560 #endif
    1561     *pu32 = val;
    1562     return rc;
    1563 }
    1564 
    1565 #ifdef IN_RING3
    15661608
    15671609static void apic_save(SSMHANDLE* f, void *opaque)
     
    17051747#endif
    17061748#endif /* experimental */
    1707             APIC_LOCK(pDev, VINF_IOM_HC_MMIO_READ);
    1708             int rc = apic_mem_readl(pDev, s, GCPhysAddr, (uint32_t *)pv);
    1709             APIC_UNLOCK(pDev);
     1749
     1750            /* It does its own locking. */
     1751            uint64_t u64Value = 0;
     1752            int rc = apicReadRegister(pDev, s, (GCPhysAddr >> 4) & 0xff, &u64Value,
     1753                                      VINF_IOM_HC_MMIO_READ, false /*fMsr*/);
     1754            *(uint32_t *)pv = (uint32_t)u64Value;
    17101755            return rc;
    17111756        }
     1757
    17121758        default:
    17131759            AssertReleaseMsgFailed(("cb=%d\n", cb)); /* for now we assume simple accesses. */
     
    17491795#ifdef IN_RING3
    17501796
    1751 /* Print a 8-dword LAPIC bit map (256 bits). */
    1752 static void lapicDumpVec(APICDeviceInfo *pDev, APICState *lapic, PCDBGFINFOHLP pHlp, unsigned start)
    1753 {
    1754     for (unsigned i = 0; i < 8; ++i)
    1755     {
    1756         uint32_t val;
    1757         apic_mem_readl(pDev, lapic, start + (i << 4), &val);
    1758         pHlp->pfnPrintf(pHlp, "%08X", val);
    1759     }
     1797/**
     1798 * Wrapper around apicReadRegister.
     1799 *
     1800 * @returns 64-bit register value.
     1801 * @param   pDev                The PDM device instance.
     1802 * @param   pApic               The Local APIC in question.
     1803 * @param   iReg                The APIC register index.
     1804 */
     1805static uint64_t apicR3InfoReadReg(APICDeviceInfo *pDev, APICState *pApic, uint32_t iReg)
     1806{
     1807    uint64_t u64Value;
     1808    int rc = apicReadRegister(pDev, pApic, iReg, &u64Value, VINF_SUCCESS, true /*fMsr*/);
     1809    AssertRCReturn(rc, UINT64_MAX);
     1810    return u64Value;
     1811}
     1812
     1813
     1814/**
     1815 * Print a 8-DWORD Local APIC bit map (256 bits).
     1816 *
     1817 * @param   pDev                The PDM device instance.
     1818 * @param   pApic               The Local APIC in question.
     1819 * @param   pHlp                The output helper.
     1820 * @param   iStartReg           The register to start at.
     1821 */
     1822static void apicR3DumpVec(APICDeviceInfo *pDev, APICState *pApic, PCDBGFINFOHLP pHlp, uint32_t iStartReg)
     1823{
     1824    for (uint32_t i = 0; i < 8; ++i)
     1825        pHlp->pfnPrintf(pHlp, "%08x", apicR3InfoReadReg(pDev, pApic, iStartReg + i));
    17601826    pHlp->pfnPrintf(pHlp, "\n");
    17611827}
    17621828
    1763 /* Print basic LAPIC state. */
    1764 static DECLCALLBACK(void) lapicInfoBasic(APICDeviceInfo  *pDev, APICState *lapic, PCDBGFINFOHLP pHlp)
    1765 {
    1766     uint32_t        val;
    1767     unsigned        max_lvt;
    1768 
    1769     pHlp->pfnPrintf(pHlp, "Local APIC at %08X:\n", lapic->apicbase);
    1770     apic_mem_readl(pDev, lapic, 0x20, &val);
    1771     pHlp->pfnPrintf(pHlp, "  LAPIC ID  : %08X\n", val);
    1772     pHlp->pfnPrintf(pHlp, "    APIC ID = %02X\n", (val >> 24) & 0xff);
    1773     apic_mem_readl(pDev, lapic, 0x30, &val);
    1774     max_lvt = (val >> 16) & 0xff;
    1775     pHlp->pfnPrintf(pHlp, "  APIC VER   : %08X\n", val);
    1776     pHlp->pfnPrintf(pHlp, "    version  = %02X\n", val & 0xff);
    1777     pHlp->pfnPrintf(pHlp, "    lvts     = %d\n", ((val >> 16) & 0xff) + 1);
    1778     apic_mem_readl(pDev, lapic, 0x80, &val);
    1779     pHlp->pfnPrintf(pHlp, "  TPR        : %08X\n", val);
    1780     pHlp->pfnPrintf(pHlp, "    task pri = %d/%d\n", (val >> 4) & 0xf, val & 0xf);
    1781     apic_mem_readl(pDev, lapic, 0xA0, &val);
    1782     pHlp->pfnPrintf(pHlp, "  PPR        : %08X\n", val);
    1783     pHlp->pfnPrintf(pHlp, "    cpu pri  = %d/%d\n", (val >> 4) & 0xf, val & 0xf);
    1784     apic_mem_readl(pDev, lapic, 0xD0, &val);
    1785     pHlp->pfnPrintf(pHlp, "  LDR       : %08X\n", val);
    1786     pHlp->pfnPrintf(pHlp, "    log id  = %02X\n", (val >> 24) & 0xff);
    1787     apic_mem_readl(pDev, lapic, 0xE0, &val);
    1788     pHlp->pfnPrintf(pHlp, "  DFR       : %08X\n", val);
    1789     apic_mem_readl(pDev, lapic, 0xF0, &val);
    1790     pHlp->pfnPrintf(pHlp, "  SVR       : %08X\n", val);
    1791     pHlp->pfnPrintf(pHlp, "    focus   = %s\n", val & (1 << 9) ? "check off" : "check on");
    1792     pHlp->pfnPrintf(pHlp, "    lapic   = %s\n", val & (1 << 8) ? "ENABLED" : "DISABLED");
    1793     pHlp->pfnPrintf(pHlp, "    vector  = %02X\n", val & 0xff);
     1829/**
     1830 * Print basic Local APIC state.
     1831 *
     1832 * @param   pDev                The PDM device instance.
     1833 * @param   pApic               The Local APIC in question.
     1834 * @param   pHlp                The output helper.
     1835 */
     1836static void apicR3InfoBasic(APICDeviceInfo  *pDev, APICState *pApic, PCDBGFINFOHLP pHlp)
     1837{
     1838    uint64_t u64;
     1839
     1840    pHlp->pfnPrintf(pHlp, "Local APIC at %08llx:\n", pApic->apicbase);
     1841    u64 = apicR3InfoReadReg(pDev, pApic, 0x2);
     1842    pHlp->pfnPrintf(pHlp, "  LAPIC ID  : %08llx\n", u64);
     1843    pHlp->pfnPrintf(pHlp, "    APIC ID = %02llx\n", (u64 >> 24) & 0xff);
     1844    u64 = apicR3InfoReadReg(pDev, pApic, 0x3);
     1845    pHlp->pfnPrintf(pHlp, "  APIC VER   : %08llx\n", u64);
     1846    pHlp->pfnPrintf(pHlp, "    version  = %02x\n", (int)RT_BYTE1(u64));
     1847    pHlp->pfnPrintf(pHlp, "    lvts     = %d\n", (int)RT_BYTE3(u64) + 1);
     1848    u64 = apicR3InfoReadReg(pDev, pApic, 0x8);
     1849    pHlp->pfnPrintf(pHlp, "  TPR        : %08llx\n", u64);
     1850    pHlp->pfnPrintf(pHlp, "    task pri = %lld/%lld\n", (u64 >> 4) & 0xf, u64 & 0xf);
     1851    u64 = apicR3InfoReadReg(pDev, pApic, 0xA);
     1852    pHlp->pfnPrintf(pHlp, "  PPR        : %08llx\n", u64);
     1853    pHlp->pfnPrintf(pHlp, "    cpu pri  = %lld/%lld\n", (u64 >> 4) & 0xf, u64 & 0xf);
     1854    u64 = apicR3InfoReadReg(pDev, pApic, 0xD);
     1855    pHlp->pfnPrintf(pHlp, "  LDR       : %08llx\n", u64);
     1856    pHlp->pfnPrintf(pHlp, "    log id  = %02llx\n", (u64 >> 24) & 0xff);
     1857    pHlp->pfnPrintf(pHlp, "  DFR       : %08llx\n", apicR3InfoReadReg(pDev, pApic, 0xE));
     1858    u64 = apicR3InfoReadReg(pDev, pApic, 0xF);
     1859    pHlp->pfnPrintf(pHlp, "  SVR       : %08llx\n", u64);
     1860    pHlp->pfnPrintf(pHlp, "    focus   = %s\n", u64 & RT_BIT(9) ? "check off" : "check on");
     1861    pHlp->pfnPrintf(pHlp, "    lapic   = %s\n", u64 & RT_BIT(8) ? "ENABLED" : "DISABLED");
     1862    pHlp->pfnPrintf(pHlp, "    vector  = %02x\n", (unsigned)RT_BYTE1(u64));
    17941863    pHlp->pfnPrintf(pHlp, "  ISR       : ");
    1795     lapicDumpVec(pDev, lapic, pHlp, 0x100);
    1796     val = get_highest_priority_int(lapic->isr);
    1797     pHlp->pfnPrintf(pHlp, "    highest = %02X\n", val == ~0U ? 0 : val);
     1864    apicR3DumpVec(pDev, pApic, pHlp, 0x10);
     1865    int iMax = get_highest_priority_int(pApic->isr);
     1866    pHlp->pfnPrintf(pHlp, "    highest = %02x\n", iMax == -1 ? 0 : iMax);
    17981867    pHlp->pfnPrintf(pHlp, "  IRR       : ");
    1799     lapicDumpVec(pDev, lapic, pHlp, 0x200);
    1800     val = get_highest_priority_int(lapic->irr);
    1801     pHlp->pfnPrintf(pHlp, "    highest = %02X\n", val == ~0U ? 0 : val);
    1802     apic_mem_readl(pDev, lapic, 0x320, &val);
    1803 }
    1804 
    1805 /* Print the more interesting LAPIC LVT entries. */
    1806 static DECLCALLBACK(void) lapicInfoLVT(APICDeviceInfo  *pDev, APICState *lapic, PCDBGFINFOHLP pHlp)
    1807 {
    1808     static const char *s_apszDeliveryModes[] =
     1868    apicR3DumpVec(pDev, pApic, pHlp, 0x20);
     1869    iMax = get_highest_priority_int(pApic->irr);
     1870    pHlp->pfnPrintf(pHlp, "    highest = %02X\n", iMax == -1 ? 0 : iMax);
     1871}
     1872
     1873
     1874/**
     1875 * Print the more interesting Local APIC LVT entries.
     1876 *
     1877 * @param   pDev                The PDM device instance.
     1878 * @param   pApic               The Local APIC in question.
     1879 * @param   pHlp                The output helper.
     1880 */
     1881static void apicR3InfoLVT(APICDeviceInfo *pDev, APICState *pApic, PCDBGFINFOHLP pHlp)
     1882{
     1883    static const char * const s_apszDeliveryModes[] =
    18091884    {
    18101885        "Fixed ", "Reserved", "SMI", "Reserved", "NMI", "INIT", "Reserved", "ExtINT"
    18111886    };
    1812     uint32_t val;
    1813 
    1814     apic_mem_readl(pDev, lapic, 0x320, &val);
    1815     pHlp->pfnPrintf(pHlp, "  LVT Timer : %08X\n", val);
    1816     pHlp->pfnPrintf(pHlp, "    mode    = %s\n", val & (1 << 17) ? "periodic" : "one-shot");
    1817     pHlp->pfnPrintf(pHlp, "    mask    = %d\n", (val >> 16) & 1);
    1818     pHlp->pfnPrintf(pHlp, "    status  = %s\n", val & (1 << 12) ? "pending" : "idle");
    1819     pHlp->pfnPrintf(pHlp, "    vector  = %02X\n", val & 0xff);
    1820     apic_mem_readl(pDev, lapic, 0x350, &val);
    1821     pHlp->pfnPrintf(pHlp, "  LVT LINT0 : %08X\n", val);
    1822     pHlp->pfnPrintf(pHlp, "    mask    = %d\n", (val >> 16) & 1);
    1823     pHlp->pfnPrintf(pHlp, "    trigger = %s\n", val & (1 << 15) ? "level" : "edge");
    1824     pHlp->pfnPrintf(pHlp, "    rem irr = %d\n", (val >> 14) & 1);
    1825     pHlp->pfnPrintf(pHlp, "    polarty = %d\n", (val >> 13) & 1);
    1826     pHlp->pfnPrintf(pHlp, "    status  = %s\n", val & (1 << 12) ? "pending" : "idle");
    1827     pHlp->pfnPrintf(pHlp, "    delivry = %s\n", s_apszDeliveryModes[(val >> 8) & 7]);
    1828     pHlp->pfnPrintf(pHlp, "    vector  = %02X\n", val & 0xff);
    1829     apic_mem_readl(pDev, lapic, 0x360, &val);
    1830     pHlp->pfnPrintf(pHlp, "  LVT LINT1 : %08X\n", val);
    1831     pHlp->pfnPrintf(pHlp, "    mask    = %d\n", (val >> 16) & 1);
    1832     pHlp->pfnPrintf(pHlp, "    trigger = %s\n", val & (1 << 15) ? "level" : "edge");
    1833     pHlp->pfnPrintf(pHlp, "    rem irr = %d\n", (val >> 14) & 1);
    1834     pHlp->pfnPrintf(pHlp, "    polarty = %d\n", (val >> 13) & 1);
    1835     pHlp->pfnPrintf(pHlp, "    status  = %s\n", val & (1 << 12) ? "pending" : "idle");
    1836     pHlp->pfnPrintf(pHlp, "    delivry = %s\n", s_apszDeliveryModes[(val >> 8) & 7]);
    1837     pHlp->pfnPrintf(pHlp, "    vector  = %02X\n", val & 0xff);
    1838 }
    1839 
    1840 /* Print LAPIC timer state. */
    1841 static DECLCALLBACK(void) lapicInfoTimer(APICDeviceInfo *pDev, APICState *lapic, PCDBGFINFOHLP pHlp)
    1842 {
    1843     uint32_t        val;
    1844     unsigned        divider;
    1845 
     1887    uint64_t u64;
     1888
     1889    u64 = apicR3InfoReadReg(pDev, pApic, 0x32);
     1890    pHlp->pfnPrintf(pHlp, "  LVT Timer : %08llx\n", u64);
     1891    pHlp->pfnPrintf(pHlp, "    mode    = %s\n", u64 & RT_BIT(17) ? "periodic" : "one-shot");
     1892    pHlp->pfnPrintf(pHlp, "    mask    = %llu\n", (u64 >> 16) & 1);
     1893    pHlp->pfnPrintf(pHlp, "    status  = %s\n", u64 & RT_BIT(12) ? "pending" : "idle");
     1894    pHlp->pfnPrintf(pHlp, "    vector  = %02llx\n", u64 & 0xff);
     1895    u64 = apicR3InfoReadReg(pDev, pApic, 0x35);
     1896    pHlp->pfnPrintf(pHlp, "  LVT LINT0 : %08llx\n", u64);
     1897    pHlp->pfnPrintf(pHlp, "    mask    = %llu\n", (u64 >> 16) & 1);
     1898    pHlp->pfnPrintf(pHlp, "    trigger = %s\n", u64 & RT_BIT(15) ? "level" : "edge");
     1899    pHlp->pfnPrintf(pHlp, "    rem irr = %llu\n", (u64 >> 14) & 1);
     1900    pHlp->pfnPrintf(pHlp, "    polarty = %llu\n", (u64 >> 13) & 1);
     1901    pHlp->pfnPrintf(pHlp, "    status  = %s\n", u64 & RT_BIT(12) ? "pending" : "idle");
     1902    pHlp->pfnPrintf(pHlp, "    delivry = %s\n", s_apszDeliveryModes[(u64 >> 8) & 7]);
     1903    pHlp->pfnPrintf(pHlp, "    vector  = %02llx\n", u64 & 0xff);
     1904    u64 = apicR3InfoReadReg(pDev, pApic, 0x36);
     1905    pHlp->pfnPrintf(pHlp, "  LVT LINT1 : %08llx\n", u64);
     1906    pHlp->pfnPrintf(pHlp, "    mask    = %llu\n", (u64 >> 16) & 1);
     1907    pHlp->pfnPrintf(pHlp, "    trigger = %s\n", u64 & RT_BIT(15) ? "level" : "edge");
     1908    pHlp->pfnPrintf(pHlp, "    rem irr = %lld\n", (u64 >> 14) & 1);
     1909    pHlp->pfnPrintf(pHlp, "    polarty = %lld\n", (u64 >> 13) & 1);
     1910    pHlp->pfnPrintf(pHlp, "    status  = %s\n", u64 & RT_BIT(12) ? "pending" : "idle");
     1911    pHlp->pfnPrintf(pHlp, "    delivry = %s\n", s_apszDeliveryModes[(u64 >> 8) & 7]);
     1912    pHlp->pfnPrintf(pHlp, "    vector  = %02llx\n", u64 & 0xff);
     1913}
     1914
     1915
     1916/**
     1917 * Print LAPIC timer state.
     1918 *
     1919 * @param   pDev                The PDM device instance.
     1920 * @param   pApic               The Local APIC in question.
     1921 * @param   pHlp                The output helper.
     1922 */
     1923static void apicR3InfoTimer(APICDeviceInfo *pDev, APICState *pApic, PCDBGFINFOHLP pHlp)
     1924{
    18461925    pHlp->pfnPrintf(pHlp, "Local APIC timer:\n");
    1847     apic_mem_readl(pDev, lapic, 0x380, &val);
    1848     pHlp->pfnPrintf(pHlp, "  Initial count : %08X\n", val);
    1849     apic_mem_readl(pDev, lapic, 0x390, &val);
    1850     pHlp->pfnPrintf(pHlp, "  Current count : %08X\n", val);
    1851     apic_mem_readl(pDev, lapic, 0x3E0, &val);
    1852     pHlp->pfnPrintf(pHlp, "  Divide config : %08X\n", val);
    1853     divider = ((val >> 1) & 0x04) | (val & 0x03);
    1854     pHlp->pfnPrintf(pHlp, "    divider     = %d\n", divider == 7 ? 1 : 2 << divider);
    1855 }
    1856 
    1857 /**
    1858  * Info handler, device version. Dumps Local APIC(s) state according to given argument.
    1859  *
    1860  * @param   pDevIns     Device instance which registered the info.
    1861  * @param   pHlp        Callback functions for doing output.
    1862  * @param   pszArgs     Argument string. Optional.
    1863  */
    1864 static DECLCALLBACK(void) lapicInfo(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
    1865 {
    1866     APICDeviceInfo  *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
    1867     APICState       *lapic;
    1868 
    1869     lapic = getLapic(pDev);
     1926    pHlp->pfnPrintf(pHlp, "  Initial count : %08llx\n", apicR3InfoReadReg(pDev, pApic, 0x38));
     1927    pHlp->pfnPrintf(pHlp, "  Current count : %08llx\n", apicR3InfoReadReg(pDev, pApic, 0x39));
     1928    uint64_t u64 = apicR3InfoReadReg(pDev, pApic, 0x3e);
     1929    pHlp->pfnPrintf(pHlp, "  Divide config : %08llx\n", u64);
     1930    unsigned uDivider = ((u64 >> 1) & 0x04) | (u64 & 0x03);
     1931    pHlp->pfnPrintf(pHlp, "    divider     = %u\n", uDivider == 7 ? 1 : 2 << uDivider);
     1932}
     1933
     1934
     1935/**
     1936 * @callback_method_impl{FNDBGFHANDLERDEV,
     1937 *      Dumps the Local APIC state according to given argument.}
     1938 */
     1939static DECLCALLBACK(void) apicR3Info(PPDMDEVINS pDevIns, PCDBGFINFOHLP pHlp, const char *pszArgs)
     1940{
     1941    APICDeviceInfo  *pDev  = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
     1942    APICState       *pApic = getLapic(pDev);
    18701943
    18711944    if (pszArgs == NULL || !strcmp(pszArgs, "basic"))
    1872         lapicInfoBasic(pDev, lapic, pHlp);
     1945        apicR3InfoBasic(pDev, pApic, pHlp);
    18731946    else if (!strcmp(pszArgs, "lvt"))
    1874         lapicInfoLVT(pDev, lapic, pHlp);
     1947        apicR3InfoLVT(pDev, pApic, pHlp);
    18751948    else if (!strcmp(pszArgs, "timer"))
    1876         lapicInfoTimer(pDev, lapic, pHlp);
     1949        apicR3InfoTimer(pDev, pApic, pHlp);
    18771950    else
    18781951        pHlp->pfnPrintf(pHlp, "Invalid argument. Recognized arguments are 'basic', 'lvt', 'timer'.\n");
    18791952}
    18801953
     1954
    18811955/**
    18821956 * @copydoc FNSSMDEVLIVEEXEC
    18831957 */
    1884 static DECLCALLBACK(int) apicLiveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass)
     1958static DECLCALLBACK(int) apicR3LiveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass)
    18851959{
    18861960    APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
     
    18941968}
    18951969
     1970
    18961971/**
    18971972 * @copydoc FNSSMDEVSAVEEXEC
    18981973 */
    1899 static DECLCALLBACK(int) apicSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
     1974static DECLCALLBACK(int) apicR3SaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
    19001975{
    19011976    APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
    19021977
    19031978    /* config */
    1904     apicLiveExec(pDevIns, pSSM, SSM_PASS_FINAL);
     1979    apicR3LiveExec(pDevIns, pSSM, SSM_PASS_FINAL);
    19051980
    19061981    /* save all APICs data, @todo: is it correct? */
     
    19131988 * @copydoc FNSSMDEVLOADEXEC
    19141989 */
    1915 static DECLCALLBACK(int) apicLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
     1990static DECLCALLBACK(int) apicR3LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
    19161991{
    19171992    APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
     
    19572032 * @copydoc FNPDMDEVRESET
    19582033 */
    1959 static DECLCALLBACK(void) apicReset(PPDMDEVINS pDevIns)
     2034static DECLCALLBACK(void) apicR3Reset(PPDMDEVINS pDevIns)
    19602035{
    19612036    APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
     
    19892064}
    19902065
     2066
    19912067/**
    19922068 * @copydoc FNPDMDEVRELOCATE
    19932069 */
    1994 static DECLCALLBACK(void) apicRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
     2070static DECLCALLBACK(void) apicR3Relocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
    19952071{
    19962072    APICDeviceInfo *pDev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
     
    20032079}
    20042080
    2005 DECLINLINE(void) initApicData(APICState* apic, uint8_t id)
    2006 {
    2007     int i;
    2008     memset(apic, 0, sizeof(*apic));
    2009 
    2010     /* See comment in msi.h for LAPIC base info */
    2011     apic->apicbase = VBOX_MSI_ADDR_BASE | MSR_IA32_APICBASE_ENABLE;
    2012     /* Mark first CPU as BSP */
    2013     if (id == 0)
    2014         apic->apicbase |= MSR_IA32_APICBASE_BSP;
    2015     for (i = 0; i < APIC_LVT_NB; i++)
    2016         apic->lvt[i] = 1 << 16; /* mask LVT */
    2017     apic->spurious_vec = 0xff;
    2018     apic->phys_id = apic->id = id;
    2019 }
     2081
     2082/**
     2083 * Initializes the state of one local APIC.
     2084 *
     2085 * @param   pApic       The Local APIC state to init.
     2086 * @param   id          The Local APIC ID.
     2087 */
     2088DECLINLINE(void) initApicData(APICState *pApic, uint8_t id)
     2089{
     2090    memset(pApic, 0, sizeof(*pApic));
     2091
     2092    /* See comment in msi.h for LAPIC base info. */
     2093    pApic->apicbase = VBOX_MSI_ADDR_BASE | MSR_IA32_APICBASE_ENABLE;
     2094    if (id == 0) /* Mark first CPU as BSP. */
     2095        pApic->apicbase |= MSR_IA32_APICBASE_BSP;
     2096
     2097    for (int i = 0; i < APIC_LVT_NB; i++)
     2098        pApic->lvt[i] = RT_BIT_32(16); /* mask LVT */
     2099
     2100    pApic->spurious_vec = 0xff;
     2101    pApic->phys_id      = id;
     2102    pApic->id           = id;
     2103}
     2104
    20202105
    20212106/**
    20222107 * @copydoc FNPDMDEVCONSTRUCT
    20232108 */
    2024 static DECLCALLBACK(int) apicConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg)
     2109static DECLCALLBACK(int) apicR3Construct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg)
    20252110{
    20262111    PDMAPICREG      ApicReg;
     
    21732258     * The the CPUID feature bit.
    21742259     */
    2175     /** @todo r=bird: See remark in the apicReset. */
     2260    /** @todo r=bird: See remark in the apicR3Reset. */
    21762261    uint32_t u32Eax, u32Ebx, u32Ecx, u32Edx;
    21772262    PDMDevHlpGetCpuId(pDevIns, 0, &u32Eax, &u32Ebx, &u32Ecx, &u32Edx);
     
    22252310        APICState *pApic = &pDev->paLapicsR3[i];
    22262311        pApic->pszDesc = MMR3HeapAPrintf(pVM, MM_TAG_PDM_DEVICE_USER, "APIC Timer #%u", i);
    2227         rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, apicTimerCallback, pApic,
     2312        rc = PDMDevHlpTMTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, apicR3TimerCallback, pApic,
    22282313                                    TMTIMER_FLAGS_NO_CRIT_SECT, pApic->pszDesc, &pApic->pTimerR3);
    22292314        if (RT_FAILURE(rc))
     
    22382323     */
    22392324    rc = PDMDevHlpSSMRegister3(pDevIns, APIC_SAVED_STATE_VERSION, sizeof(*pDev),
    2240                                apicLiveExec, apicSaveExec, apicLoadExec);
     2325                               apicR3LiveExec, apicR3SaveExec, apicR3LoadExec);
    22412326    if (RT_FAILURE(rc))
    22422327        return rc;
     
    22452330     * Register debugger info callback.
    22462331     */
    2247     PDMDevHlpDBGFInfoRegister(pDevIns, "lapic", "Display Local APIC state for current CPU. "
    2248                               "Recognizes 'basic', 'lvt', 'timer' as arguments, defaulting to 'basic'.", lapicInfo);
     2332    PDMDevHlpDBGFInfoRegister(pDevIns, "apic", "Display Local APIC state for current CPU. "
     2333                              "Recognizes 'basic', 'lvt', 'timer' as arguments, defaulting to 'basic'.", apicR3Info);
    22492334
    22502335#ifdef VBOX_WITH_STATISTICS
     
    23002385    sizeof(APICState),
    23012386    /* pfnConstruct */
    2302     apicConstruct,
     2387    apicR3Construct,
    23032388    /* pfnDestruct */
    23042389    NULL,
    23052390    /* pfnRelocate */
    2306     apicRelocate,
     2391    apicR3Relocate,
    23072392    /* pfnIOCtl */
    23082393    NULL,
     
    23102395    NULL,
    23112396    /* pfnReset */
    2312     apicReset,
     2397    apicR3Reset,
    23132398    /* pfnSuspend */
    23142399    NULL,
  • trunk/src/VBox/VMM/VMMAll/PDMAll.cpp

    r37475 r39060  
    336336    {
    337337        AssertPtr(pVM->pdm.s.Apic.CTX_SUFF(pfnReadMSR));
    338         pdmLock(pVM);
    339338        int rc = pVM->pdm.s.Apic.CTX_SUFF(pfnReadMSR)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), iCpu, u32Reg, pu64Value);
    340         pdmUnlock(pVM);
    341339        return rc;
    342340    }
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