From 920557971b60e53c2f3f22e5d6c620ab1ed411fd Mon Sep 17 00:00:00 2001 From: Paulo Alcantara Date: Sun, 28 Jun 2015 14:58:56 -0300 Subject: ich9: add TCO interface emulation This interface provides some registers within a 32-byte range and can be acessed through PCI-to-LPC bridge interface (PMBASE + 0x60). It's commonly used as a watchdog timer to detect system lockups through SMIs that are generated -- if TCO_EN bit is set -- on every timeout. If NO_REBOOT bit is not set in GCS (General Control and Status register), the system will be resetted upon second timeout if TCO_RLD register wasn't previously written to prevent timeout. This patch adds support to TCO watchdog logic and few other features like mapping NMIs to SMIs (NMI2SMI_EN bit), system intruder detection, etc. are not implemented yet. Signed-off-by: Paulo Alcantara Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin --- hw/isa/lpc_ich9.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'hw/isa/lpc_ich9.c') diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c index bd655b8405..7af24fa8eb 100644 --- a/hw/isa/lpc_ich9.c +++ b/hw/isa/lpc_ich9.c @@ -138,6 +138,7 @@ static void ich9_cc_reset(ICH9LPCState *lpc) pci_set_long(c + ICH9_CC_D27IR, ICH9_CC_DIR_DEFAULT); pci_set_long(c + ICH9_CC_D26IR, ICH9_CC_DIR_DEFAULT); pci_set_long(c + ICH9_CC_D25IR, ICH9_CC_DIR_DEFAULT); + pci_set_long(c + ICH9_CC_GCS, ICH9_CC_GCS_DEFAULT); ich9_cc_update(lpc); } @@ -313,6 +314,16 @@ PCIINTxRoute ich9_route_intx_pin_to_irq(void *opaque, int pirq_pin) return route; } +void ich9_generate_smi(void) +{ + cpu_interrupt(first_cpu, CPU_INTERRUPT_SMI); +} + +void ich9_generate_nmi(void) +{ + cpu_interrupt(first_cpu, CPU_INTERRUPT_NMI); +} + static int ich9_lpc_sci_irq(ICH9LPCState *lpc) { switch (lpc->d.config[ICH9_LPC_ACPI_CTRL] & @@ -357,13 +368,13 @@ static void ich9_set_sci(void *opaque, int irq_num, int level) } } -void ich9_lpc_pm_init(PCIDevice *lpc_pci, bool smm_enabled) +void ich9_lpc_pm_init(PCIDevice *lpc_pci, bool smm_enabled, bool enable_tco) { ICH9LPCState *lpc = ICH9_LPC_DEVICE(lpc_pci); qemu_irq sci_irq; sci_irq = qemu_allocate_irq(ich9_set_sci, lpc, 0); - ich9_pm_init(lpc_pci, &lpc->pm, smm_enabled, sci_irq); + ich9_pm_init(lpc_pci, &lpc->pm, smm_enabled, enable_tco, sci_irq); ich9_lpc_reset(&lpc->d.qdev); } -- cgit v1.2.1