VirtualBox

Changeset 12428 in vbox for trunk


Ignore:
Timestamp:
Sep 12, 2008 3:08:00 PM (16 years ago)
Author:
vboxsync
Message:

more SMP work

Location:
trunk/src/VBox
Files:
3 edited

Legend:

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

    r12311 r12428  
    159159    uint16_t            pm1a_sts;
    160160    uint16_t            pm1a_ctl;
    161     uint16_t            Alignment0;
     161    /** Number of logical CPUs in guest */
     162    uint16_t            cCpus;
    162163    int64_t             pm_timer_initial;
    163164    PTMTIMERR3          tsR3;
     
    199200    /** Pointer to the driver connector interface */
    200201    R3PTRTYPE(PPDMIACPICONNECTOR) pDrv;
    201 #if 0
    202   /** Number of logical CPUs in guest */
    203     uint16_t             cCpus;
    204 #endif
    205202};
    206203
     
    403400
    404401/** Multiple APIC Description Table */
     402#ifdef VBOX_WITH_SMP_GUESTS
     403
     404#define PCAT_COMPAT     0x1                     /**< system has also a dual-8259 setup */
     405
     406/*
     407 * This structure looks somewhat convoluted due layout of MADT table in MP case.
     408 * There extpected to be multiple LAPIC records for each CPU, thus we cannot
     409 * use regular C structure and proxy to raw memory instead.
     410 */
     411class ACPITBLMADT
     412{
     413    /*
     414     * All actual data stored in dynamically allocated memory pointed by this field.
     415     */
     416    uint8_t*            pData;
     417    /*
     418     * Number of CPU entries in this MADT.
     419     */
     420    uint32_t            cCpus;
     421   
     422 public:
     423    /*
     424     * Address of ACPI header
     425     */
     426    inline ACPITBLHEADER* header_addr() const
     427    {
     428        return (ACPITBLHEADER*)pData;
     429    }
     430   
     431    /*
     432     * Address of local APIC for each CPU. Note that different CPUs address different LAPICs,
     433     * although address is the same for all of them.
     434     */
     435    inline uint32_t* u32LAPIC_addr() const
     436    {
     437        return  (uint32_t*)(header_addr() + 1);
     438    }
     439   
     440    /*
     441     * Address of APIC flags
     442     */
     443    inline uint32_t* u32Flags_addr() const
     444    {
     445        return (uint32_t*)(u32LAPIC_addr() + 1);
     446    }
     447   
     448    /*
     449     * Address of per-CPU LAPIC descriptions
     450     */
     451    inline ACPITBLLAPIC* LApics_addr() const
     452    {
     453        return (ACPITBLLAPIC*)(u32Flags_addr() + 1);
     454    }
     455
     456    /*
     457     * Address of IO APIC description
     458     */
     459    inline ACPITBLIOAPIC* IOApic_addr() const
     460    {
     461        return (ACPITBLIOAPIC*)(LApics_addr() + cCpus);
     462    }
     463
     464    /*
     465     * Size of MADT.
     466     * Note that this function assumes IOApic to be the last field in structure.
     467     */
     468    inline uint32_t size() const
     469    {
     470        return (uint8_t*)(IOApic_addr() + 1)-(uint8_t*)header_addr();
     471    }
     472
     473    /*
     474     * Raw data of MADT.
     475     */
     476    inline const uint8_t* data() const
     477    {
     478        return pData;
     479    }
     480
     481    /*
     482     * Size of MADT for given ACPI config, useful to compute layout.
     483     */
     484    static uint32_t sizeFor(ACPIState *s)
     485    {
     486        return ACPITBLMADT(s->cCpus).size();
     487    }
     488
     489    /*
     490     * Constructor, only works in Ring 3, doesn't look like a big deal.
     491     */
     492    ACPITBLMADT(uint16_t cpus)
     493    {
     494        cCpus = cpus;
     495        pData = 0;
     496#ifdef IN_RING3
     497        uint32_t sSize = size();
     498        pData = (uint8_t*)RTMemAllocZ(sSize);
     499#else
     500        AssertMsgFailed(("cannot use in inner rings"));
     501#endif
     502    }
     503
     504    ~ACPITBLMADT()
     505    {
     506#ifdef IN_RING3
     507        RTMemFree(pData);
     508#else
     509        AssertMsgFailed(("cannot use in inner rings"));
     510#endif
     511    }
     512};
     513#else
    405514struct ACPITBLMADT
    406515{
     
    413522};
    414523AssertCompileSize(ACPITBLMADT, 64);
     524#endif
    415525
    416526#pragma pack()
     
    644754static void acpiSetupMADT (ACPIState *s, RTGCPHYS32 addr)
    645755{
     756#if VBOX_WITH_SMP_GUESTS
     757    uint16_t cpus = s->cCpus;
     758    ACPITBLMADT madt(cpus);
     759
     760    acpiPrepareHeader(madt.header_addr(), "APIC", madt.size(), 2);
     761   
     762    *madt.u32LAPIC_addr()          = RT_H2LE_U32(0xfee00000);
     763    *madt.u32Flags_addr()          = RT_H2LE_U32(PCAT_COMPAT);
     764   
     765    ACPITBLLAPIC* lapic = madt.LApics_addr();
     766    for (uint16_t i = 0; i < cpus; i++)
     767    {
     768        lapic->u8Type      = 0;
     769        lapic->u8Length    = sizeof(ACPITBLLAPIC);
     770        lapic->u8ProcId    = i;
     771        lapic->u8ApicId    = i;
     772        lapic->u32Flags    = RT_H2LE_U32(LAPIC_ENABLED);
     773        lapic++;
     774    }
     775
     776    ACPITBLIOAPIC* ioapic = madt.IOApic_addr();
     777
     778    ioapic->u8Type     = 1;
     779    ioapic->u8Length   = sizeof(ACPITBLIOAPIC);
     780    ioapic->u8IOApicId = cpus;
     781    ioapic->u8Reserved = 0;
     782    ioapic->u32Address = RT_H2LE_U32(0xfec00000);
     783    ioapic->u32GSIB    = RT_H2LE_U32(0);
     784
     785    madt.header_addr()->u8Checksum = acpiChecksum (madt.data(), madt.size());
     786    acpiPhyscpy (s, addr, madt.data(), madt.size());
     787
     788#else
    646789    ACPITBLMADT madt;
    647790
     
    670813    madt.header.u8Checksum = acpiChecksum ((uint8_t*)&madt, sizeof(madt));
    671814    acpiPhyscpy (s, addr, &madt, sizeof(madt));
     815#endif
    672816}
    673817
     
    15121656                                N_("Configuration error: Invalid \"RamSize\", maximum allowed "
    15131657                                   "value is 4095MB"));
    1514 
    15151658    rsdt_addr = 0;
    15161659    xsdt_addr = RT_ALIGN_32 (rsdt_addr + rsdt_tbl_len, 16);
     
    15201663    {
    15211664        apic_addr = RT_ALIGN_32 (facs_addr + sizeof(ACPITBLFACS), 16);
     1665#ifdef VBOX_WITH_SMP_GUESTS
     1666        /*
     1667         * @todo r=nike maybe some refactoring needed to compute tables layout,
     1668         * but as this code is executed only once it doesn't make sense to optimize much
     1669         */
     1670        dsdt_addr = RT_ALIGN_32 (apic_addr + ACPITBLMADT::sizeFor(s), 16);
     1671#else
    15221672        dsdt_addr = RT_ALIGN_32 (apic_addr + sizeof(ACPITBLMADT), 16);
     1673#endif
    15231674    }
    15241675    else
     
    15981749                                N_("Configuration error: Failed to read \"IOAPIC\""));
    15991750
    1600 #if 0
    16011751    rc = CFGMR3QueryU16Def(pCfgHandle, "NumCPUs", &s->cCpus, 1);
    16021752    if (RT_FAILURE(rc))
    16031753        return PDMDEV_SET_ERROR(pDevIns, rc,
    16041754                                N_("Configuration error: Querying \"NumCPUs\" as integer failed"));
    1605 #endif
    16061755
    16071756    /* query whether we are supposed to present an FDC controller */
  • trunk/src/VBox/Devices/PC/DevPcBios.cpp

    r12311 r12428  
    13971397
    13981398#ifdef VBOX_WITH_SMP_GUESTS
    1399     pThis->cCpus = 2;
    1400     LogRel(("Running with %d CPUs\n", pThis->cCpus));
     1399    LogRel(("[SMP] BIOS with %d CPUs\n", pThis->cCpus));
    14011400#else
    14021401    if (pThis->cCpus != 1)
  • trunk/src/VBox/Main/ConsoleImpl2.cpp

    r12028 r12428  
    134134    hrc = pMachine->COMGETTER(MemorySize)(&cRamMBs);                                H();
    135135
     136#ifdef VBOX_WITH_SMP_GUESTS
     137    /* @todo: r=nike: Testing code, should use actual getter when ready */
     138    uint16_t cNumCpus = 2;
     139#else
     140    uint16_t cNumCpus = 1;
     141#endif
    136142
    137143    /*
     
    151157    rc = CFGMR3InsertBytes(pRoot,   "UUID", pUuid, sizeof(*pUuid));                 RC_CHECK();
    152158    rc = CFGMR3InsertInteger(pRoot, "RamSize",              cRamMBs * _1M);         RC_CHECK();
     159    rc = CFGMR3InsertInteger(pRoot, "NumCPUs",              cNumCpus);              RC_CHECK();
    153160    rc = CFGMR3InsertInteger(pRoot, "TimerMillies",         10);                    RC_CHECK();
    154161    rc = CFGMR3InsertInteger(pRoot, "RawR3Enabled",         1);     /* boolean */   RC_CHECK();
     
    272279    rc = CFGMR3InsertNode(pInst,    "Config", &pBiosCfg);                           RC_CHECK();
    273280    rc = CFGMR3InsertInteger(pBiosCfg,  "RamSize",              cRamMBs * _1M);     RC_CHECK();
     281    rc = CFGMR3InsertInteger(pBiosCfg,  "NumCPUs",              cNumCpus);          RC_CHECK();
    274282    rc = CFGMR3InsertString(pBiosCfg,   "HardDiskDevice",       "piix3ide");        RC_CHECK();
    275283    rc = CFGMR3InsertString(pBiosCfg,   "FloppyDevice",         "i82078");          RC_CHECK();
     
    457465        rc = CFGMR3InsertNode(pInst,    "Config", &pCfg);                           RC_CHECK();
    458466        rc = CFGMR3InsertInteger(pCfg,  "RamSize",          cRamMBs * _1M);         RC_CHECK();
     467        rc = CFGMR3InsertInteger(pCfg,  "NumCPUs",          cNumCpus);              RC_CHECK();
     468
    459469        rc = CFGMR3InsertInteger(pCfg,  "IOAPIC", fIOAPIC);                         RC_CHECK();
    460470        rc = CFGMR3InsertInteger(pCfg,  "FdcEnabled", fFdcEnabled);                 RC_CHECK();
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