VirtualBox

Ignore:
Timestamp:
Sep 19, 2008 5:58:06 PM (16 years ago)
Author:
vboxsync
Message:

further APIC work

File:
1 edited

Legend:

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

    r12598 r12612  
    7878#define IOAPIC_UNLOCK(pThis) (pThis)->CTX_SUFF(pIoApicHlp)->pfnUnlock((pThis)->CTX_SUFF(pDevIns))
    7979
    80 /**  @def FIRST_LAPIC
     80/**  @def LAPIC_BASE
    8181 * Return address of first LAPIC state. */
    82 #define FIRST_LAPIC(pThis) ((APICState*)(pThis)->CTX_SUFF(pLapics))
    83 
    84 #define FOR_EACH_LAPIC(dev, code)                         \
     82#define LAPIC_BASE(pThis) ((APICState*)(pThis)->CTX_SUFF(pLapics))
     83
     84#define foreach_apic(dev, mask, code)                     \
    8585    do {                                                  \
    8686        uint32_t i;                                       \
    87         APICState* apic = FIRST_LAPIC(dev);               \
    88         for (i=0; i < dev->cCpus; i++)                    \
     87        APICState* apic = LAPIC_BASE(dev);                \
     88        for (i = 0; i < dev->cCpus; i++)                  \
    8989        {                                                 \
    90             code;                                         \
     90            if (mask & (1 << (apic->id)))                 \
     91            {                                             \
     92                code;                                     \
     93            }                                             \
    9194            apic++;                                       \
    9295        }                                                 \
     
    285288} APICDeviceInfo;
    286289
    287 DECLINLINE(APICState*) getLAPIC(APICDeviceInfo* dev)
     290DECLINLINE(APICState*) getLapic(APICDeviceInfo* dev)
    288291{
    289292    uint32_t id = dev->CTX_SUFF(pApicHlp)->pfnGetCpuId(dev->CTX_SUFF(pDevIns));
    290     return FIRST_LAPIC(dev) + id;
    291 }
    292 
     293    return LAPIC_BASE(dev) + id;
     294}
     295
     296
     297DECLINLINE(void) cpuSetInterrupt(APICDeviceInfo* dev, uint32_t cpuid)
     298{
     299    dev->CTX_SUFF(pApicHlp)->pfnSetInterruptFF(dev->CTX_SUFF(pDevIns));
     300}
     301
     302DECLINLINE(void) cpuClearInterrupt(APICDeviceInfo* dev, uint32_t cpuid)
     303{
     304    dev->CTX_SUFF(pApicHlp)->pfnClearInterruptFF(dev->CTX_SUFF(pDevIns));
     305}
    293306#endif /* VBOX */
    294307
     
    343356    switch (delivery_mode) {
    344357        case APIC_DM_LOWPRI:
    345 #ifndef VBOX
    346             /* XXX: search for focus processor, arbitration */
     358        {
     359            int d = -1;
     360            if (deliver_bitmask)
     361                d = ffs_bit(deliver_bitmask);
     362            if (d >= 0)
    347363            {
    348                 int i, d;
    349                 d = -1;
    350                 for(i = 0; i < MAX_APIC_WORDS; i++) {
    351                     if (deliver_bitmask[i]) {
    352                         d = i * 32 + ffs_bit(deliver_bitmask[i]);
    353                         break;
    354                     }
    355                 }
    356                 if (d >= 0) {
    357                     apic_iter = local_apics[d];
    358                     if (apic_iter) {
    359                         apic_set_irq(apic_iter, vector_num, trigger_mode);
    360                     }
    361                 }
     364                APICState* apic = LAPIC_BASE(dev) + d;
     365                apic_set_irq(dev, apic, vector_num, trigger_mode);
    362366            }
    363 #else
    364             {
    365                 int d = -1;
    366                 if (deliver_bitmask)
    367                     d = ffs_bit(deliver_bitmask);
    368                 if (d >= 0)
    369                 {
    370                     APICState* apic = FIRST_LAPIC(dev) + d;
    371                     apic_set_irq(dev, apic, vector_num, trigger_mode);
    372                 }
    373             }
    374 #endif
    375367            return;
     368        }
    376369        case APIC_DM_FIXED:
    377370            /* XXX: arbitration */
     
    379372
    380373        case APIC_DM_SMI:
     374            /** @todo: what do we really do with SMI */
     375            foreach_apic(dev, deliver_bitmask,
     376                         cpuSetInterrupt(dev, apic->id));
     377            return;
     378
    381379        case APIC_DM_NMI:
    382             break;
     380            /** @todo: what do we really do with NMI */
     381            foreach_apic(dev, deliver_bitmask,
     382                         cpuSetInterrupt(dev, apic->id));
     383            return;
    383384
    384385        case APIC_DM_INIT:
    385386            /* normal INIT IPI sent to processors */
    386387#ifdef VBOX
    387             apic_init_ipi (s);
     388            foreach_apic(dev, deliver_bitmask,
     389                         apic_init_ipi(apic));
    388390#else
    389391            for (apic_iter = first_local_apic; apic_iter != NULL;
     
    403405
    404406#ifdef VBOX
    405     if (deliver_bitmask & (1 << s->id))
    406         apic_set_irq (dev, s, vector_num, trigger_mode);
     407    foreach_apic(dev, deliver_bitmask,
     408                       apic_set_irq (dev, apic, vector_num, trigger_mode));
    407409#else  /* VBOX */
    408410    for (apic_iter = first_local_apic; apic_iter != NULL;
     
    435437{
    436438    APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
    437     APICState *s = getLAPIC(dev);
     439    APICState *s = getLapic(dev);
    438440    Log(("cpu_set_apic_base: %016RX64\n", val));
    439441
     
    447449
    448450        /* Clear any pending APIC interrupt action flag. */
    449         dev->CTX_SUFF(pApicHlp)->pfnClearInterruptFF(dev->CTX_SUFF(pDevIns));
     451        cpuClearInterrupt(dev, s->id);
    450452        dev->CTX_SUFF(pApicHlp)->pfnChangeFeature(pDevIns, false);
    451453    }
     
    518520{
    519521    APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
    520     APICState *s = getLAPIC(dev);
     522    APICState *s = getLapic(dev);
    521523    Log(("apicGetBase: %016llx\n", (uint64_t)s->apicbase));
    522524    return s->apicbase;
     
    526528{
    527529    APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
    528     APICState *s = getLAPIC(dev);
     530    APICState *s = getLapic(dev);
    529531    LogFlow(("apicSetTPR: val=%#x (trp %#x -> %#x)\n", val, s->tpr, (val & 0x0f) << 4));
    530532    apic_update_tpr(dev, s, (val & 0x0f) << 4);
     
    534536{
    535537    APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
    536     APICState *s = getLAPIC(dev);
     538    APICState *s = getLapic(dev);
    537539    Log2(("apicGetTPR: returns %#x\n", s->tpr >> 4));
    538540    return s->tpr >> 4;
     
    548550{
    549551    APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
    550     APICState *s = getLAPIC(dev);
     552    APICState *s = getLapic(dev);
    551553    LogFlow(("apicBusDeliverCallback: s=%p pDevIns=%p u8Dest=%#x u8DestMode=%#x u8DeliveryMode=%#x iVector=%#x u8Polarity=%#x u8TriggerMode=%#x\n",
    552554             s, pDevIns, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode));
     
    609611    {
    610612        /* Clear any pending APIC interrupt action flag. */
    611         dev->CTX_SUFF(pApicHlp)->pfnClearInterruptFF(dev->CTX_SUFF(pDevIns));
     613        cpuClearInterrupt(dev, s->id);
    612614        return false;
    613615    }
     
    624626    cpu_interrupt(s->cpu_env, CPU_INTERRUPT_HARD);
    625627#else
    626     dev->CTX_SUFF(pApicHlp)->pfnSetInterruptFF(dev->CTX_SUFF(pDevIns));
     628    cpuSetInterrupt(dev, s->id);
    627629    return true;
    628630#endif
     
    638640    if (!dev)
    639641        return false;
    640     APICState *s = getLAPIC(dev);
     642    APICState *s = getLapic(dev);
    641643
    642644    irrv = get_highest_priority_int(s->irr);
     
    665667        Log(("apic_update_tpr: deactivate interrupt that was masked by the TPR update (%x)\n", val));
    666668        STAM_COUNTER_INC(&dev->StatClearedActiveIrq);
    667         dev->CTX_SUFF(pApicHlp)->pfnClearInterruptFF(dev->CTX_SUFF(pDevIns));
     669        cpuClearInterrupt(dev, s->id);
    668670    }
    669671}
     
    700702#endif /* VBOX */
    701703{
    702 #if 0
    703     uint32_t mask = 0;
    704 #ifndef VBOX
    705     APICState *apic_iter;
    706 #endif /* !VBOX */
    707 
    708     if (dest_mode == 0) {
    709         if (dest == 0xff)
    710             mask = 0xff;
    711         else
    712             mask = 1 << dest;
    713     } else {
    714         /* XXX: cluster mode */
    715 #ifdef VBOX
    716         if (dest & s->log_dest)
    717             mask |= 1 << s->id;
    718 #else /* !VBOX */
    719         for (apic_iter = first_local_apic; apic_iter != NULL;
    720              apic_iter = apic_iter->next_apic) {
    721             if (dest & apic_iter->log_dest)
    722                 mask |= (1 << apic_iter->id);
    723         }
    724 #endif /* !VBOX */
    725     }
    726 
    727     return mask;
    728 #else
    729704    uint32_t mask = 0;
    730705
     
    738713    else
    739714    {
    740         APICState *apic = FIRST_LAPIC(dev);
     715        APICState *apic = LAPIC_BASE(dev);
    741716        uint32_t i;
    742717       
     
    763738
    764739    return mask;
    765 #endif
    766740}
    767741
     
    850824                if (level == 0 && trig_mode == 1) {
    851825#ifdef VBOX
    852                     FOR_EACH_LAPIC(dev,
    853                                    if (deliver_bitmask & (1 << apic->id))
    854                                    {
    855                                        apic->arb_id = apic->id;
    856                                    });
     826                    foreach_apic(dev, deliver_bitmask,
     827                                       apic->arb_id = apic->id);
    857828#else /* !VBOX */
    858829                    for (apic_iter = first_local_apic; apic_iter != NULL;
     
    878849            }
    879850#else
    880             FOR_EACH_LAPIC(dev, apic_startup(dev, apic, vector_num));
     851            foreach_apic(dev, deliver_bitmask,
     852                         apic_startup(dev, apic, vector_num));
    881853#endif /* !VBOX */
    882854            return;
     
    900872{
    901873    APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
    902     APICState *s = getLAPIC(dev);
     874    APICState *s = getLapic(dev);
    903875#endif /* VBOX */
    904876    int intno;
     
    995967{
    996968    APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
    997     APICState *s = getLAPIC(dev);
     969    APICState *s = getLapic(dev);
    998970    dev->pApicHlpR3->pfnLock(pDevIns, VERR_INTERNAL_ERROR);
    999971#endif /* VBOX */
     
    16541626
    16551627/* LAPIC */
    1656 
    1657 /* LAPICs MMIO is wrong, in SMP there is no relation between memory range and
    1658    lapic, it's only the CPU that executes this memory access is what matters */
    1659 
    16601628PDMBOTHCBDECL(int) apicMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
    16611629{
    16621630    APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
    1663     APICState *s = getLAPIC(dev);
     1631    APICState *s = getLapic(dev);
    16641632
    16651633#ifdef VBOX_WITH_SMP_GUESTS
    1666     LogRel(("[SMP] apicMMIORead %p at %ullx\n", pDevIns, (uint64_t)GCPhysAddr));
    1667 #endif
    1668 
    1669     /** @todo: add LAPIC range validity checks (multiple LAPICs can theoretically have
     1634    LogRel(("[SMP] apicMMIORead at %llx\n", (uint64_t)GCPhysAddr));
     1635#endif
     1636
     1637    /** @todo: add LAPIC range validity checks (different LAPICs can theoretically have
    16701638               different physical addresses, see #3092) */
    16711639
     
    17151683{
    17161684    APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
    1717     APICState *s = getLAPIC(dev);
     1685    APICState *s = getLapic(dev);
     1686
     1687#ifdef VBOX_WITH_SMP_GUESTS
     1688    LogRel(("[SMP] apicMMIOWrite at %llx\n", (uint64_t)GCPhysAddr));
     1689#endif
    17181690
    17191691    /** @todo: add LAPIC range validity checks (multiple LAPICs can theoretically have
     
    17521724{
    17531725    APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
    1754     /* @todo: process all LAPICS */
    1755     APICState* s = FIRST_LAPIC(dev);
    1756     apic_save(pSSMHandle, s);
    1757     /* @todo: save CPU count? */
     1726
     1727    /* save all APICs data, @todo: is it correct? */
     1728    foreach_apic(dev, 0xffffffff, apic_save(pSSMHandle, apic));
     1729
    17581730    return TMR3TimerSave(dev->CTX_SUFF(pTimer), pSSMHandle);
    17591731}
     
    17651737{
    17661738    APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
    1767     /* @todo: process all LAPICS */
    1768     APICState* s = FIRST_LAPIC(dev);
    1769     if (apic_load(pSSMHandle, s, u32Version)) {
    1770         AssertFailed();
    1771         return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
    1772     }
    1773      /* @todo: restore CPU count? */
     1739    /* load all APICs data, @todo: is it correct? */
     1740    foreach_apic(dev, 0xffffffff,
     1741                 if (apic_load(pSSMHandle, apic, u32Version))
     1742                 {
     1743                      AssertFailed();
     1744                      return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
     1745                 }
     1746                 );
    17741747    return TMR3TimerLoad(dev->CTX_SUFF(pTimer), pSSMHandle);
    17751748}
     
    17861759
    17871760     /* @todo: process all LAPICS? Or only one? */
    1788     APICState* s = FIRST_LAPIC(dev);
     1761    APICState* s = LAPIC_BASE(dev);
    17891762
    17901763    apic_init_ipi(s);
     
    17961769    dev->pApicHlpR3->pfnChangeFeature(dev->pDevInsR3, true);
    17971770    /* Clear any pending APIC interrupt action flag. */
    1798     dev->pApicHlpR3->pfnClearInterruptFF(pDevIns);
     1771    cpuClearInterrupt(dev, s->id);
    17991772    APIC_UNLOCK(dev);
    18001773}
     
    18121785}
    18131786
    1814 DECLINLINE(void) initAPIC(APICState* apic, uint8_t id)
     1787DECLINLINE(void) initApicData(APICState* apic, uint8_t id)
    18151788{
    18161789    int i;
    1817     ::memset(apic, 0, sizeof(*apic));
     1790    memset(apic, 0, sizeof(*apic));
    18181791    apic->apicbase  = UINT32_C(0xfee00000) | MSR_IA32_APICBASE_BSP | MSR_IA32_APICBASE_ENABLE;
    18191792    for (i = 0; i < APIC_LVT_NB; i++)
     
    18941867    for (i = 0; i < cCpus; i++)
    18951868    {
    1896         initAPIC((APICState*)pThis->pLapicsR3+i, i);
     1869        initApicData((APICState*)pThis->pLapicsR3 + i, i);
    18971870    }
    18981871
     
    19761949     *        (see IA32_APIC_BASE_MSR)
    19771950     */
    1978     rc = PDMDevHlpMMIORegister(pDevIns, FIRST_LAPIC(pThis)->apicbase & ~0xfff, 0x1000, pThis,
     1951    rc = PDMDevHlpMMIORegister(pDevIns, LAPIC_BASE(pThis)->apicbase & ~0xfff, 0x1000, pThis,
    19791952                               apicMMIOWrite, apicMMIORead, NULL, "APIC Memory");
    19801953    if (RT_FAILURE(rc))
     
    19841957        pThis->pApicHlpRC = pThis->pApicHlpR3->pfnGetRCHelpers(pDevIns);
    19851958
    1986         rc = PDMDevHlpMMIORegisterGC(pDevIns, FIRST_LAPIC(pThis)->apicbase & ~0xfff, 0x1000, 0,
     1959        rc = PDMDevHlpMMIORegisterGC(pDevIns, LAPIC_BASE(pThis)->apicbase & ~0xfff, 0x1000, 0,
    19871960                                     "apicMMIOWrite", "apicMMIORead", NULL);
    19881961        if (RT_FAILURE(rc))
     
    19931966        pThis->pApicHlpR0 = pThis->pApicHlpR3->pfnGetR0Helpers(pDevIns);
    19941967
    1995         rc = PDMDevHlpMMIORegisterR0(pDevIns, FIRST_LAPIC(pThis)->apicbase & ~0xfff, 0x1000, 0,
     1968        rc = PDMDevHlpMMIORegisterR0(pDevIns, LAPIC_BASE(pThis)->apicbase & ~0xfff, 0x1000, 0,
    19961969                                     "apicMMIOWrite", "apicMMIORead", NULL);
    19971970        if (RT_FAILURE(rc))
     
    20802053
    20812054#endif /* IN_RING3 */
    2082 
    2083 
    20842055
    20852056
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