summaryrefslogtreecommitdiffstats
path: root/hw/watchdog/wdt_aspeed.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/watchdog/wdt_aspeed.c')
-rw-r--r--hw/watchdog/wdt_aspeed.c26
1 files changed, 24 insertions, 2 deletions
diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
index 6352ba1b0e..69c37af9a6 100644
--- a/hw/watchdog/wdt_aspeed.c
+++ b/hw/watchdog/wdt_aspeed.c
@@ -118,13 +118,27 @@ static void aspeed_wdt_reload_1mhz(AspeedWDTState *s)
}
}
+static uint64_t aspeed_2400_sanitize_ctrl(uint64_t data)
+{
+ return data & 0xffff;
+}
+
+static uint64_t aspeed_2500_sanitize_ctrl(uint64_t data)
+{
+ return (data & ~(0xfUL << 8)) | WDT_CTRL_1MHZ_CLK;
+}
+
+static uint64_t aspeed_2600_sanitize_ctrl(uint64_t data)
+{
+ return data & ~(0x7UL << 7);
+}
static void aspeed_wdt_write(void *opaque, hwaddr offset, uint64_t data,
unsigned size)
{
AspeedWDTState *s = ASPEED_WDT(opaque);
AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(s);
- bool enable = data & WDT_CTRL_ENABLE;
+ bool enable;
offset >>= 2;
@@ -144,12 +158,16 @@ static void aspeed_wdt_write(void *opaque, hwaddr offset, uint64_t data,
}
break;
case WDT_CTRL:
+ data = awc->sanitize_ctrl(data);
+ enable = data & WDT_CTRL_ENABLE;
if (enable && !aspeed_wdt_is_enabled(s)) {
s->regs[WDT_CTRL] = data;
awc->wdt_reload(s);
} else if (!enable && aspeed_wdt_is_enabled(s)) {
s->regs[WDT_CTRL] = data;
timer_del(s->timer);
+ } else {
+ s->regs[WDT_CTRL] = data;
}
break;
case WDT_RESET_WIDTH:
@@ -207,11 +225,12 @@ static const MemoryRegionOps aspeed_wdt_ops = {
static void aspeed_wdt_reset(DeviceState *dev)
{
AspeedWDTState *s = ASPEED_WDT(dev);
+ AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(s);
s->regs[WDT_STATUS] = 0x3EF1480;
s->regs[WDT_RELOAD_VALUE] = 0x03EF1480;
s->regs[WDT_RESTART] = 0;
- s->regs[WDT_CTRL] = 0;
+ s->regs[WDT_CTRL] = awc->sanitize_ctrl(0);
s->regs[WDT_RESET_WIDTH] = 0xFF;
timer_del(s->timer);
@@ -293,6 +312,7 @@ static void aspeed_2400_wdt_class_init(ObjectClass *klass, void *data)
awc->ext_pulse_width_mask = 0xff;
awc->reset_ctrl_reg = SCU_RESET_CONTROL1;
awc->wdt_reload = aspeed_wdt_reload;
+ awc->sanitize_ctrl = aspeed_2400_sanitize_ctrl;
}
static const TypeInfo aspeed_2400_wdt_info = {
@@ -328,6 +348,7 @@ static void aspeed_2500_wdt_class_init(ObjectClass *klass, void *data)
awc->reset_ctrl_reg = SCU_RESET_CONTROL1;
awc->reset_pulse = aspeed_2500_wdt_reset_pulse;
awc->wdt_reload = aspeed_wdt_reload_1mhz;
+ awc->sanitize_ctrl = aspeed_2500_sanitize_ctrl;
}
static const TypeInfo aspeed_2500_wdt_info = {
@@ -348,6 +369,7 @@ static void aspeed_2600_wdt_class_init(ObjectClass *klass, void *data)
awc->reset_ctrl_reg = AST2600_SCU_RESET_CONTROL1;
awc->reset_pulse = aspeed_2500_wdt_reset_pulse;
awc->wdt_reload = aspeed_wdt_reload_1mhz;
+ awc->sanitize_ctrl = aspeed_2600_sanitize_ctrl;
}
static const TypeInfo aspeed_2600_wdt_info = {