Skip to content

Commit

Permalink
hw/watchdog/sbsa_gwdt: Make watchdog timer frequency a QOM property
Browse files Browse the repository at this point in the history
Currently the sbsa_gdwt watchdog device hardcodes its frequency at
62.5MHz. In real hardware, this watchdog is supposed to be driven
from the system counter, which also drives the CPU generic timers.
Newer CPU types (in particular from Armv8.6) should have a CPU
generic timer frequency of 1GHz, so we can't leave the watchdog
on the old QEMU default of 62.5GHz.

Make the frequency a QOM property so it can be set by the board,
and have our only board that uses this device set that frequency
to the same value it sets the CPU frequency.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Message-id: 20240426122913.3427983-4-peter.maydell@linaro.org
  • Loading branch information
pm215 committed Apr 30, 2024
1 parent ee4336f commit 88c756b
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 3 deletions.
1 change: 1 addition & 0 deletions hw/arm/sbsa-ref.c
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,7 @@ static void create_wdt(const SBSAMachineState *sms)
SysBusDevice *s = SYS_BUS_DEVICE(dev);
int irq = sbsa_ref_irqmap[SBSA_GWDT_WS0];

qdev_prop_set_uint64(dev, "clock-frequency", SBSA_GTIMER_HZ);
sysbus_realize_and_unref(s, &error_fatal);
sysbus_mmio_map(s, 0, rbase);
sysbus_mmio_map(s, 1, cbase);
Expand Down
15 changes: 14 additions & 1 deletion hw/watchdog/sbsa_gwdt.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "qemu/osdep.h"
#include "sysemu/reset.h"
#include "sysemu/watchdog.h"
#include "hw/qdev-properties.h"
#include "hw/watchdog/sbsa_gwdt.h"
#include "qemu/timer.h"
#include "migration/vmstate.h"
Expand Down Expand Up @@ -109,7 +110,7 @@ static void sbsa_gwdt_update_timer(SBSA_GWDTState *s, WdtRefreshType rtype)
timeout = s->woru;
timeout <<= 32;
timeout |= s->worl;
timeout = muldiv64(timeout, NANOSECONDS_PER_SECOND, SBSA_TIMER_FREQ);
timeout = muldiv64(timeout, NANOSECONDS_PER_SECOND, s->freq);
timeout += qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL);

if ((rtype == EXPLICIT_REFRESH) || ((rtype == TIMEOUT_REFRESH) &&
Expand Down Expand Up @@ -261,6 +262,17 @@ static void wdt_sbsa_gwdt_realize(DeviceState *dev, Error **errp)
dev);
}

static Property wdt_sbsa_gwdt_props[] = {
/*
* Timer frequency in Hz. This must match the frequency used by
* the CPU's generic timer. Default 62.5Hz matches QEMU's legacy
* CPU timer frequency default.
*/
DEFINE_PROP_UINT64("clock-frequency", struct SBSA_GWDTState, freq,
62500000),
DEFINE_PROP_END_OF_LIST(),
};

static void wdt_sbsa_gwdt_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
Expand All @@ -271,6 +283,7 @@ static void wdt_sbsa_gwdt_class_init(ObjectClass *klass, void *data)
set_bit(DEVICE_CATEGORY_WATCHDOG, dc->categories);
dc->vmsd = &vmstate_sbsa_gwdt;
dc->desc = "SBSA-compliant generic watchdog device";
device_class_set_props(dc, wdt_sbsa_gwdt_props);
}

static const TypeInfo wdt_sbsa_gwdt_info = {
Expand Down
3 changes: 1 addition & 2 deletions include/hw/watchdog/sbsa_gwdt.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,6 @@
#define SBSA_GWDT_RMMIO_SIZE 0x1000
#define SBSA_GWDT_CMMIO_SIZE 0x1000

#define SBSA_TIMER_FREQ 62500000 /* Hz */

typedef struct SBSA_GWDTState {
/* <private> */
SysBusDevice parent_obj;
Expand All @@ -67,6 +65,7 @@ typedef struct SBSA_GWDTState {
qemu_irq irq;

QEMUTimer *timer;
uint64_t freq;

uint32_t id;
uint32_t wcs;
Expand Down

0 comments on commit 88c756b

Please sign in to comment.