@@ -98,6 +98,7 @@ static void ich9_smi_writel(void *opaque, hwaddr addr, uint64_t val,
ICH9LPCPMRegs *pm = opaque;
TCOIORegs *tr = &pm->tco_regs;
uint64_t tco_en;
+ uint32_t mask;
switch (addr) {
case 0:
@@ -109,6 +110,10 @@ static void ich9_smi_writel(void *opaque, hwaddr addr, uint64_t val,
pm->smi_en &= ~pm->smi_en_wmask;
pm->smi_en |= (val & pm->smi_en_wmask);
break;
+ case 4:
+ mask = pm->smi_sts & ~val;
+ pm->smi_sts &= ~(ICH9_PMIO_SMI_STS_TCO | ICH9_PMIO_SMI_STS_APMC);
+ pm->smi_sts |= mask & (ICH9_PMIO_SMI_STS_TCO | ICH9_PMIO_SMI_STS_APMC);
}
}
@@ -71,6 +71,7 @@ static void tco_timer_expired(void *opaque)
}
if (pm->smi_en & ICH9_PMIO_SMI_EN_TCO_EN) {
+ lpc->pm.smi_sts |= ICH9_PMIO_SMI_STS_TCO;
ich9_generate_smi();
}
tr->tco.rld = tr->tco.tmr;
@@ -139,6 +140,9 @@ static uint32_t tco_ioport_readw(TCOIORegs *tr, uint32_t addr)
static void tco_ioport_writew(TCOIORegs *tr, uint32_t addr, uint32_t val)
{
+ ICH9LPCPMRegs *pm = container_of(tr, ICH9LPCPMRegs, tco_regs);
+ ICH9LPCState *lpc = container_of(pm, ICH9LPCState, pm);
+
trace_tco_io_write(addr, val);
switch (addr) {
case TCO_RLD:
@@ -153,6 +157,7 @@ static void tco_ioport_writew(TCOIORegs *tr, uint32_t addr, uint32_t val)
case TCO_DAT_IN:
tr->tco.din = val;
tr->tco.sts1 |= SW_TCO_SMI;
+ lpc->pm.smi_sts |= ICH9_PMIO_SMI_STS_TCO;
ich9_generate_smi();
break;
case TCO_DAT_OUT:
@@ -471,6 +471,7 @@ static void ich9_apm_ctrl_changed(uint32_t val, void *arg)
/* SMI_EN = PMBASE + 30. SMI control and enable register */
if (lpc->pm.smi_en & ICH9_PMIO_SMI_EN_APMC_EN) {
+ lpc->pm.smi_sts |= ICH9_PMIO_SMI_STS_APMC;
if (lpc->smi_negotiated_features &
(UINT64_C(1) << ICH9_LPC_SMI_F_BROADCAST_BIT)) {
CPUState *cs;
@@ -202,6 +202,8 @@ struct ICH9LPCState {
#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_SMI_STS_APMC (1 << 5)
+#define ICH9_PMIO_SMI_STS_TCO (1 << 13)
#define ICH9_PMIO_TCO_RLD 0x60
#define ICH9_PMIO_TCO_LEN 32
The guest SMI handler wants to know the cause for the SMI, thus properly emulate the RWC APMC and TCO bit in the SMI_STS register. TEST: coreboot generic ICH9 SMI handler is able to determine the source for the SMI and will invoke the APM callback. Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com> --- hw/acpi/ich9.c | 5 +++++ hw/acpi/ich9_tco.c | 5 +++++ hw/isa/lpc_ich9.c | 1 + include/hw/southbridge/ich9.h | 2 ++ 4 files changed, 13 insertions(+)