VirtualBox

Changeset 13013 in vbox


Ignore:
Timestamp:
Oct 6, 2008 2:48:49 PM (17 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
37452
Message:

infrastructure work for X2APIC support

Location:
trunk
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/VBox/pdmapi.h

    r12989 r13013  
    5151VMMDECL(int)    PDMApicSetTPR(PVM pVM, uint8_t u8TPR);
    5252VMMDECL(int)    PDMApicGetTPR(PVM pVM, uint8_t *pu8TPR, bool *pfPending);
     53VMMDECL(int)    PDMApicWRMSR(PVM pVM, VMCPUID iCpu, uint32_t u32Reg, uint64_t u64Value);
     54VMMDECL(int)    PDMApicRDMSR(PVM pVM, VMCPUID iCpu, uint32_t u32Reg, uint64_t *pu64Value);
    5355VMMDECL(int)    PDMVMMDevHeapR3ToGCPhys(PVM pVM, RTR3PTR pv, RTGCPHYS *pGCPhys);
    5456
  • trunk/include/VBox/pdmdev.h

    r13005 r13013  
    992992
    993993    /**
     994     * WRMSR in APIC range.
     995     *
     996     * @returns VBox status code.
     997     * @param   pDevIns         Device instance of the APIC.
     998     * @param   iCpu            Target CPU.
     999     * @param   u32Reg          MSR to write.
     1000     * @param   u64Value        Value to write.
     1001     */
     1002    DECLR3CALLBACKMEMBER(uint32_t, pfnWRMSRR3, (PPDMDEVINS pDevIns, VMCPUID iCpu, uint32_t u32Reg, uint64_t u64Value));
     1003
     1004    /**
     1005     * RDMSR in APIC range.
     1006     *
     1007     * @returns VBox status code.
     1008     * @param   pDevIns         Device instance of the APIC.
     1009     * @param   iCpu            Target CPU.
     1010     * @param   u32Reg          MSR to read.
     1011     * @param   pu64Value       Value read.
     1012     */
     1013    DECLR3CALLBACKMEMBER(uint32_t, pfnRDMSRR3, (PPDMDEVINS pDevIns, VMCPUID iCpu, uint32_t u32Reg, uint64_t *pu64Value));
     1014
     1015    /**
    9941016     * Private interface between the IOAPIC and APIC.
    9951017     *
     
    10241046    /** The name of the RC GetTPR entry point. */
    10251047    const char         *pszGetTPRRC;
     1048    /** The name of the RC WRMSR entry point. */
     1049    const char         *pszWRMSRRC;
     1050    /** The name of the RC RDMSR entry point. */
     1051    const char         *pszRDMSRRC;
    10261052    /** The name of the RC BusDeliver entry point. */
    10271053    const char         *pszBusDeliverRC;
     
    10391065    /** The name of the R0 GetTPR entry point. */
    10401066    const char         *pszGetTPRR0;
     1067    /** The name of the R0 WRMSR entry point. */
     1068    const char         *pszWRMSRR0;
     1069    /** The name of the R0 RDMSR entry point. */
     1070    const char         *pszRDMSRR0;
    10411071    /** The name of the R0 BusDeliver entry point. */
    10421072    const char         *pszBusDeliverR0;
  • trunk/include/VBox/x86.h

    r12971 r13013  
    820820/** EPT capabilities. */
    821821#define MSR_IA32_VMX_EPT_CAPS               0x48C
     822/** X2APIC MSR ranges. */
     823#define MSR_IA32_APIC_START                 0x800
     824#define MSR_IA32_APIC_END                   0x900
    822825
    823826/** K6 EFER - Extended Feature Enable Register. */
  • trunk/src/VBox/Devices/PC/DevAPIC.cpp

    r12977 r13013  
    307307} APICDeviceInfo;
    308308
     309DECLINLINE(APICState*) getLapicById(APICDeviceInfo* dev, VMCPUID id)
     310{
     311    AssertFatalMsg(id < dev->cCpus, ("CPU id %d out of range\n", id));
     312    return LAPIC_BASE(dev) + id;
     313}
     314
    309315DECLINLINE(APICState*) getLapic(APICDeviceInfo* dev)
    310316{
    311317    /* LAPIC's array is indexed by CPU id */
    312318    VMCPUID id = dev->CTX_SUFF(pApicHlp)->pfnGetCpuId(dev->CTX_SUFF(pDevIns));
    313     return LAPIC_BASE(dev) + id;
     319    return getLapicById(dev, id);
    314320}
    315321
     
    360366                                           uint8_t u8DeliveryMode, uint8_t iVector, uint8_t u8Polarity,
    361367                                           uint8_t u8TriggerMode);
     368PDMBOTHCBDECL(uint32_t) apicWRMSR(PPDMDEVINS pDevIns, VMCPUID iCpu, uint32_t u32Reg, uint64_t u64Value);
     369PDMBOTHCBDECL(uint32_t) apicRDMSR(PPDMDEVINS pDevIns, VMCPUID iCpu, uint32_t u32Reg, uint64_t *pu64Value);
    362370PDMBOTHCBDECL(int)  ioapicMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
    363371PDMBOTHCBDECL(int)  ioapicMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
     
    571579    Log2(("apicGetTPR: returns %#x\n", s->tpr >> 4));
    572580    return s->tpr >> 4;
     581}
     582
     583PDMBOTHCBDECL(uint32_t) apicWRMSR(PPDMDEVINS pDevIns, VMCPUID iCpu, uint32_t u32Reg, uint64_t u64Value)
     584{
     585    return 0;
     586}
     587PDMBOTHCBDECL(uint32_t) apicRDMSR(PPDMDEVINS pDevIns, VMCPUID iCpu, uint32_t u32Reg, uint64_t *pu64Value)
     588{
     589    return 0;
    573590}
    574591
     
    19511968    ApicReg.pfnSetTPRR3             = apicSetTPR;
    19521969    ApicReg.pfnGetTPRR3             = apicGetTPR;
     1970    ApicReg.pfnWRMSRR3              = apicWRMSR;
     1971    ApicReg.pfnRDMSRR3              = apicRDMSR;
    19531972    ApicReg.pfnBusDeliverR3         = apicBusDeliverCallback;
    19541973    if (fGCEnabled) {
     
    19591978        ApicReg.pszSetTPRRC         = "apicSetTPR";
    19601979        ApicReg.pszGetTPRRC         = "apicGetTPR";
     1980        ApicReg.pszWRMSRRC          = "apicWRMSR";
     1981        ApicReg.pszRDMSRRC          = "apicRDMSR";
    19611982        ApicReg.pszBusDeliverRC     = "apicBusDeliverCallback";
    19621983    } else {
     
    19671988        ApicReg.pszSetTPRRC         = NULL;
    19681989        ApicReg.pszGetTPRRC         = NULL;
     1990        ApicReg.pszWRMSRRC          = NULL;
     1991        ApicReg.pszRDMSRRC          = NULL;
    19691992        ApicReg.pszBusDeliverRC     = NULL;
    19701993    }
     
    19761999        ApicReg.pszSetTPRR0         = "apicSetTPR";
    19772000        ApicReg.pszGetTPRR0         = "apicGetTPR";
     2001        ApicReg.pszWRMSRR0          = "apicWRMSR";
     2002        ApicReg.pszRDMSRR0          = "apicRDMSR";
    19782003        ApicReg.pszBusDeliverR0     = "apicBusDeliverCallback";
    19792004    } else {
     
    19842009        ApicReg.pszSetTPRR0         = NULL;
    19852010        ApicReg.pszGetTPRR0         = NULL;
     2011        ApicReg.pszWRMSRR0          = NULL;
     2012        ApicReg.pszRDMSRR0          = NULL;
    19862013        ApicReg.pszBusDeliverR0     = NULL;
    19872014    }
  • trunk/src/VBox/VMM/PDM.cpp

    r13005 r13013  
    432432        pVM->pdm.s.Apic.pfnGetTPRRC         += offDelta;
    433433        pVM->pdm.s.Apic.pfnBusDeliverRC     += offDelta;
     434        pVM->pdm.s.Apic.pfnWRMSRRC          += offDelta;
     435        pVM->pdm.s.Apic.pfnRDMSRRC          += offDelta;
    434436    }
    435437
  • trunk/src/VBox/VMM/PDMDevHlp.cpp

    r12984 r13013  
    14891489    VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
    14901490    LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: pApicReg=%p:{.u32Version=%#x, .pfnGetInterruptR3=%p, .pfnSetBaseR3=%p, .pfnGetBaseR3=%p, "
    1491              ".pfnSetTPRR3=%p, .pfnGetTPRR3=%p, .pfnBusDeliverR3=%p, pszGetInterruptRC=%p:{%s}, pszSetBaseRC=%p:{%s}, pszGetBaseRC=%p:{%s}, "
    1492              ".pszSetTPRRC=%p:{%s}, .pszGetTPRRC=%p:{%s}, .pszBusDeliverRC=%p:{%s}} ppApicHlpR3=%p\n",
     1491             ".pfnSetTPRR3=%p, .pfnGetTPRR3=%p, .pfnWRMSR3=%p, .pfnRDMSR3=%p, .pfnBusDeliverR3=%p, pszGetInterruptRC=%p:{%s}, pszSetBaseRC=%p:{%s}, pszGetBaseRC=%p:{%s}, "
     1492             ".pszSetTPRRC=%p:{%s}, .pszGetTPRRC=%p:{%s}, .pszWRMSRRC=%p:{%s}, .pszRDMSRRC=%p:{%s}, .pszBusDeliverRC=%p:{%s}} ppApicHlpR3=%p\n",
    14931493             pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pApicReg, pApicReg->u32Version, pApicReg->pfnGetInterruptR3, pApicReg->pfnSetBaseR3,
    1494              pApicReg->pfnGetBaseR3, pApicReg->pfnSetTPRR3, pApicReg->pfnGetTPRR3, pApicReg->pfnBusDeliverR3, pApicReg->pszGetInterruptRC,
     1494             pApicReg->pfnGetBaseR3, pApicReg->pfnSetTPRR3, pApicReg->pfnGetTPRR3, pApicReg->pfnWRMSRR3, pApicReg->pfnRDMSRR3, pApicReg->pfnBusDeliverR3, pApicReg->pszGetInterruptRC,
    14951495             pApicReg->pszGetInterruptRC, pApicReg->pszSetBaseRC, pApicReg->pszSetBaseRC, pApicReg->pszGetBaseRC, pApicReg->pszGetBaseRC,
    1496              pApicReg->pszSetTPRRC, pApicReg->pszSetTPRRC, pApicReg->pszGetTPRRC, pApicReg->pszGetTPRRC, pApicReg->pszBusDeliverRC,
     1496             pApicReg->pszSetTPRRC, pApicReg->pszSetTPRRC, pApicReg->pszGetTPRRC, pApicReg->pszGetTPRRC, pApicReg->pszWRMSRRC, pApicReg->pszWRMSRRC, pApicReg->pszRDMSRRC, pApicReg->pszRDMSRRC, pApicReg->pszBusDeliverRC,
    14971497             pApicReg->pszBusDeliverRC, ppApicHlpR3));
    14981498
     
    15121512        ||  !pApicReg->pfnSetTPRR3
    15131513        ||  !pApicReg->pfnGetTPRR3
     1514        ||  !pApicReg->pfnWRMSRR3
     1515        ||  !pApicReg->pfnRDMSRR3
    15141516        ||  !pApicReg->pfnBusDeliverR3)
    15151517    {
     
    15201522        Assert(pApicReg->pfnSetTPRR3);
    15211523        Assert(pApicReg->pfnGetTPRR3);
     1524        Assert(pApicReg->pfnWRMSRR3);
     1525        Assert(pApicReg->pfnRDMSRR3);
    15221526        Assert(pApicReg->pfnBusDeliverR3);
    15231527        LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc (R3 callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
     
    15301534            ||  pApicReg->pszSetTPRRC
    15311535            ||  pApicReg->pszGetTPRRC
     1536            ||  pApicReg->pszWRMSRRC
     1537            ||  pApicReg->pszRDMSRRC
    15321538            ||  pApicReg->pszBusDeliverRC)
    15331539        &&  (   !VALID_PTR(pApicReg->pszGetInterruptRC)
     
    15371543            ||  !VALID_PTR(pApicReg->pszSetTPRRC)
    15381544            ||  !VALID_PTR(pApicReg->pszGetTPRRC)
     1545            ||  !VALID_PTR(pApicReg->pszWRMSRRC)
     1546            ||  !VALID_PTR(pApicReg->pszRDMSRRC)
    15391547            ||  !VALID_PTR(pApicReg->pszBusDeliverRC))
    15401548       )
     
    15461554        Assert(VALID_PTR(pApicReg->pszSetTPRRC));
    15471555        Assert(VALID_PTR(pApicReg->pszGetTPRRC));
     1556        Assert(VALID_PTR(pApicReg->pszRDMSRRC));
     1557        Assert(VALID_PTR(pApicReg->pszWRMSRRC));
    15481558        Assert(VALID_PTR(pApicReg->pszBusDeliverRC));
    15491559        LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc (RC callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
     
    15561566            ||  pApicReg->pszSetTPRR0
    15571567            ||  pApicReg->pszGetTPRR0
     1568            ||  pApicReg->pszWRMSRR0
     1569            ||  pApicReg->pszRDMSRR0
    15581570            ||  pApicReg->pszBusDeliverR0)
    15591571        &&  (   !VALID_PTR(pApicReg->pszGetInterruptR0)
     
    15631575            ||  !VALID_PTR(pApicReg->pszSetTPRR0)
    15641576            ||  !VALID_PTR(pApicReg->pszGetTPRR0)
     1577            ||  !VALID_PTR(pApicReg->pszRDMSRR0)
     1578            ||  !VALID_PTR(pApicReg->pszWRMSRR0)
    15651579            ||  !VALID_PTR(pApicReg->pszBusDeliverR0))
    15661580       )
     
    15721586        Assert(VALID_PTR(pApicReg->pszSetTPRR0));
    15731587        Assert(VALID_PTR(pApicReg->pszGetTPRR0));
     1588        Assert(VALID_PTR(pApicReg->pszRDMSRR0));
     1589        Assert(VALID_PTR(pApicReg->pszWRMSRR0));
    15741590        Assert(VALID_PTR(pApicReg->pszBusDeliverR0));
    15751591        LogFlow(("pdmR3DevHlp_APICRegister: caller='%s'/%d: returns %Vrc (R0 callbacks)\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VERR_INVALID_PARAMETER));
     
    15841600
    15851601    /*
    1586      * Only one APIC device. (malc: only in UP case actually)
     1602     * Only one APIC device. On SMP we have single logical device covering all LAPICs,
     1603     * as they need to communicate and share state easily.
    15871604     */
    15881605    PVM pVM = pDevIns->Internal.s.pVMR3;
     
    16251642            rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszGetTPRRC, &pVM->pdm.s.Apic.pfnGetTPRRC);
    16261643            AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszGetTPRRC, rc));
     1644        }
     1645        if (RT_SUCCESS(rc))
     1646        {
     1647            rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszWRMSRRC, &pVM->pdm.s.Apic.pfnWRMSRRC);
     1648            AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszWRMSRRC, rc));
     1649        }
     1650        if (RT_SUCCESS(rc))
     1651        {
     1652            rc = PDMR3LdrGetSymbolRCLazy(pVM, pDevIns->pDevReg->szRCMod, pApicReg->pszRDMSRRC, &pVM->pdm.s.Apic.pfnRDMSRRC);
     1653            AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szRCMod, pApicReg->pszRDMSRRC, rc));
    16271654        }
    16281655        if (RT_SUCCESS(rc))
     
    16471674        pVM->pdm.s.Apic.pfnSetTPRRC         = 0;
    16481675        pVM->pdm.s.Apic.pfnGetTPRRC         = 0;
     1676        pVM->pdm.s.Apic.pfnWRMSRRC          = 0;
     1677        pVM->pdm.s.Apic.pfnRDMSRRC          = 0;
    16491678        pVM->pdm.s.Apic.pfnBusDeliverRC     = 0;
    16501679    }
     
    16811710            rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszGetTPRR0, &pVM->pdm.s.Apic.pfnGetTPRR0);
    16821711            AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszGetTPRR0, rc));
     1712        }
     1713        if (RT_SUCCESS(rc))
     1714        {
     1715            rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszWRMSRR0, &pVM->pdm.s.Apic.pfnWRMSRR0);
     1716            AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszWRMSRR0, rc));
     1717        }
     1718        if (RT_SUCCESS(rc))
     1719        {
     1720            rc = PDMR3LdrGetSymbolR0Lazy(pVM, pDevIns->pDevReg->szR0Mod, pApicReg->pszRDMSRR0, &pVM->pdm.s.Apic.pfnRDMSRR0);
     1721            AssertMsgRC(rc, ("%s::%s rc=%Vrc\n", pDevIns->pDevReg->szR0Mod, pApicReg->pszRDMSRR0, rc));
    16831722        }
    16841723        if (RT_SUCCESS(rc))
     
    17031742        pVM->pdm.s.Apic.pfnSetTPRR0         = 0;
    17041743        pVM->pdm.s.Apic.pfnGetTPRR0         = 0;
     1744        pVM->pdm.s.Apic.pfnWRMSRR0          = 0;
     1745        pVM->pdm.s.Apic.pfnRDMSRR0          = 0;
    17051746        pVM->pdm.s.Apic.pfnBusDeliverR0     = 0;
    17061747        pVM->pdm.s.Apic.pDevInsR0           = 0;
     
    17171758    pVM->pdm.s.Apic.pfnSetTPRR3         = pApicReg->pfnSetTPRR3;
    17181759    pVM->pdm.s.Apic.pfnGetTPRR3         = pApicReg->pfnGetTPRR3;
     1760    pVM->pdm.s.Apic.pfnWRMSRR3          = pApicReg->pfnWRMSRR3;
     1761    pVM->pdm.s.Apic.pfnRDMSRR3          = pApicReg->pfnRDMSRR3;
    17191762    pVM->pdm.s.Apic.pfnBusDeliverR3     = pApicReg->pfnBusDeliverR3;
    17201763    Log(("PDM: Registered APIC device '%s'/%d pDevIns=%p\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pDevIns));
  • trunk/src/VBox/VMM/PDMInternal.h

    r12985 r13013  
    409409    /** @copydoc PDMAPICREG::pfnGetTPRR3 */
    410410    DECLR3CALLBACKMEMBER(uint8_t,   pfnGetTPRR3,(PPDMDEVINS pDevIns));
     411    /** @copydoc PDMAPICREG::pfnWRMSRR3 */
     412    DECLR3CALLBACKMEMBER(uint32_t,  pfnWRMSRR3, (PPDMDEVINS pDevIns, VMCPUID iCpu, uint32_t u32Reg, uint64_t u64Value));
     413    /** @copydoc PDMAPICREG::pfnRDMSRR3 */
     414    DECLR3CALLBACKMEMBER(uint32_t,  pfnRDMSRR3, (PPDMDEVINS pDevIns, VMCPUID iCpu, uint32_t u32Reg, uint64_t *pu64Value));
    411415    /** @copydoc PDMAPICREG::pfnBusDeliverR3 */
    412416    DECLR3CALLBACKMEMBER(void,      pfnBusDeliverR3,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
     
    427431    /** @copydoc PDMAPICREG::pfnGetTPRR3 */
    428432    DECLR0CALLBACKMEMBER(uint8_t,   pfnGetTPRR0,(PPDMDEVINS pDevIns));
     433     /** @copydoc PDMAPICREG::pfnWRMSRR3 */
     434    DECLR0CALLBACKMEMBER(uint32_t,  pfnWRMSRR0, (PPDMDEVINS pDevIns, VMCPUID iCpu, uint32_t u32Reg, uint64_t u64Value));
     435    /** @copydoc PDMAPICREG::pfnRDMSRR3 */
     436    DECLR0CALLBACKMEMBER(uint32_t,  pfnRDMSRR0, (PPDMDEVINS pDevIns, VMCPUID iCpu, uint32_t u32Reg, uint64_t *pu64Value));
    429437    /** @copydoc PDMAPICREG::pfnBusDeliverR3 */
    430438    DECLR0CALLBACKMEMBER(void,      pfnBusDeliverR0,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
     
    445453    /** @copydoc PDMAPICREG::pfnGetTPRR3 */
    446454    DECLRCCALLBACKMEMBER(uint8_t,   pfnGetTPRRC,(PPDMDEVINS pDevIns));
     455    /** @copydoc PDMAPICREG::pfnWRMSRR3 */
     456    DECLRCCALLBACKMEMBER(uint32_t,  pfnWRMSRRC, (PPDMDEVINS pDevIns, VMCPUID iCpu, uint32_t u32Reg, uint64_t u64Value));
     457    /** @copydoc PDMAPICREG::pfnRDMSRR3 */
     458    DECLRCCALLBACKMEMBER(uint32_t,  pfnRDMSRRC, (PPDMDEVINS pDevIns, VMCPUID iCpu, uint32_t u32Reg, uint64_t *pu64Value));
    447459    /** @copydoc PDMAPICREG::pfnBusDeliverR3 */
    448460    DECLRCCALLBACKMEMBER(void,      pfnBusDeliverRC,(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
  • trunk/src/VBox/VMM/VMMAll/EMAll.cpp

    r12989 r13013  
    3434#include "EMInternal.h"
    3535#include <VBox/vm.h>
     36#include <VBox/vmm.h>
    3637#include <VBox/hwaccm.h>
    3738#include <VBox/tm.h>
     
    25762577#endif
    25772578    default:
    2578         /* We should actually trigger a #GP here, but don't as that might cause more trouble. */
    2579         val = 0;
    2580         break;
     2579        /* In X2APIC specification this range is reserved for APIC control. */
     2580        if ((pRegFrame->ecx >= MSR_IA32_APIC_START) && (pRegFrame->ecx < MSR_IA32_APIC_END))
     2581        {
     2582            rc = PDMApicRDMSR(pVM, VMMGetCpuId(pVM), pRegFrame->ecx, &val);
     2583        }
     2584        else
     2585        {
     2586            /* We should actually trigger a #GP here, but don't as that might cause more trouble. */
     2587            val = 0;
     2588            break;
     2589        }
    25812590    }
    25822591    Log(("EMInterpretRdmsr %s (%x) -> val=%VX64\n", emMSRtoString(pRegFrame->ecx), pRegFrame->ecx, val));
    2583     pRegFrame->eax = (uint32_t) val;
    2584     pRegFrame->edx = (uint32_t) (val >> 32ULL);
    2585     return VINF_SUCCESS;
     2592    if (rc == VINF_SUCCESS)
     2593    {
     2594        pRegFrame->eax = (uint32_t) val;
     2595        pRegFrame->edx = (uint32_t) (val >> 32ULL);
     2596    }
     2597    return rc;
    25862598}
    25872599
     
    27142726
    27152727    default:
     2728        /* In X2APIC specification this range is reserved for APIC control. */
     2729        if ((pRegFrame->ecx >=  MSR_IA32_APIC_START) && (pRegFrame->ecx <  MSR_IA32_APIC_END))
     2730        {
     2731            return PDMApicWRMSR(pVM, VMMGetCpuId(pVM), pRegFrame->ecx, val);
     2732        }
    27162733        /* We should actually trigger a #GP here, but don't as that might cause more trouble. */
    27172734        break;
  • trunk/src/VBox/VMM/VMMAll/PDMAll.cpp

    r12989 r13013  
    253253}
    254254
     255/**
     256 * WRMSR in APIC range.
     257 *
     258 * @returns VBox status code.
     259 * @param   pVM             VM handle.
     260 * @param   iCpu            Target CPU.
     261 * @param   u32Reg          MSR to write.
     262 * @param   u64Value        Value to write.
     263 */
     264VMMDECL(int) PDMApicWRMSR(PVM pVM, VMCPUID iCpu, uint32_t u32Reg, uint64_t u64Value)
     265{
     266    if (pVM->pdm.s.Apic.CTX_SUFF(pDevIns))
     267    {
     268        Assert(pVM->pdm.s.Apic.CTX_SUFF(pfnWRMSR));
     269        pdmLock(pVM);
     270        pVM->pdm.s.Apic.CTX_SUFF(pfnWRMSR)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), iCpu, u32Reg, u64Value);
     271        pdmUnlock(pVM);
     272        return VINF_SUCCESS;
     273    }
     274    return VERR_PDM_NO_APIC_INSTANCE;
     275}
     276
     277/**
     278 * RDMSR in APIC range.
     279 *
     280 * @returns VBox status code.
     281 * @param   pVM             VM handle.
     282 * @param   iCpu            Target CPU.
     283 * @param   u32Reg          MSR to read.
     284 * @param   pu64Value       Value read.
     285 */
     286VMMDECL(int) PDMApicRDMSR(PVM pVM, VMCPUID iCpu, uint32_t u32Reg, uint64_t *pu64Value)
     287{
     288    if (pVM->pdm.s.Apic.CTX_SUFF(pDevIns))
     289    {
     290        Assert(pVM->pdm.s.Apic.CTX_SUFF(pfnRDMSR));
     291        pdmLock(pVM);
     292        pVM->pdm.s.Apic.CTX_SUFF(pfnRDMSR)(pVM->pdm.s.Apic.CTX_SUFF(pDevIns), iCpu, u32Reg, pu64Value);
     293        pdmUnlock(pVM);
     294        return VINF_SUCCESS;
     295    }
     296    return VERR_PDM_NO_APIC_INSTANCE;
     297}
     298
    255299
    256300/**
  • trunk/src/VBox/VMM/testcase/tstVMStructGC.cpp

    r12985 r13013  
    275275    GEN_CHECK_OFF(PDM, Apic.pfnGetBaseR3);
    276276    GEN_CHECK_OFF(PDM, Apic.pfnSetTPRR3);
     277    GEN_CHECK_OFF(PDM, Apic.pfnWRMSRR3);
     278    GEN_CHECK_OFF(PDM, Apic.pfnRDMSRR3);
    277279    GEN_CHECK_OFF(PDM, Apic.pfnGetTPRR3);
    278280    GEN_CHECK_OFF(PDM, Apic.pfnBusDeliverR3);
     
    283285    GEN_CHECK_OFF(PDM, Apic.pfnSetTPRR0);
    284286    GEN_CHECK_OFF(PDM, Apic.pfnGetTPRR0);
     287    GEN_CHECK_OFF(PDM, Apic.pfnWRMSRR0);
     288    GEN_CHECK_OFF(PDM, Apic.pfnRDMSRR0);
    285289    GEN_CHECK_OFF(PDM, Apic.pfnBusDeliverR0);
    286290    GEN_CHECK_OFF(PDM, Apic.pDevInsRC);
     
    290294    GEN_CHECK_OFF(PDM, Apic.pfnSetTPRRC);
    291295    GEN_CHECK_OFF(PDM, Apic.pfnGetTPRRC);
     296    GEN_CHECK_OFF(PDM, Apic.pfnWRMSRRC);
     297    GEN_CHECK_OFF(PDM, Apic.pfnRDMSRRC);
    292298    GEN_CHECK_OFF(PDM, Apic.pfnBusDeliverRC);
    293299    GEN_CHECK_OFF(PDM, IoApic);
  • trunk/src/recompiler/VBoxREMWrapper.cpp

    r12655 r13013  
    645645    { REMPARMDESC_FLAGS_INT,        sizeof(uint8_t), NULL }
    646646};
     647static const REMPARMDESC g_aArgsPDMApicWRMSR[] =
     648{
     649    { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
     650    { REMPARMDESC_FLAGS_INT,        sizeof(VMCPUID), NULL },
     651    { REMPARMDESC_FLAGS_INT,        sizeof(uint32_t), NULL },
     652    { REMPARMDESC_FLAGS_INT,        sizeof(uint64_t), NULL }
     653};
     654static const REMPARMDESC g_aArgsPDMApicRDMSR[] =
     655{
     656    { REMPARMDESC_FLAGS_INT,        sizeof(PVM), NULL },
     657    { REMPARMDESC_FLAGS_INT,        sizeof(VMCPUID), NULL },
     658    { REMPARMDESC_FLAGS_INT,        sizeof(uint32_t), NULL },
     659    { REMPARMDESC_FLAGS_INT,        sizeof(uint64_t *), NULL }
     660};
    647661static const REMPARMDESC g_aArgsPDMGetInterrupt[] =
    648662{
     
    10041018    { "REMR3NotifyInterruptClear",              (void *)&pfnREMR3NotifyInterruptClear,              &g_aArgsVM[0],                              RT_ELEMENTS(g_aArgsVM),                                REMFNDESC_FLAGS_RET_VOID,   0,              NULL },
    10051019    { "REMR3NotifyTimerPending",                (void *)&pfnREMR3NotifyTimerPending,                &g_aArgsVM[0],                              RT_ELEMENTS(g_aArgsVM),                                REMFNDESC_FLAGS_RET_VOID,   0,              NULL },
    1006     { "REMR3NotifyDmaPending",                  (void *)&pfnREMR3NotifyDmaPending,                  &g_aArgsVM[0],                              RT_ELEMENTS(g_aArgsVM),                                REMFNDESC_FLAGS_RET_VOID,   0,              NULL },
     1020   { "REMR3NotifyDmaPending",                  (void *)&pfnREMR3NotifyDmaPending,                  &g_aArgsVM[0],                              RT_ELEMENTS(g_aArgsVM),                                REMFNDESC_FLAGS_RET_VOID,   0,              NULL },
    10071021    { "REMR3NotifyQueuePending",                (void *)&pfnREMR3NotifyQueuePending,                &g_aArgsVM[0],                              RT_ELEMENTS(g_aArgsVM),                                REMFNDESC_FLAGS_RET_VOID,   0,              NULL },
    10081022    { "REMR3NotifyFF",                          (void *)&pfnREMR3NotifyFF,                          &g_aArgsVM[0],                              RT_ELEMENTS(g_aArgsVM),                                REMFNDESC_FLAGS_RET_VOID,   0,              NULL },
     
    10651079    { "PDMApicSetBase",                         (void *)(uintptr_t)&PDMApicSetBase,                 &g_aArgsPDMApicSetBase[0],                  RT_ELEMENTS(g_aArgsPDMApicSetBase),                    REMFNDESC_FLAGS_RET_INT,    sizeof(int),        NULL },
    10661080    { "PDMApicSetTPR",                          (void *)(uintptr_t)&PDMApicSetTPR,                  &g_aArgsPDMApicSetTPR[0],                   RT_ELEMENTS(g_aArgsPDMApicSetTPR),                     REMFNDESC_FLAGS_RET_INT,    sizeof(int),        NULL },
     1081    { "PDMApicWRMSR",                           (void *)(uintptr_t)&PDMApicWRMSR,                  &g_aArgsPDMApicWRMSR[0],                   RT_ELEMENTS(g_aArgsPDMApicWRMSR),                     REMFNDESC_FLAGS_RET_INT,    sizeof(int),           NULL },
     1082    { "PDMApicRDMSR",                           (void *)(uintptr_t)&PDMApicRDMSR,                  &g_aArgsPDMApicRDMSR[0],                   RT_ELEMENTS(g_aArgsPDMApicRDMSR),                     REMFNDESC_FLAGS_RET_INT,    sizeof(int),           NULL },
    10671083    { "PDMR3DmaRun",                            (void *)(uintptr_t)&PDMR3DmaRun,                    &g_aArgsVM[0],                              RT_ELEMENTS(g_aArgsVM),                                REMFNDESC_FLAGS_RET_VOID,   0,                  NULL },
    10681084    { "PDMGetInterrupt",                        (void *)(uintptr_t)&PDMGetInterrupt,                &g_aArgsPDMGetInterrupt[0],                 RT_ELEMENTS(g_aArgsPDMGetInterrupt),                   REMFNDESC_FLAGS_RET_INT,    sizeof(int),        NULL },
  • trunk/src/recompiler/VBoxRecompiler.c

    r12828 r13013  
    40874087
    40884088
     4089uint64_t cpu_apic_rdmsr(CPUX86State *env, uint32_t reg)
     4090{
     4091    uint64_t value;
     4092    int rc = PDMApicRDMSR(env->pVM, 0/* cpu */, reg, &value);
     4093    if (rc != VINF_SUCCESS)
     4094    {
     4095        /** @todo: exception ? */
     4096        value = 0;
     4097    }
     4098    return value;
     4099}
     4100
     4101void     cpu_apic_wrmsr(CPUX86State *env, uint32_t reg, uint64_t value)
     4102{
     4103    int rc = PDMApicWRMSR(env->pVM, 0 /* cpu */, reg, value);
     4104    if (rc != VINF_SUCCESS)
     4105    {
     4106        /** @todo: exception ? */
     4107    }
     4108}
    40894109/* -+- I/O Ports -+- */
    40904110
  • trunk/src/recompiler/target-i386/cpu.h

    r11982 r13013  
    260260#define MSR_EFER_NXE   (1 << 11)
    261261#define MSR_EFER_FFXSR (1 << 14)
     262#define MSR_APIC_RANGE_START            0x800
     263#define MSR_APIC_RANGE_END              0x900
    262264
    263265#define MSR_STAR                        0xc0000081
     
    851853uint8_t cpu_get_apic_tpr(CPUX86State *env);
    852854#endif
     855uint64_t cpu_apic_rdmsr(CPUX86State *env, uint32_t reg);
     856void     cpu_apic_wrmsr(CPUX86State *env, uint32_t reg, uint64_t value);
    853857void cpu_smm_update(CPUX86State *env);
    854858
  • trunk/src/recompiler/target-i386/helper.c

    r12679 r13013  
    30733073#endif
    30743074    default:
    3075         /* XXX: exception ? */
    3076         break;
     3075    {
     3076        uint32_t ecx = (uint32_t)ECX;
     3077        /* In X2APIC specification this range is reserved for APIC control. */
     3078        if ((ecx >= MSR_APIC_RANGE_START) && (ecx < MSR_APIC_RANGE_END))
     3079        {
     3080            cpu_apic_wrmsr(env, ecx, val);
     3081        }
     3082        else
     3083        {
     3084            /* @todo: exception ? */
     3085        }
     3086        break;
     3087    }
    30773088    }
    30783089}
     
    31243135#endif
    31253136    default:
    3126         /* XXX: exception ? */
    3127         val = 0;
    3128         break;
     3137    {
     3138        uint32_t ecx = (uint32_t)ECX;
     3139        /* In X2APIC specification this range is reserved for APIC control. */
     3140        if ((ecx >= MSR_APIC_RANGE_START) && (ecx < MSR_APIC_RANGE_END))
     3141        {
     3142            val = cpu_apic_rdmsr(env, ecx);
     3143        }
     3144        else
     3145        {
     3146            /** @todo: exception ? */
     3147            val = 0;
     3148            break;
     3149        }
     3150    }
    31293151    }
    31303152    EAX = (uint32_t)(val);
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