From patchwork Wed Nov 14 20:54:04 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Baron X-Patchwork-Id: 199034 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id BB13B2C00A3 for ; Thu, 15 Nov 2012 08:59:29 +1100 (EST) Received: from localhost ([::1]:51293 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TYjzJ-0000Eq-1n for incoming@patchwork.ozlabs.org; Wed, 14 Nov 2012 15:55:09 -0500 Received: from eggs.gnu.org ([208.118.235.92]:53089) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TYjyN-0006oA-Fv for qemu-devel@nongnu.org; Wed, 14 Nov 2012 15:54:14 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TYjyK-0004QV-Dc for qemu-devel@nongnu.org; Wed, 14 Nov 2012 15:54:11 -0500 Received: from mx1.redhat.com ([209.132.183.28]:31330) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TYjyK-0004Q7-2v for qemu-devel@nongnu.org; Wed, 14 Nov 2012 15:54:08 -0500 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id qAEKs4Wh006406 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 14 Nov 2012 15:54:05 -0500 Received: from redhat.com (dhcp-185-114.bos.redhat.com [10.16.185.114]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id qAEKs4FH032158; Wed, 14 Nov 2012 15:54:04 -0500 Date: Wed, 14 Nov 2012 15:54:04 -0500 From: Jason Baron To: anthony@codemonkey.ws, qemu-devel@nongnu.org Message-Id: <6b52ebdd548a797ef093a4a0541b051e145258d6.1352922993.git.jbaron@redhat.com> In-Reply-To: References: X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: alex.williamson@redhat.com, mst@redhat.com, jan.kiszka@siemens.com, armbru@redhat.com, agraf@suse.de, blauwirbel@gmail.com, yamahata@valinux.co.jp, juzhang@redhat.com, kevin@koconnor.net, kraxel@redhat.com, gsomlo@gmail.com, mkletzan@redhat.com, pbonzini@redhat.com, lcapitulino@redhat.com, afaerber@suse.de Subject: [Qemu-devel] [PATCH v4 05/14] ich9: Add acpi support and definitions X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Jason Baron Lay the groundwork for subsequent ich9 support. Signed-off-by: Isaku Yamahata Signed-off-by: Jason Baron --- hw/Makefile.objs | 1 + hw/acpi_ich9.c | 315 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ hw/acpi_ich9.h | 47 ++++++++ hw/ich9.h | 207 +++++++++++++++++++++++++++++++++++ hw/pci_ids.h | 12 ++ 5 files changed, 582 insertions(+), 0 deletions(-) create mode 100644 hw/acpi_ich9.c create mode 100644 hw/acpi_ich9.h create mode 100644 hw/ich9.h diff --git a/hw/Makefile.objs b/hw/Makefile.objs index be9ef83..0d1348c 100644 --- a/hw/Makefile.objs +++ b/hw/Makefile.objs @@ -38,6 +38,7 @@ common-obj-$(CONFIG_SMARTCARD_NSS) += ccid-card-emulated.o common-obj-$(CONFIG_I8259) += i8259_common.o i8259.o common-obj-y += fifo.o common-obj-y += pam.o +common-obj-y += acpi_ich9.o # PPC devices common-obj-$(CONFIG_PREP_PCI) += prep_pci.o diff --git a/hw/acpi_ich9.c b/hw/acpi_ich9.c new file mode 100644 index 0000000..c45921c --- /dev/null +++ b/hw/acpi_ich9.c @@ -0,0 +1,315 @@ +/* + * ACPI implementation + * + * 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, see + */ +/* + * Copyright (c) 2009 Isaku Yamahata + * VA Linux Systems Japan K.K. + * Copyright (C) 2012 Jason Baron + * + * This is based on acpi.c. + */ +#include "hw.h" +#include "pc.h" +#include "pci.h" +#include "qemu-timer.h" +#include "sysemu.h" +#include "acpi.h" + +#include "ich9.h" + +//#define DEBUG + +#ifdef DEBUG +#define ICH9_DEBUG(fmt, ...) \ +do { printf("%s "fmt, __func__, ## __VA_ARGS__); } while (0) +#else +#define ICH9_DEBUG(fmt, ...) do { } while (0) +#endif + +static void pm_ioport_write_fallback(void *opaque, uint32_t addr, int len, + uint32_t val); +static uint32_t pm_ioport_read_fallback(void *opaque, uint32_t addr, int len); + +static void pm_update_sci(ICH9LPCPMRegs *pm) +{ + int sci_level, pm1a_sts; + + pm1a_sts = acpi_pm1_evt_get_sts(&pm->acpi_regs); + + sci_level = (((pm1a_sts & pm->acpi_regs.pm1.evt.en) & + (ACPI_BITMASK_RT_CLOCK_ENABLE | + ACPI_BITMASK_POWER_BUTTON_ENABLE | + ACPI_BITMASK_GLOBAL_LOCK_ENABLE | + ACPI_BITMASK_TIMER_ENABLE)) != 0); + qemu_set_irq(pm->irq, sci_level); + + /* schedule a timer interruption if needed */ + acpi_pm_tmr_update(&pm->acpi_regs, + (pm->acpi_regs.pm1.evt.en & ACPI_BITMASK_TIMER_ENABLE) && + !(pm1a_sts & ACPI_BITMASK_TIMER_STATUS)); +} + +static void ich9_pm_update_sci_fn(ACPIREGS *regs) +{ + ICH9LPCPMRegs *pm = container_of(regs, ICH9LPCPMRegs, acpi_regs); + pm_update_sci(pm); +} + +static void pm_ioport_writeb(void *opaque, uint32_t addr, uint32_t val) +{ + ICH9LPCPMRegs *pm = opaque; + + switch (addr & ICH9_PMIO_MASK) { + case ICH9_PMIO_GPE0_STS ... (ICH9_PMIO_GPE0_STS + ICH9_PMIO_GPE0_LEN - 1): + acpi_gpe_ioport_writeb(&pm->acpi_regs, addr, val); + break; + default: + break; + } + + ICH9_DEBUG("port=0x%04x val=0x%04x\n", addr, val); +} + +static uint32_t pm_ioport_readb(void *opaque, uint32_t addr) +{ + ICH9LPCPMRegs *pm = opaque; + uint32_t val = 0; + + switch (addr & ICH9_PMIO_MASK) { + case ICH9_PMIO_GPE0_STS ... (ICH9_PMIO_GPE0_STS + ICH9_PMIO_GPE0_LEN - 1): + val = acpi_gpe_ioport_readb(&pm->acpi_regs, addr); + break; + default: + val = 0; + break; + } + ICH9_DEBUG("port=0x%04x val=0x%04x\n", addr, val); + return val; +} + +static void pm_ioport_writew(void *opaque, uint32_t addr, uint32_t val) +{ + ICH9LPCPMRegs *pm = opaque; + + switch (addr & ICH9_PMIO_MASK) { + case ICH9_PMIO_PM1_STS: + acpi_pm1_evt_write_sts(&pm->acpi_regs, val); + pm_update_sci(pm); + break; + case ICH9_PMIO_PM1_EN: + pm->acpi_regs.pm1.evt.en = val; + pm_update_sci(pm); + break; + case ICH9_PMIO_PM1_CNT: + acpi_pm1_cnt_write(&pm->acpi_regs, val, 0); + break; + default: + pm_ioport_write_fallback(opaque, addr, 2, val); + break; + } + ICH9_DEBUG("port=0x%04x val=0x%04x\n", addr, val); +} + +static uint32_t pm_ioport_readw(void *opaque, uint32_t addr) +{ + ICH9LPCPMRegs *pm = opaque; + uint32_t val; + + switch (addr & ICH9_PMIO_MASK) { + case ICH9_PMIO_PM1_STS: + val = acpi_pm1_evt_get_sts(&pm->acpi_regs); + break; + case ICH9_PMIO_PM1_EN: + val = pm->acpi_regs.pm1.evt.en; + break; + case ICH9_PMIO_PM1_CNT: + val = pm->acpi_regs.pm1.cnt.cnt; + break; + default: + val = pm_ioport_read_fallback(opaque, addr, 2); + break; + } + ICH9_DEBUG("port=0x%04x val=0x%04x\n", addr, val); + return val; +} + +static void pm_ioport_writel(void *opaque, uint32_t addr, uint32_t val) +{ + ICH9LPCPMRegs *pm = opaque; + + switch (addr & ICH9_PMIO_MASK) { + case ICH9_PMIO_SMI_EN: + pm->smi_en = val; + break; + default: + pm_ioport_write_fallback(opaque, addr, 4, val); + break; + } + ICH9_DEBUG("port=0x%04x val=0x%08x\n", addr, val); +} + +static uint32_t pm_ioport_readl(void *opaque, uint32_t addr) +{ + ICH9LPCPMRegs *pm = opaque; + uint32_t val; + + switch (addr & ICH9_PMIO_MASK) { + case ICH9_PMIO_PM1_TMR: + val = acpi_pm_tmr_get(&pm->acpi_regs); + break; + case ICH9_PMIO_SMI_EN: + val = pm->smi_en; + break; + + default: + val = pm_ioport_read_fallback(opaque, addr, 4); + break; + } + ICH9_DEBUG("port=0x%04x val=0x%08x\n", addr, val); + return val; +} + +static void pm_ioport_write_fallback(void *opaque, uint32_t addr, int len, + uint32_t val) + { + int subsize = (len == 4) ? 2 : 1; + IOPortWriteFunc *ioport_write = + (subsize == 2) ? pm_ioport_writew : pm_ioport_writeb; + + int i; + + for (i = 0; i < len; i += subsize) { + ioport_write(opaque, addr, val); + val >>= 8 * subsize; + } +} + +static uint32_t pm_ioport_read_fallback(void *opaque, uint32_t addr, int len) +{ + int subsize = (len == 4) ? 2 : 1; + IOPortReadFunc *ioport_read = + (subsize == 2) ? pm_ioport_readw : pm_ioport_readb; + + uint32_t val; + int i; + + val = 0; + for (i = 0; i < len; i += subsize) { + val <<= 8 * subsize; + val |= ioport_read(opaque, addr); + } + + return val; +} + +void ich9_pm_iospace_update(ICH9LPCPMRegs *pm, uint32_t pm_io_base) +{ + ICH9_DEBUG("to 0x%x\n", pm_io_base); + + assert((pm_io_base & ICH9_PMIO_MASK) == 0); + + if (pm->pm_io_base != 0) { + isa_unassign_ioport(pm->pm_io_base, ICH9_PMIO_SIZE); + } + + /* don't map at 0 */ + if (pm_io_base == 0) { + return; + } + + register_ioport_write(pm_io_base, ICH9_PMIO_SIZE, 1, pm_ioport_writeb, pm); + register_ioport_read(pm_io_base, ICH9_PMIO_SIZE, 1, pm_ioport_readb, pm); + register_ioport_write(pm_io_base, ICH9_PMIO_SIZE, 2, pm_ioport_writew, pm); + register_ioport_read(pm_io_base, ICH9_PMIO_SIZE, 2, pm_ioport_readw, pm); + register_ioport_write(pm_io_base, ICH9_PMIO_SIZE, 4, pm_ioport_writel, pm); + register_ioport_read(pm_io_base, ICH9_PMIO_SIZE, 4, pm_ioport_readl, pm); + + pm->pm_io_base = pm_io_base; + acpi_gpe_blk(&pm->acpi_regs, pm_io_base + ICH9_PMIO_GPE0_STS); +} + +static int ich9_pm_post_load(void *opaque, int version_id) +{ + ICH9LPCPMRegs *pm = opaque; + uint32_t pm_io_base = pm->pm_io_base; + pm->pm_io_base = 0; + ich9_pm_iospace_update(pm, pm_io_base); + return 0; +} + +#define VMSTATE_GPE_ARRAY(_field, _state) \ + { \ + .name = (stringify(_field)), \ + .version_id = 0, \ + .num = ICH9_PMIO_GPE0_LEN, \ + .info = &vmstate_info_uint8, \ + .size = sizeof(uint8_t), \ + .flags = VMS_ARRAY | VMS_POINTER, \ + .offset = vmstate_offset_pointer(_state, _field, uint8_t), \ + } + +const VMStateDescription vmstate_ich9_pm = { + .name = "ich9_pm", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, + .post_load = ich9_pm_post_load, + .fields = (VMStateField[]) { + VMSTATE_UINT16(acpi_regs.pm1.evt.sts, ICH9LPCPMRegs), + VMSTATE_UINT16(acpi_regs.pm1.evt.en, ICH9LPCPMRegs), + VMSTATE_UINT16(acpi_regs.pm1.cnt.cnt, ICH9LPCPMRegs), + VMSTATE_TIMER(acpi_regs.tmr.timer, ICH9LPCPMRegs), + VMSTATE_INT64(acpi_regs.tmr.overflow_time, ICH9LPCPMRegs), + VMSTATE_GPE_ARRAY(acpi_regs.gpe.sts, ICH9LPCPMRegs), + VMSTATE_GPE_ARRAY(acpi_regs.gpe.en, ICH9LPCPMRegs), + VMSTATE_UINT32(smi_en, ICH9LPCPMRegs), + VMSTATE_UINT32(smi_sts, ICH9LPCPMRegs), + VMSTATE_END_OF_LIST() + } +}; + +static void pm_reset(void *opaque) +{ + ICH9LPCPMRegs *pm = opaque; + ich9_pm_iospace_update(pm, 0); + + acpi_pm1_evt_reset(&pm->acpi_regs); + acpi_pm1_cnt_reset(&pm->acpi_regs); + acpi_pm_tmr_reset(&pm->acpi_regs); + acpi_gpe_reset(&pm->acpi_regs); + + pm_update_sci(pm); +} + +static void pm_powerdown_req(Notifier *n, void *opaque) +{ + ICH9LPCPMRegs *pm = container_of(n, ICH9LPCPMRegs, powerdown_notifier); + + acpi_pm1_evt_power_down(&pm->acpi_regs); +} + +void ich9_pm_init(ICH9LPCPMRegs *pm, qemu_irq sci_irq, qemu_irq cmos_s3) +{ + acpi_pm_tmr_init(&pm->acpi_regs, ich9_pm_update_sci_fn); + acpi_pm1_cnt_init(&pm->acpi_regs); + acpi_gpe_init(&pm->acpi_regs, ICH9_PMIO_GPE0_LEN); + + pm->irq = sci_irq; + qemu_register_reset(pm_reset, pm); + pm->powerdown_notifier.notify = pm_powerdown_req; + qemu_register_powerdown_notifier(&pm->powerdown_notifier); +} diff --git a/hw/acpi_ich9.h b/hw/acpi_ich9.h new file mode 100644 index 0000000..180c406 --- /dev/null +++ b/hw/acpi_ich9.h @@ -0,0 +1,47 @@ +/* + * QEMU GMCH/ICH9 LPC PM Emulation + * + * Copyright (c) 2009 Isaku Yamahata + * VA Linux Systems Japan K.K. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * 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, see + */ + +#ifndef HW_ACPI_ICH9_H +#define HW_ACPI_ICH9_H + +#include "acpi.h" + +typedef struct ICH9LPCPMRegs { + /* + * In ich9 spec says that pm1_cnt register is 32bit width and + * that the upper 16bits are reserved and unused. + * PM1a_CNT_BLK = 2 in FADT so it is defined as uint16_t. + */ + ACPIREGS acpi_regs; + uint32_t smi_en; + uint32_t smi_sts; + + qemu_irq irq; /* SCI */ + + uint32_t pm_io_base; + Notifier powerdown_notifier; +} ICH9LPCPMRegs; + +void ich9_pm_init(ICH9LPCPMRegs *pm, + qemu_irq sci_irq, qemu_irq cmos_s3_resume); +void ich9_pm_iospace_update(ICH9LPCPMRegs *pm, uint32_t pm_io_base); +extern const VMStateDescription vmstate_ich9_pm; + +#endif /* HW_ACPI_ICH9_H */ diff --git a/hw/ich9.h b/hw/ich9.h new file mode 100644 index 0000000..de49135 --- /dev/null +++ b/hw/ich9.h @@ -0,0 +1,207 @@ +#ifndef HW_ICH9_H +#define HW_ICH9_H + +#include "hw.h" +#include "range.h" +#include "isa.h" +#include "sysbus.h" +#include "pc.h" +#include "apm.h" +#include "ioapic.h" +#include "pci.h" +#include "pcie_host.h" +#include "pci_bridge.h" +#include "acpi.h" +#include "acpi_ich9.h" +#include "pam.h" +#include "pci_internals.h" + +void ich9_lpc_set_irq(void *opaque, int irq_num, int level); +int ich9_lpc_map_irq(PCIDevice *pci_dev, int intx); +void ich9_lpc_pm_init(PCIDevice *pci_lpc, qemu_irq cmos_s3); +PCIBus *ich9_d2pbr_init(PCIBus *bus, int devfn, int sec_bus); +i2c_bus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t smb_io_base); + +#define ICH9_CC_SIZE (16 * 1024) /* 16KB */ + +#define TYPE_ICH9_LPC_DEVICE "ICH9 LPC" +#define ICH9_LPC_DEVICE(obj) \ + OBJECT_CHECK(ICH9LPCState, (obj), TYPE_ICH9_LPC_DEVICE) + +typedef struct ICH9LPCState { + /* ICH9 LPC PCI to ISA bridge */ + PCIDevice d; + + /* (pci device, intx) -> pirq + * In real chipset case, the unused slots are never used + * as ICH9 supports only D25-D32 irq routing. + * On the other hand in qemu case, any slot/function can be populated + * via command line option. + * So fallback interrupt routing for any devices in any slots is necessary. + */ + uint8_t irr[PCI_SLOT_MAX][PCI_NUM_PINS]; + + APMState apm; + ICH9LPCPMRegs pm; + uint32_t sci_level; /* track sci level */ + + /* 10.1 Chipset Configuration registers(Memory Space) + which is pointed by RCBA */ + uint8_t chip_config[ICH9_CC_SIZE]; + /* isa bus */ + ISABus *isa_bus; + MemoryRegion rbca_mem; + + qemu_irq *pic; + qemu_irq *ioapic; +} ICH9LPCState; + +#define Q35_MASK(bit, ms_bit, ls_bit) \ +((uint##bit##_t)(((1ULL << ((ms_bit) + 1)) - 1) & ~((1ULL << ls_bit) - 1))) + +/* ICH9: Chipset Configuration Registers */ +#define ICH9_CC_ADDR_MASK (ICH9_CC_SIZE - 1) + +#define ICH9_CC +#define ICH9_CC_D28IP 0x310C +#define ICH9_CC_D28IP_SHIFT 4 +#define ICH9_CC_D28IP_MASK 0xf +#define ICH9_CC_D28IP_DEFAULT 0x00214321 +#define ICH9_CC_D31IR 0x3140 +#define ICH9_CC_D30IR 0x3142 +#define ICH9_CC_D29IR 0x3144 +#define ICH9_CC_D28IR 0x3146 +#define ICH9_CC_D27IR 0x3148 +#define ICH9_CC_D26IR 0x314C +#define ICH9_CC_D25IR 0x3150 +#define ICH9_CC_DIR_DEFAULT 0x3210 +#define ICH9_CC_D30IR_DEFAULT 0x0 +#define ICH9_CC_DIR_SHIFT 4 +#define ICH9_CC_DIR_MASK 0x7 +#define ICH9_CC_OIC 0x31FF +#define ICH9_CC_OIC_AEN 0x1 + +/* D28:F[0-5] */ +#define ICH9_PCIE_DEV 28 +#define ICH9_PCIE_FUNC_MAX 6 + + +/* D29:F0 USB UHCI Controller #1 */ +#define ICH9_USB_UHCI1_DEV 29 +#define ICH9_USB_UHCI1_FUNC 0 + +/* D30:F0 DMI-to-PCI brdige */ +#define ICH9_D2P_BRIDGE "ICH9 D2P BRIDGE" +#define ICH9_D2P_BRIDGE_SAVEVM_VERSION 0 + +#define ICH9_D2P_BRIDGE_DEV 30 +#define ICH9_D2P_BRIDGE_FUNC 0 + +#define ICH9_D2P_SECONDARY_DEFAULT (256 - 8) + +#define ICH9_D2P_A2_REVISION 0x92 + + +/* D31:F1 LPC controller */ +#define ICH9_A2_LPC "ICH9 A2 LPC" +#define ICH9_A2_LPC_SAVEVM_VERSION 0 + +#define ICH9_LPC_DEV 31 +#define ICH9_LPC_FUNC 0 + +#define ICH9_A2_LPC_REVISION 0x2 +#define ICH9_LPC_NB_PIRQS 8 /* PCI A-H */ + +#define ICH9_LPC_PMBASE 0x40 +#define ICH9_LPC_PMBASE_BASE_ADDRESS_MASK Q35_MASK(32, 15, 7) +#define ICH9_LPC_PMBASE_RTE 0x1 +#define ICH9_LPC_PMBASE_DEFAULT 0x1 +#define ICH9_LPC_ACPI_CTRL 0x44 +#define ICH9_LPC_ACPI_CTRL_ACPI_EN 0x80 +#define ICH9_LPC_ACPI_CTRL_SCI_IRQ_SEL_MASK Q35_MASK(8, 2, 0) +#define ICH9_LPC_ACPI_CTRL_9 0x0 +#define ICH9_LPC_ACPI_CTRL_10 0x1 +#define ICH9_LPC_ACPI_CTRL_11 0x2 +#define ICH9_LPC_ACPI_CTRL_20 0x4 +#define ICH9_LPC_ACPI_CTRL_21 0x5 +#define ICH9_LPC_ACPI_CTRL_DEFAULT 0x0 + +#define ICH9_LPC_PIRQA_ROUT 0x60 +#define ICH9_LPC_PIRQB_ROUT 0x61 +#define ICH9_LPC_PIRQC_ROUT 0x62 +#define ICH9_LPC_PIRQD_ROUT 0x63 + +#define ICH9_LPC_PIRQE_ROUT 0x68 +#define ICH9_LPC_PIRQF_ROUT 0x69 +#define ICH9_LPC_PIRQG_ROUT 0x6a +#define ICH9_LPC_PIRQH_ROUT 0x6b + +#define ICH9_LPC_PIRQ_ROUT_IRQEN 0x80 +#define ICH9_LPC_PIRQ_ROUT_MASK Q35_MASK(8, 3, 0) +#define ICH9_LPC_PIRQ_ROUT_DEFAULT 0x80 + +#define ICH9_LPC_RCBA 0xf0 +#define ICH9_LPC_RCBA_BA_MASK Q35_MASK(32, 31, 14) +#define ICH9_LPC_RCBA_EN 0x1 +#define ICH9_LPC_RCBA_DEFAULT 0x0 + +#define ICH9_LPC_PIC_NUM_PINS 16 +#define ICH9_LPC_IOAPIC_NUM_PINS 24 + +/* D31:F2 SATA Controller #1 */ +#define ICH9_SATA1_DEV 31 +#define ICH9_SATA1_FUNC 2 + +/* D30:F1 power management I/O registers + offset from the address ICH9_LPC_PMBASE */ + +/* ICH9 LPC PM I/O registers are 128 ports and 128-aligned */ +#define ICH9_PMIO_SIZE 128 +#define ICH9_PMIO_MASK (ICH9_PMIO_SIZE - 1) + +#define ICH9_PMIO_PM1_STS 0x00 +#define ICH9_PMIO_PM1_EN 0x02 +#define ICH9_PMIO_PM1_CNT 0x04 +#define ICH9_PMIO_PM1_TMR 0x08 +#define ICH9_PMIO_GPE0_STS 0x20 +#define ICH9_PMIO_GPE0_EN 0x28 +#define ICH9_PMIO_GPE0_LEN 16 +#define ICH9_PMIO_SMI_EN 0x30 +#define ICH9_PMIO_SMI_EN_APMC_EN (1 << 5) +#define ICH9_PMIO_SMI_STS 0x34 + +/* FADT ACPI_ENABLE/ACPI_DISABLE */ +#define ICH9_APM_ACPI_ENABLE 0x2 +#define ICH9_APM_ACPI_DISABLE 0x3 + + +/* D31:F3 SMBus controller */ +#define ICH9_A2_SMB_REVISION 0x02 +#define ICH9_SMB_PI 0x00 + +#define ICH9_SMB_SMBMBAR0 0x10 +#define ICH9_SMB_SMBMBAR1 0x14 +#define ICH9_SMB_SMBM_BAR 0 +#define ICH9_SMB_SMBM_SIZE (1 << 8) +#define ICH9_SMB_SMB_BASE 0x20 +#define ICH9_SMB_SMB_BASE_BAR 4 +#define ICH9_SMB_SMB_BASE_SIZE (1 << 5) +#define ICH9_SMB_HOSTC 0x40 +#define ICH9_SMB_HOSTC_SSRESET ((uint8_t)(1 << 3)) +#define ICH9_SMB_HOSTC_I2C_EN ((uint8_t)(1 << 2)) +#define ICH9_SMB_HOSTC_SMB_SMI_EN ((uint8_t)(1 << 1)) +#define ICH9_SMB_HOSTC_HST_EN ((uint8_t)(1 << 0)) + +/* D31:F3 SMBus I/O and memory mapped I/O registers */ +#define ICH9_SMB_DEV 31 +#define ICH9_SMB_FUNC 3 + +#define ICH9_SMB_HST_STS 0x00 +#define ICH9_SMB_HST_CNT 0x02 +#define ICH9_SMB_HST_CMD 0x03 +#define ICH9_SMB_XMIT_SLVA 0x04 +#define ICH9_SMB_HST_D0 0x05 +#define ICH9_SMB_HST_D1 0x06 +#define ICH9_SMB_HOST_BLOCK_DB 0x07 + +#endif /* HW_ICH9_H */ diff --git a/hw/pci_ids.h b/hw/pci_ids.h index 41f3570..d1e83dd 100644 --- a/hw/pci_ids.h +++ b/hw/pci_ids.h @@ -36,6 +36,7 @@ #define PCI_CLASS_BRIDGE_HOST 0x0600 #define PCI_CLASS_BRIDGE_ISA 0x0601 #define PCI_CLASS_BRIDGE_PCI 0x0604 +#define PCI_CLASS_BRDIGE_PCI_INF_SUB 0x01 #define PCI_CLASS_BRIDGE_OTHER 0x0680 #define PCI_CLASS_COMMUNICATION_SERIAL 0x0700 @@ -116,6 +117,17 @@ #define PCI_DEVICE_ID_INTEL_82371AB 0x7111 #define PCI_DEVICE_ID_INTEL_82371AB_2 0x7112 #define PCI_DEVICE_ID_INTEL_82371AB_3 0x7113 + +#define PCI_DEVICE_ID_INTEL_ICH9_0 0x2910 +#define PCI_DEVICE_ID_INTEL_ICH9_1 0x2917 +#define PCI_DEVICE_ID_INTEL_ICH9_2 0x2912 +#define PCI_DEVICE_ID_INTEL_ICH9_3 0x2913 +#define PCI_DEVICE_ID_INTEL_ICH9_4 0x2914 +#define PCI_DEVICE_ID_INTEL_ICH9_5 0x2919 +#define PCI_DEVICE_ID_INTEL_ICH9_6 0x2930 +#define PCI_DEVICE_ID_INTEL_ICH9_7 0x2916 +#define PCI_DEVICE_ID_INTEL_ICH9_8 0x2918 + #define PCI_DEVICE_ID_INTEL_82801I_UHCI1 0x2934 #define PCI_DEVICE_ID_INTEL_82801I_UHCI2 0x2935 #define PCI_DEVICE_ID_INTEL_82801I_UHCI3 0x2936