qemu-devel
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]