mb/emulation/qemu-q35: Define and use MMCONF_BUS_NUMBER

Also refactor the machine type checks to avoid code duplication.

Tested, still boots to payload with 256, 128 and 64 busses.

Change-Id: Ib394ba605bbfeee75aa645e989c23034cceff348
Signed-off-by: Angel Pons <th3fanbus@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/50025
Reviewed-by: Nico Huber <nico.h@gmx.de>
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
diff --git a/src/mainboard/emulation/qemu-q35/Kconfig b/src/mainboard/emulation/qemu-q35/Kconfig
index 9958caf..4bbfd57 100644
--- a/src/mainboard/emulation/qemu-q35/Kconfig
+++ b/src/mainboard/emulation/qemu-q35/Kconfig
@@ -63,6 +63,10 @@
 config MMCONF_BASE_ADDRESS
 	default 0xb0000000
 
+config MMCONF_BUS_NUMBER
+	int
+	default 256
+
 # fw_cfg tables can be larger than the default when TPM is enabled
 config MAX_ACPI_TABLE_SIZE_KB
 	int
diff --git a/src/mainboard/emulation/qemu-q35/Makefile.inc b/src/mainboard/emulation/qemu-q35/Makefile.inc
index 4bd91f0..99980e3 100644
--- a/src/mainboard/emulation/qemu-q35/Makefile.inc
+++ b/src/mainboard/emulation/qemu-q35/Makefile.inc
@@ -1,4 +1,5 @@
 bootblock-y += bootblock.c
+bootblock-y += memmap.c
 
 romstage-y += ../qemu-i440fx/fw_cfg.c
 romstage-y += ../qemu-i440fx/memmap.c
diff --git a/src/mainboard/emulation/qemu-q35/acpi_tables.c b/src/mainboard/emulation/qemu-q35/acpi_tables.c
index 03d357c..90bab2f 100644
--- a/src/mainboard/emulation/qemu-q35/acpi_tables.c
+++ b/src/mainboard/emulation/qemu-q35/acpi_tables.c
@@ -10,7 +10,6 @@
 
 #include "../qemu-i440fx/fw_cfg.h"
 #include "../qemu-i440fx/acpi.h"
