aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYang Zhong <yang.zhong@intel.com>2017-03-30 18:32:53 +0800
committerPaolo Bonzini <pbonzini@redhat.com>2017-03-30 10:47:29 +0200
commitac9488f26528394856b94bda0797f5bd9c69a26a (patch)
treeb014a3d8bb551b6c63f9e6954e76500fe1508448
parentea7d0e304775e81c07269e22b4412d328c3fb2fa (diff)
downloadqboot-ac9488f26528394856b94bda0797f5bd9c69a26a.zip
qboot-ac9488f26528394856b94bda0797f5bd9c69a26a.tar.gz
qboot-ac9488f26528394856b94bda0797f5bd9c69a26a.tar.bz2
qboot: enable mmconfig
Need to enable mmconfig in qboot and also need to reserve mmconfig space in bios. Signed-off-by: Yang Zhong <yang.zhong@intel.com> Message-Id: <1490869973-4562-1-git-send-email-yang.zhong@intel.com> [Do not affect e820 memory map on i440FX chipset. - Paolo] Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--hwsetup.c28
-rw-r--r--include/bios.h1
-rw-r--r--include/pci.h3
-rw-r--r--main.c17
4 files changed, 46 insertions, 3 deletions
diff --git a/hwsetup.c b/hwsetup.c
index 0e186eb..e8a452e 100644
--- a/hwsetup.c
+++ b/hwsetup.c
@@ -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
diff --git a/main.c b/main.c
index 1913b37..f092289 100644
--- a/main.c
+++ b/main.c
@@ -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();