VirtualBox

Changeset 12588 in vbox


Ignore:
Timestamp:
Sep 18, 2008 5:47:53 PM (16 years ago)
Author:
vboxsync
Message:

reworked APIC structures layout - hopefully not broken smth accidentally

Location:
trunk/src/VBox
Files:
4 edited

Legend:

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

    r12570 r12588  
    7878#define IOAPIC_UNLOCK(pThis) (pThis)->CTX_SUFF(pIoApicHlp)->pfnUnlock((pThis)->CTX_SUFF(pDevIns))
    7979
     80/**  @def FIRST_LAPIC
     81 * Return address of first LAPIC state. If this macro is use - it's probably
     82 * something wrong or fishy with the code using it, unless explained. */
     83#define FIRST_LAPIC(pThis) ((APICState*)(pThis)->CTX_SUFF(pLapics))
    8084
    8185#endif /* VBOX */
     
    181185    QEMUTimer *timer;
    182186    struct APICState *next_apic;
    183 #else /* VBOX */
    184 #ifdef VBOX_WITH_SMP_GUESTS
    185     //struct APICState *next_apic;
    186 #endif
    187     /** The device instance - R3 Ptr. */
    188     PPDMDEVINSR3    pDevInsR3;
    189     /** The APIC helpers - R3 Ptr. */
    190     PCPDMAPICHLPR3  pApicHlpR3;
    191     /** The APIC timer - R3 Ptr. */
    192     PTMTIMERR3      pTimerR3;
    193 
    194     /** The device instance - R0 Ptr. */
    195     PPDMDEVINSR0    pDevInsR0;
    196     /** The APIC helpers - R0 Ptr. */
    197     PCPDMAPICHLPR0  pApicHlpR0;
    198     /** The APIC timer - R0 Ptr. */
    199     PTMTIMERR0      pTimerR0;
    200 
    201     /** The device instance - RC Ptr. */
    202     PPDMDEVINSRC    pDevInsRC;
    203     /** The APIC helpers - RC Ptr. */
    204     PCPDMAPICHLPRC  pApicHlpRC;
    205     /** The APIC timer - RC Ptr. */
    206     PTMTIMERRC      pTimerRC;
    207 
    208     /** Number of attempts made to optimize TPR accesses. */
    209     uint32_t        ulTPRPatchAttempts;
    210 
    211 # ifdef VBOX_WITH_STATISTICS
    212     STAMCOUNTER     StatMMIOReadGC;
    213     STAMCOUNTER     StatMMIOReadHC;
    214     STAMCOUNTER     StatMMIOWriteGC;
    215     STAMCOUNTER     StatMMIOWriteHC;
    216     STAMCOUNTER     StatClearedActiveIrq;
    217 # endif
    218187#endif /* VBOX */
    219188} APICState;
     
    255224#ifdef VBOX
    256225typedef struct IOAPICState IOAPICState;
     226
     227typedef struct
     228{
     229    /** The device instance - R3 Ptr. */
     230    PPDMDEVINSR3    pDevInsR3;
     231    /** The APIC helpers - R3 Ptr. */
     232    PCPDMAPICHLPR3  pApicHlpR3;
     233    /** The APIC timer - R3 Ptr. */
     234    PTMTIMERR3      pTimerR3;
     235    /** LAPICs states - R3 Ptr */
     236    RTR3PTR         pLapicsR3;
     237
     238    /** The device instance - R0 Ptr. */
     239    PPDMDEVINSR0    pDevInsR0;
     240    /** The APIC helpers - R0 Ptr. */
     241    PCPDMAPICHLPR0  pApicHlpR0;
     242    /** The APIC timer - R0 Ptr. */
     243    PTMTIMERR0      pTimerR0;
     244    /** LAPICs states - R0 Ptr */
     245    RTR0PTR         pLapicsR0;
     246
     247    /** The device instance - RC Ptr. */
     248    PPDMDEVINSRC    pDevInsRC;
     249    /** The APIC helpers - RC Ptr. */
     250    PCPDMAPICHLPRC  pApicHlpRC;
     251    /** The APIC timer - RC Ptr. */
     252    PTMTIMERRC      pTimerRC;
     253     /** LAPICs states - RC Ptr */
     254    RTRCPTR         pLapicsRC;
     255
     256    /** Number of attempts made to optimize TPR accesses. */
     257    uint32_t        ulTPRPatchAttempts;
     258   
     259    /** Number of LAPICs on the system (same as CPU count). */
     260    uint32_t        cCpus;
     261
     262# ifdef VBOX_WITH_STATISTICS
     263    STAMCOUNTER     StatMMIOReadGC;
     264    STAMCOUNTER     StatMMIOReadHC;
     265    STAMCOUNTER     StatMMIOWriteGC;
     266    STAMCOUNTER     StatMMIOWriteHC;
     267    STAMCOUNTER     StatClearedActiveIrq;
     268# endif
     269} APICDeviceInfo;
     270
     271DECLINLINE(APICState*) getLAPIC(APICDeviceInfo* dev)
     272{
     273    uint32_t id = dev->CTX_SUFF(pApicHlp)->pfnGetCpuId(dev->CTX_SUFF(pDevIns));
     274    return FIRST_LAPIC(dev) + id;
     275}
     276
    257277#endif /* VBOX */
    258278
     
    265285
    266286static void apic_init_ipi(APICState *s);
    267 static void apic_set_irq(APICState *s, int vector_num, int trigger_mode);
    268 static bool apic_update_irq(APICState *s);
     287static void apic_set_irq(APICDeviceInfo* dev, APICState *s, int vector_num, int trigger_mode);
     288static bool apic_update_irq(APICDeviceInfo* dev, APICState *s);
    269289
    270290#ifdef VBOX
     
    286306PDMBOTHCBDECL(void) ioapicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
    287307
    288 static void apic_update_tpr(APICState *s, uint32_t val);
     308static void apic_update_tpr(APICDeviceInfo *dev, APICState* s, uint32_t val);
    289309__END_DECLS
    290310#endif /* VBOX */
     
    297317    APICState *apic_iter;
    298318#else /* VBOX */
    299 static void apic_bus_deliver(APICState *s, uint32_t deliver_bitmask, uint8_t delivery_mode,
     319static void apic_bus_deliver(APICDeviceInfo* dev,
     320                             APICState *s, uint32_t deliver_bitmask, uint8_t delivery_mode,
    300321                             uint8_t vector_num, uint8_t polarity,
    301322                             uint8_t trigger_mode)
     
    336357#ifdef VBOX
    337358    if (deliver_bitmask & (1 << s->id))
    338         apic_set_irq (s, vector_num, trigger_mode);
     359        apic_set_irq (dev, s, vector_num, trigger_mode);
    339360#else  /* VBOX */
    340361    for (apic_iter = first_local_apic; apic_iter != NULL;
     
    366387PDMBOTHCBDECL(void) apicSetBase(PPDMDEVINS pDevIns, uint64_t val)
    367388{
    368     APICState *s = PDMINS_2_DATA(pDevIns, APICState *);
     389    APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
     390    APICState *s = getLAPIC(dev);
    369391    Log(("cpu_set_apic_base: %016RX64\n", val));
    370392
     
    378400
    379401        /* Clear any pending APIC interrupt action flag. */
    380         s->CTX_SUFF(pApicHlp)->pfnClearInterruptFF(s->CTX_SUFF(pDevIns));
    381         s->CTX_SUFF(pApicHlp)->pfnChangeFeature(pDevIns, false);
     402        dev->CTX_SUFF(pApicHlp)->pfnClearInterruptFF(dev->CTX_SUFF(pDevIns));
     403        dev->CTX_SUFF(pApicHlp)->pfnChangeFeature(pDevIns, false);
    382404    }
    383405}
     
    448470PDMBOTHCBDECL(uint64_t) apicGetBase(PPDMDEVINS pDevIns)
    449471{
    450     APICState *s = PDMINS_2_DATA(pDevIns, APICState *);
     472    APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
     473    APICState *s = getLAPIC(dev);
    451474    Log(("apicGetBase: %016llx\n", (uint64_t)s->apicbase));
    452475    return s->apicbase;
     
    455478PDMBOTHCBDECL(void) apicSetTPR(PPDMDEVINS pDevIns, uint8_t val)
    456479{
    457     APICState *s = PDMINS_2_DATA(pDevIns, APICState *);
     480    APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
     481    APICState *s = getLAPIC(dev);
    458482    LogFlow(("apicSetTPR: val=%#x (trp %#x -> %#x)\n", val, s->tpr, (val & 0x0f) << 4));
    459     apic_update_tpr(s, (val & 0x0f) << 4);
     483    apic_update_tpr(dev, s, (val & 0x0f) << 4);
    460484}
    461485
    462486PDMBOTHCBDECL(uint8_t) apicGetTPR(PPDMDEVINS pDevIns)
    463487{
    464     APICState *s = PDMINS_2_DATA(pDevIns, APICState *);
     488    APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
     489    APICState *s = getLAPIC(dev);
    465490    Log2(("apicGetTPR: returns %#x\n", s->tpr >> 4));
    466491    return s->tpr >> 4;
     
    475500                                           uint8_t u8TriggerMode)
    476501{
    477     APICState *s = PDMINS_2_DATA(pDevIns, APICState *);
     502    APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
     503    APICState *s = getLAPIC(dev);
    478504    LogFlow(("apicBusDeliverCallback: s=%p pDevIns=%p u8Dest=%#x u8DestMode=%#x u8DeliveryMode=%#x iVector=%#x u8Polarity=%#x u8TriggerMode=%#x\n",
    479505             s, pDevIns, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode));
    480     apic_bus_deliver(s, apic_get_delivery_bitmask(s, u8Dest, u8DestMode),
     506    apic_bus_deliver(dev, s, apic_get_delivery_bitmask(s, u8Dest, u8DestMode),
    481507                     u8DeliveryMode, iVector, u8Polarity, u8TriggerMode);
    482508}
     
    533559
    534560/* signal the CPU if an irq is pending */
    535 static bool apic_update_irq(APICState *s)
     561static bool apic_update_irq(APICDeviceInfo *dev, APICState* s)
    536562{
    537563    int irrv, ppr;
     
    540566    {
    541567        /* Clear any pending APIC interrupt action flag. */
    542         s->CTX_SUFF(pApicHlp)->pfnClearInterruptFF(s->CTX_SUFF(pDevIns));
     568        dev->CTX_SUFF(pApicHlp)->pfnClearInterruptFF(dev->CTX_SUFF(pDevIns));
    543569        return false;
    544570    }
     
    555581    cpu_interrupt(s->cpu_env, CPU_INTERRUPT_HARD);
    556582#else
    557     s->CTX_SUFF(pApicHlp)->pfnSetInterruptFF(s->CTX_SUFF(pDevIns));
     583    dev->CTX_SUFF(pApicHlp)->pfnSetInterruptFF(dev->CTX_SUFF(pDevIns));
    558584    return true;
    559585#endif
     
    566592{
    567593    int irrv, ppr;
    568 
    569     APICState *s = PDMINS_2_DATA(pDevIns, APICState *);
    570     if (!s)
     594    APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
     595    if (!dev)
    571596        return false;
     597    APICState *s = getLAPIC(dev);
    572598
    573599    irrv = get_highest_priority_int(s->irr);
     
    582608}
    583609
    584 static void apic_update_tpr(APICState *s, uint32_t val)
     610static void apic_update_tpr(APICDeviceInfo *dev, APICState* s, uint32_t val)
    585611{
    586612    bool fIrqIsActive = false;
    587613    bool fIrqWasActive = false;
    588614
    589     fIrqWasActive = apic_update_irq(s);
     615    fIrqWasActive = apic_update_irq(dev, s);
    590616    s->tpr        = val;
    591     fIrqIsActive  = apic_update_irq(s);
     617    fIrqIsActive  = apic_update_irq(dev, s);
    592618
    593619    /* If an interrupt is pending and now masked, then clear the FF flag. */
     
    595621    {
    596622        Log(("apic_update_tpr: deactivate interrupt that was masked by the TPR update (%x)\n", val));
    597         STAM_COUNTER_INC(&s->StatClearedActiveIrq);
    598         s->CTX_SUFF(pApicHlp)->pfnClearInterruptFF(s->CTX_SUFF(pDevIns));
    599     }
    600 }
    601 #endif
    602 
    603 static void apic_set_irq(APICState *s, int vector_num, int trigger_mode)
     623        STAM_COUNTER_INC(&dev->StatClearedActiveIrq);
     624        dev->CTX_SUFF(pApicHlp)->pfnClearInterruptFF(dev->CTX_SUFF(pDevIns));
     625    }
     626}
     627#endif
     628
     629static void apic_set_irq(APICDeviceInfo *dev,  APICState* s, int vector_num, int trigger_mode)
    604630{
    605631    LogFlow(("apic_set_irq vector=%x, trigger_mode=%x\n", vector_num, trigger_mode));
     
    609635    else
    610636        reset_bit(s->tmr, vector_num);
    611     apic_update_irq(s);
    612 }
    613 
    614 static void apic_eoi(APICState *s)
     637    apic_update_irq(dev, s);
     638}
     639
     640static void apic_eoi(APICDeviceInfo *dev, APICState* s)
    615641{
    616642    int isrv;
     
    622648    /* XXX: send the EOI packet to the APIC bus to allow the I/O APIC to
    623649            set the remote IRR bit for level triggered interrupts. */
    624     apic_update_irq(s);
     650    apic_update_irq(dev, s);
    625651}
    626652
     
    683709}
    684710
    685 static void apic_deliver(APICState *s, uint8_t dest, uint8_t dest_mode,
     711static void apic_deliver(APICDeviceInfo* dev, APICState *s,
     712                         uint8_t dest, uint8_t dest_mode,
    686713                         uint8_t delivery_mode, uint8_t vector_num,
    687714                         uint8_t polarity, uint8_t trigger_mode)
     
    757784                     trigger_mode);
    758785#else /* VBOX */
    759     apic_bus_deliver(s, deliver_bitmask, delivery_mode, vector_num, polarity,
     786    apic_bus_deliver(dev, s, deliver_bitmask, delivery_mode, vector_num, polarity,
    760787                     trigger_mode);
    761788#endif /* VBOX */
     
    769796PDMBOTHCBDECL(int) apicGetInterrupt(PPDMDEVINS pDevIns)
    770797{
    771     APICState *s = PDMINS_2_DATA(pDevIns, APICState *);
     798    APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
     799    APICState *s = getLAPIC(dev);
    772800#endif /* VBOX */
    773801    int intno;
     
    796824    reset_bit(s->irr, intno);
    797825    set_bit(s->isr, intno);
    798     apic_update_irq(s);
     826    apic_update_irq(dev, s);
    799827    LogFlow(("apic_get_interrupt: returns %d\n", intno));
    800828    return intno;
    801829}
    802830
    803 static uint32_t apic_get_current_count(APICState *s)
     831static uint32_t apic_get_current_count(APICDeviceInfo* dev, APICState *s)
    804832{
    805833    int64_t d;
     
    809837        s->count_shift;
    810838#else /* VBOX */
    811     d = (TMTimerGet(s->CTX_SUFF(pTimer)) - s->initial_count_load_time) >>
     839    d = (TMTimerGet(dev->CTX_SUFF(pTimer)) - s->initial_count_load_time) >>
    812840        s->count_shift;
    813841#endif /* VBOX */
     
    824852}
    825853
    826 static void apic_timer_update(APICState *s, int64_t current_time)
     854static void apic_timer_update(APICDeviceInfo* dev, APICState *s, int64_t current_time)
    827855{
    828856    int64_t next_time, d;
     
    842870        qemu_mod_timer(s->timer, next_time);
    843871#else
    844         TMTimerSet(s->CTX_SUFF(pTimer), next_time);
     872        TMTimerSet(dev->CTX_SUFF(pTimer), next_time);
    845873#endif
    846874        s->next_time = next_time;
     
    850878        qemu_del_timer(s->timer);
    851879#else
    852         TMTimerStop(s->CTX_SUFF(pTimer));
     880        TMTimerStop(dev->CTX_SUFF(pTimer));
    853881#endif
    854882    }
     
    863891static DECLCALLBACK(void) apicTimer(PPDMDEVINS pDevIns, PTMTIMER pTimer)
    864892{
    865     APICState *s = PDMINS_2_DATA(pDevIns, APICState *);
    866     s->pApicHlpR3->pfnLock(pDevIns, VERR_INTERNAL_ERROR);
     893    APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
     894    APICState *s = getLAPIC(dev);
     895    dev->pApicHlpR3->pfnLock(pDevIns, VERR_INTERNAL_ERROR);
    867896#endif /* VBOX */
    868897
    869898    if (!(s->lvt[APIC_LVT_TIMER] & APIC_LVT_MASKED)) {
    870899        LogFlow(("apic_timer: trigger irq\n"));
    871         apic_set_irq(s, s->lvt[APIC_LVT_TIMER] & 0xff, APIC_TRIGGER_EDGE);
    872     }
    873     apic_timer_update(s, s->next_time);
    874 
    875 #ifdef VBOX
    876     APIC_UNLOCK(s);
     900        apic_set_irq(dev, s, s->lvt[APIC_LVT_TIMER] & 0xff, APIC_TRIGGER_EDGE);
     901    }
     902    apic_timer_update(dev, s, s->next_time);
     903
     904#ifdef VBOX
     905    APIC_UNLOCK(dev);
    877906#endif
    878907}
     
    884913    return 0;
    885914}
    886 
    887915static uint32_t apic_mem_readw(void *opaque, target_phys_addr_t addr)
    888916{
     
    906934    APICState *s;
    907935#else /* VBOX */
    908 static uint32_t apic_mem_readl(APICState *s, target_phys_addr_t addr)
     936static uint32_t apic_mem_readl(APICDeviceInfo* dev, APICState *s, target_phys_addr_t addr)
    909937{
    910938#endif /* VBOX */
     
    9971025        break;
    9981026    case 0x39:
    999         val = apic_get_current_count(s);
     1027        val = apic_get_current_count(dev, s);
    10001028        break;
    10011029    case 0x3e:
     
    10201048    APICState *s;
    10211049#else /* VBOX */
    1022 static int apic_mem_writel(APICState *s, target_phys_addr_t addr, uint32_t val)
     1050static int apic_mem_writel(APICDeviceInfo* dev, APICState *s, target_phys_addr_t addr, uint32_t val)
    10231051{
    10241052#endif /* VBOX */
     
    10461074    case 0x08:
    10471075#ifdef VBOX
    1048         apic_update_tpr(s, val);
     1076        apic_update_tpr(dev, s, val);
    10491077#else
    10501078        s->tpr = val;
     
    10571085        break;
    10581086    case 0x0b: /* EOI */
    1059         apic_eoi(s);
     1087        apic_eoi(dev, s);
    10601088        break;
    10611089    case 0x0d:
     
    10671095    case 0x0f:
    10681096        s->spurious_vec = val & 0x1ff;
    1069         apic_update_irq(s);
     1097        apic_update_irq(dev, s);
    10701098        break;
    10711099#ifndef VBOX
     
    10851113    case 0x30:
    10861114        s->icr[0] = val;
    1087         apic_deliver(s, (s->icr[1] >> 24) & 0xff, (s->icr[0] >> 11) & 1,
     1115        apic_deliver(dev, s, (s->icr[1] >> 24) & 0xff, (s->icr[0] >> 11) & 1,
    10881116                     (s->icr[0] >> 8) & 7, (s->icr[0] & 0xff),
    10891117                     (s->icr[0] >> 14) & 1, (s->icr[0] >> 15) & 1);
     
    11041132                apic_timer_update(s, qemu_get_clock(vm_clock));
    11051133#else /* VBOX */
    1106                 apic_timer_update(s, TMTimerGet(s->CTX_SUFF(pTimer)));
     1134                apic_timer_update(dev, s, TMTimerGet(dev->CTX_SUFF(pTimer)));
    11071135#endif /* VBOX*/
    11081136        }
     
    11131141        s->initial_count_load_time = qemu_get_clock(vm_clock);
    11141142#else /* VBOX */
    1115         s->initial_count_load_time = TMTimerGet(s->CTX_SUFF(pTimer));
     1143        s->initial_count_load_time = TMTimerGet(dev->CTX_SUFF(pTimer));
    11161144#endif /* VBOX*/
    1117         apic_timer_update(s, s->initial_count_load_time);
     1145        apic_timer_update(dev, s, s->initial_count_load_time);
    11181146        break;
    11191147    case 0x39:
     
    12121240    return 0;
    12131241}
    1214 
     1242#ifndef VBOX
    12151243static void apic_reset(void *opaque)
    12161244{
    12171245    APICState *s = (APICState*)opaque;
    1218 #ifdef VBOX
    1219     TMTimerStop(s->CTX_SUFF(pTimer));
    1220 
    1221     /* malc, I've removed the initing duplicated in apic_init_ipi(). This
    1222      * arb_id was left over.. */
    1223     s->arb_id = 0;
    1224 
    1225     /* Reset should re-enable the APIC. */
    1226     s->apicbase = 0xfee00000 | MSR_IA32_APICBASE_BSP | MSR_IA32_APICBASE_ENABLE;
    1227     s->pApicHlpR3->pfnChangeFeature(s->pDevInsR3, true);
    1228 
    1229 #endif /* VBOX */
    12301246    apic_init_ipi(s);
    12311247}
     1248#endif
    12321249
    12331250#endif /* IN_RING3 */
     
    15431560PDMBOTHCBDECL(int) apicMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
    15441561{
    1545     APICState *s = PDMINS_2_DATA(pDevIns, APICState *);
     1562    APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
     1563    APICState *s = getLAPIC(dev);
    15461564
    15471565#ifdef VBOX_WITH_SMP_GUESTS
     
    15491567#endif
    15501568
    1551     STAM_COUNTER_INC(&CTXSUFF(s->StatMMIORead));
     1569    STAM_COUNTER_INC(&CTXSUFF(dev->StatMMIORead));
    15521570    switch (cb)
    15531571    {
     
    15791597#endif
    15801598#endif /* experimental */
    1581             APIC_LOCK(s, VINF_IOM_HC_MMIO_READ);
    1582             *(uint32_t *)pv = apic_mem_readl(s, GCPhysAddr);
    1583             APIC_UNLOCK(s);
     1599            APIC_LOCK(dev, VINF_IOM_HC_MMIO_READ);
     1600            *(uint32_t *)pv = apic_mem_readl(dev, s, GCPhysAddr);
     1601            APIC_UNLOCK(dev);
    15841602            break;
    15851603        }
     
    15931611PDMBOTHCBDECL(int) apicMMIOWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb)
    15941612{
    1595     APICState *s = PDMINS_2_DATA(pDevIns, APICState *);
    1596 
    1597     STAM_COUNTER_INC(&CTXSUFF(s->StatMMIOWrite));
     1613    APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
     1614    APICState *s = getLAPIC(dev);
     1615
     1616    STAM_COUNTER_INC(&CTXSUFF(dev->StatMMIOWrite));
    15981617    switch (cb)
    15991618    {
     
    16061625        {
    16071626            int rc;
    1608             APIC_LOCK(s, VINF_IOM_HC_MMIO_WRITE);
    1609             rc = apic_mem_writel(s, GCPhysAddr, *(uint32_t *)pv);
    1610             APIC_UNLOCK(s);
     1627            APIC_LOCK(dev, VINF_IOM_HC_MMIO_WRITE);
     1628            rc = apic_mem_writel(dev, s, GCPhysAddr, *(uint32_t *)pv);
     1629            APIC_UNLOCK(dev);
    16111630            return rc;
    16121631        }
     
    16261645static DECLCALLBACK(int) apicSaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle)
    16271646{
    1628     APICState *s = PDMINS_2_DATA(pDevIns, APICState *);
     1647    APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
     1648    /* @todo: process all LAPICS */
     1649    APICState* s = FIRST_LAPIC(dev);
    16291650    apic_save(pSSMHandle, s);
    1630     return TMR3TimerSave(s->CTX_SUFF(pTimer), pSSMHandle);
     1651    /* @todo: save CPU count? */
     1652    return TMR3TimerSave(dev->CTX_SUFF(pTimer), pSSMHandle);
    16311653}
    16321654
     
    16361658static DECLCALLBACK(int) apicLoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSMHandle, uint32_t u32Version)
    16371659{
    1638     APICState *s = PDMINS_2_DATA(pDevIns, APICState *);
     1660    APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
     1661    /* @todo: process all LAPICS */
     1662    APICState* s = FIRST_LAPIC(dev);
    16391663    if (apic_load(pSSMHandle, s, u32Version)) {
    16401664        AssertFailed();
    16411665        return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
    16421666    }
    1643     return TMR3TimerLoad(s->CTX_SUFF(pTimer), pSSMHandle);
     1667     /* @todo: restore CPU count? */
     1668    return TMR3TimerLoad(dev->CTX_SUFF(pTimer), pSSMHandle);
    16441669}
    16451670
     
    16491674static DECLCALLBACK(void) apicReset(PPDMDEVINS pDevIns)
    16501675{
    1651     APICState *s = PDMINS_2_DATA(pDevIns, APICState *);
    1652     s->pApicHlpR3->pfnLock(pDevIns, VERR_INTERNAL_ERROR);
    1653     apic_reset(s);
     1676    APICDeviceInfo* dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
     1677    dev->pApicHlpR3->pfnLock(pDevIns, VERR_INTERNAL_ERROR);
     1678
     1679    TMTimerStop(dev->CTX_SUFF(pTimer));
     1680
     1681     /* @todo: process all LAPICS? Or only one? */
     1682    APICState* s = FIRST_LAPIC(dev);
     1683
     1684    apic_init_ipi(s);
     1685    /* malc, I've removed the initing duplicated in apic_init_ipi(). This
     1686     * arb_id was left over.. */
     1687    s->arb_id = 0;
     1688    /* Reset should re-enable the APIC. */
     1689    s->apicbase = 0xfee00000 | MSR_IA32_APICBASE_BSP | MSR_IA32_APICBASE_ENABLE;
     1690    dev->pApicHlpR3->pfnChangeFeature(dev->pDevInsR3, true);
    16541691    /* Clear any pending APIC interrupt action flag. */
    1655     s->pApicHlpR3->pfnClearInterruptFF(pDevIns);
    1656     APIC_UNLOCK(s);
     1692    dev->pApicHlpR3->pfnClearInterruptFF(pDevIns);
     1693    APIC_UNLOCK(dev);
    16571694}
    16581695
     
    16621699static DECLCALLBACK(void) apicRelocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
    16631700{
    1664     APICState *pThis = PDMINS_2_DATA(pDevIns, APICState *);
     1701    APICDeviceInfo *pThis = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
     1702   
    16651703    pThis->pDevInsRC  = PDMDEVINS_2_RCPTR(pDevIns);
    16661704    pThis->pApicHlpRC = pThis->pApicHlpR3->pfnGetRCHelpers(pDevIns);
    16671705    pThis->pTimerRC   = TMTimerRCPtr(pThis->CTX_SUFF(pTimer));
     1706}
     1707
     1708DECLINLINE(void) initAPIC(APICState* apic, uint8_t id)
     1709{
     1710    int i;
     1711    ::memset(apic, 0, sizeof(*apic));
     1712    apic->apicbase  = UINT32_C(0xfee00000) | MSR_IA32_APICBASE_BSP | MSR_IA32_APICBASE_ENABLE;
     1713    for (i = 0; i < APIC_LVT_NB; i++)
     1714        apic->lvt[i] = 1 << 16; /* mask LVT */
     1715    apic->spurious_vec = 0xff;
     1716    apic->id = id;
    16681717}
    16691718
     
    16731722static DECLCALLBACK(int) apicConstruct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfgHandle)
    16741723{
    1675     APICState      *pThis = PDMINS_2_DATA(pDevIns, APICState *);
    16761724    PDMAPICREG      ApicReg;
    16771725    int             rc;
    1678     int             i;
     1726    uint32_t        i;
    16791727    bool            fIOAPIC;
    16801728    bool            fGCEnabled;
    16811729    bool            fR0Enabled;
    1682 
    1683 #ifndef VBOX_WITH_SMP_GUESTS
     1730    APICDeviceInfo  *pThis = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
     1731    uint32_t        cCpus;
     1732
     1733    /*
     1734     * Only single device instance.
     1735     */
    16841736    Assert(iInstance == 0);
    1685 #else
    1686     LogRel(("[SMP] apicConstruct: %d %p\n", iInstance, pDevIns));
    1687 #endif
    16881737
    16891738    /*
    16901739     * Validate configuration.
    16911740     */
    1692     if (!CFGMR3AreValuesValid(pCfgHandle, "IOAPIC\0" "GCEnabled\0" "R0Enabled\0"))
     1741    if (!CFGMR3AreValuesValid(pCfgHandle,
     1742                              "IOAPIC\0"
     1743                              "GCEnabled\0"
     1744                              "R0Enabled\0"
     1745                              "NumCPUs\0"))
    16931746        return VERR_PDM_DEVINS_UNKNOWN_CFG_VALUES;
    16941747
     
    17071760        return PDMDEV_SET_ERROR(pDevIns, rc,
    17081761                                N_("Configuration error: Failed to query boolean value \"R0Enabled\""));
    1709     Log(("APIC: fR0Enabled=%RTbool fGCEnabled=%RTbool fIOAPIC=%RTbool\n", fR0Enabled, fGCEnabled, fIOAPIC));
     1762   
     1763    rc = CFGMR3QueryU32Def(pCfgHandle, "NumCPUs", &cCpus, 1);
     1764    if (RT_FAILURE(rc))
     1765        return PDMDEV_SET_ERROR(pDevIns, rc,
     1766                                N_("Configuration error: Failed to query integer value \"NumCPUs\""));
     1767
     1768    Log(("APIC: cCpus=%d fR0Enabled=%RTbool fGCEnabled=%RTbool fIOAPIC=%RTbool\n", cCpus, fR0Enabled, fGCEnabled, fIOAPIC));
    17101769
    17111770    /*
     
    17151774    pThis->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
    17161775    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 
     1776
     1777    PVM pVM = PDMDevHlpGetVM(pDevIns);
     1778   
     1779    /*
     1780     * We are not freeing this memory, as it's automatically released when guest exits.
     1781     */
     1782    rc = MMHyperAlloc(pVM, cCpus*sizeof(APICState), 1, MM_TAG_PDM_DEVICE_USER, (void **)&pThis->pLapicsR3);
     1783    if (RT_FAILURE(rc))
     1784        return VERR_NO_MEMORY;
     1785    pThis->pLapicsR0 = MMHyperR3ToR0(pVM, pThis->pLapicsR3);
     1786    pThis->pLapicsRC = MMHyperR3ToRC(pVM, pThis->pLapicsR3);
     1787
     1788    for (i = 0; i < cCpus; i++)
     1789    {
     1790        initAPIC((APICState*)pThis->pLapicsR3+i, i);
     1791    }
    17221792
    17231793    /*
     
    17971867    /*
    17981868     * Register the MMIO range.
     1869     * @todo: may need to rethink for cases when different LAPICs mapped to different address
     1870     *        (see IA32_APIC_BASE_MSR)
    17991871     */
    1800     rc = PDMDevHlpMMIORegister(pDevIns, pThis->apicbase & ~0xfff, 0x1000, pThis,
     1872    rc = PDMDevHlpMMIORegister(pDevIns, FIRST_LAPIC(pThis)->apicbase & ~0xfff, 0x1000, pThis,
    18011873                               apicMMIOWrite, apicMMIORead, NULL, "APIC Memory");
    18021874    if (RT_FAILURE(rc))
     
    18061878        pThis->pApicHlpRC = pThis->pApicHlpR3->pfnGetRCHelpers(pDevIns);
    18071879
    1808         rc = PDMDevHlpMMIORegisterGC(pDevIns, pThis->apicbase & ~0xfff, 0x1000, 0,
     1880        rc = PDMDevHlpMMIORegisterGC(pDevIns, FIRST_LAPIC(pThis)->apicbase & ~0xfff, 0x1000, 0,
    18091881                                     "apicMMIOWrite", "apicMMIORead", NULL);
    18101882        if (RT_FAILURE(rc))
     
    18151887        pThis->pApicHlpR0 = pThis->pApicHlpR3->pfnGetR0Helpers(pDevIns);
    18161888
    1817         rc = PDMDevHlpMMIORegisterR0(pDevIns, pThis->apicbase & ~0xfff, 0x1000, 0,
     1889        rc = PDMDevHlpMMIORegisterR0(pDevIns, FIRST_LAPIC(pThis)->apicbase & ~0xfff, 0x1000, 0,
    18181890                                     "apicMMIOWrite", "apicMMIORead", NULL);
    18191891        if (RT_FAILURE(rc))
     
    18341906     * Saved state.
    18351907     */
    1836     rc = PDMDevHlpSSMRegister(pDevIns, pDevIns->pDevReg->szDeviceName, iInstance, 1 /* version */,
     1908    rc = PDMDevHlpSSMRegister(pDevIns, pDevIns->pDevReg->szDeviceName, iInstance, 2 /* version */,
    18371909                              sizeof(*pThis), NULL, apicSaveExec, NULL, NULL, apicLoadExec, NULL);
    18381910    if (RT_FAILURE(rc))
     
    18741946    PDM_DEVREG_CLASS_PIC,
    18751947    /* cMaxInstances */
    1876 #ifdef VBOX_WITH_SMP_GUESTS
    1877     8,
    1878 #else
    18791948    1,
    1880 #endif
    18811949    /* cbInstance */
    18821950    sizeof(APICState),
  • trunk/src/VBox/Devices/testcase/tstDeviceStructSize.cpp

    r11556 r12588  
    224224//    CHECK_MEMBER_ALIGNMENT(PCNetState, StatMMIOReadGC, 8);
    225225    CHECK_MEMBER_ALIGNMENT(DEVPIC, StatSetIrqGC, 8);
    226     CHECK_MEMBER_ALIGNMENT(APICState, StatMMIOReadGC, 8);
     226    CHECK_MEMBER_ALIGNMENT(APICDeviceInfo, StatMMIOReadGC, 8);
    227227    CHECK_MEMBER_ALIGNMENT(IOAPICState, StatMMIOReadGC, 8);
    228228    CHECK_MEMBER_ALIGNMENT(IOAPICState, StatMMIOReadGC, 8);
  • trunk/src/VBox/Devices/testcase/tstDeviceStructSizeGC.cpp

    r12509 r12588  
    567567    GEN_CHECK_OFF(APICState, initial_count_load_time);
    568568    GEN_CHECK_OFF(APICState, next_time);
    569     GEN_CHECK_OFF(APICState, pDevInsR3);
    570     GEN_CHECK_OFF(APICState, pApicHlpR3);
    571     GEN_CHECK_OFF(APICState, pTimerR3);
    572     GEN_CHECK_OFF(APICState, pDevInsR0);
    573     GEN_CHECK_OFF(APICState, pApicHlpR0);
    574     GEN_CHECK_OFF(APICState, pTimerR0);
    575     GEN_CHECK_OFF(APICState, pDevInsRC);
    576     GEN_CHECK_OFF(APICState, pApicHlpRC);
    577     GEN_CHECK_OFF(APICState, pTimerRC);
    578     GEN_CHECK_OFF(APICState, ulTPRPatchAttempts);
     569
     570    GEN_CHECK_SIZE(APICDeviceInfo);
     571    GEN_CHECK_OFF(APICDeviceInfo, pDevInsR3);
     572    GEN_CHECK_OFF(APICDeviceInfo, pApicHlpR3);
     573    GEN_CHECK_OFF(APICDeviceInfo, pTimerR3);
     574    GEN_CHECK_OFF(APICDeviceInfo, pDevInsR0);
     575    GEN_CHECK_OFF(APICDeviceInfo, pApicHlpR0);
     576    GEN_CHECK_OFF(APICDeviceInfo, pTimerR0);
     577    GEN_CHECK_OFF(APICDeviceInfo, pDevInsRC);
     578    GEN_CHECK_OFF(APICDeviceInfo, pApicHlpRC);
     579    GEN_CHECK_OFF(APICDeviceInfo, pTimerRC);
     580    GEN_CHECK_OFF(APICDeviceInfo, ulTPRPatchAttempts);
    579581#ifdef VBOX_WITH_STATISTICS
    580     GEN_CHECK_OFF(APICState, StatMMIOReadGC);
    581     GEN_CHECK_OFF(APICState, StatMMIOWriteHC);
     582    GEN_CHECK_OFF(APICDeviceInfo, StatMMIOReadGC);
     583    GEN_CHECK_OFF(APICDeviceInfo, StatMMIOWriteHC);
    582584#endif
    583585
  • trunk/src/VBox/Main/ConsoleImpl2.cpp

    r12520 r12588  
    499499    /*
    500500     * Advanced Programmable Interrupt Controller.
    501      * SMP: Each CPU has a LAPIC (cross-calls).
     501     * SMP: Each CPU has a LAPIC, but we have a single device representing all LAPICs states,
     502     *      thus only single insert
    502503     */
    503504    rc = CFGMR3InsertNode(pDevices, "apic", &pDev);                                 RC_CHECK();
    504     for (unsigned iCpu = 0; iCpu < cCpus; iCpu++)
    505     {
    506         rc = CFGMR3InsertNodeF(pDev, &pInst, "%u", iCpu);                           RC_CHECK();
    507         rc = CFGMR3InsertInteger(pInst, "Trusted",          1);     /* boolean */   RC_CHECK();
    508         rc = CFGMR3InsertNode(pInst,    "Config", &pCfg);                           RC_CHECK();
    509         rc = CFGMR3InsertInteger(pCfg,  "IOAPIC", fIOAPIC);                         RC_CHECK();
    510     }
    511 
     505    rc = CFGMR3InsertNode(pDev, "0", &pInst);                                       RC_CHECK();
     506    rc = CFGMR3InsertInteger(pInst, "Trusted",              1);     /* boolean */   RC_CHECK();
     507    rc = CFGMR3InsertNode(pInst,    "Config", &pCfg);                               RC_CHECK();
     508    rc = CFGMR3InsertInteger(pCfg,  "IOAPIC", fIOAPIC);                             RC_CHECK();
     509    rc = CFGMR3InsertInteger(pCfg,  "NumCPUs", cCpus);                              RC_CHECK();
     510
     511    /* SMP: @todo: IOAPIC may be required for SMP configs */
    512512    if (fIOAPIC)
    513513    {
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