@@ -14,7 +14,18 @@
#define Q35_HOST_PCIE_START_BUS_NUMBER 0
#define Q35_HOST_PCIE_END_BUS_NUMBER 255
-#define PCI_DEVICE_ID_INTEL_ICH9_LPC 0x2918
+/* TODO: Replace this hack for a non-hack!
+ * PCI_DEVICE_ID_INTEL_ICH9_LPC must be set to
+ * `setpci -s 00:1f.0 0x02.w` (LPC device id)
+ * of the host - so that seabios recognises
+ * the hardware QEMU is providing,
+ * which now includes the hosts LPC */
+#define Q35_BEARLAKE 0x2918 // QEMU DEFAULT
+#define Q35_COUGARPOINT 0x1c4e
+#define Q35_PANTHERPOINT 0x
+#define Q35_LYNXPOINT 0x8c4e
+
+#define PCI_DEVICE_ID_INTEL_ICH9_LPC Q35_COUGARPOINT
#define ICH9_LPC_PMBASE 0x40
#define ICH9_LPC_PMBASE_RTE 0x1
@@ -389,20 +389,111 @@ static void i440fx_mem_addr_setup(struct pci_device
*dev, void *arg)
static void mch_mem_addr_setup(struct pci_device *dev, void *arg)
{
- u64 addr = Q35_HOST_BRIDGE_PCIEXBAR_ADDR;
- u32 size = Q35_HOST_BRIDGE_PCIEXBAR_SIZE;
+ /* Base addresses are either calculated by their location with respect
to
+ * TOM as described by Intel documentation.
+ * Or they are allocated using malloc. In either case, the new base
addresses
+ * are written to pci_config space, where by qemu(q35) and vfio catch
these changes
+ * and respond accordingly.
+ * The intention is to mimic the hosts BIOS role in configuring the
PCI_CONFIG space.
+ * TODO: Clearly, this is not complete
+ * - as complete Direct Assignment is not completly working.*/
+
+ /* TODO: Move these defines to be consistent with seabios */
+ #define Q35_TOM 0xa0
+ #define Q35_TOM_BASEADDR 0x7FFFF00000
+ #define Q35_TOUUD 0xa8
+ #define Q35_TOUUD_BASEADDR 0x7FFFF00000
+ #define Q35_TOLUD 0xbc
+ #define Q35_TOLUD_BASEADDR 0xFFF00000
+ #define Q35_APIC_FLASH_TXT_SIZE 20 * 1024 * 1024
+ #define Q35_PCIEXBAR_SIZE 256 * 1024 * 1024
+ #define Q35_IDK_SIZE 768 * 1024 * 1024
+ #define Q35_PCIEXBAR_BASEADDR 0x7FF0000000
+ #define Q35_BDSM 0xb0
+ #define Q35_BDSM_BASEADDR 0xFFF00000
+ #define Q35_GMCH_DSM_MASK 0xF8
+ #define Q35_BGSM 0xb4
+ #define Q35_BGSM_BASEADDR 0xFFF00000
+ #define Q35_GMCH_GSM_MASK 0x300
+ #define Q35_TSEG 0xb8
+ #define Q35_TSEG_BASEADDR 0xFFF00000
+ #define TSEG_SIZE 8 * 1024 * 1024
+ #define Q35_MCHBAR 0x48
+ #define Q35_MCHBAR_BASEADDR 0x7FFFFF8000
+ #define Q35_MCHBAR_EN 0x1
+ #define Q35_MCHBAR_SIZE 0x8000
+ #define Q35_DMIBAR 0x68
+ #define Q35_DMIBAR_BASEADDR 0x7FFFFFF000
+ #define Q35_DMIBAR_EN 0x1
+ #define Q35_DMIBAR_SIZE 0x1000
+ #define IGD_OPREGION 0xfc
+ #define IGD_OPREGION_PAGES 3
+ #define IGD_OPREGION_SIZE IGD_OPREGION_PAGES * PAGE_SIZE
+ #define IGD_BDSM 0x5c
+ #define Q35_GDSM 0x52
+
+ u16 q35bdf = dev->bdf;
+
+ /* setup TOM - Top Of Memory */
+ u32 tom_lower, tom_upper;
+ u64 tom, touud;
+
+ if (RamSizeOver4G)
+ {
+ /* TODO: not finished. +4GB no supported */
+ tom = (0x100000000 + RamSizeOver4G) & Q35_TOM_BASEADDR;
+ touud = tom & Q35_TOUUD_BASEADDR; // minus all Intel ME stolen
memory if reclaim/remap is disabled
+ dprintf(1, "Q35: RamSizeOver4G: %016llX\n", tom);
+ }
+ else
+ {
+ tom = RamSize & Q35_TOM_BASEADDR;
+ touud = 0x0; // disabled if RamSize is under 4G
+ dprintf(1, "Q35: RamSize: %x\n", RamSize);
+ }
- /* setup mmconfig */
- u16 bdf = dev->bdf;
- u32 upper = addr >> 32;
- u32 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);
- add_e820(addr, size, E820_RESERVED);
+ tom_lower = (tom & 0xffffffff);
+ tom_upper = tom >> 32;
+ pci_config_writel(q35bdf,
+ Q35_TOM,
+ tom_lower);
+ pci_config_writel(q35bdf,
+ Q35_TOM+0x4,
+ tom_upper);
+
+ /* setup TOUUD - Top of Upper Usable DRAM */
+ u32 touud_lower, touud_upper;
+ touud_lower = (touud & 0xffffffff);
+ touud_upper = touud >> 32;
+ pci_config_writel(q35bdf,
+ Q35_TOUUD,
+ touud_lower);
+ pci_config_writel(q35bdf,
+ Q35_TOUUD+0x4,
+ touud_upper);
+
+ /* setup TOLUD - Top of Lower Usable DRAM */
+ u32 tolud;
+
+ tolud = (tom - Q35_APIC_FLASH_TXT_SIZE) & Q35_TOLUD_BASEADDR;
+ pci_config_writel(q35bdf,
+ Q35_TOLUD,
+ tolud);
+
+
+ /* setup PCIEXBAR/MMCONFIG */
+ u64 pciexbar;
+ pciexbar = Q35_HOST_BRIDGE_PCIEXBAR_ADDR;
+
+ u32 upper = pciexbar >> 32;
+ u32 lower = (pciexbar & 0xffffffff) | Q35_HOST_BRIDGE_PCIEXBAREN;
+ pci_config_writel(q35bdf, Q35_HOST_BRIDGE_PCIEXBAR, 0); // This sets
bit 2:1 0x0 == 256 MB (PCIEXBAR_SIZE)
+ pci_config_writel(q35bdf, Q35_HOST_BRIDGE_PCIEXBAR + 4, upper);
+ pci_config_writel(q35bdf, Q35_HOST_BRIDGE_PCIEXBAR, lower);