Hi,
These patches are mostly cherry-picked from Jason's q35 patch series. It carries some bugfixes and preparations for the q35 chipset support, but not yet the q35 code itself. Should be ready for merge.
cheers, Gerd
Gerd Hoffmann (1): piix: fix mtrr setup
Isaku Yamahata (2): seabios: acpi, fadt: make while fadt initialization chipset specific seabios: pci: enable SERR of normal device.
Jason Baron (1): seabios: make mttr UC area setup dynamic
src/acpi.c | 34 ++++++++++++++++++---------------- src/config.h | 1 - src/mtrr.c | 5 +++-- src/pci.h | 1 + src/pciinit.c | 24 +++++++++++++++++++++++- src/post.c | 6 +++--- 6 files changed, 48 insertions(+), 23 deletions(-)
From: Jason Baron jbaron@redhat.com
Set up the UC area of mtrr dynamically based on mtrr_base. This allows the bios to work for other chipsets that might want to set the mtrr. Since BUILD_MAX_HIGHMEM is no longer used we can remove the config parameter.
This change reverses the order of pci_setup() and smm_init() with mtrr_setup().
Signed-off-by: Jason Baron jbaron@redhat.com --- src/config.h | 1 - src/mtrr.c | 5 +++-- src/pci.h | 1 + src/pciinit.c | 2 ++ src/post.c | 6 +++--- 5 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/src/config.h b/src/config.h index 0d4066d..71c0b7e 100644 --- a/src/config.h +++ b/src/config.h @@ -44,7 +44,6 @@ #define BUILD_SMM_INIT_ADDR 0x38000 #define BUILD_SMM_ADDR 0xa8000 #define BUILD_SMM_SIZE 0x8000 -#define BUILD_MAX_HIGHMEM 0xe0000000
#define BUILD_PCIMEM_START 0xe0000000 #define BUILD_PCIMEM_END 0xfec00000 /* IOAPIC is mapped at */ diff --git a/src/mtrr.c b/src/mtrr.c index 0957834..81a78c6 100644 --- a/src/mtrr.c +++ b/src/mtrr.c @@ -7,6 +7,7 @@ #include "util.h" // dprintf #include "config.h" // CONFIG_* #include "xen.h" // usingXen +#include "pci.h" // mtrr_base
#define MSR_MTRRcap 0x000000fe #define MSR_MTRRfix64K_00000 0x00000250 @@ -94,9 +95,9 @@ void mtrr_setup(void) wrmsr_smp(MTRRphysMask_MSR(i), 0); } /* Mark 3.5-4GB as UC, anything not specified defaults to WB */ - wrmsr_smp(MTRRphysBase_MSR(0), BUILD_MAX_HIGHMEM | MTRR_MEMTYPE_UC); + wrmsr_smp(MTRRphysBase_MSR(0), mtrr_base | MTRR_MEMTYPE_UC); wrmsr_smp(MTRRphysMask_MSR(0) - , (-((1ull<<32)-BUILD_MAX_HIGHMEM) & phys_mask) | 0x800); + , (-((1ull<<32)-mtrr_base) & phys_mask) | 0x800);
// Enable fixed and variable MTRRs; set default type. wrmsr_smp(MSR_MTRRdefType, 0xc00 | MTRR_MEMTYPE_WB); diff --git a/src/pci.h b/src/pci.h index fe663b8..104638d 100644 --- a/src/pci.h +++ b/src/pci.h @@ -56,6 +56,7 @@ struct pci_device { // Local information on device. int have_driver; }; +extern u64 mtrr_base; extern u64 pcimem_start, pcimem_end; extern u64 pcimem64_start, pcimem64_end; extern struct pci_device *PCIDevices; diff --git a/src/pciinit.c b/src/pciinit.c index 31115ee..0b4a9e4 100644 --- a/src/pciinit.c +++ b/src/pciinit.c @@ -30,6 +30,8 @@ static const char *region_type_name[] = { [ PCI_REGION_TYPE_PREFMEM ] = "prefmem", };
+u64 mtrr_base = BUILD_PCIMEM_START; + u64 pcimem_start = BUILD_PCIMEM_START; u64 pcimem_end = BUILD_PCIMEM_END; u64 pcimem64_start = BUILD_PCIMEM64_START; diff --git a/src/post.c b/src/post.c index 0133f75..ffb4717 100644 --- a/src/post.c +++ b/src/post.c @@ -232,13 +232,13 @@ maininit(void) timer_setup(); mathcp_setup();
- // Initialize mtrr - mtrr_setup(); - // Initialize pci pci_setup(); smm_init();
+ // Initialize mtrr + mtrr_setup(); + // Setup Xen hypercalls xen_init_hypercalls();
Add a piix4 memory setup function to make the control flow more clear.
Set the new mtrr_base variable to the start of the 32bit pci window to make sure the mtrr entry added covers the I/O window.
Make the 32bit pci window start at 0x80000000, 0xc0000000 or 0xe000000 (depending on the memory installed) so we can cover the whole window with a single mtrr entry.
Signed-off-by: Gerd Hoffmann kraxel@redhat.com --- src/pciinit.c | 19 +++++++++++++++++++ 1 files changed, 19 insertions(+), 0 deletions(-)
diff --git a/src/pciinit.c b/src/pciinit.c index 0b4a9e4..137c667 100644 --- a/src/pciinit.c +++ b/src/pciinit.c @@ -597,10 +597,29 @@ static void pci_region_map_entries(struct pci_bus *busses, struct pci_region *r) } }
+void i440fx_mem_addr_init(struct pci_device *dev, void *arg) +{ + if (RamSize <= 0x80000000) + pcimem_start = 0x80000000; + else if (RamSize <= 0xc0000000) + pcimem_start = 0xc0000000; + + mtrr_base = pcimem_start; +} + +static const struct pci_device_id pci_mem_addr_tbl[] = { + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, + i440fx_mem_addr_init), + PCI_DEVICE_END, +}; + static void pci_bios_map_devices(struct pci_bus *busses) { pcimem_start = RamSize;
+ /* chipset specific memory setup */ + pci_find_init_device(pci_mem_addr_tbl, NULL); + if (pci_bios_init_root_regions(busses)) { struct pci_region r64_mem, r64_pref; r64_mem.list = NULL;
On Tue, Nov 20, 2012 at 05:45:30PM +0100, Gerd Hoffmann wrote:
Add a piix4 memory setup function to make the control flow more clear.
[...]
static void pci_bios_map_devices(struct pci_bus *busses) { pcimem_start = RamSize;
- /* chipset specific memory setup */
- pci_find_init_device(pci_mem_addr_tbl, NULL);
I find setting the pcimem_start in the middle of the resource assignment to be a little confusing. How about just setting it up prior to the scan - something like the below?
-Kevin
diff --git a/src/pciinit.c b/src/pciinit.c index d61f0a8..a2ee86c 100644 --- a/src/pciinit.c +++ b/src/pciinit.c @@ -226,6 +226,35 @@ static void pci_bios_init_devices(void)
/**************************************************************** + * Platform device initialization + ****************************************************************/ + +void i440fx_mem_addr_init(struct pci_device *dev, void *arg) +{ + if (RamSize <= 0x80000000) + pcimem_start = 0x80000000; + else if (RamSize <= 0xc0000000) + pcimem_start = 0xc0000000; + + mtrr_base = pcimem_start; +} + +static const struct pci_device_id pci_platform_tbl[] = { + PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, + i440fx_mem_addr_init), + PCI_DEVICE_END +}; + +static void pci_bios_init_platform(void) +{ + struct pci_device *pci; + foreachpci(pci) { + pci_init_device(pci_platform_tbl, pci, NULL); + } +} + + +/**************************************************************** * Bus initialization ****************************************************************/
@@ -583,8 +612,6 @@ static void pci_region_map_entries(struct pci_bus *busses, struct pci_region *r)
static void pci_bios_map_devices(struct pci_bus *busses) { - pcimem_start = RamSize; - if (pci_bios_init_root_regions(busses)) { struct pci_region r64_mem, r64_pref; r64_mem.list = NULL; @@ -647,6 +674,9 @@ pci_setup(void) dprintf(1, "=== PCI device probing ===\n"); pci_probe_devices();
+ pcimem_start = RamSize; + pci_bios_init_platform(); + dprintf(1, "=== PCI new allocation pass #1 ===\n"); struct pci_bus *busses = malloc_tmp(sizeof(*busses) * (MaxPCIBus + 1)); if (!busses) {
On 11/21/12 02:53, Kevin O'Connor wrote:
I find setting the pcimem_start in the middle of the resource assignment to be a little confusing. How about just setting it up prior to the scan - something like the below?
Looks good to me.
cheers, Gerd
From: Isaku Yamahata yamahata@valinux.co.jp
make while fadt initialization chipset specific.
Reviewed-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Isaku Yamahata yamahata@valinux.co.jp Signed-off-by: Jason Baron jbaron@redhat.com --- src/acpi.c | 34 ++++++++++++++++++---------------- 1 files changed, 18 insertions(+), 16 deletions(-)
diff --git a/src/acpi.c b/src/acpi.c index 6d239fa..1fc170f 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -233,13 +233,31 @@ build_header(struct acpi_table_header *h, u32 sig, int len, u8 rev) #define PIIX4_GPE0_BLK 0xafe0 #define PIIX4_GPE0_BLK_LEN 4
+#define PIIX4_PM_INTRRUPT 9 // irq 9 + static void piix4_fadt_init(struct pci_device *pci, void *arg) { struct fadt_descriptor_rev1 *fadt = arg; + + fadt->model = 1; + fadt->reserved1 = 0; + fadt->sci_int = cpu_to_le16(PIIX4_PM_INTRRUPT); + fadt->smi_cmd = cpu_to_le32(PORT_SMI_CMD); fadt->acpi_enable = PIIX4_ACPI_ENABLE; fadt->acpi_disable = PIIX4_ACPI_DISABLE; + fadt->pm1a_evt_blk = cpu_to_le32(PORT_ACPI_PM_BASE); + fadt->pm1a_cnt_blk = cpu_to_le32(PORT_ACPI_PM_BASE + 0x04); + fadt->pm_tmr_blk = cpu_to_le32(PORT_ACPI_PM_BASE + 0x08); fadt->gpe0_blk = cpu_to_le32(PIIX4_GPE0_BLK); + fadt->pm1_evt_len = 4; + fadt->pm1_cnt_len = 2; + fadt->pm_tmr_len = 4; fadt->gpe0_blk_len = PIIX4_GPE0_BLK_LEN; + fadt->plvl2_lat = cpu_to_le16(0xfff); // C2 state not supported + fadt->plvl3_lat = cpu_to_le16(0xfff); // C3 state not supported + /* WBINVD + PROC_C1 + SLP_BUTTON + RTC_S4 + USE_PLATFORM_CLOCK */ + fadt->flags = cpu_to_le32((1 << 0) | (1 << 2) | (1 << 5) | (1 << 7) | + (1 << 15)); }
static const struct pci_device_id fadt_init_tbl[] = { @@ -281,23 +299,7 @@ build_fadt(struct pci_device *pci) fadt->firmware_ctrl = cpu_to_le32((u32)facs); fadt->dsdt = 0; /* dsdt will be filled later in acpi_bios_init() by fill_dsdt() */ - fadt->model = 1; - fadt->reserved1 = 0; - int pm_sci_int = pci_config_readb(pci->bdf, PCI_INTERRUPT_LINE); - fadt->sci_int = cpu_to_le16(pm_sci_int); - fadt->smi_cmd = cpu_to_le32(PORT_SMI_CMD); - fadt->pm1a_evt_blk = cpu_to_le32(PORT_ACPI_PM_BASE); - fadt->pm1a_cnt_blk = cpu_to_le32(PORT_ACPI_PM_BASE + 0x04); - fadt->pm_tmr_blk = cpu_to_le32(PORT_ACPI_PM_BASE + 0x08); - fadt->pm1_evt_len = 4; - fadt->pm1_cnt_len = 2; - fadt->pm_tmr_len = 4; - fadt->plvl2_lat = cpu_to_le16(0xfff); // C2 state not supported - fadt->plvl3_lat = cpu_to_le16(0xfff); // C3 state not supported pci_init_device(fadt_init_tbl, pci, fadt); - /* WBINVD + PROC_C1 + SLP_BUTTON + RTC_S4 + USE_PLATFORM_CLOCK */ - fadt->flags = cpu_to_le32((1 << 0) | (1 << 2) | (1 << 5) | (1 << 7) | - (1 << 15));
build_header((void*)fadt, FACP_SIGNATURE, sizeof(*fadt), 1);
From: Isaku Yamahata yamahata@valinux.co.jp
enable SERR of normal device for AER.
Reviewed-by: Paolo Bonzini pbonzini@redhat.com Signed-off-by: Isaku Yamahata yamahata@valinux.co.jp Signed-off-by: Jason Baron jbaron@redhat.com --- src/pciinit.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/src/pciinit.c b/src/pciinit.c index 137c667..6176e40 100644 --- a/src/pciinit.c +++ b/src/pciinit.c @@ -218,7 +218,8 @@ static void pci_bios_init_device(struct pci_device *pci) pci_init_device(pci_class_tbl, pci, NULL);
/* enable memory mappings */ - pci_config_maskw(bdf, PCI_COMMAND, 0, PCI_COMMAND_IO | PCI_COMMAND_MEMORY); + pci_config_maskw(bdf, PCI_COMMAND, 0, + PCI_COMMAND_IO | PCI_COMMAND_MEMORY | PCI_COMMAND_SERR);
/* map the interrupt */ int pin = pci_config_readb(bdf, PCI_INTERRUPT_PIN);