-#include "q35.h"
 
 void mainboard_fill_fadt(acpi_fadt_t *fadt)
 {
@@ -40,18 +39,8 @@
 
 unsigned long acpi_fill_mcfg(unsigned long current)
 {
-	struct device *dev;
-	u32 reg;
-
-	dev = dev_find_device(0x8086, 0x29c0, 0);
-	if (!dev)
-		return current;
-
-	reg = pci_read_config32(dev, D0F0_PCIEXBAR_LO);
-	if ((reg & 0x07) != 0x01)  /* require enabled + 256MB size */
-		return current;
-
-	current += acpi_create_mcfg_mmconfig((acpi_mcfg_mmconfig_t *) current,
-					     reg & 0xf0000000, 0x0, 0x0, 255);
+	current += acpi_create_mcfg_mmconfig((acpi_mcfg_mmconfig_t *)current,
+					     CONFIG_MMCONF_BASE_ADDRESS, 0, 0,
+					     CONFIG_MMCONF_BUS_NUMBER - 1);
 	return current;
 }
diff --git a/src/mainboard/emulation/qemu-q35/bootblock.c b/src/mainboard/emulation/qemu-q35/bootblock.c
index 7303680..cdca27a 100644
--- a/src/mainboard/emulation/qemu-q35/bootblock.c
+++ b/src/mainboard/emulation/qemu-q35/bootblock.c
@@ -10,8 +10,6 @@
 
 static void bootblock_northbridge_init(void)
 {
-	uint32_t reg;
-
 	/*
 	 * The "io" variant of the config access is explicitly used to
 	 * setup the PCIEXBAR because CONFIG(MMCONF_SUPPORT) is set to
@@ -24,16 +22,12 @@
 	 * The PCIEXBAR is assumed to live in the memory mapped IO space under
 	 * 4GiB.
 	 */
-	reg = 0;
-	pci_io_write_config32(HOST_BRIDGE, D0F0_PCIEXBAR_HI, reg);
-	reg = CONFIG_MMCONF_BASE_ADDRESS | 1; /* 256MiB - 0-255 buses. */
-	pci_io_write_config32(HOST_BRIDGE, D0F0_PCIEXBAR_LO, reg);
+	const uint32_t pciexbar = make_pciexbar();
+	pci_io_write_config32(HOST_BRIDGE, D0F0_PCIEXBAR_HI, 0);
+	pci_io_write_config32(HOST_BRIDGE, D0F0_PCIEXBAR_LO, pciexbar);
 
-	/* MCFG is now active. If it's not qemu was started for machine PC */
-	if (CONFIG(BOOTBLOCK_CONSOLE) &&
-	    (pci_read_config32(HOST_BRIDGE, D0F0_PCIEXBAR_LO) !=
-	     (CONFIG_MMCONF_BASE_ADDRESS | 1)))
-		die("You must run qemu for machine Q35 (-M q35)");
+	if (CONFIG(BOOTBLOCK_CONSOLE))
+		mainboard_machine_check();
 }
 
 static void bootblock_southbridge_init(void)
diff --git a/src/mainboard/emulation/qemu-q35/mainboard.c b/src/mainboard/emulation/qemu-q35/mainboard.c
index 0911671..540db04 100644
--- a/src/mainboard/emulation/qemu-q35/mainboard.c
+++ b/src/mainboard/emulation/qemu-q35/mainboard.c
@@ -41,9 +41,7 @@
 {
 	pci_dev_read_resources(dev);
 
-	/* reserve mmconfig */
-	fixed_mem_resource(dev, 2, CONFIG_MMCONF_BASE_ADDRESS >> 10, 0x10000000 >> 10,
-			   IORESOURCE_RESERVE);
+	mmconf_resource(dev, 2);
 
 	if (CONFIG(ARCH_RAMSTAGE_X86_64)) {
 		/* Reserve page tables in DRAM. FIXME: Remove once x86_64 page tables reside in CBMEM */
diff --git a/src/mainboard/emulation/qemu-q35/memmap.c b/src/mainboard/emulation/qemu-q35/memmap.c
index 10b35d7..f3ce42c 100644
--- a/src/mainboard/emulation/qemu-q35/memmap.c
+++ b/src/mainboard/emulation/qemu-q35/memmap.c
@@ -2,6 +2,7 @@
 
 #define __SIMPLE_DEVICE__
 
+#include <assert.h>
 #include <console/console.h>
 #include <cpu/x86/smm.h>
 #include <device/pci_ops.h>
@@ -10,6 +11,28 @@
 
 #include "q35.h"
 
+static uint32_t encode_pciexbar_length(void)
+{
+	switch (CONFIG_MMCONF_BUS_NUMBER) {
+		case 256: return 0 << 1;
+		case 128: return 1 << 1;
+		case  64: return 2 << 1;
+		default:  return dead_code_t(uint32_t);
+	}
+}
+
+uint32_t make_pciexbar(void)
+{
+	return CONFIG_MMCONF_BASE_ADDRESS | encode_pciexbar_length() | 1;
+}
+
+/* Check that MCFG is active. If it's not, QEMU was started for machine PC */
+void mainboard_machine_check(void)
+{
+	if (pci_read_config32(HOST_BRIDGE, D0F0_PCIEXBAR_LO) != make_pciexbar())
+		die("You must run qemu for machine Q35 (-M q35)");
+}
+
 /* QEMU-specific register */
 #define EXT_TSEG_MBYTES	0x50
 
diff --git a/src/mainboard/emulation/qemu-q35/q35.h b/src/mainboard/emulation/qemu-q35/q35.h
index dcdd172..ae0fa38 100644
--- a/src/mainboard/emulation/qemu-q35/q35.h
+++ b/src/mainboard/emulation/qemu-q35/q35.h
@@ -4,6 +4,7 @@
 #define __MAINBOARD_EMU_Q35_H__
 
 #include <device/pci_type.h>
+#include <types.h>
 
 #define HOST_BRIDGE	PCI_DEV(0, 0, 0)
 
@@ -23,4 +24,8 @@
 #define  TSEG_SZ_MASK		(3 << 1)
 #define  H_SMRAME		(1 << 7)
 
+uint32_t make_pciexbar(void);
+
+void mainboard_machine_check(void);
+
 #endif
diff --git a/src/mainboard/emulation/qemu-q35/romstage.c b/src/mainboard/emulation/qemu-q35/romstage.c
index e9637e8..c9bc339 100644
--- a/src/mainboard/emulation/qemu-q35/romstage.c
+++ b/src/mainboard/emulation/qemu-q35/romstage.c
@@ -8,20 +8,12 @@
 
 #include "q35.h"
 
-static void mainboard_machine_check(void)
-{
-	/* Check that MCFG is active. If it's not qemu was started for machine PC */
-	if (!CONFIG(BOOTBLOCK_CONSOLE) &&
-	    (pci_read_config32(HOST_BRIDGE, D0F0_PCIEXBAR_LO) !=
-	     (CONFIG_MMCONF_BASE_ADDRESS | 1)))
-		die("You must run qemu for machine Q35 (-M q35)");
-}
-
 void mainboard_romstage_entry(void)
 {
 	i82801ix_early_init();
 
-	mainboard_machine_check();
+	if (!CONFIG(BOOTBLOCK_CONSOLE))
+		mainboard_machine_check();
 
 	cbmem_recovery(0);
 }