VirtualBox

Changeset 32591 in vbox


Ignore:
Timestamp:
Sep 17, 2010 11:32:31 AM (14 years ago)
Author:
vboxsync
Message:

ACPI: support for MCFG table

File:
1 edited

Legend:

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

    r32477 r32591  
    165165    SYSTEM_INFO_INDEX_IOC_ADDRESS       = 18, /**< IO controller PCI address */
    166166    SYSTEM_INFO_INDEX_HBC_ADDRESS       = 19, /**< host bus controller PCI address */
    167     SYSTEM_INFO_INDEX_END               = 20, 
     167    SYSTEM_INFO_INDEX_END               = 20,
    168168    SYSTEM_INFO_INDEX_INVALID           = 0x80,
    169169    SYSTEM_INFO_INDEX_VALID             = 0x200
     
    258258    /** Flag whether CPU hot plugging is enabled. */
    259259    bool                fCpuHotPlug;
     260    /** If MCFG ACPI table shown to the guest */
     261    bool                fUseMcfg;
    260262    /** Primary NIC PCI address. */
    261263    uint32_t            u32NicPciAddress;
     
    274276    /** PCI address of the host bus controller device. */
    275277    uint32_t            u32HbcPciAddress;
     278    /* Physical address of PCI config space MMIO region */
     279    uint64_t            u64PciConfigMMioAddress;
    276280
    277281    /** ACPI port base interface. */
     
    525529AssertCompileSize(ACPITBLHPET, 56);
    526530
     531/** MCFG Descriptor Structure */
     532struct ACPITBLMCFG
     533{
     534    ACPITBLHEADER aHeader;
     535    uint64_t      u64Reserved;
     536};
     537AssertCompileSize(ACPITBLMCFG, 44);
     538
     539/* Number of such entries can be computed from the whole table length in header */
     540struct ACPITBLMCFGENTRY
     541{
     542    uint64_t      u64BaseAddress;
     543    uint16_t      u16PciSegmentGroup;
     544    uint8_t       u8StartBus;
     545    uint8_t       u8EndBus;
     546    uint32_t      u32Reserved;
     547};
     548AssertCompileSize(ACPITBLMCFGENTRY, 16);
     549
    527550# ifdef IN_RING3 /** @todo r=bird: Move this down to where it's used. */
    528551
     
    9901013}
    9911014
     1015/** MMCONFIG PCI config space access (MCFG) descriptor */
     1016static void acpiSetupMCFG(ACPIState *s, RTGCPHYS32 addr,
     1017                          RTGCPHYS64 u64PciConfigBase,
     1018                          uint8_t    u8StartBus,
     1019                          uint8_t    u8EndBus)
     1020{
     1021    struct {
     1022        ACPITBLMCFG       hdr;
     1023        ACPITBLMCFGENTRY  entry;
     1024    } tbl;
     1025
     1026    memset(&tbl, 0, sizeof(tbl));
     1027
     1028    acpiPrepareHeader(&tbl.hdr.aHeader, "MCFG", sizeof(tbl), 1);
     1029    tbl.entry.u64BaseAddress = u64PciConfigBase;
     1030    tbl.entry.u8StartBus = u8StartBus;
     1031    tbl.entry.u8EndBus = u8EndBus;
     1032    // u16PciSegmentGroup must match _SEG in ACPI table
     1033
     1034    tbl.hdr.aHeader.u8Checksum = acpiChecksum((uint8_t *)&tbl, sizeof(tbl));
     1035
     1036    acpiPhyscpy(s, addr, (const uint8_t *)&tbl, sizeof(tbl));
     1037}
     1038
    9921039/* SCI IRQ */
    9931040DECLINLINE(void) acpiSetIrq(ACPIState *s, int level)
     
    21222169    int        rc;
    21232170    RTGCPHYS32 GCPhysCur, GCPhysRsdt, GCPhysXsdt, GCPhysFadtAcpi1, GCPhysFadtAcpi2, GCPhysFacs, GCPhysDsdt;
    2124     RTGCPHYS32 GCPhysHpet = 0, GCPhysApic = 0, GCPhysSsdt = 0;
     2171    RTGCPHYS32 GCPhysHpet = 0, GCPhysApic = 0, GCPhysSsdt = 0, GCPhysMcfg = 0;
    21252172    uint32_t   addend = 0;
    21262173    RTGCPHYS32 aGCPhysRsdt[4];
    21272174    RTGCPHYS32 aGCPhysXsdt[4];
    2128     uint32_t   cAddr, iMadt = 0, iHpet = 0, iSsdt = 0;
     2175    uint32_t   cAddr, iMadt = 0, iHpet = 0, iSsdt = 0, iMcfg = 0;
    21292176    size_t     cbRsdt = sizeof(ACPITBLHEADER);
    21302177    size_t     cbXsdt = sizeof(ACPITBLHEADER);
     
    21362183    if (s->fUseHpet)
    21372184        iHpet = cAddr++;        /* HPET */
     2185
     2186    if (s->fUseMcfg)
     2187        iMcfg = cAddr++;        /* MCFG */
    21382188
    21392189    iSsdt = cAddr++;            /* SSDT */
     
    21922242        GCPhysHpet = GCPhysCur;
    21932243        GCPhysCur = RT_ALIGN_32(GCPhysCur + sizeof(ACPITBLHPET), 16);
     2244    }
     2245    if (s->fUseMcfg)
     2246    {
     2247        GCPhysMcfg = GCPhysCur;
     2248        /* Assume one entry */
     2249        GCPhysCur = RT_ALIGN_32(GCPhysCur + sizeof(ACPITBLMCFG) + sizeof(ACPITBLMCFGENTRY), 16);
    21942250    }
    21952251
     
    22262282    if (s->fUseHpet)
    22272283        Log((" HPET 0x%08X", GCPhysHpet + addend));
     2284    if (s->fUseMcfg)
     2285        Log((" MCFG 0x%08X", GCPhysMcfg + addend));
    22282286    Log((" SSDT 0x%08X", GCPhysSsdt + addend));
    22292287    Log(("\n"));
     
    22492307        aGCPhysXsdt[iHpet] = GCPhysHpet + addend;
    22502308    }
     2309    if (s->fUseMcfg)
     2310    {
     2311        acpiSetupMCFG(s, GCPhysMcfg + addend, s->u64PciConfigMMioAddress, 0, 1);
     2312        aGCPhysRsdt[iMcfg] = GCPhysMcfg + addend;
     2313        aGCPhysXsdt[iMcfg] = GCPhysMcfg + addend;
     2314    }
     2315
    22512316    acpiSetupSSDT(s, GCPhysSsdt + addend, pSsdtCode, cbSsdtSize);
    22522317    acpiCleanupSsdt(s->pDevIns, pSsdtCode);
     
    24642529                              "R0Enabled\0"
    24652530                              "HpetEnabled\0"
     2531                              "McfgEnabled\0"
    24662532                              "SmcEnabled\0"
    24672533                              "FdcEnabled\0"
     
    25052571        return PDMDEV_SET_ERROR(pDevIns, rc,
    25062572                                N_("Configuration error: Failed to read \"HpetEnabled\""));
     2573    /* query whether we are supposed to present HPET */
     2574    rc = CFGMR3QueryU64Def(pCfg, "McfgBase", &s->u64PciConfigMMioAddress, 0);
     2575    if (RT_FAILURE(rc))
     2576        return PDMDEV_SET_ERROR(pDevIns, rc,
     2577                                N_("Configuration error: Failed to read \"McfgBase\""));
     2578    s->fUseMcfg = (s->u64PciConfigMMioAddress != 0);
     2579
    25072580    /* query whether we are supposed to present SMC */
    25082581    rc = CFGMR3QueryBoolDef(pCfg, "SmcEnabled", &s->fUseSmc, false);
     
    27002773
    27012774    /* See p. 50 of PIIX4 manual */
    2702     dev->config[0x04] = 0x01; /* command */
    2703     dev->config[0x05] = 0x00;
    2704 
    2705     dev->config[0x06] = 0x80; /* status */
    2706     dev->config[0x07] = 0x02;
    2707 
    2708     dev->config[0x08] = 0x08; /* revision number */
    2709 
    2710     dev->config[0x09] = 0x00; /* class code */
    2711     dev->config[0x0a] = 0x80;
    2712     dev->config[0x0b] = 0x06;
    2713 
    2714     dev->config[0x0e] = 0x80; /* header type */
    2715 
    2716     dev->config[0x0f] = 0x00; /* reserved */
    2717 
    2718     dev->config[0x3c] = SCI_INT; /* interrupt line */
     2775    PCIDevSetCommand(dev, 0x01);
     2776    PCIDevSetStatus(dev, 0x0280);
     2777
     2778    PCIDevSetRevisionId(dev, 0x08);
     2779
     2780    PCIDevSetClassProg(dev, 0x00);
     2781    PCIDevSetClassSub(dev, 0x80);
     2782    PCIDevSetClassBase(dev, 0x06);
     2783
     2784    PCIDevSetHeaderType(dev, 0x80);
     2785
     2786    PCIDevSetBIST(dev, 0x00);
     2787
     2788    PCIDevSetInterruptLine(dev, SCI_INT);
    27192789
    27202790#if 0
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