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@redhat.com> Reviewed-on: http://review.coreboot.org/3430 Reviewed-by: Paul Menzel <paulepanter@users.sourceforge.net> Tested-by: build bot (Jenkins) Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
This commit is contained in:
committed by
Ronald G. Minnich
parent
9839a385bb
commit
ee941b38d6
@ -19,3 +19,4 @@
|
|||||||
ramstage-y += qemu.c
|
ramstage-y += qemu.c
|
||||||
subdirs-y += ../x86/mtrr
|
subdirs-y += ../x86/mtrr
|
||||||
subdirs-y += ../x86/lapic
|
subdirs-y += ../x86/lapic
|
||||||
|
subdirs-y += ../x86/smm
|
||||||
|
@ -6,6 +6,9 @@ choice
|
|||||||
config BOARD_EMULATION_QEMU_X86_I440FX
|
config BOARD_EMULATION_QEMU_X86_I440FX
|
||||||
bool "QEMU x86 i440fx/piix4 (aka qemu -M pc)"
|
bool "QEMU x86 i440fx/piix4 (aka qemu -M pc)"
|
||||||
|
|
||||||
|
config BOARD_EMULATION_QEMU_X86_Q35
|
||||||
|
bool "QEMU x86 q35/ich9 (aka qemu -M q35, since v1.4)"
|
||||||
|
|
||||||
config BOARD_EMULATION_QEMU_ARMV7
|
config BOARD_EMULATION_QEMU_ARMV7
|
||||||
bool "QEMU armv7 (vexpress-a9)"
|
bool "QEMU armv7 (vexpress-a9)"
|
||||||
|
|
||||||
@ -14,9 +17,10 @@ endchoice
|
|||||||
config BOARD_EMULATION_QEMU_X86
|
config BOARD_EMULATION_QEMU_X86
|
||||||
bool
|
bool
|
||||||
default y
|
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-i440fx/Kconfig"
|
||||||
|
source "src/mainboard/emulation/qemu-q35/Kconfig"
|
||||||
source "src/mainboard/emulation/qemu-armv7/Kconfig"
|
source "src/mainboard/emulation/qemu-armv7/Kconfig"
|
||||||
|
|
||||||
config MAINBOARD_VENDOR
|
config MAINBOARD_VENDOR
|
||||||
|
@ -195,3 +195,8 @@ struct chip_operations mainboard_emulation_qemu_i440fx_ops = {
|
|||||||
CHIP_NAME("QEMU Northbridge i440fx")
|
CHIP_NAME("QEMU Northbridge i440fx")
|
||||||
.enable_dev = northbridge_enable,
|
.enable_dev = northbridge_enable,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct chip_operations mainboard_emulation_qemu_q35_ops = {
|
||||||
|
CHIP_NAME("QEMU Northbridge q35")
|
||||||
|
.enable_dev = northbridge_enable,
|
||||||
|
};
|
||||||
|
39
src/mainboard/emulation/qemu-q35/Kconfig
Normal file
39
src/mainboard/emulation/qemu-q35/Kconfig
Normal file
@ -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
|
3
src/mainboard/emulation/qemu-q35/Makefile.inc
Normal file
3
src/mainboard/emulation/qemu-q35/Makefile.inc
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
cpu_incs += $(src)/mainboard/emulation/qemu-i440fx/cache_as_ram.inc
|
||||||
|
ramstage-y += ../qemu-i440fx/northbridge.c
|
||||||
|
ramstage-y += ../qemu-i440fx/fw_cfg.c
|
339
src/mainboard/emulation/qemu-q35/acpi_tables.c
Normal file
339
src/mainboard/emulation/qemu-q35/acpi_tables.c
Normal file
@ -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;
|
||||||
|
}
|
41
src/mainboard/emulation/qemu-q35/devicetree.cb
Normal file
41
src/mainboard/emulation/qemu-q35/devicetree.cb
Normal file
@ -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
|
454
src/mainboard/emulation/qemu-q35/dsdt.asl
Normal file
454
src/mainboard/emulation/qemu-q35/dsdt.asl
Normal file
@ -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-i440fx/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-i440fx/acpi/pci-crs.asl"
|
||||||
|
#include "../qemu-i440fx/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-i440fx/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-i440fx/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) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
89
src/mainboard/emulation/qemu-q35/mainboard.c
Normal file
89
src/mainboard/emulation/qemu-q35/mainboard.c
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of the coreboot project.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2004 Stefan Reinauer <stefan.reinauer@coreboot.org>
|
||||||
|
* Copyright (C) 2010 Kevin O'Connor <kevin@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,
|
||||||
|
};
|
63
src/mainboard/emulation/qemu-q35/romstage.c
Normal file
63
src/mainboard/emulation/qemu-q35/romstage.c
Normal file
@ -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-i440fx/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
|
||||||
|
|
||||||
|
}
|
Reference in New Issue
Block a user