diff options
-rw-r--r-- | hwsetup.c | 28 | ||||
-rw-r--r-- | include/bios.h | 1 | ||||
-rw-r--r-- | include/pci.h | 3 | ||||
-rw-r--r-- | main.c | 17 |
4 files changed, 46 insertions, 3 deletions
@@ -127,3 +127,31 @@ void setup_hw(void) setup_pic(); } + +#define Q35_HOST_BRIDGE_PCIEXBAREN 1 +#define Q35_HOST_BRIDGE_PCIEXBAR 0x60 + +static void setup_q35_mmconfig(void) +{ + const int bdf = 0; + uint64_t addr = PCIE_MMCONFIG_BASE; + uint32_t upper = addr >> 32; + uint32_t lower = (addr & 0xffffffff) | Q35_HOST_BRIDGE_PCIEXBAREN; + + pci_config_writel(bdf, Q35_HOST_BRIDGE_PCIEXBAR, 0); + pci_config_writel(bdf, Q35_HOST_BRIDGE_PCIEXBAR + 4, upper); + pci_config_writel(bdf, Q35_HOST_BRIDGE_PCIEXBAR, lower); +} + +bool setup_mmconfig(void) +{ + const int bdf = 0; + uint32_t id = pci_config_readl(bdf, 0); + + if (id == (PCI_VENDOR_ID_INTEL | (PCI_DEVICE_ID_INTEL_Q35_MCH << 16))) { + setup_q35_mmconfig(); + return true; + } + + return false; +} diff --git a/include/bios.h b/include/bios.h index bc96f87..df60c5a 100644 --- a/include/bios.h +++ b/include/bios.h @@ -40,6 +40,7 @@ extern void bios_int15(void); extern void setup_pci(void); extern void setup_hw(void); +extern bool setup_mmconfig(void); extern void extract_acpi(void); extern void boot_from_fwcfg(void); extern bool boot_from_cbfs(void *base, size_t sz); diff --git a/include/pci.h b/include/pci.h index bb37b86..7f40f38 100644 --- a/include/pci.h +++ b/include/pci.h @@ -72,4 +72,7 @@ static inline uint8_t pci_config_readb(uint16_t bdf, uint32_t addr) #define PCI_DEVICE_ID_INTEL_82371SB_1 0x7010 #define PCI_DEVICE_ID_INTEL_82371AB 0x7111 +#define PCIE_MMCONFIG_BASE 0xb0000000 +#define PCIE_MMCONFIG_SIZE (256 * 1024 * 1024) + #endif @@ -6,6 +6,7 @@ #include "segment.h" #include "fw_cfg.h" #include "pflash.h" +#include "pci.h" static void set_realmode_int(int vec, void *p) { @@ -30,6 +31,7 @@ static void setup_idt(void) /* Top of memory below 4GB. */ uint32_t lowmem; struct e820map *e820; +static bool have_mmconfig; static void extract_e820(void) { @@ -42,7 +44,7 @@ static void extract_e820(void) panic(); size = fw_cfg_file_size(id); - nr_map = size / sizeof(e820->map[0]) + 4; + nr_map = size / sizeof(e820->map[0]) + 5; e820 = malloc(offsetof(struct e820map, map[nr_map])); e820->nr_map = nr_map; @@ -54,8 +56,16 @@ static void extract_e820(void) { .addr = 0xd0000, .size = 128 * 1024, .type = E820_NVS }; /* ACPI tables */ e820->map[3] = (struct e820entry) { .addr = 0xf0000, .size = 64 * 1024, .type = E820_RESERVED }; /* firmware */ - fw_cfg_read_file(id, &e820->map[4], size); - for (i = 4; i < e820->nr_map; i++) + + i = 4; + if (have_mmconfig) + e820->map[i++] = (struct e820entry) + { .addr = PCIE_MMCONFIG_BASE, .size = PCIE_MMCONFIG_SIZE, .type = E820_RESERVED }; + else + nr_map--; + + fw_cfg_read_file(id, &e820->map[i], size); + for (; i < e820->nr_map; i++) if (e820->map[i].addr == 0) { lowmem = e820->map[i].size; e820->map[i].addr = 1024 * 1024; @@ -85,6 +95,7 @@ int __attribute__ ((section (".text.startup"))) main(void) // in order to probe CBFS! asm("ljmp $0x8, $1f; 1:"); + have_mmconfig = setup_mmconfig(); setup_pci(); setup_idt(); fw_cfg_setup(); |