[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 2/3] hw/isa/lpc_ich9: Implement SMI_STS for APMC
From: |
Patrick Rudolph |
Subject: |
[PATCH 2/3] hw/isa/lpc_ich9: Implement SMI_STS for APMC |
Date: |
Wed, 18 Oct 2023 13:52:30 +0200 |
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(+)
diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index 25e2c7243e..74d1824595 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -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);
}
}
diff --git a/hw/acpi/ich9_tco.c b/hw/acpi/ich9_tco.c
index 1540f4fd46..0f1cb19864 100644
--- a/hw/acpi/ich9_tco.c
+++ b/hw/acpi/ich9_tco.c
@@ -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:
diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
index 01d6a46c3d..eb25e6429e 100644
--- a/hw/isa/lpc_ich9.c
+++ b/hw/isa/lpc_ich9.c
@@ -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;
diff --git a/include/hw/southbridge/ich9.h b/include/hw/southbridge/ich9.h
index 1281eb654c..4f5d6cefaa 100644
--- a/include/hw/southbridge/ich9.h
+++ b/include/hw/southbridge/ich9.h
@@ -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
--
2.41.0