aboutsummaryrefslogtreecommitdiff
path: root/include/hw
diff options
context:
space:
mode:
Diffstat (limited to 'include/hw')
-rw-r--r--include/hw/acpi/ich9.h8
-rw-r--r--include/hw/acpi/tco.h82
-rw-r--r--include/hw/boards.h3
-rw-r--r--include/hw/i386/ich9.h11
-rw-r--r--include/hw/i386/pc.h1
5 files changed, 102 insertions, 3 deletions
diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h
index ac24bbe9a3..345fd8d92b 100644
--- a/include/hw/acpi/ich9.h
+++ b/include/hw/acpi/ich9.h
@@ -25,6 +25,7 @@
#include "hw/acpi/cpu_hotplug.h"
#include "hw/acpi/memory_hotplug.h"
#include "hw/acpi/acpi_dev_interface.h"
+#include "hw/acpi/tco.h"
typedef struct ICH9LPCPMRegs {
/*
@@ -55,10 +56,15 @@ typedef struct ICH9LPCPMRegs {
uint8_t disable_s4;
uint8_t s4_val;
uint8_t smm_enabled;
+ bool enable_tco;
+ TCOIORegs tco_regs;
} ICH9LPCPMRegs;
void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm,
- bool smm_enabled, qemu_irq sci_irq);
+ bool smm_enabled,
+ bool enable_tco,
+ qemu_irq sci_irq);
+
void ich9_pm_iospace_update(ICH9LPCPMRegs *pm, uint32_t pm_io_base);
extern const VMStateDescription vmstate_ich9_pm;
diff --git a/include/hw/acpi/tco.h b/include/hw/acpi/tco.h
new file mode 100644
index 0000000000..c63afc8ca3
--- /dev/null
+++ b/include/hw/acpi/tco.h
@@ -0,0 +1,82 @@
+/*
+ * QEMU ICH9 TCO emulation
+ *
+ * Copyright (c) 2015 Paulo Alcantara <pcacjr@zytor.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#ifndef HW_ACPI_TCO_H
+#define HW_ACPI_TCO_H
+
+#include "qemu/typedefs.h"
+#include "qemu-common.h"
+
+/* As per ICH9 spec, the internal timer has an error of ~0.6s on every tick */
+#define TCO_TICK_NSEC 600000000LL
+
+/* TCO I/O register offsets */
+enum {
+ TCO_RLD = 0x00,
+ TCO_DAT_IN = 0x02,
+ TCO_DAT_OUT = 0x03,
+ TCO1_STS = 0x04,
+ TCO2_STS = 0x06,
+ TCO1_CNT = 0x08,
+ TCO2_CNT = 0x0a,
+ TCO_MESSAGE1 = 0x0c,
+ TCO_MESSAGE2 = 0x0d,
+ TCO_WDCNT = 0x0e,
+ SW_IRQ_GEN = 0x10,
+ TCO_TMR = 0x12,
+};
+
+/* TCO I/O register control/status bits */
+enum {
+ SW_TCO_SMI = 1 << 1,
+ TCO_INT_STS = 1 << 2,
+ TCO_LOCK = 1 << 12,
+ TCO_TMR_HLT = 1 << 11,
+ TCO_TIMEOUT = 1 << 3,
+ TCO_SECOND_TO_STS = 1 << 1,
+ TCO_BOOT_STS = 1 << 2,
+};
+
+/* TCO I/O registers mask bits */
+enum {
+ TCO_RLD_MASK = 0x3ff,
+ TCO1_STS_MASK = 0xe870,
+ TCO2_STS_MASK = 0xfff8,
+ TCO1_CNT_MASK = 0xfeff,
+ TCO_TMR_MASK = 0x3ff,
+};
+
+typedef struct TCOIORegs {
+ struct {
+ uint16_t rld;
+ uint8_t din;
+ uint8_t dout;
+ uint16_t sts1;
+ uint16_t sts2;
+ uint16_t cnt1;
+ uint16_t cnt2;
+ uint8_t msg1;
+ uint8_t msg2;
+ uint8_t wdcnt;
+ uint16_t tmr;
+ } tco;
+ uint8_t sw_irq_gen;
+
+ QEMUTimer *tco_timer;
+ int64_t expire_time;
+ uint8_t timeouts_no;
+
+ MemoryRegion io;
+} TCOIORegs;
+
+/* tco.c */
+void acpi_pm_tco_init(TCOIORegs *tr, MemoryRegion *parent);
+
+extern const VMStateDescription vmstate_tco_io_sts;
+
+#endif /* HW_ACPI_TCO_H */
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 6379901528..2aec9cbb12 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -99,7 +99,8 @@ struct MachineClass {
no_floppy:1,
no_cdrom:1,
no_sdcard:1,
- has_dynamic_sysbus:1;
+ has_dynamic_sysbus:1,
+ no_tco:1;
int is_default;
const char *default_machine_opts;
const char *default_boot_order;
diff --git a/include/hw/i386/ich9.h b/include/hw/i386/ich9.h
index b317a481c8..ecb3b1038c 100644
--- a/include/hw/i386/ich9.h
+++ b/include/hw/i386/ich9.h
@@ -17,9 +17,12 @@
void ich9_lpc_set_irq(void *opaque, int irq_num, int level);
int ich9_lpc_map_irq(PCIDevice *pci_dev, int intx);
PCIINTxRoute ich9_route_intx_pin_to_irq(void *opaque, int pirq_pin);
-void ich9_lpc_pm_init(PCIDevice *pci_lpc, bool smm_enabled);
+void ich9_lpc_pm_init(PCIDevice *pci_lpc, bool smm_enabled, bool enable_tco);
I2CBus *ich9_smb_init(PCIBus *bus, int devfn, uint32_t smb_io_base);
+void ich9_generate_smi(void);
+void ich9_generate_nmi(void);
+
#define ICH9_CC_SIZE (16 * 1024) /* 16KB */
#define TYPE_ICH9_LPC_DEVICE "ICH9-LPC"
@@ -90,6 +93,9 @@ Object *ich9_lpc_find(void);
#define ICH9_CC_DIR_MASK 0x7
#define ICH9_CC_OIC 0x31FF
#define ICH9_CC_OIC_AEN 0x1
+#define ICH9_CC_GCS 0x3410
+#define ICH9_CC_GCS_DEFAULT 0x00000020
+#define ICH9_CC_GCS_NO_REBOOT (1 << 5)
/* D28:F[0-5] */
#define ICH9_PCIE_DEV 28
@@ -186,7 +192,10 @@ Object *ich9_lpc_find(void);
#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_EN_TCO_EN (1 << 13)
#define ICH9_PMIO_SMI_STS 0x34
+#define ICH9_PMIO_TCO_RLD 0x60
+#define ICH9_PMIO_TCO_LEN 32
/* FADT ACPI_ENABLE/ACPI_DISABLE */
#define ICH9_APM_ACPI_ENABLE 0x2
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 786a1d511c..f9df68e0bb 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -88,6 +88,7 @@ typedef struct PcPciInfo {
#define ACPI_PM_PROP_PM_IO_BASE "pm_io_base"
#define ACPI_PM_PROP_GPE0_BLK "gpe0_blk"
#define ACPI_PM_PROP_GPE0_BLK_LEN "gpe0_blk_len"
+#define ACPI_PM_PROP_TCO_ENABLED "enable_tco"
struct PcGuestInfo {
bool isapc_ram_fw;