From: "Dominic Prinz" <git@dprinz.de>
To: <qemu-devel@nongnu.org>
Cc: "Michael S. Tsirkin" <mst@redhat.com>,
"Marcel Apfelbaum" <marcel.apfelbaum@gmail.com>,
"Igor Mammedov" <imammedo@redhat.com>,
"Dominic Prinz" <git@dprinz.de>
Subject: Re: [PATCH v2] hw/acpi/ich9: Add periodic and swsmi timer
Date: Sat, 07 Sep 2024 22:18:50 +0200 [thread overview]
Message-ID: <D40BW36MF3QO.1BSWXNJMCEFK8@dprinz.de> (raw)
In-Reply-To: <D3LLXABB7UZ1.1RHBKW1GU9I3D@dp-laptop>
Second ping
https://patchew.org/QEMU/1e4d59a49e7f2e02cf522e799a7bf5f3fa3fba1f.1722414006.git.git@dprinz.de/
https://lore.kernel.org/qemu-devel/1e4d59a49e7f2e02cf522e799a7bf5f3fa3fba1f.1722414006.git.git@dprinz.de/
On Wed Aug 21, 2024 at 3:00 PM CEST, Dominic Prinz wrote:
> Ping
>
> https://patchew.org/QEMU/1e4d59a49e7f2e02cf522e799a7bf5f3fa3fba1f.1722414006.git.git@dprinz.de/
> https://lore.kernel.org/qemu-devel/1e4d59a49e7f2e02cf522e799a7bf5f3fa3fba1f.1722414006.git.git@dprinz.de/
>
> On Wed Jul 31, 2024 at 10:28 AM CEST, Dominic Prinz wrote:
> > This patch implements the periodic and the swsmi ICH9 chipset timer. They are
> > especially useful when prototyping UEFI firmware (e.g. with EDK2's OVMF)
> > using QEMU.
> >
> > For backwards compatibility, the compat properties "x-smi-swsmi-timer",
> > and "x-smi-periodic-timer" are introduced.
> >
> > Additionally, writes to the SMI_STS register are enabled for the
> > corresponding two bits.
> >
> > Signed-off-by: Dominic Prinz <git@dprinz.de>
> > ---
> > Changes since previous version:
> > - Ensured backwards compatablity by introducing two compat properties
> > - Introduced write mask for SMI_STS register to make future work easier
> >
> > hw/acpi/ich9.c | 23 +++++++++
> > hw/acpi/ich9_timer.c | 93 +++++++++++++++++++++++++++++++++++
> > hw/acpi/meson.build | 2 +-
> > hw/i386/pc.c | 2 +
> > hw/isa/lpc_ich9.c | 14 ++++++
> > include/hw/acpi/ich9.h | 6 +++
> > include/hw/acpi/ich9_timer.h | 23 +++++++++
> > include/hw/southbridge/ich9.h | 4 ++
> > 8 files changed, 166 insertions(+), 1 deletion(-)
> > create mode 100644 hw/acpi/ich9_timer.c
> > create mode 100644 include/hw/acpi/ich9_timer.h
> >
> > diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
> > index 02d8546bd3..c15e5b8281 100644
> > --- a/hw/acpi/ich9.c
> > +++ b/hw/acpi/ich9.c
> > @@ -35,6 +35,7 @@
> > #include "sysemu/runstate.h"
> > #include "hw/acpi/acpi.h"
> > #include "hw/acpi/ich9_tco.h"
> > +#include "hw/acpi/ich9_timer.h"
> >
> > #include "hw/southbridge/ich9.h"
> > #include "hw/mem/pc-dimm.h"
> > @@ -108,6 +109,18 @@ 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);
> > + if (pm->swsmi_timer_enabled) {
> > + ich9_pm_update_swsmi_timer(pm, pm->smi_en &
> > + ICH9_PMIO_SMI_EN_SWSMI_EN);
> > + }
> > + if (pm->periodic_timer_enabled) {
> > + ich9_pm_update_periodic_timer(pm, pm->smi_en &
> > + ICH9_PMIO_SMI_EN_PERIODIC_EN);
> > + }
> > + break;
> > + case 4:
> > + pm->smi_sts &= ~pm->smi_sts_wmask;
> > + pm->smi_sts |= (val & pm->smi_sts_wmask);
> > break;
> > }
> > }
> > @@ -286,6 +299,8 @@ static void pm_powerdown_req(Notifier *n, void *opaque)
> >
> > void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm, qemu_irq sci_irq)
> > {
> > + pm->smi_sts_wmask = 0;
> > +
> > memory_region_init(&pm->io, OBJECT(lpc_pci), "ich9-pm", ICH9_PMIO_SIZE);
> > memory_region_set_enabled(&pm->io, false);
> > memory_region_add_subregion(pci_address_space_io(lpc_pci),
> > @@ -305,6 +320,14 @@ void ich9_pm_init(PCIDevice *lpc_pci, ICH9LPCPMRegs *pm, qemu_irq sci_irq)
> > "acpi-smi", 8);
> > memory_region_add_subregion(&pm->io, ICH9_PMIO_SMI_EN, &pm->io_smi);
> >
> > + if (pm->swsmi_timer_enabled) {
> > + ich9_pm_swsmi_timer_init(pm);
> > + }
> > +
> > + if (pm->periodic_timer_enabled) {
> > + ich9_pm_periodic_timer_init(pm);
> > + }
> > +
> > if (pm->enable_tco) {
> > acpi_pm_tco_init(&pm->tco_regs, &pm->io);
> > }
> > diff --git a/hw/acpi/ich9_timer.c b/hw/acpi/ich9_timer.c
> > new file mode 100644
> > index 0000000000..5b1c910156
> > --- /dev/null
> > +++ b/hw/acpi/ich9_timer.c
> > @@ -0,0 +1,93 @@
> > +/*
> > + * QEMU ICH9 Timer emulation
> > + *
> > + * Copyright (c) 2024 Dominic Prinz <git@dprinz.de>
> > + *
> > + * This work is licensed under the terms of the GNU GPL, version 2 or later.
> > + * See the COPYING file in the top-level directory.
> > + */
> > +
> > +#include "qemu/osdep.h"
> > +#include "hw/core/cpu.h"
> > +#include "hw/pci/pci.h"
> > +#include "hw/southbridge/ich9.h"
> > +#include "qemu/timer.h"
> > +
> > +#include "hw/acpi/ich9_timer.h"
> > +
> > +void ich9_pm_update_swsmi_timer(ICH9LPCPMRegs *pm, bool enable)
> > +{
> > + uint16_t swsmi_rate_sel;
> > + int64_t expire_time;
> > + ICH9LPCState *lpc;
> > +
> > + if (enable) {
> > + lpc = container_of(pm, ICH9LPCState, pm);
> > + swsmi_rate_sel =
> > + (pci_get_word(lpc->d.config + ICH9_LPC_GEN_PMCON_3) & 0xc0) >> 6;
> > +
> > + if (swsmi_rate_sel == 0) {
> > + expire_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 1500000LL;
> > + } else {
> > + expire_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
> > + 8 * (1 << swsmi_rate_sel) * 1000000LL;
> > + }
> > +
> > + timer_mod(pm->swsmi_timer, expire_time);
> > + } else {
> > + timer_del(pm->swsmi_timer);
> > + }
> > +}
> > +
> > +static void ich9_pm_swsmi_timer_expired(void *opaque)
> > +{
> > + ICH9LPCPMRegs *pm = opaque;
> > +
> > + pm->smi_sts |= ICH9_PMIO_SMI_STS_SWSMI_STS;
> > + ich9_generate_smi();
> > +
> > + ich9_pm_update_swsmi_timer(pm, pm->smi_en & ICH9_PMIO_SMI_EN_SWSMI_EN);
> > +}
> > +
> > +void ich9_pm_swsmi_timer_init(ICH9LPCPMRegs *pm)
> > +{
> > + pm->smi_sts_wmask |= ICH9_PMIO_SMI_STS_SWSMI_STS;
> > + pm->swsmi_timer =
> > + timer_new_ns(QEMU_CLOCK_VIRTUAL, ich9_pm_swsmi_timer_expired, pm);
> > +}
> > +
> > +void ich9_pm_update_periodic_timer(ICH9LPCPMRegs *pm, bool enable)
> > +{
> > + uint16_t per_smi_sel;
> > + int64_t expire_time;
> > + ICH9LPCState *lpc;
> > +
> > + if (enable) {
> > + lpc = container_of(pm, ICH9LPCState, pm);
> > + per_smi_sel = pci_get_word(lpc->d.config + ICH9_LPC_GEN_PMCON_1) & 3;
> > + expire_time = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
> > + 8 * (1 << (3 - per_smi_sel)) * NANOSECONDS_PER_SECOND;
> > +
> > + timer_mod(pm->periodic_timer, expire_time);
> > + } else {
> > + timer_del(pm->periodic_timer);
> > + }
> > +}
> > +
> > +static void ich9_pm_periodic_timer_expired(void *opaque)
> > +{
> > + ICH9LPCPMRegs *pm = opaque;
> > +
> > + pm->smi_sts = ICH9_PMIO_SMI_STS_PERIODIC_STS;
> > + ich9_generate_smi();
> > +
> > + ich9_pm_update_periodic_timer(pm,
> > + pm->smi_en & ICH9_PMIO_SMI_EN_PERIODIC_EN);
> > +}
> > +
> > +void ich9_pm_periodic_timer_init(ICH9LPCPMRegs *pm)
> > +{
> > + pm->smi_sts_wmask |= ICH9_PMIO_SMI_STS_PERIODIC_STS;
> > + pm->periodic_timer =
> > + timer_new_ns(QEMU_CLOCK_VIRTUAL, ich9_pm_periodic_timer_expired, pm);
> > +}
> > diff --git a/hw/acpi/meson.build b/hw/acpi/meson.build
> > index fa5c07db90..7f8ccc9b7a 100644
> > --- a/hw/acpi/meson.build
> > +++ b/hw/acpi/meson.build
> > @@ -24,7 +24,7 @@ acpi_ss.add(when: 'CONFIG_ACPI_PCI_BRIDGE', if_true: files('pci-bridge.c'))
> > acpi_ss.add(when: 'CONFIG_ACPI_PCIHP', if_true: files('pcihp.c'))
> > acpi_ss.add(when: 'CONFIG_ACPI_PCIHP', if_false: files('acpi-pci-hotplug-stub.c'))
> > acpi_ss.add(when: 'CONFIG_ACPI_VIOT', if_true: files('viot.c'))
> > -acpi_ss.add(when: 'CONFIG_ACPI_ICH9', if_true: files('ich9.c', 'ich9_tco.c'))
> > +acpi_ss.add(when: 'CONFIG_ACPI_ICH9', if_true: files('ich9.c', 'ich9_tco.c', 'ich9_timer.c'))
> > acpi_ss.add(when: 'CONFIG_ACPI_ERST', if_true: files('erst.c'))
> > acpi_ss.add(when: 'CONFIG_IPMI', if_true: files('ipmi.c'), if_false: files('ipmi-stub.c'))
> > acpi_ss.add(when: 'CONFIG_PC', if_false: files('acpi-x86-stub.c'))
> > diff --git a/hw/i386/pc.c b/hw/i386/pc.c
> > index c74931d577..a97b1b1f57 100644
> > --- a/hw/i386/pc.c
> > +++ b/hw/i386/pc.c
> > @@ -85,6 +85,8 @@ GlobalProperty pc_compat_9_0[] = {
> > { TYPE_X86_CPU, "guest-phys-bits", "0" },
> > { "sev-guest", "legacy-vm-type", "on" },
> > { TYPE_X86_CPU, "legacy-multi-node", "on" },
> > + { "ICH9-LPC", "x-smi-swsmi-timer", "off" },
> > + { "ICH9-LPC", "x-smi-periodic-timer", "off" },
> > };
> > const size_t pc_compat_9_0_len = G_N_ELEMENTS(pc_compat_9_0);
> >
> > diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
> > index bd727b2320..ab17b76f54 100644
> > --- a/hw/isa/lpc_ich9.c
> > +++ b/hw/isa/lpc_ich9.c
> > @@ -43,6 +43,7 @@
> > #include "hw/southbridge/ich9.h"
> > #include "hw/acpi/acpi.h"
> > #include "hw/acpi/ich9.h"
> > +#include "hw/acpi/ich9_timer.h"
> > #include "hw/pci/pci_bus.h"
> > #include "hw/qdev-properties.h"
> > #include "sysemu/runstate.h"
> > @@ -531,6 +532,15 @@ ich9_lpc_pmcon_update(ICH9LPCState *lpc)
> > uint16_t gen_pmcon_1 = pci_get_word(lpc->d.config + ICH9_LPC_GEN_PMCON_1);
> > uint16_t wmask;
> >
> > + if (lpc->pm.swsmi_timer_enabled) {
> > + ich9_pm_update_swsmi_timer(
> > + &lpc->pm, lpc->pm.smi_en & ICH9_PMIO_SMI_EN_SWSMI_EN);
> > + }
> > + if (lpc->pm.periodic_timer_enabled) {
> > + ich9_pm_update_periodic_timer(
> > + &lpc->pm, lpc->pm.smi_en & ICH9_PMIO_SMI_EN_PERIODIC_EN);
> > + }
> > +
> > if (gen_pmcon_1 & ICH9_LPC_GEN_PMCON_1_SMI_LOCK) {
> > wmask = pci_get_word(lpc->d.wmask + ICH9_LPC_GEN_PMCON_1);
> > wmask &= ~ICH9_LPC_GEN_PMCON_1_SMI_LOCK;
> > @@ -826,6 +836,10 @@ static Property ich9_lpc_properties[] = {
> > ICH9_LPC_SMI_F_CPU_HOTPLUG_BIT, true),
> > DEFINE_PROP_BIT64("x-smi-cpu-hotunplug", ICH9LPCState, smi_host_features,
> > ICH9_LPC_SMI_F_CPU_HOT_UNPLUG_BIT, true),
> > + DEFINE_PROP_BOOL("x-smi-swsmi-timer", ICH9LPCState,
> > + pm.swsmi_timer_enabled, true),
> > + DEFINE_PROP_BOOL("x-smi-periodic-timer", ICH9LPCState,
> > + pm.periodic_timer_enabled, true),
> > DEFINE_PROP_END_OF_LIST(),
> > };
> >
> > diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h
> > index 2faf7f0cae..245fe08dc2 100644
> > --- a/include/hw/acpi/ich9.h
> > +++ b/include/hw/acpi/ich9.h
> > @@ -46,6 +46,7 @@ typedef struct ICH9LPCPMRegs {
> > uint32_t smi_en;
> > uint32_t smi_en_wmask;
> > uint32_t smi_sts;
> > + uint32_t smi_sts_wmask;
> >
> > qemu_irq irq; /* SCI */
> >
> > @@ -68,6 +69,11 @@ typedef struct ICH9LPCPMRegs {
> > bool smm_compat;
> > bool enable_tco;
> > TCOIORegs tco_regs;
> > +
> > + bool swsmi_timer_enabled;
> > + bool periodic_timer_enabled;
> > + QEMUTimer *swsmi_timer;
> > + QEMUTimer *periodic_timer;
> > } ICH9LPCPMRegs;
> >
> > #define ACPI_PM_PROP_TCO_ENABLED "enable_tco"
> > diff --git a/include/hw/acpi/ich9_timer.h b/include/hw/acpi/ich9_timer.h
> > new file mode 100644
> > index 0000000000..5112df4385
> > --- /dev/null
> > +++ b/include/hw/acpi/ich9_timer.h
> > @@ -0,0 +1,23 @@
> > +/*
> > + * QEMU ICH9 Timer emulation
> > + *
> > + * Copyright (c) 2024 Dominic Prinz <git@dprinz.de>
> > + *
> > + * 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_ICH9_TIMER_H
> > +#define HW_ACPI_ICH9_TIMER_H
> > +
> > +#include "hw/acpi/ich9.h"
> > +
> > +void ich9_pm_update_swsmi_timer(ICH9LPCPMRegs *pm, bool enable);
> > +
> > +void ich9_pm_swsmi_timer_init(ICH9LPCPMRegs *pm);
> > +
> > +void ich9_pm_update_periodic_timer(ICH9LPCPMRegs *pm, bool enable);
> > +
> > +void ich9_pm_periodic_timer_init(ICH9LPCPMRegs *pm);
> > +
> > +#endif
> > diff --git a/include/hw/southbridge/ich9.h b/include/hw/southbridge/ich9.h
> > index fd01649d04..6c60017024 100644
> > --- a/include/hw/southbridge/ich9.h
> > +++ b/include/hw/southbridge/ich9.h
> > @@ -196,8 +196,12 @@ struct ICH9LPCState {
> > #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_SWSMI_EN (1 << 6)
> > #define ICH9_PMIO_SMI_EN_TCO_EN (1 << 13)
> > +#define ICH9_PMIO_SMI_EN_PERIODIC_EN (1 << 14)
> > #define ICH9_PMIO_SMI_STS 0x34
> > +#define ICH9_PMIO_SMI_STS_SWSMI_STS (1 << 6)
> > +#define ICH9_PMIO_SMI_STS_PERIODIC_STS (1 << 14)
> > #define ICH9_PMIO_TCO_RLD 0x60
> > #define ICH9_PMIO_TCO_LEN 32
> >
> > --
> > 2.34.1
next prev parent reply other threads:[~2024-09-07 20:19 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-07-19 10:20 [PATCH] hw/acpi/ich9: Add periodic and swsmi timer Dominic Prinz
2024-07-30 18:42 ` Dominic Prinz
2024-07-30 18:53 ` Michael S. Tsirkin
2024-07-31 8:28 ` [PATCH v2] " Dominic Prinz
2024-08-21 13:00 ` Dominic Prinz
2024-09-07 20:18 ` Dominic Prinz [this message]
2024-09-10 15:20 ` Michael S. Tsirkin
2024-09-10 18:08 ` [PATCH v3] " Dominic Prinz
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=D40BW36MF3QO.1BSWXNJMCEFK8@dprinz.de \
--to=git@dprinz.de \
--cc=imammedo@redhat.com \
--cc=marcel.apfelbaum@gmail.com \
--cc=mst@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).