VirtualBox

Changeset 12555 in vbox for trunk/src


Ignore:
Timestamp:
Sep 18, 2008 10:46:25 AM (16 years ago)
Author:
vboxsync
Message:

configure CPU count in VMM, use per-CPU MMIO regions for APIC

Location:
trunk/src/VBox
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/PC/DevAPIC.cpp

    r12487 r12555  
    773773    int intno;
    774774
    775     /* if the APIC is installed or enabled, we let the 8259 handle the
     775    /* if the APIC is not installed or enabled, we let the 8259 handle the
    776776       IRQs */
    777777    if (!s) {
     
    16681668}
    16691669
    1670 /**
    1671  * @copydoc FNPDMDEVCONSTRUCT
    1672  */
    1673 static DECLCALLBACK(int) apicConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfgHandle)
    1674 {
    1675     APICState      *pThis = PDMINS_2_DATA(pDevIns, APICState *);
     1670static inline int registerAPIC(APICState *pThis, PPDMDEVINS pDevIns, PCFGMNODE pCfgHandle, bool fR0Enabled, bool fGCEnabled)
     1671{
    16761672    PDMAPICREG      ApicReg;
    16771673    int             rc;
    1678     int             i;
    1679     bool            fIOAPIC;
    1680     bool            fGCEnabled;
    1681     bool            fR0Enabled;
    1682 
    1683 #ifndef VBOX_WITH_SMP_GUESTS
    1684     Assert(iInstance == 0);
    1685 #else
    1686     LogRel(("[SMP] apicConstruct: %d %p\n", iInstance, pDevIns));
    1687 #endif
    1688 
    1689     /*
    1690      * Validate configuration.
    1691      */
    1692     if (!CFGMR3AreValuesValid(pCfgHandle, "IOAPIC\0" "GCEnabled\0" "R0Enabled\0"))
    1693         return VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES;
    1694 
    1695     rc = CFGMR3QueryBoolDef(pCfgHandle, "IOAPIC", &fIOAPIC, true);
    1696     if (RT_FAILURE(rc))
    1697         return PDMDEV_SET_ERROR(pDevIns, rc,
    1698                                 N_("Configuration error: Failed to read \"IOAPIC\""));
    1699 
    1700     rc = CFGMR3QueryBoolDef(pCfgHandle, "GCEnabled", &fGCEnabled, true);
    1701     if (RT_FAILURE(rc))
    1702         return PDMDEV_SET_ERROR(pDevIns, rc,
    1703                                 N_("Configuration error: Failed to query boolean value \"GCEnabled\""));
    1704 
    1705     rc = CFGMR3QueryBoolDef(pCfgHandle, "R0Enabled", &fR0Enabled, true);
    1706     if (RT_FAILURE(rc))
    1707         return PDMDEV_SET_ERROR(pDevIns, rc,
    1708                                 N_("Configuration error: Failed to query boolean value \"R0Enabled\""));
    1709     Log(("APIC: fR0Enabled=%RTbool fGCEnabled=%RTbool fIOAPIC=%RTbool\n", fR0Enabled, fGCEnabled, fIOAPIC));
    1710 
    1711     /*
    1712      * Init the data.
    1713      */
    1714     pThis->pDevInsR3 = pDevIns;
    1715     pThis->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
    1716     pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
    1717     pThis->apicbase  = UINT32_C(0xfee00000) | MSR_IA32_APICBASE_BSP | MSR_IA32_APICBASE_ENABLE;
    1718     for (i = 0; i < APIC_LVT_NB; i++)
    1719         pThis->lvt[i] = 1 << 16; /* mask LVT */
    1720     pThis->spurious_vec = 0xff;
    1721 
    1722 
     1674   
    17231675    /*
    17241676     * Register the APIC.
     
    17741726        return rc;
    17751727    }
    1776 
     1728   
     1729    return VINF_SUCCESS;
     1730}
     1731
     1732/**
     1733 * @copydoc FNPDMDEVCONSTRUCT
     1734 */
     1735static DECLCALLBACK(int) apicConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfgHandle)
     1736{
     1737    APICState      *pThis = PDMINS_2_DATA(pDevIns, APICState *);
     1738    int             i;
     1739    int             rc;
     1740    bool            fGCEnabled;
     1741    bool            fR0Enabled;
     1742    bool            fIOAPIC;
     1743
     1744#ifndef VBOX_WITH_SMP_GUESTS
     1745    Assert(iInstance == 0);
     1746#else
     1747    LogRel(("[SMP] apicConstruct: %d %p\n", iInstance, pDevIns));
     1748#endif
    17771749    /*
    1778      * The the CPUID feature bit.
     1750     * Validate configuration.
    17791751     */
    1780     uint32_t u32Eax, u32Ebx, u32Ecx, u32Edx;
    1781     PDMDevHlpGetCpuId(pDevIns, 0, &u32Eax, &u32Ebx, &u32Ecx, &u32Edx);
    1782     if (u32Eax >= 1)
     1752    if (!CFGMR3AreValuesValid(pCfgHandle,
     1753                              "IOAPIC\0"
     1754                              "GCEnabled\0"
     1755                              "R0Enabled\0"))
     1756        return VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES;
     1757   
     1758    rc = CFGMR3QueryBoolDef(pCfgHandle, "IOAPIC", &fIOAPIC, true);
     1759    if (RT_FAILURE(rc))
     1760        return PDMDEV_SET_ERROR(pDevIns, rc,
     1761                                N_("Configuration error: Failed to read \"IOAPIC\""));
     1762
     1763    rc = CFGMR3QueryBoolDef(pCfgHandle, "GCEnabled", &fGCEnabled, true);
     1764    if (RT_FAILURE(rc))
     1765        return PDMDEV_SET_ERROR(pDevIns, rc,
     1766                                N_("Configuration error: Failed to query boolean value \"GCEnabled\""));
     1767
     1768    rc = CFGMR3QueryBoolDef(pCfgHandle, "R0Enabled", &fR0Enabled, true);
     1769    if (RT_FAILURE(rc))
     1770        return PDMDEV_SET_ERROR(pDevIns, rc,
     1771                                N_("Configuration error: Failed to query boolean value \"R0Enabled\""));
     1772    Log(("APIC: fR0Enabled=%RTbool fGCEnabled=%RTbool fIOAPIC=%RTbool\n", fR0Enabled, fGCEnabled, fIOAPIC));
     1773
     1774    /*
     1775     * Init the data.
     1776     */
     1777    pThis->pDevInsR3 = pDevIns;
     1778    pThis->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
     1779    pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
     1780    pThis->apicbase  = UINT32_C(0xfee00000) | MSR_IA32_APICBASE_BSP | MSR_IA32_APICBASE_ENABLE;
     1781    for (i = 0; i < APIC_LVT_NB; i++)
     1782        pThis->lvt[i] = 1 << 16; /* mask LVT */
     1783    pThis->spurious_vec = 0xff;
     1784    pThis->id = iInstance;
     1785
     1786    /* we need to register APIC only for the first instance */
     1787    if (iInstance == 0)
    17831788    {
    1784         if (   fIOAPIC                       /* If IOAPIC is enabled, enable Local APIC in any case */
    1785                || (   u32Ebx == X86_CPUID_VENDOR_INTEL_EBX
    1786                       && u32Ecx == X86_CPUID_VENDOR_INTEL_ECX
    1787                       && u32Edx == X86_CPUID_VENDOR_INTEL_EDX /* GenuineIntel */)
    1788                || (   u32Ebx == X86_CPUID_VENDOR_AMD_EBX
    1789                       && u32Ecx == X86_CPUID_VENDOR_AMD_ECX
    1790                       && u32Edx == X86_CPUID_VENDOR_AMD_EDX   /* AuthenticAMD */))
     1789        rc = registerAPIC(pThis, pDevIns, pCfgHandle, fR0Enabled, fGCEnabled);
     1790        if (RT_FAILURE(rc))
     1791            return rc;
     1792        /*
     1793         * The the CPUID feature bit.
     1794         * @todo: should we keep CPUID per vCPU, or per-VM? In first case we need to modify CPUID for all vCPUs
     1795         */
     1796        uint32_t u32Eax, u32Ebx, u32Ecx, u32Edx;
     1797        PDMDevHlpGetCpuId(pDevIns, 0, &u32Eax, &u32Ebx, &u32Ecx, &u32Edx);
     1798        if (u32Eax >= 1)
    17911799        {
    1792             LogRel(("Activating Local APIC\n"));
    1793             pThis->pApicHlpR3->pfnChangeFeature(pDevIns, true);
     1800            if (   fIOAPIC                       /* If IOAPIC is enabled, enable Local APIC in any case */
     1801                   || (   u32Ebx == X86_CPUID_VENDOR_INTEL_EBX
     1802                          && u32Ecx == X86_CPUID_VENDOR_INTEL_ECX
     1803                          && u32Edx == X86_CPUID_VENDOR_INTEL_EDX /* GenuineIntel */)
     1804                   || (   u32Ebx == X86_CPUID_VENDOR_AMD_EBX
     1805                          && u32Ecx == X86_CPUID_VENDOR_AMD_ECX
     1806                          && u32Edx == X86_CPUID_VENDOR_AMD_EDX   /* AuthenticAMD */))
     1807            {
     1808                LogRel(("Activating Local APIC\n"));
     1809                pThis->pApicHlpR3->pfnChangeFeature(pDevIns, true);
     1810            }
    17941811        }
    17951812    }
    17961813
    17971814    /*
    1798      * Register the MMIO range.
     1815     * Register the MMIO range, for all instances.
    17991816     */
    1800     rc = PDMDevHlpMMIORegister(pDevIns, pThis->apicbase & ~0xfff, 0x1000, pThis,
    1801                                apicMMIOWrite, apicMMIORead, NULL, "APIC Memory");
     1817    rc = PDMDevHlpMMIORegisterPerCPU(pDevIns, /* APIC id == CPU number */ pThis->id,
     1818                                     pThis->apicbase & ~0xfff, 0x1000, pThis,
     1819                                     apicMMIOWrite, apicMMIORead, NULL, "APIC Memory");
    18021820    if (RT_FAILURE(rc))
    18031821        return rc;
     
    18061824        pThis->pApicHlpRC = pThis->pApicHlpR3->pfnGetRCHelpers(pDevIns);
    18071825
    1808         rc = PDMDevHlpMMIORegisterGC(pDevIns, pThis->apicbase & ~0xfff, 0x1000, 0,
    1809                                      "apicMMIOWrite", "apicMMIORead", NULL);
     1826        rc = PDMDevHlpMMIORegisterPerCPUGC(pDevIns, /* APIC id == CPU number */ pThis->id,
     1827                                           pThis->apicbase & ~0xfff, 0x1000, 0,
     1828                                           "apicMMIOWrite", "apicMMIORead", NULL);
    18101829        if (RT_FAILURE(rc))
    18111830            return rc;
     
    18151834        pThis->pApicHlpR0 = pThis->pApicHlpR3->pfnGetR0Helpers(pDevIns);
    18161835
    1817         rc = PDMDevHlpMMIORegisterR0(pDevIns, pThis->apicbase & ~0xfff, 0x1000, 0,
    1818                                      "apicMMIOWrite", "apicMMIORead", NULL);
     1836        rc = PDMDevHlpMMIORegisterPerCPUR0(pDevIns, /* APIC id == CPU number */ pThis->id,
     1837                                           pThis->apicbase & ~0xfff, 0x1000, 0,
     1838                                           "apicMMIOWrite", "apicMMIORead", NULL);
    18191839        if (RT_FAILURE(rc))
    18201840            return rc;
  • trunk/src/VBox/Devices/PC/DevPcBios.cpp

    r12468 r12555  
    13991399    LogRel(("[SMP] BIOS with %d CPUs\n", pThis->cCpus));
    14001400#else
     1401    /* @todo: move this check up in configuration chain */
    14011402    if (pThis->cCpus != 1)
    14021403    {
  • trunk/src/VBox/VMM/VMM.cpp

    r12545 r12555  
    375375    pVM->vmm.s.fSwitcherDisabled = false;
    376376
    377     /** @todo fetch the configured number of VCPUs. */
    378     pVM->cCPUs = 1;
     377    /* we use 32-bit for CPU count internally for alignment purposes,
     378     * but config counter is 16-bit */
     379    uint16_t cpus;
     380    rc = CFGMR3QueryU16Def(CFGMR3GetRoot(pVM), "NumCPUs", &cpus, 1);
     381    if (RT_FAILURE(rc))
     382        AssertMsgRCReturn(rc, ("Configuration error: Querying \"NumCPUs\" as integer failed, rc=%Vrc\n", rc), rc);
     383    pVM->cCPUs = cpus;
     384#ifdef VBOX_WITH_SMP_GUESTS
     385    LogRel(("[SMP] VMM with %d CPUs\n", pVM->cCPUs));
     386#endif
     387
    379388    /** Current CPU id; @todo move to per CPU structure. */
    380389    pVM->idCPU = 0;
Note: See TracChangeset for help on using the changeset viewer.

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