VirtualBox

Changeset 26883 in vbox for trunk/src


Ignore:
Timestamp:
Feb 27, 2010 3:58:25 PM (15 years ago)
Author:
vboxsync
Message:

MADT, MPTABLES: implemented correct description of IRQ routing in dual PIC config we emulate - Snow Leo now works

Location:
trunk/src/VBox/Devices/PC
Files:
2 edited

Legend:

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

    r26861 r26883  
    476476AssertCompileSize(ACPITBLIOAPIC, 12);
    477477
     478/** Interrupt Source Override Structure */
     479struct ACPITBLISO
     480{
     481    uint8_t             u8Type;                 /**< 2 ==  Interrupt Source Override*/
     482    uint8_t             u8Length;               /**< 10 */
     483    uint8_t             u8Bus;                  /**< Bus */
     484    uint8_t             u8Source;               /**< Bus-relative interrupt source (IRQ) */
     485    uint32_t            u32GSI;                 /**< Global System Interrupt */
     486    uint16_t            u16Flags;               /**< MPS INTI flags Global */
     487};
     488AssertCompileSize(ACPITBLISO, 10);
     489#define NUMBER_OF_IRQ_SOURCE_OVERRIDES 1
    478490
    479491/** HPET Descriptor Structure */
     
    519531    uint32_t            m_cCpus;
    520532
     533    /**
     534     * Number of interrupt overrides.
     535     */
     536     uint32_t            m_cIsos;
     537
    521538public:
    522539    /**
     
    546563
    547564    /**
     565     * Address of ISO description
     566     */
     567    inline ACPITBLISO *ISO_addr(void) const
     568    {
     569        return (ACPITBLISO *)(u32Flags_addr() + 1);
     570    }
     571
     572    /**
    548573     * Address of per-CPU LAPIC descriptions
    549574     */
    550575    inline ACPITBLLAPIC *LApics_addr(void) const
    551576    {
    552         return (ACPITBLLAPIC *)(u32Flags_addr() + 1);
     577        return (ACPITBLLAPIC *)(ISO_addr() + m_cIsos);
    553578    }
    554579
     
    581606     * Size of MADT for given ACPI config, useful to compute layout.
    582607     */
    583     static uint32_t sizeFor(ACPIState *s)
    584     {
    585         return AcpiTableMADT(s->cCpus).size();
     608    static uint32_t sizeFor(ACPIState *s, uint32_t cIsos)
     609    {
     610        return AcpiTableMADT(s->cCpus, cIsos).size();
    586611    }
    587612
     
    589614     * Constructor, only works in Ring 3, doesn't look like a big deal.
    590615     */
    591     AcpiTableMADT(uint32_t cCpus)
     616    AcpiTableMADT(uint32_t cCpus, uint32_t cIsos)
    592617    {
    593618        m_cCpus  = cCpus;
     619        m_cIsos  = cIsos;
    594620        m_pbData = NULL;                /* size() uses this and gcc will complain if not initilized. */
    595621        uint32_t cb = size();
     
    875901{
    876902    uint16_t cpus = s->cCpus;
    877     AcpiTableMADT madt(cpus);
     903    AcpiTableMADT madt(cpus, 1 /* one source override */ );
    878904
    879905    acpiPrepareHeader(madt.header_addr(), "APIC", madt.size(), 2);
     
    882908    *madt.u32Flags_addr()          = RT_H2LE_U32(PCAT_COMPAT);
    883909
     910    /* LAPICs records */
    884911    ACPITBLLAPIC* lapic = madt.LApics_addr();
    885912    for (uint16_t i = 0; i < cpus; i++)
     
    888915        lapic->u8Length    = sizeof(ACPITBLLAPIC);
    889916        lapic->u8ProcId    = i;
     917        /** Must match numbering convention in MPTABLES */
    890918        lapic->u8ApicId    = i;
    891919        lapic->u32Flags    = VMCPUSET_IS_PRESENT(&s->CpuSetAttached, i) ? RT_H2LE_U32(LAPIC_ENABLED) : 0;
     
    893921    }
    894922
     923    /* IO-APIC record */
    895924    ACPITBLIOAPIC* ioapic = madt.IOApic_addr();
    896 
    897925    ioapic->u8Type     = 1;
    898926    ioapic->u8Length   = sizeof(ACPITBLIOAPIC);
    899     /** @todo is this the right id? */
     927    /** Must match MP tables ID */
    900928    ioapic->u8IOApicId = cpus;
    901929    ioapic->u8Reserved = 0;
    902930    ioapic->u32Address = RT_H2LE_U32(0xfec00000);
    903931    ioapic->u32GSIB    = RT_H2LE_U32(0);
     932
     933    /* Interrupt Source Overrides */
     934    ACPITBLISO* isos = madt.ISO_addr();
     935    isos[0].u8Type     = 2;
     936    isos[0].u8Length   = sizeof(ACPITBLISO);
     937    isos[0].u8Bus      = 0; /* Must be 0 */
     938    isos[0].u8Source   = 0; /* IRQ0 */
     939    isos[0].u32GSI     = 2; /* connected to pin 2 */
     940    isos[0].u16Flags   = 0; /* conform to the bus */
     941    Assert(NUMBER_OF_IRQ_SOURCE_OVERRIDES == 1);
    904942
    905943    madt.header_addr()->u8Checksum = acpiChecksum(madt.data(), madt.size());
     
    20442082    {
    20452083        GCPhysApic = GCPhysCur;
    2046         GCPhysCur = RT_ALIGN_32(GCPhysCur + AcpiTableMADT::sizeFor(s), 16);
     2084        GCPhysCur = RT_ALIGN_32(GCPhysCur + AcpiTableMADT::sizeFor(s, NUMBER_OF_IRQ_SOURCE_OVERRIDES), 16);
    20472085    }
    20482086    if (s->fUseHpet)
  • trunk/src/VBox/Devices/PC/DevFwCommon.cpp

    r26728 r26883  
    232232    uint32_t        u32AddrLocalApic;
    233233    uint16_t        u16ExtTableLength;
    234     uint8_t         u8ExtTableChecksxum;
     234    uint8_t         u8ExtTableChecksum;
    235235    uint8_t         u8Reserved;
    236236} *PMPSCFGTBLHEADER;
     
    733733    pCfgTab->u16EntryCount         =  cCpus /* Processors */
    734734                                   +  1 /* ISA Bus */
     735                                   +  1 /* PCI Bus */
    735736                                   +  1 /* I/O-APIC */
    736                                    + 16 /* Interrupts */;
     737                                   + 16 /* Interrupts */
     738                                   +  1 /* Local interrupts */;
    737739    pCfgTab->u32AddrLocalApic      = 0xfee00000;
    738740    pCfgTab->u16ExtTableLength     =  0;
    739     pCfgTab->u8ExtTableChecksxum   =  0;
     741    pCfgTab->u8ExtTableChecksum    =  0;
    740742    pCfgTab->u8Reserved            =  0;
    741743
     
    757759    {
    758760        pProcEntry->u8EntryType        = 0; /* processor entry */
    759         pProcEntry->u8LocalApicId      = i;
    760         pProcEntry->u8LocalApicVersion = 0x11;
     761        pProcEntry->u8LocalApicId      = i + 1;
     762        pProcEntry->u8LocalApicVersion = 0x14;
    761763        pProcEntry->u8CPUFlags         = (i == 0 ? 2 /* bootstrap processor */ : 0 /* application processor */) | 1 /* enabled */;
    762764        pProcEntry->u32CPUSignature    = u32CPUSignature;
     
    767769    }
    768770
     771    uint32_t iBusIdPci0 = 0;
     772    uint32_t iBusIdIsa  = 1;
     773
    769774    /* ISA bus */
    770775    PMPSBUSENTRY pBusEntry         = (PMPSBUSENTRY)pProcEntry;
    771776    pBusEntry->u8EntryType         = 1; /* bus entry */
    772     pBusEntry->u8BusId             = 0; /* this ID is referenced by the interrupt entries */
     777    pBusEntry->u8BusId             = iBusIdIsa; /* this ID is referenced by the interrupt entries */
    773778    memcpy(pBusEntry->au8BusTypeStr, "ISA   ", 6);
    774 
    775     /* PCI bus? */
     779    pBusEntry++;
     780
     781    /* PCI bus */
     782    pBusEntry->u8EntryType         = 1; /* bus entry */
     783    pBusEntry->u8BusId             = iBusIdPci0; /* this ID can be referenced by the interrupt entries */
     784    memcpy(pBusEntry->au8BusTypeStr, "PCI   ", 6);
     785
    776786
    777787    /* I/O-APIC.
     
    779789     *           ... At least one I/O APIC must be enabled." */
    780790    PMPSIOAPICENTRY pIOAPICEntry   = (PMPSIOAPICENTRY)(pBusEntry+1);
    781     uint16_t apicId = cCpus;
     791    uint16_t iApicId = 0;
    782792    pIOAPICEntry->u8EntryType      = 2; /* I/O-APIC entry */
    783     pIOAPICEntry->u8Id             = apicId; /* this ID is referenced by the interrupt entries */
     793    pIOAPICEntry->u8Id             = iApicId; /* this ID is referenced by the interrupt entries */
    784794    pIOAPICEntry->u8Version        = 0x11;
    785795    pIOAPICEntry->u8Flags          = 1 /* enable */;
    786796    pIOAPICEntry->u32Addr          = 0xfec00000;
    787797
     798    /* Interrupt tables */
     799    /* Bus vectors */
    788800    PMPSIOIRQENTRY pIrqEntry       = (PMPSIOIRQENTRY)(pIOAPICEntry+1);
    789     for (int i = 0; i < 16; i++, pIrqEntry++)
     801    for (int iPin = 0; iPin < 16; iPin++, pIrqEntry++)
    790802    {
    791803        pIrqEntry->u8EntryType     = 3; /* I/O interrupt entry */
    792         pIrqEntry->u8Type          = 0; /* INT, vectored interrupt */
    793         pIrqEntry->u16Flags        = 0; /* polarity of APIC I/O input signal = conforms to bus,
    794                                            trigger mode = conforms to bus */
    795         pIrqEntry->u8SrcBusId      = 0; /* ISA bus */
    796         pIrqEntry->u8SrcBusIrq     = i;
    797         pIrqEntry->u8DstIOAPICId   = apicId;
    798         pIrqEntry->u8DstIOAPICInt  = i;
    799     }
     804        /*
     805         * 0 - INT, vectored interrupt,
     806         * 3 - ExtINT, vectored interrupt provided by PIC
     807         * As we emulate system with both APIC and PIC, it's needed for their coexistence.
     808         */
     809        pIrqEntry->u8Type          = (iPin == 0) ? 3 : 0;
     810        pIrqEntry->u16Flags        = 0;              /* polarity of APIC I/O input signal = conforms to bus,
     811                                                        trigger mode = conforms to bus */
     812        pIrqEntry->u8SrcBusId      = iBusIdIsa;      /* ISA bus */
     813        /* IRQ0 mapped to pin 2, other are identity mapped */
     814        pIrqEntry->u8SrcBusIrq     = (iPin == 2) ? 0 : iPin; /* IRQ on the bus */
     815        pIrqEntry->u8DstIOAPICId   = iApicId;        /* destintion IO-APIC */
     816        pIrqEntry->u8DstIOAPICInt  = iPin;           /* pin on destination IO-APIC */
     817    }
     818    /* Local delivery */
     819    pIrqEntry->u8EntryType     = 4; /* Local interrupt entry */
     820    pIrqEntry->u8Type          = 3; /* ExtINT */
     821    pIrqEntry->u16Flags        = (1 << 2) | 1; /* active-high, edge-triggered */
     822    pIrqEntry->u8SrcBusId      = iBusIdIsa;
     823    pIrqEntry->u8SrcBusIrq     = 0;
     824    pIrqEntry->u8DstIOAPICId   = 0xff;
     825    pIrqEntry->u8DstIOAPICInt  = 0;
     826    pIrqEntry++;
    800827
    801828    pCfgTab->u16Length             = (uint8_t*)pIrqEntry - pTable;
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