VirtualBox

vbox的更動 12598 路徑 trunk/src/VBox/Devices/PC


忽略:
時間撮記:
2008-9-19 上午11:50:47 (16 年 以前)
作者:
vboxsync
訊息:

some interrupt routing code

檔案:
修改 1 筆資料

圖例:

未更動
新增
刪除
  • trunk/src/VBox/Devices/PC/DevAPIC.cpp

    r12588 r12598  
    7979
    8080/**  @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. */
     81 * Return address of first LAPIC state. */
    8382#define FIRST_LAPIC(pThis) ((APICState*)(pThis)->CTX_SUFF(pLapics))
     83
     84#define FOR_EACH_LAPIC(dev, code)                         \
     85    do {                                                  \
     86        uint32_t i;                                       \
     87        APICState* apic = FIRST_LAPIC(dev);               \
     88        for (i=0; i < dev->cCpus; i++)                    \
     89        {                                                 \
     90            code;                                         \
     91            apic++;                                       \
     92        }                                                 \
     93    } while (0)
     94
     95# define set_bit(pvBitmap, iBit)    ASMBitSet(pvBitmap, iBit)
     96# define reset_bit(pvBitmap, iBit)  ASMBitClear(pvBitmap, iBit)
     97# define fls_bit(value)             (ASMBitLastSetU32(value) - 1)
     98# define ffs_bit(value)             (ASMBitFirstSetU32(value) - 1)
    8499
    85100#endif /* VBOX */
     
    227242typedef struct
    228243{
     244    /** @todo: APIC timer must be per-APIC */
    229245    /** The device instance - R3 Ptr. */
    230246    PPDMDEVINSR3    pDevInsR3;
     
    257273    uint32_t        ulTPRPatchAttempts;
    258274   
    259     /** Number of LAPICs on the system (same as CPU count). */
     275    /** Number of CPUs on the system (same as LAPIC count). */
    260276    uint32_t        cCpus;
    261277
     
    289305
    290306#ifdef VBOX
    291 static uint32_t apic_get_delivery_bitmask(APICState *s, uint8_t dest, uint8_t dest_mode);
     307static uint32_t apic_get_delivery_bitmask(APICDeviceInfo* dev, APICState *s, uint8_t dest, uint8_t dest_mode);
    292308__BEGIN_DECLS
    293309PDMBOTHCBDECL(int)  apicMMIORead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS GCPhysAddr, void *pv, unsigned cb);
     
    327343    switch (delivery_mode) {
    328344        case APIC_DM_LOWPRI:
     345#ifndef VBOX
     346            /* XXX: search for focus processor, arbitration */
     347            {
     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                }
     362            }
     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
     375            return;
    329376        case APIC_DM_FIXED:
    330377            /* XXX: arbitration */
     
    504551    LogFlow(("apicBusDeliverCallback: s=%p pDevIns=%p u8Dest=%#x u8DestMode=%#x u8DeliveryMode=%#x iVector=%#x u8Polarity=%#x u8TriggerMode=%#x\n",
    505552             s, pDevIns, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode));
    506     apic_bus_deliver(dev, s, apic_get_delivery_bitmask(s, u8Dest, u8DestMode),
     553    apic_bus_deliver(dev, s, apic_get_delivery_bitmask(dev, s, u8Dest, u8DestMode),
    507554                     u8DeliveryMode, iVector, u8Polarity, u8TriggerMode);
    508555}
    509 
    510 # define set_bit(pvBitmap, iBit)    ASMBitSet(pvBitmap, iBit)
    511 # define reset_bit(pvBitmap, iBit)  ASMBitClear(pvBitmap, iBit)
    512 # define fls_bit(value)             (ASMBitLastSetU32(value) - 1)
    513556
    514557#endif /* VBOX */
     
    654697static uint32_t apic_get_delivery_bitmask(uint8_t dest, uint8_t dest_mode)
    655698#else /* VBOX */
    656 static uint32_t apic_get_delivery_bitmask(APICState *s, uint8_t dest, uint8_t dest_mode)
     699static uint32_t apic_get_delivery_bitmask(APICDeviceInfo *dev, APICState *s, uint8_t dest, uint8_t dest_mode)
    657700#endif /* VBOX */
    658701{
     702#if 0
    659703    uint32_t mask = 0;
    660704#ifndef VBOX
     
    682726
    683727    return mask;
    684 }
    685 
     728#else
     729    uint32_t mask = 0;
     730
     731    if (dest_mode == 0)
     732    {
     733        if (dest == 0xff)
     734            mask = 0xff;
     735        else
     736            mask = 1 << dest;
     737    }
     738    else
     739    {
     740        APICState *apic = FIRST_LAPIC(dev);
     741        uint32_t i;
     742       
     743        /* XXX: cluster mode */
     744        for(i = 0; i < dev->cCpus; i++)
     745        {
     746            if (apic->dest_mode == 0xf)
     747            {
     748                if (dest & apic->log_dest)
     749                    mask |= (1 << apic->id);
     750            }
     751            else if (apic->dest_mode == 0x0)
     752            {
     753                if ((dest & 0xf0) == (apic->log_dest & 0xf0)
     754                    &&
     755                    (dest & apic->log_dest & 0x0f))
     756                {
     757                    mask |= (1 << i);
     758                }
     759            }
     760        }
     761        apic++;
     762    }
     763
     764    return mask;
     765#endif
     766}
    686767
    687768static void apic_init_ipi(APICState *s)
     
    709790}
    710791
     792
     793/* send a SIPI message to the CPU to start it */
     794static void apic_startup(APICDeviceInfo* dev, APICState *s, int vector_num)
     795{
     796#ifndef VBOX
     797    CPUState *env = s->cpu_env;
     798    if (!env->halted)
     799        return;
     800    env->eip = 0;
     801    cpu_x86_load_seg_cache(env, R_CS, vector_num << 8, vector_num << 12,
     802                           0xffff, 0);
     803    env->halted = 0;
     804#else
     805    /** @todo: init CPUs */
     806    LogRel(("[SMP] apic_startup: %d on CPUs %d\n", vector_num, s->id));
     807#endif
     808}
    711809static void apic_deliver(APICDeviceInfo* dev, APICState *s,
    712810                         uint8_t dest, uint8_t dest_mode,
     
    721819
    722820    LogFlow(("apic_deliver dest=%x dest_mode=%x delivery_mode=%x vector_num=%x polarity=%x trigger_mode=%x\n", dest, dest_mode, delivery_mode, vector_num, polarity, trigger_mode));
     821   
     822    switch (dest_shorthand) {
     823        case 0:
     824#ifndef VBOX
     825            deliver_bitmask = apic_get_delivery_bitmask(dest, dest_mode);
     826#else /* VBOX */
     827            deliver_bitmask = apic_get_delivery_bitmask(dev, s, dest, dest_mode);
     828#endif /* !VBOX */
     829            break;
     830        case 1:
     831            deliver_bitmask = (1 << s->id);
     832            break;
     833        case 2:
     834            deliver_bitmask = 0xffffffff;
     835            break;
     836        case 3:
     837            deliver_bitmask = 0xffffffff & ~(1 << s->id);
     838            break;
     839    }
     840   
    723841    switch (delivery_mode) {
    724842        case APIC_DM_LOWPRI:
     
    732850                if (level == 0 && trig_mode == 1) {
    733851#ifdef VBOX
    734                     if (deliver_bitmask & (1 << s->id)) {
    735                         s->arb_id = s->id;
    736                     }
     852                    FOR_EACH_LAPIC(dev,
     853                                   if (deliver_bitmask & (1 << apic->id))
     854                                   {
     855                                       apic->arb_id = apic->id;
     856                                   });
    737857#else /* !VBOX */
    738858                    for (apic_iter = first_local_apic; apic_iter != NULL;
     
    757877                }
    758878            }
     879#else
     880            FOR_EACH_LAPIC(dev, apic_startup(dev, apic, vector_num));
    759881#endif /* !VBOX */
    760882            return;
    761     }
    762 
    763     switch (dest_shorthand) {
    764         case 0:
    765 #ifndef VBOX
    766             deliver_bitmask = apic_get_delivery_bitmask(dest, dest_mode);
    767 #else /* VBOX */
    768             deliver_bitmask = apic_get_delivery_bitmask(s, dest, dest_mode);
    769 #endif /* !VBOX */
    770             break;
    771         case 1:
    772             deliver_bitmask = (1 << s->id);
    773             break;
    774         case 2:
    775             deliver_bitmask = 0xffffffff;
    776             break;
    777         case 3:
    778             deliver_bitmask = 0xffffffff & ~(1 << s->id);
    779             break;
    780883    }
    781884
     
    801904    int intno;
    802905
    803     /* if the APIC is installed or enabled, we let the 8259 handle the
     906    /* if the APIC is not installed or enabled, we let the 8259 handle the
    804907       IRQs */
    805908    if (!s) {
     
    9651068        val = apic_get_ppr(s);
    9661069        break;
    967 #ifdef VBOX
    9681070    case 0x0b:
    9691071        Log(("apic_mem_readl %x %x -> write only returning 0\n", addr, index));
    9701072        val = 0;
    9711073        break;
    972 #endif
    973 
    9741074    case 0x0d:
    9751075        val = s->log_dest << 24;
     
    15671667#endif
    15681668
     1669    /** @todo: add LAPIC range validity checks (multiple LAPICs can theoretically have
     1670               different physical addresses, see #3092) */
     1671
    15691672    STAM_COUNTER_INC(&CTXSUFF(dev->StatMMIORead));
    15701673    switch (cb)
     
    16131716    APICDeviceInfo *dev = PDMINS_2_DATA(pDevIns, APICDeviceInfo *);
    16141717    APICState *s = getLAPIC(dev);
     1718
     1719    /** @todo: add LAPIC range validity checks (multiple LAPICs can theoretically have
     1720               different physical addresses, see #3092) */
    16151721
    16161722    STAM_COUNTER_INC(&CTXSUFF(dev->StatMMIOWrite));
     
    17741880    pThis->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
    17751881    pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
     1882    pThis->cCpus     = cCpus;
    17761883
    17771884    PVM pVM = PDMDevHlpGetVM(pDevIns);
    1778    
    17791885    /*
    17801886     * We are not freeing this memory, as it's automatically released when guest exits.
     
    17851891    pThis->pLapicsR0 = MMHyperR3ToR0(pVM, pThis->pLapicsR3);
    17861892    pThis->pLapicsRC = MMHyperR3ToRC(pVM, pThis->pLapicsR3);
    1787 
     1893   
    17881894    for (i = 0; i < cCpus; i++)
    17891895    {
注意: 瀏覽 TracChangeset 來幫助您使用更動檢視器

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