[coreboot-gerrit] Patch set updated for coreboot: f15eb2b qemu: add q35 support

Gerd Hoffmann (kraxel@redhat.com) gerrit at coreboot.org
Tue Jun 11 18:28:07 CEST 2013


Gerd Hoffmann (kraxel at redhat.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/3430

-gerrit

commit f15eb2b98fad7304c8160edec855b8e5c3a3f28d
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Fri Jun 7 16:03:44 2013 +0200

    qemu: add q35 support
    
    Add support for the new q35 chipset emulation added in qemu 1.4.
    
    Change-Id: Iabfaa1310dc7b54c9d224635addebdfafe1fbfaf
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
---
 src/cpu/qemu-x86/Makefile.inc                  |   1 +
 src/mainboard/emulation/Kconfig                |   6 +-
 src/mainboard/emulation/qemu-q35/Kconfig       |  39 +++
 src/mainboard/emulation/qemu-q35/Makefile.inc  |   3 +
 src/mainboard/emulation/qemu-q35/acpi_tables.c | 339 ++++++++++++++++++
 src/mainboard/emulation/qemu-q35/devicetree.cb |  41 +++
 src/mainboard/emulation/qemu-q35/dsdt.asl      | 454 +++++++++++++++++++++++++
 src/mainboard/emulation/qemu-q35/mainboard.c   |  89 +++++
 src/mainboard/emulation/qemu-q35/romstage.c    |  63 ++++
 src/mainboard/emulation/qemu-x86/northbridge.c |   5 +
 10 files changed, 1039 insertions(+), 1 deletion(-)

diff --git a/src/cpu/qemu-x86/Makefile.inc b/src/cpu/qemu-x86/Makefile.inc
index e206b4d..c65fcd0 100644
--- a/src/cpu/qemu-x86/Makefile.inc
+++ b/src/cpu/qemu-x86/Makefile.inc
@@ -19,3 +19,4 @@
 ramstage-y += qemu.c
 subdirs-y += ../x86/mtrr
 subdirs-y += ../x86/lapic
+subdirs-y += ../x86/smm
diff --git a/src/mainboard/emulation/Kconfig b/src/mainboard/emulation/Kconfig
index 72b70af..a4ecec6 100644
--- a/src/mainboard/emulation/Kconfig
+++ b/src/mainboard/emulation/Kconfig
@@ -6,6 +6,9 @@ choice
 config BOARD_EMULATION_QEMU_X86_I440FX
 	bool "QEMU x86 i440fx/piix4 (aka qemu -M pc)"
 
+config BOARD_EMULATION_QEMU_X86_Q35
+	bool "QEMU x86 i440fx/piix4 (aka qemu -M q35, since v1.4)"
+
 config BOARD_EMULATION_QEMU_ARMV7
 	bool "QEMU armv7 (vexpress-a9)"
 
@@ -14,9 +17,10 @@ endchoice
 config BOARD_EMULATION_QEMU_X86
 	bool
 	default y
-	depends on BOARD_EMULATION_QEMU_X86_I440FX
+	depends on BOARD_EMULATION_QEMU_X86_I440FX || BOARD_EMULATION_QEMU_X86_Q35
 
 source "src/mainboard/emulation/qemu-i440fx/Kconfig"
+source "src/mainboard/emulation/qemu-q35/Kconfig"
 source "src/mainboard/emulation/qemu-armv7/Kconfig"
 
 config MAINBOARD_VENDOR
diff --git a/src/mainboard/emulation/qemu-q35/Kconfig b/src/mainboard/emulation/qemu-q35/Kconfig
new file mode 100644
index 0000000..95209cb
--- /dev/null
+++ b/src/mainboard/emulation/qemu-q35/Kconfig
@@ -0,0 +1,39 @@
+if BOARD_EMULATION_QEMU_X86_Q35
+
+config BOARD_SPECIFIC_OPTIONS # dummy
+	def_bool y
+	select ARCH_X86
+	select CPU_QEMU_X86
+	select SOUTHBRIDGE_INTEL_I82801IX
+	select IOAPIC_INTERRUPTS_ON_APIC_SERIAL_BUS
+	select MMCONF_SUPPORT
+	select CACHE_AS_RAM
+#	select HAVE_OPTION_TABLE
+#	select HAVE_PIRQ_TABLE
+	select HAVE_ACPI_TABLES
+#	select HAVE_ACPI_RESUME
+	select BOARD_ROMSIZE_KB_256
+	select EARLY_CBMEM_INIT
+
+config MAINBOARD_DIR
+	string
+	default emulation/qemu-q35
+
+config MAINBOARD_PART_NUMBER
+	string
+	default "QEMU x86 q35/ich9"
+
+#config IRQ_SLOT_COUNT
+#	int
+#	default 6
+
+#config DCACHE_RAM_BASE
+#	hex
+#	default 0xd0000
+
+#config DCACHE_RAM_SIZE
+#	hex
+#	default 0x10000
+
+
+endif # BOARD_EMULATION_QEMU_X86
diff --git a/src/mainboard/emulation/qemu-q35/Makefile.inc b/src/mainboard/emulation/qemu-q35/Makefile.inc
new file mode 100644
index 0000000..2365d28
--- /dev/null
+++ b/src/mainboard/emulation/qemu-q35/Makefile.inc
@@ -0,0 +1,3 @@
+cpu_incs += $(src)/mainboard/emulation/qemu-x86/cache_as_ram.inc
+ramstage-y += ../qemu-x86/northbridge.c
+ramstage-y += ../qemu-x86/fw_cfg.c
diff --git a/src/mainboard/emulation/qemu-q35/acpi_tables.c b/src/mainboard/emulation/qemu-q35/acpi_tables.c
new file mode 100644
index 0000000..d894dc1
--- /dev/null
+++ b/src/mainboard/emulation/qemu-q35/acpi_tables.c
@@ -0,0 +1,339 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2007-2009 coresystems GmbH
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <types.h>
+#include <string.h>
+#include <console/console.h>
+#include <arch/acpi.h>
+#include <arch/ioapic.h>
+#include <arch/acpigen.h>
+#include <arch/smp/mpspec.h>
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <cpu/x86/msr.h>
+
+extern const unsigned char AmlCode[];
+#if CONFIG_HAVE_ACPI_SLIC
+unsigned long acpi_create_slic(unsigned long current);
+#endif
+
+void acpi_create_fadt(acpi_fadt_t * fadt, acpi_facs_t * facs, void *dsdt)
+{
+	acpi_header_t *header = &(fadt->header);
+	u16 pmbase = pci_read_config16(dev_find_slot(0, PCI_DEVFN(0x1f,0)), 0x40) & 0xfffe;
+	memset((void *) fadt, 0, sizeof(acpi_fadt_t));
+	memcpy(header->signature, "FACP", 4);
+	header->length = sizeof(acpi_fadt_t);
+	header->revision = 3;
+	memcpy(header->oem_id, OEM_ID, 6);
+	memcpy(header->oem_table_id, ACPI_TABLE_CREATOR, 8);
+	memcpy(header->asl_compiler_id, ASLC, 4);
+	header->asl_compiler_revision = 0;
+
+	fadt->firmware_ctrl = (unsigned long) facs;
+	fadt->dsdt = (unsigned long) dsdt;
+	fadt->model = 0x00;
+	fadt->preferred_pm_profile = PM_MOBILE;
+	fadt->sci_int = 0x9;
+	fadt->smi_cmd = 0;
+	fadt->acpi_enable = 0;
+	fadt->acpi_disable = 0;
+	fadt->s4bios_req = 0x0;
+	fadt->pstate_cnt = 0;
+
+	fadt->pm1a_evt_blk = pmbase;
+	fadt->pm1b_evt_blk = 0x0;
+	fadt->pm1a_cnt_blk = pmbase + 0x4;
+	fadt->pm1b_cnt_blk = 0x0;
+	fadt->pm2_cnt_blk = pmbase + 0x50;
+	fadt->pm_tmr_blk = pmbase + 0x8;
+	fadt->gpe0_blk = pmbase + 0x20;
+	fadt->gpe1_blk = 0;
+
+	fadt->pm1_evt_len = 4;
+	fadt->pm1_cnt_len = 2; /* Upper word is reserved and
+				  Linux complains about 32 bit. */
+	fadt->pm2_cnt_len = 1;
+	fadt->pm_tmr_len = 4;
+	fadt->gpe0_blk_len = 16;
+	fadt->gpe1_blk_len = 0;
+	fadt->gpe1_base = 0;
+	fadt->cst_cnt = 0;
+	fadt->p_lvl2_lat = 1;
+	fadt->p_lvl3_lat = 0x39;
+	fadt->flush_size = 0;
+	fadt->flush_stride = 0;
+	fadt->duty_offset = 1;
+	fadt->duty_width = 3;
+	fadt->day_alrm = 0xd;
+	fadt->mon_alrm = 0x00;
+	fadt->century = 0x32;
+	fadt->iapc_boot_arch = 0x00;
+	fadt->flags = ACPI_FADT_WBINVD | ACPI_FADT_C1_SUPPORTED |
+			ACPI_FADT_SLEEP_BUTTON | ACPI_FADT_S4_RTC_WAKE |
+			ACPI_FADT_DOCKING_SUPPORTED | ACPI_FADT_RESET_REGISTER |
+			ACPI_FADT_PLATFORM_CLOCK;
+
+	fadt->reset_reg.space_id = ACPI_ADDRESS_SPACE_IO;
+	fadt->reset_reg.bit_width = 8;
+	fadt->reset_reg.bit_offset = 0;
+	fadt->reset_reg.resv = 0;
+	fadt->reset_reg.addrl = 0xcf9;
+	fadt->reset_reg.addrh = 0;
+	fadt->reset_value = 0x06;
+
+	fadt->x_firmware_ctl_l = 0; /* Set X_FIRMWARE_CTRL only if FACS is */
+	fadt->x_firmware_ctl_h = 0; /* above 4GB. If X_FIRMWARE_CTRL is set, */
+				    /* then FIRMWARE_CTRL must be zero. */
+	fadt->x_dsdt_l = (unsigned long)dsdt;
+	fadt->x_dsdt_h = 0;
+
+	fadt->x_pm1a_evt_blk.space_id = 1;
+	fadt->x_pm1a_evt_blk.bit_width = 32;
+	fadt->x_pm1a_evt_blk.bit_offset = 0;
+	fadt->x_pm1a_evt_blk.resv = 0;
+	fadt->x_pm1a_evt_blk.addrl = pmbase;
+	fadt->x_pm1a_evt_blk.addrh = 0x0;
+
+	fadt->x_pm1b_evt_blk.space_id = 0;
+	fadt->x_pm1b_evt_blk.bit_width = 0;
+	fadt->x_pm1b_evt_blk.bit_offset = 0;
+	fadt->x_pm1b_evt_blk.resv = 0;
+	fadt->x_pm1b_evt_blk.addrl = 0x0;
+	fadt->x_pm1b_evt_blk.addrh = 0x0;
+
+	fadt->x_pm1a_cnt_blk.space_id = 1;
+	fadt->x_pm1a_cnt_blk.bit_width = 16; /* Upper word is reserved and
+						Linux complains about 32 bit. */
+	fadt->x_pm1a_cnt_blk.bit_offset = 0;
+	fadt->x_pm1a_cnt_blk.resv = 0;
+	fadt->x_pm1a_cnt_blk.addrl = pmbase + 0x4;
+	fadt->x_pm1a_cnt_blk.addrh = 0x0;
+
+	fadt->x_pm1b_cnt_blk.space_id = 0;
+	fadt->x_pm1b_cnt_blk.bit_width = 0;
+	fadt->x_pm1b_cnt_blk.bit_offset = 0;
+	fadt->x_pm1b_cnt_blk.resv = 0;
+	fadt->x_pm1b_cnt_blk.addrl = 0x0;
+	fadt->x_pm1b_cnt_blk.addrh = 0x0;
+
+	fadt->x_pm2_cnt_blk.space_id = 1;
+	fadt->x_pm2_cnt_blk.bit_width = 8;
+	fadt->x_pm2_cnt_blk.bit_offset = 0;
+	fadt->x_pm2_cnt_blk.resv = 0;
+	fadt->x_pm2_cnt_blk.addrl = pmbase + 0x50;
+	fadt->x_pm2_cnt_blk.addrh = 0x0;
+
+	fadt->x_pm_tmr_blk.space_id = 1;
+	fadt->x_pm_tmr_blk.bit_width = 32;
+	fadt->x_pm_tmr_blk.bit_offset = 0;
+	fadt->x_pm_tmr_blk.resv = 0;
+	fadt->x_pm_tmr_blk.addrl = pmbase + 0x8;
+	fadt->x_pm_tmr_blk.addrh = 0x0;
+
+	fadt->x_gpe0_blk.space_id = 1;
+	fadt->x_gpe0_blk.bit_width = 128;
+	fadt->x_gpe0_blk.bit_offset = 0;
+	fadt->x_gpe0_blk.resv = 0;
+	fadt->x_gpe0_blk.addrl = pmbase + 0x20;
+	fadt->x_gpe0_blk.addrh = 0x0;
+
+	fadt->x_gpe1_blk.space_id = 0;
+	fadt->x_gpe1_blk.bit_width = 0;
+	fadt->x_gpe1_blk.bit_offset = 0;
+	fadt->x_gpe1_blk.resv = 0;
+	fadt->x_gpe1_blk.addrl = 0x0;
+	fadt->x_gpe1_blk.addrh = 0x0;
+
+	header->checksum =
+	    acpi_checksum((void *) fadt, header->length);
+}
+
+unsigned long acpi_fill_madt(unsigned long current)
+{
+	/* Local APICs */
+	current = acpi_create_madt_lapics(current);
+
+	/* IOAPIC */
+	current += acpi_create_madt_ioapic((acpi_madt_ioapic_t *) current,
+				2, IO_APIC_ADDR, 0);
+
+	/* INT_SRC_OVR */
+	current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *)
+		 current, 0, 0, 2, 0);
+	current += acpi_create_madt_irqoverride((acpi_madt_irqoverride_t *)
+		 current, 0, 9, 9, MP_IRQ_TRIGGER_LEVEL | MP_IRQ_POLARITY_HIGH);
+
+	return current;
+}
+
+unsigned long acpi_fill_ssdt_generator(unsigned long current, const char *oem_table_id)
+{
+	// Not implemented
+	return current;
+}
+
+unsigned long acpi_fill_slit(unsigned long current)
+{
+	// Not implemented
+	return current;
+}
+
+unsigned long acpi_fill_mcfg(unsigned long current)
+{
+	device_t dev;
+	u32 reg;
+
+	dev = dev_find_device(0x8086, 0x29c0, 0);
+	if (!dev)
+		return current;
+
+	reg = pci_read_config32(dev, 0x60);
+	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);
+	return current;
+}
+
+unsigned long acpi_fill_srat(unsigned long current)
+{
+	/* No NUMA, no SRAT */
+	return current;
+}
+
+#define ALIGN_CURRENT current = (ALIGN(current, 16))
+unsigned long write_acpi_tables(unsigned long start)
+{
+	unsigned long current;
+	acpi_rsdp_t *rsdp;
+	acpi_rsdt_t *rsdt;
+	acpi_xsdt_t *xsdt;
+	acpi_hpet_t *hpet;
+	acpi_madt_t *madt;
+	acpi_mcfg_t *mcfg;
+	acpi_fadt_t *fadt;
+	acpi_facs_t *facs;
+#if CONFIG_HAVE_ACPI_SLIC
+	acpi_header_t *slic;
+#endif
+	acpi_header_t *ssdt;
+	acpi_header_t *dsdt;
+
+	current = start;
+
+	/* Align ACPI tables to 16byte */
+	ALIGN_CURRENT;
+
+	printk(BIOS_INFO, "ACPI: Writing ACPI tables at %lx.\n", start);
+
+	/* We need at least an RSDP and an RSDT Table */
+	rsdp = (acpi_rsdp_t *) current;
+	current += sizeof(acpi_rsdp_t);
+	ALIGN_CURRENT;
+	rsdt = (acpi_rsdt_t *) current;
+	current += sizeof(acpi_rsdt_t);
+	ALIGN_CURRENT;
+	xsdt = (acpi_xsdt_t *) current;
+	current += sizeof(acpi_xsdt_t);
+	ALIGN_CURRENT;
+
+	/* clear all table memory */
+	memset((void *) start, 0, current - start);
+
+	acpi_write_rsdp(rsdp, rsdt, xsdt);
+	acpi_write_rsdt(rsdt);
+	acpi_write_xsdt(xsdt);
+
+	/*
+	 * We explicitly add these tables later on:
+	 */
+	printk(BIOS_DEBUG, "ACPI:    * HPET\n");
+
+	hpet = (acpi_hpet_t *) current;
+	current += sizeof(acpi_hpet_t);
+	ALIGN_CURRENT;
+	acpi_create_hpet(hpet);
+	acpi_add_table(rsdp, hpet);
+
+	/* If we want to use HPET Timers Linux wants an MADT */
+	printk(BIOS_DEBUG, "ACPI:    * MADT\n");
+
+	madt = (acpi_madt_t *) current;
+	acpi_create_madt(madt);
+	current += madt->header.length;
+	ALIGN_CURRENT;
+	acpi_add_table(rsdp, madt);
+
+	printk(BIOS_DEBUG, "ACPI:    * MCFG\n");
+	mcfg = (acpi_mcfg_t *) current;
+	acpi_create_mcfg(mcfg);
+	current += mcfg->header.length;
+	ALIGN_CURRENT;
+	acpi_add_table(rsdp, mcfg);
+
+	printk(BIOS_DEBUG, "ACPI:     * FACS\n");
+	facs = (acpi_facs_t *) current;
+	current += sizeof(acpi_facs_t);
+	ALIGN_CURRENT;
+	acpi_create_facs(facs);
+
+	dsdt = (acpi_header_t *) current;
+	memcpy(dsdt, &AmlCode, sizeof(acpi_header_t));
+	current += dsdt->length;
+	memcpy(dsdt, &AmlCode, dsdt->length);
+
+	ALIGN_CURRENT;
+
+	/* We patched up the DSDT, so we need to recalculate the checksum */
+	dsdt->checksum = 0;
+	dsdt->checksum = acpi_checksum((void *)dsdt, dsdt->length);
+
+	printk(BIOS_DEBUG, "ACPI:     * DSDT @ %p Length %x\n", dsdt,
+		     dsdt->length);
+
+#if CONFIG_HAVE_ACPI_SLIC
+	printk(BIOS_DEBUG, "ACPI:     * SLIC\n");
+	slic = (acpi_header_t *)current;
+	current += acpi_create_slic(current);
+	ALIGN_CURRENT;
+	acpi_add_table(rsdp, slic);
+#endif
+
+	printk(BIOS_DEBUG, "ACPI:     * FADT\n");
+	fadt = (acpi_fadt_t *) current;
+	current += sizeof(acpi_fadt_t);
+	ALIGN_CURRENT;
+
+	acpi_create_fadt(fadt, facs, dsdt);
+	acpi_add_table(rsdp, fadt);
+
+	printk(BIOS_DEBUG, "ACPI:     * SSDT\n");
+	ssdt = (acpi_header_t *)current;
+	acpi_create_ssdt_generator(ssdt, ACPI_TABLE_CREATOR);
+	current += ssdt->length;
+	acpi_add_table(rsdp, ssdt);
+	ALIGN_CURRENT;
+
+	printk(BIOS_DEBUG, "current = %lx\n", current);
+	printk(BIOS_INFO, "ACPI: done.\n");
+	return current;
+}
diff --git a/src/mainboard/emulation/qemu-q35/devicetree.cb b/src/mainboard/emulation/qemu-q35/devicetree.cb
new file mode 100644
index 0000000..1ac55a0
--- /dev/null
+++ b/src/mainboard/emulation/qemu-q35/devicetree.cb
@@ -0,0 +1,41 @@
+chip mainboard/emulation/qemu-q35
+	device cpu_cluster 0 on
+		chip cpu/qemu-x86
+			device lapic 0 on end
+		end
+	end
+	device domain 0 on
+		device pci 0.0 on end		# northbridge (q35)
+		chip southbridge/intel/i82801ix
+			register "sata_ahci" = "1"
+
+			# present unconditionally
+			device pci 1f.0 on end	# LPC
+			device pci 1f.2 on end	# SATA
+			device pci 1f.3 on end	# SMBus
+
+			# presence depends in qemu config
+			# (see docs/q35-chipset.cfg in qemu src tree)
+			device pci 1a.0 on end	# UHCI #4
+			device pci 1a.1 on end	# UHCI #5
+			device pci 1a.2 on end	# UHCI #6
+			device pci 1a.7 on end	# EHCI #2
+			device pci 1b.0 on end	# HD Audio
+			device pci 1c.0 on end	# PCIe Port #1
+			device pci 1c.1 on end	# PCIe Port #2
+			device pci 1c.2 on end	# PCIe Port #3
+			device pci 1c.3 on end	# PCIe Port #4
+			device pci 1c.4 on end	# PCIe Port #5
+			device pci 1c.5 on end	# PCIe Port #6
+			device pci 1d.0 on end	# UHCI #1
+			device pci 1d.1 on end	# UHCI #2
+			device pci 1d.2 on end	# UHCI #3
+			device pci 1d.7 on end	# EHCI #1
+
+			# not present (not emulated by qemu)
+			device pci 19.0 off end
+			device pci 1f.5 off end
+			device pci 1f.6 off end
+		end
+	end
+end
diff --git a/src/mainboard/emulation/qemu-q35/dsdt.asl b/src/mainboard/emulation/qemu-q35/dsdt.asl
new file mode 100644
index 0000000..4204663
--- /dev/null
+++ b/src/mainboard/emulation/qemu-q35/dsdt.asl
@@ -0,0 +1,454 @@
+/*
+ * Bochs/QEMU ACPI DSDT ASL definition
+ *
+ * Copyright (c) 2006 Fabrice Bellard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+/*
+ * Copyright (c) 2010 Isaku Yamahata
+ *                    yamahata at valinux co jp
+ * Based on acpi-dsdt.dsl, but heavily modified for q35 chipset.
+ */
+
+DefinitionBlock (
+    "dsdt.aml",         // Output Filename
+    "DSDT",             // Signature
+    0x01,               // DSDT Compliance Revision
+    "CORE",             // OEMID
+    "COREBOOT",         // TABLE ID
+    0x2                 // OEM Revision
+    )
+{
+
+#include "../qemu-x86/acpi/dbug.asl"
+
+    Scope(\_SB) {
+        OperationRegion(PCST, SystemIO, 0xae00, 0x0c)
+        OperationRegion(PCSB, SystemIO, 0xae0c, 0x01)
+        Field(PCSB, AnyAcc, NoLock, WriteAsZeros) {
+            PCIB, 8,
+        }
+    }
+
+
+/****************************************************************
+ * PCI Bus definition
+ ****************************************************************/
+
+    Scope(\_SB) {
+        Device(PCI0) {
+            Name(_HID, EisaId("PNP0A08"))
+            Name(_CID, EisaId("PNP0A03"))
+            Name(_ADR, 0x00)
+            Name(_UID, 1)
+
+            // _OSC: based on sample of ACPI3.0b spec
+            Name(SUPP, 0) // PCI _OSC Support Field value
+            Name(CTRL, 0) // PCI _OSC Control Field value
+            Method(_OSC, 4) {
+                // Create DWORD-addressable fields from the Capabilities Buffer
+                CreateDWordField(Arg3, 0, CDW1)
+
+                // Check for proper UUID
+                If (LEqual(Arg0, ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766"))) {
+                    // Create DWORD-addressable fields from the Capabilities Buffer
+                    CreateDWordField(Arg3, 4, CDW2)
+                    CreateDWordField(Arg3, 8, CDW3)
+
+                    // Save Capabilities DWORD2 & 3
+                    Store(CDW2, SUPP)
+                    Store(CDW3, CTRL)
+
+                    // Always allow native PME, AER (no dependencies)
+                    // Never allow SHPC (no SHPC controller in this system)
+                    And(CTRL, 0x1D, CTRL)
+
+#if 0 // For now, nothing to do
+                    If (Not(And(CDW1, 1))) { // Query flag clear?
+                        // Disable GPEs for features granted native control.
+                        If (And(CTRL, 0x01)) { // Hot plug control granted?
+                            Store(0, HPCE) // clear the hot plug SCI enable bit
+                            Store(1, HPCS) // clear the hot plug SCI status bit
+                        }
+                        If (And(CTRL, 0x04)) { // PME control granted?
+                            Store(0, PMCE) // clear the PME SCI enable bit
+                            Store(1, PMCS) // clear the PME SCI status bit
+                        }
+                        If (And(CTRL, 0x10)) { // OS restoring PCI Express cap structure?
+                            // Set status to not restore PCI Express cap structure
+                            // upon resume from S3
+                            Store(1, S3CR)
+                        }
+                    }
+#endif
+                    If (LNotEqual(Arg1, One)) {
+                        // Unknown revision
+                        Or(CDW1, 0x08, CDW1)
+                    }
+                    If (LNotEqual(CDW3, CTRL)) {
+                        // Capabilities bits were masked
+                        Or(CDW1, 0x10, CDW1)
+                    }
+                    // Update DWORD3 in the buffer
+                    Store(CTRL, CDW3)
+                } Else {
+                    Or(CDW1, 4, CDW1) // Unrecognized UUID
+                }
+                Return (Arg3)
+            }
+        }
+    }
+
+#include "../qemu-x86/acpi/pci-crs.asl"
+#include "../qemu-x86/acpi/hpet.asl"
+
+
+/****************************************************************
+ * VGA
+ ****************************************************************/
+
+    Scope(\_SB.PCI0) {
+        Device(VGA) {
+            Name(_ADR, 0x00010000)
+            Method(_S1D, 0, NotSerialized) {
+                Return (0x00)
+            }
+            Method(_S2D, 0, NotSerialized) {
+                Return (0x00)
+            }
+            Method(_S3D, 0, NotSerialized) {
+                Return (0x00)
+            }
+        }
+    }
+
+
+/****************************************************************
+ * LPC ISA bridge
+ ****************************************************************/
+
+    Scope(\_SB.PCI0) {
+        /* PCI D31:f0 LPC ISA bridge */
+        Device(ISA) {
+            /* PCI D31:f0 */
+            Name(_ADR, 0x001f0000)
+
+            /* ICH9 PCI to ISA irq remapping */
+            OperationRegion(PIRQ, PCI_Config, 0x60, 0x0C)
+
+            OperationRegion(LPCD, PCI_Config, 0x80, 0x2)
+            Field(LPCD, AnyAcc, NoLock, Preserve) {
+                COMA,   3,
+                    ,   1,
+                COMB,   3,
+
+                Offset(0x01),
+                LPTD,   2,
+                    ,   2,
+                FDCD,   2
+            }
+            OperationRegion(LPCE, PCI_Config, 0x82, 0x2)
+            Field(LPCE, AnyAcc, NoLock, Preserve) {
+                CAEN,   1,
+                CBEN,   1,
+                LPEN,   1,
+                FDEN,   1
+            }
+        }
+    }
+
+#include "../qemu-x86/acpi/isa.asl"
+
+
+/****************************************************************
+ * PCI IRQs
+ ****************************************************************/
+
+    /* Zero => PIC mode, One => APIC Mode */
+    Name(\PICF, Zero)
+    Method(\_PIC, 1, NotSerialized) {
+        Store(Arg0, \PICF)
+    }
+
+    Scope(\_SB) {
+        Scope(PCI0) {
+#define prt_slot_lnk(nr, lnk0, lnk1, lnk2, lnk3)  \
+    Package() { nr##ffff, 0, lnk0, 0 },           \
+    Package() { nr##ffff, 1, lnk1, 0 },           \
+    Package() { nr##ffff, 2, lnk2, 0 },           \
+    Package() { nr##ffff, 3, lnk3, 0 }
+
+#define prt_slot_lnkA(nr) prt_slot_lnk(nr, LNKA, LNKB, LNKC, LNKD)
+#define prt_slot_lnkB(nr) prt_slot_lnk(nr, LNKB, LNKC, LNKD, LNKA)
+#define prt_slot_lnkC(nr) prt_slot_lnk(nr, LNKC, LNKD, LNKA, LNKB)
+#define prt_slot_lnkD(nr) prt_slot_lnk(nr, LNKD, LNKA, LNKB, LNKC)
+
+#define prt_slot_lnkE(nr) prt_slot_lnk(nr, LNKE, LNKF, LNKG, LNKH)
+#define prt_slot_lnkF(nr) prt_slot_lnk(nr, LNKF, LNKG, LNKH, LNKE)
+#define prt_slot_lnkG(nr) prt_slot_lnk(nr, LNKG, LNKH, LNKE, LNKF)
+#define prt_slot_lnkH(nr) prt_slot_lnk(nr, LNKH, LNKE, LNKF, LNKG)
+
+            Name(PRTP, package() {
+                prt_slot_lnkE(0x0000),
+                prt_slot_lnkF(0x0001),
+                prt_slot_lnkG(0x0002),
+                prt_slot_lnkH(0x0003),
+                prt_slot_lnkE(0x0004),
+                prt_slot_lnkF(0x0005),
+                prt_slot_lnkG(0x0006),
+                prt_slot_lnkH(0x0007),
+                prt_slot_lnkE(0x0008),
+                prt_slot_lnkF(0x0009),
+                prt_slot_lnkG(0x000a),
+                prt_slot_lnkH(0x000b),
+                prt_slot_lnkE(0x000c),
+                prt_slot_lnkF(0x000d),
+                prt_slot_lnkG(0x000e),
+                prt_slot_lnkH(0x000f),
+                prt_slot_lnkE(0x0010),
+                prt_slot_lnkF(0x0011),
+                prt_slot_lnkG(0x0012),
+                prt_slot_lnkH(0x0013),
+                prt_slot_lnkE(0x0014),
+                prt_slot_lnkF(0x0015),
+                prt_slot_lnkG(0x0016),
+                prt_slot_lnkH(0x0017),
+                prt_slot_lnkE(0x0018),
+
+                /* INTA -> PIRQA for slot 25 - 31
+                   see the default value of D<N>IR */
+                prt_slot_lnkA(0x0019),
+                prt_slot_lnkA(0x001a),
+                prt_slot_lnkA(0x001b),
+                prt_slot_lnkA(0x001c),
+                prt_slot_lnkA(0x001d),
+
+                /* PCIe->PCI bridge. use PIRQ[E-H] */
+                prt_slot_lnkE(0x001e),
+
+                prt_slot_lnkA(0x001f)
+            })
+
+#define prt_slot_gsi(nr, gsi0, gsi1, gsi2, gsi3)  \
+    Package() { nr##ffff, 0, gsi0, 0 },           \
+    Package() { nr##ffff, 1, gsi1, 0 },           \
+    Package() { nr##ffff, 2, gsi2, 0 },           \
+    Package() { nr##ffff, 3, gsi3, 0 }
+
+#define prt_slot_gsiA(nr) prt_slot_gsi(nr, GSIA, GSIB, GSIC, GSID)
+#define prt_slot_gsiB(nr) prt_slot_gsi(nr, GSIB, GSIC, GSID, GSIA)
+#define prt_slot_gsiC(nr) prt_slot_gsi(nr, GSIC, GSID, GSIA, GSIB)
+#define prt_slot_gsiD(nr) prt_slot_gsi(nr, GSID, GSIA, GSIB, GSIC)
+
+#define prt_slot_gsiE(nr) prt_slot_gsi(nr, GSIE, GSIF, GSIG, GSIH)
+#define prt_slot_gsiF(nr) prt_slot_gsi(nr, GSIF, GSIG, GSIH, GSIE)
+#define prt_slot_gsiG(nr) prt_slot_gsi(nr, GSIG, GSIH, GSIE, GSIF)
+#define prt_slot_gsiH(nr) prt_slot_gsi(nr, GSIH, GSIE, GSIF, GSIG)
+
+            Name(PRTA, package() {
+                prt_slot_gsiE(0x0000),
+                prt_slot_gsiF(0x0001),
+                prt_slot_gsiG(0x0002),
+                prt_slot_gsiH(0x0003),
+                prt_slot_gsiE(0x0004),
+                prt_slot_gsiF(0x0005),
+                prt_slot_gsiG(0x0006),
+                prt_slot_gsiH(0x0007),
+                prt_slot_gsiE(0x0008),
+                prt_slot_gsiF(0x0009),
+                prt_slot_gsiG(0x000a),
+                prt_slot_gsiH(0x000b),
+                prt_slot_gsiE(0x000c),
+                prt_slot_gsiF(0x000d),
+                prt_slot_gsiG(0x000e),
+                prt_slot_gsiH(0x000f),
+                prt_slot_gsiE(0x0010),
+                prt_slot_gsiF(0x0011),
+                prt_slot_gsiG(0x0012),
+                prt_slot_gsiH(0x0013),
+                prt_slot_gsiE(0x0014),
+                prt_slot_gsiF(0x0015),
+                prt_slot_gsiG(0x0016),
+                prt_slot_gsiH(0x0017),
+                prt_slot_gsiE(0x0018),
+
+                /* INTA -> PIRQA for slot 25 - 31, but 30
+                   see the default value of D<N>IR */
+                prt_slot_gsiA(0x0019),
+                prt_slot_gsiA(0x001a),
+                prt_slot_gsiA(0x001b),
+                prt_slot_gsiA(0x001c),
+                prt_slot_gsiA(0x001d),
+
+                /* PCIe->PCI bridge. use PIRQ[E-H] */
+                prt_slot_gsiE(0x001e),
+
+                prt_slot_gsiA(0x001f)
+            })
+
+            Method(_PRT, 0, NotSerialized) {
+                /* PCI IRQ routing table, example from ACPI 2.0a specification,
+                   section 6.2.8.1 */
+                /* Note: we provide the same info as the PCI routing
+                   table of the Bochs BIOS */
+                If (LEqual(\PICF, Zero)) {
+                    Return (PRTP)
+                } Else {
+                    Return (PRTA)
+                }
+            }
+        }
+
+        Field(PCI0.ISA.PIRQ, ByteAcc, NoLock, Preserve) {
+            PRQA,   8,
+            PRQB,   8,
+            PRQC,   8,
+            PRQD,   8,
+
+            Offset(0x08),
+            PRQE,   8,
+            PRQF,   8,
+            PRQG,   8,
+            PRQH,   8
+        }
+
+        Method(IQST, 1, NotSerialized) {
+            // _STA method - get status
+            If (And(0x80, Arg0)) {
+                Return (0x09)
+            }
+            Return (0x0B)
+        }
+        Method(IQCR, 1, NotSerialized) {
+            // _CRS method - get current settings
+            Name(PRR0, ResourceTemplate() {
+                Interrupt(, Level, ActiveHigh, Shared) { 0 }
+            })
+            CreateDWordField(PRR0, 0x05, PRRI)
+            Store(And(Arg0, 0x0F), PRRI)
+            Return (PRR0)
+        }
+
+#define define_link(link, uid, reg)                             \
+        Device(link) {                                          \
+            Name(_HID, EISAID("PNP0C0F"))                       \
+            Name(_UID, uid)                                     \
+            Name(_PRS, ResourceTemplate() {                     \
+                Interrupt(, Level, ActiveHigh, Shared) {        \
+                    5, 10, 11                                   \
+                }                                               \
+            })                                                  \
+            Method(_STA, 0, NotSerialized) {                    \
+                Return (IQST(reg))                              \
+            }                                                   \
+            Method(_DIS, 0, NotSerialized) {                    \
+                Or(reg, 0x80, reg)                              \
+            }                                                   \
+            Method(_CRS, 0, NotSerialized) {                    \
+                Return (IQCR(reg))                              \
+            }                                                   \
+            Method(_SRS, 1, NotSerialized) {                    \
+                CreateDWordField(Arg0, 0x05, PRRI)              \
+                Store(PRRI, reg)                                \
+            }                                                   \
+        }
+
+        define_link(LNKA, 0, PRQA)
+        define_link(LNKB, 1, PRQB)
+        define_link(LNKC, 2, PRQC)
+        define_link(LNKD, 3, PRQD)
+        define_link(LNKE, 4, PRQE)
+        define_link(LNKF, 5, PRQF)
+        define_link(LNKG, 6, PRQG)
+        define_link(LNKH, 7, PRQH)
+
+#define define_gsi_link(link, uid, gsi)                         \
+        Device(link) {                                          \
+            Name(_HID, EISAID("PNP0C0F"))                       \
+            Name(_UID, uid)                                     \
+            Name(_PRS, ResourceTemplate() {                     \
+                Interrupt(, Level, ActiveHigh, Shared) {        \
+                    gsi                                         \
+                }                                               \
+            })                                                  \
+            Name(_CRS, ResourceTemplate() {                     \
+                Interrupt(, Level, ActiveHigh, Shared) {        \
+                    gsi                                         \
+                }                                               \
+            })                                                  \
+            Method(_SRS, 1, NotSerialized) {                    \
+            }                                                   \
+        }
+
+        define_gsi_link(GSIA, 0, 0x10)
+        define_gsi_link(GSIB, 0, 0x11)
+        define_gsi_link(GSIC, 0, 0x12)
+        define_gsi_link(GSID, 0, 0x13)
+        define_gsi_link(GSIE, 0, 0x14)
+        define_gsi_link(GSIF, 0, 0x15)
+        define_gsi_link(GSIG, 0, 0x16)
+        define_gsi_link(GSIH, 0, 0x17)
+    }
+
+#if 0
+#include "../qemu-x86/acpi/cpu-hotplug.asl"
+#endif
+
+
+/****************************************************************
+ * General purpose events
+ ****************************************************************/
+
+    Scope(\_GPE) {
+        Name(_HID, "ACPI0006")
+
+        Method(_L00) {
+        }
+        Method(_L01) {
+#if 0
+            // CPU hotplug event
+            \_SB.PRSC()
+#endif
+        }
+        Method(_L02) {
+        }
+        Method(_L03) {
+        }
+        Method(_L04) {
+        }
+        Method(_L05) {
+        }
+        Method(_L06) {
+        }
+        Method(_L07) {
+        }
+        Method(_L08) {
+        }
+        Method(_L09) {
+        }
+        Method(_L0A) {
+        }
+        Method(_L0B) {
+        }
+        Method(_L0C) {
+        }
+        Method(_L0D) {
+        }
+        Method(_L0E) {
+        }
+        Method(_L0F) {
+        }
+    }
+}
diff --git a/src/mainboard/emulation/qemu-q35/mainboard.c b/src/mainboard/emulation/qemu-q35/mainboard.c
new file mode 100644
index 0000000..c2f7346
--- /dev/null
+++ b/src/mainboard/emulation/qemu-q35/mainboard.c
@@ -0,0 +1,89 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Stefan Reinauer <stefan.reinauer at coreboot.org>
+ * Copyright (C) 2010 Kevin O'Connor <kevin at koconnor.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <device/device.h>
+#include <device/pci.h>
+#include <device/pci_ids.h>
+#include <device/pci_ops.h>
+#include <pc80/keyboard.h>
+#include <arch/io.h>
+#include <console/console.h>
+
+#define Q35_PAM0            0x90
+#define Q35_PCIEXBAR_ADDR   0xb0000000
+
+static const unsigned char qemu_q35_irqs[] = {
+	10, 10, 11, 11,
+	10, 10, 11, 11,
+};
+
+static void qemu_nb_init(device_t dev)
+{
+	/* Map memory at 0xc0000 - 0xfffff */
+	int i;
+	uint8_t v = pci_read_config8(dev, Q35_PAM0);
+	v |= 0x30;
+	pci_write_config8(dev, Q35_PAM0, v);
+	pci_write_config8(dev, Q35_PAM0 + 1, 0x33);
+	pci_write_config8(dev, Q35_PAM0 + 2, 0x33);
+	pci_write_config8(dev, Q35_PAM0 + 3, 0x33);
+	pci_write_config8(dev, Q35_PAM0 + 4, 0x33);
+	pci_write_config8(dev, Q35_PAM0 + 5, 0x33);
+	pci_write_config8(dev, Q35_PAM0 + 6, 0x33);
+
+	/* This sneaked in here, because Qemu does not
+	 * emulate a SuperIO chip
+	 */
+	pc_keyboard_init(0);
+
+	/* setup IRQ routing for pci slots */
+	for (i = 0; i < 25; i++)
+		pci_assign_irqs(0, i, qemu_q35_irqs + (i % 4));
+	/* setup IRQ routing southbridge devices */
+	for (i = 25; i < 32; i++)
+		pci_assign_irqs(0, i, qemu_q35_irqs);
+
+	/* setup mmconfig */
+	pci_write_config32(dev, 0x60, Q35_PCIEXBAR_ADDR | 1);
+}
+
+static void qemu_nb_read_resources(struct device *dev)
+{
+	pci_dev_read_resources(dev);
+
+	/* reserve mmconfig */
+	fixed_mem_resource(dev, 2, Q35_PCIEXBAR_ADDR >> 10, 0x10000000 >> 10,
+			   IORESOURCE_RESERVE);
+}
+
+
+static struct device_operations nb_operations = {
+ 	.read_resources   = qemu_nb_read_resources,
+ 	.set_resources    = pci_dev_set_resources,
+ 	.enable_resources = pci_dev_enable_resources,
+ 	.init             = qemu_nb_init,
+	.ops_pci          = 0,
+};
+
+static const struct pci_driver nb_driver __pci_driver = {
+	.ops = &nb_operations,
+	.vendor = 0x8086,
+	.device = 0x29c0,
+};
diff --git a/src/mainboard/emulation/qemu-q35/romstage.c b/src/mainboard/emulation/qemu-q35/romstage.c
new file mode 100644
index 0000000..1104ba8
--- /dev/null
+++ b/src/mainboard/emulation/qemu-q35/romstage.c
@@ -0,0 +1,63 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2004 Stefan Reinauer
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+#include <device/pci_def.h>
+#include <device/pci_ids.h>
+#include <arch/io.h>
+#include <device/pnp_def.h>
+#include <arch/hlt.h>
+#include <pc80/mc146818rtc.h>
+#include <console/console.h>
+#include <southbridge/intel/i82801ix/i82801ix.h>
+#include <cpu/x86/bist.h>
+#include <timestamp.h>
+#include "drivers/pc80/udelay_io.c"
+#include "lib/delay.c"
+#include "cpu/x86/lapic/boot_cpu.c"
+
+#include "../qemu-x86/memory.c"
+
+void main(unsigned long bist)
+{
+	int cbmem_was_initted;
+
+	/* init_timer(); */
+	post_code(0x05);
+
+	i82801ix_early_init();
+	console_init();
+
+	/* Halt if there was a built in self test failure */
+	report_bist_failure(bist);
+
+	//print_pci_devices();
+	//dump_pci_devices();
+
+	cbmem_was_initted = !cbmem_initialize();
+#if CONFIG_COLLECT_TIMESTAMPS
+	timestamp_init(rdtsc());
+	timestamp_add_now(TS_START_ROMSTAGE);
+#endif
+#if CONFIG_CONSOLE_CBMEM
+	/* Keep this the last thing this function does. */
+	cbmemc_reinit();
+#endif
+
+}
diff --git a/src/mainboard/emulation/qemu-x86/northbridge.c b/src/mainboard/emulation/qemu-x86/northbridge.c
index c2e4ba2..0e540d7 100644
--- a/src/mainboard/emulation/qemu-x86/northbridge.c
+++ b/src/mainboard/emulation/qemu-x86/northbridge.c
@@ -189,3 +189,8 @@ struct chip_operations mainboard_emulation_qemu_i440fx_ops = {
 	CHIP_NAME("QEMU Northbridge i440fx")
 	.enable_dev = northbridge_enable,
 };
+
+struct chip_operations mainboard_emulation_qemu_q35_ops = {
+	CHIP_NAME("QEMU Northbridge q35")
+	.enable_dev = northbridge_enable,
+};



More information about the coreboot-gerrit mailing list