[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 10/14] pcibos: add mcfg entry to ACPI table for q35
From: |
Isaku Yamahata |
Subject: |
[Qemu-devel] [PATCH 10/14] pcibos: add mcfg entry to ACPI table for q35 pcie. |
Date: |
Wed, 30 Sep 2009 19:18:45 +0900 |
add mcfg entry to ACPI table for q35 pcie.
Signed-off-by: Isaku Yamahata <address@hidden>
---
rombios32.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 81 insertions(+), 7 deletions(-)
diff --git a/rombios32.c b/rombios32.c
index f7e906f..3259433 100644
--- a/rombios32.c
+++ b/rombios32.c
@@ -715,6 +715,13 @@ void smp_probe(void)
#define Q35_HOST_BRIDGE_PAM0 0x90
#define Q35_HOST_BRDIGE_SMRAM 0x9d
+#define Q35_HOST_BRIDGE_PCIEXBAR 0x60
+#define Q35_HOST_BRIDGE_PCIEXBAR_ADDR 0xe0000000
+#define Q35_HOST_BRIDGE_PCIEXBAREN ((uint64_t)1)
+#define Q35_HOST_PCIE_PCI_SEGMENT 0
+#define Q35_HOST_PCIE_START_BUS_NUMBER 0
+#define Q35_HOST_PCIE_END_BUS_NUMBER 255
+
#define PCI_DEVICE_ID_INTEL_ICH9_LPC 0x2918
#define ICH9_LPC_PMBASE 0x40
#define ICH9_PMBASE_SMI_EN 0x30
@@ -890,6 +897,18 @@ static void mch_bios_lock_shadow_ram(PCIDevice *d)
bios_lock_shadow_ram_common(d, Q35_HOST_BRIDGE_PAM0);
}
+static void mch_pcie_init(PCIDevice *d)
+{
+ uint64_t val = Q35_HOST_BRIDGE_PCIEXBAR_ADDR | Q35_HOST_BRIDGE_PCIEXBAREN;
+ uint32_t upper = val >> 32;
+ uint32_t lower = val & 0xffffffff;
+
+ /* at first disable the region. and then update/enable it. */
+ pci_config_writel(d, Q35_HOST_BRIDGE_PCIEXBAR, 0);
+ pci_config_writel(d, Q35_HOST_BRIDGE_PCIEXBAR + 4, upper);
+ pci_config_writel(d, Q35_HOST_BRIDGE_PCIEXBAR, lower);
+}
+
static void bios_lock_shadow_ram(void)
{
if (i440_found)
@@ -942,6 +961,7 @@ static void pci_bios_init_bridges(PCIDevice *d)
device_id == PCI_DEVICE_ID_INTEL_Q35_MCH) {
/* ich9 PCI host bridge */
mch_bios_shadow_init(d);
+ mch_pcie_init(d);
}
}
@@ -1481,7 +1501,7 @@ struct rsdt_descriptor_rev1
{
ACPI_TABLE_HEADER_DEF /* ACPI common table
header */
#ifdef BX_QEMU
- uint32_t table_offset_entry [5]; /* Array
of pointers to other */
+ uint32_t table_offset_entry [6]; /* Array
of pointers to other */
#else
uint32_t table_offset_entry [3]; /* Array
of pointers to other */
#endif
@@ -1708,6 +1728,22 @@ struct madt_int_override
} __attribute__((__packed__));
#endif
+/* PCI fw r3.0 MCFG table. stolen from linux header file */
+struct acpi_table_mcfg {
+ ACPI_TABLE_HEADER_DEF;
+ uint8_t reserved[8];
+} __attribute__((__packed__));
+
+/* Subtable */
+struct acpi_mcfg_allocation {
+ uint64_t address; /* Base address,
processor-relative */
+ uint16_t pci_segment; /* PCI segment group number */
+ uint8_t start_bus_number; /* Starting PCI Bus
number */
+ uint8_t end_bus_number; /* Final PCI Bus number
*/
+ uint32_t reserved;
+} __attribute__((__packed__));
+
+
#include "acpi-dsdt.hex"
static inline uint16_t cpu_to_le16(uint16_t x)
@@ -1832,12 +1868,17 @@ void acpi_bios_init(void)
struct system_resource_affinity_table *srat;
struct acpi_20_hpet *hpet;
uint32_t hpet_addr;
+ uint32_t mcfg_addr = 0;
+ uint32_t mcfg_size;
+ struct acpi_table_mcfg *mcfg = NULL;
+ struct acpi_mcfg_allocation *mcfg_alloc = NULL;
#endif
uint32_t base_addr, rsdt_addr, fadt_addr, addr, facs_addr, dsdt_addr,
ssdt_addr;
uint32_t acpi_tables_size, madt_addr, madt_size, rsdt_size;
uint32_t srat_addr,srat_size;
uint16_t i, external_tables;
int nb_numa_nodes;
+ int nb_entry;
/* reserve memory space for tables */
#ifdef BX_USE_EBDA_TABLES
@@ -1916,6 +1957,16 @@ void acpi_bios_init(void)
hpet_addr = addr;
hpet = (void *)(addr);
addr += sizeof(*hpet);
+
+ mcfg_size = 0;
+ if (mch_found) {
+ addr = (addr + 7) & ~7;
+ mcfg_addr = addr;
+ mcfg = (void*)addr;
+ mcfg_alloc = (void*)(addr + sizeof(*mcfg));
+ mcfg_size = sizeof(*mcfg) + sizeof(*mcfg_alloc);
+ addr += mcfg_size;
+ }
#endif
/* RSDP */
@@ -2117,19 +2168,42 @@ void acpi_bios_init(void)
if(addr >= ram_size)
BX_PANIC("ACPI table overflow\n");
}
+
+ /* MCFG */
+ if (mch_found) {
+ memset(mcfg, 0, mcfg_size);
+ mcfg_alloc->address = Q35_HOST_BRIDGE_PCIEXBAR_ADDR;
+ mcfg_alloc->pci_segment = Q35_HOST_PCIE_PCI_SEGMENT;
+ mcfg_alloc->start_bus_number = Q35_HOST_PCIE_START_BUS_NUMBER;
+ mcfg_alloc->end_bus_number = Q35_HOST_PCIE_END_BUS_NUMBER;
+
+ acpi_build_table_header((struct acpi_table_header *)mcfg,
+ "MCFG", mcfg_size, 1);
+ }
#endif
/* RSDT */
- rsdt->table_offset_entry[0] = cpu_to_le32(fadt_addr);
- rsdt->table_offset_entry[1] = cpu_to_le32(madt_addr);
- rsdt->table_offset_entry[2] = cpu_to_le32(ssdt_addr);
+ nb_entry = 0;
+ rsdt->table_offset_entry[nb_entry++] = cpu_to_le32(fadt_addr);
+ rsdt->table_offset_entry[nb_entry++] = cpu_to_le32(madt_addr);
+ rsdt->table_offset_entry[nb_entry++] = cpu_to_le32(ssdt_addr);
#ifdef BX_QEMU
- rsdt->table_offset_entry[3] = cpu_to_le32(hpet_addr);
+ rsdt->table_offset_entry[nb_entry++] = cpu_to_le32(hpet_addr);
if (nb_numa_nodes > 0)
- rsdt->table_offset_entry[4] = cpu_to_le32(srat_addr);
+ rsdt->table_offset_entry[nb_entry++] = cpu_to_le32(srat_addr);
+ if (mcfg_size > 0)
+ rsdt->table_offset_entry[nb_entry++] = cpu_to_le32(mcfg_addr);
#endif
+ if (sizeof(rsdt->table_offset_entry) /
+ sizeof(rsdt->table_offset_entry[0]) >= nb_entry)
+ BX_INFO("rdst table_offset_entry size is too short %d."
+ "increase it to %d.\n",
+ sizeof(rsdt->table_offset_entry) /
+ sizeof(rsdt->table_offset_entry[0]),
+ nb_entry);
acpi_build_table_header((struct acpi_table_header *)rsdt, "RSDT",
- rsdt_size - (nb_numa_nodes > 0? 0: sizeof(uint32_t)), 1);
+ offsetof(struct rsdt_descriptor_rev1, table_offset_entry) +
+ nb_entry * sizeof(uint32_t), 1);
acpi_tables_size = addr - base_addr;
--
1.6.0.2
- [Qemu-devel] [PATCH 09/14] pcbios: comment out PCI_FIXED_HOST_BRIDGE for gmch host pci bridge to undef., (continued)
- [Qemu-devel] [PATCH 09/14] pcbios: comment out PCI_FIXED_HOST_BRIDGE for gmch host pci bridge to undef., Isaku Yamahata, 2009/09/30
- [Qemu-devel] [PATCH 06/14] pcbios: rombios32: make pci space assigner preferchable memory aware., Isaku Yamahata, 2009/09/30
- [Qemu-devel] [PATCH 02/14] pcbios: fix makesym.perl, Isaku Yamahata, 2009/09/30
- [Qemu-devel] [PATCH 14/14] pcibos/acpi dsdt: APIC mode support for q35 chipset, Isaku Yamahata, 2009/09/30
- [Qemu-devel] [PATCH 08/14] pcibos: initialize q35 chipset., Isaku Yamahata, 2009/09/30
- [Qemu-devel] [PATCH 01/14] pcbios: add generated files to dot gitignore., Isaku Yamahata, 2009/09/30
- [Qemu-devel] [PATCH 03/14] pcbios: remove iasl output file when error., Isaku Yamahata, 2009/09/30
- [Qemu-devel] [PATCH 05/14] pcbios: rombios32: make pci memory space assignment 64bit aware., Isaku Yamahata, 2009/09/30
- [Qemu-devel] [PATCH 12/14] pcbios: make pci bar initialization to be aware of preferchable memory., Isaku Yamahata, 2009/09/30
- [Qemu-devel] [PATCH 07/14] pcbios: enable debug output for debug., Isaku Yamahata, 2009/09/30
- [Qemu-devel] [PATCH 10/14] pcibos: add mcfg entry to ACPI table for q35 pcie.,
Isaku Yamahata <=
- [Qemu-devel] [PATCH 04/14] pcbios: make set_e820_range() full 64bit aware., Isaku Yamahata, 2009/09/30
- [Qemu-devel] [PATCH 11/14] pcbios: reserve mcfg area by e820 for linux to use mcfg., Isaku Yamahata, 2009/09/30
- [Qemu-devel] Re: [PATCH 00/14] pcbios: support q35 chipset, Anthony Liguori, 2009/09/30