aboutsummaryrefslogtreecommitdiff
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.c73
1 files changed, 58 insertions, 15 deletions
diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c
index 69c37af9a6..d70b656f8e 100644
--- a/hw/watchdog/wdt_aspeed.c
+++ b/hw/watchdog/wdt_aspeed.c
@@ -14,11 +14,11 @@
#include "qemu/module.h"
#include "qemu/timer.h"
#include "sysemu/watchdog.h"
-#include "hw/misc/aspeed_scu.h"
#include "hw/qdev-properties.h"
#include "hw/sysbus.h"
#include "hw/watchdog/wdt_aspeed.h"
#include "migration/vmstate.h"
+#include "trace.h"
#define WDT_STATUS (0x00 / 4)
#define WDT_RELOAD_VALUE (0x04 / 4)
@@ -41,6 +41,11 @@
#define WDT_PUSH_PULL_MAGIC (0xA8 << 24)
#define WDT_OPEN_DRAIN_MAGIC (0x8A << 24)
#define WDT_RESET_MASK1 (0x1c / 4)
+#define WDT_RESET_MASK2 (0x20 / 4)
+
+#define WDT_SW_RESET_CTRL (0x24 / 4)
+#define WDT_SW_RESET_MASK1 (0x28 / 4)
+#define WDT_SW_RESET_MASK2 (0x2c / 4)
#define WDT_TIMEOUT_STATUS (0x10 / 4)
#define WDT_TIMEOUT_CLEAR (0x14 / 4)
@@ -60,6 +65,8 @@ static uint64_t aspeed_wdt_read(void *opaque, hwaddr offset, unsigned size)
{
AspeedWDTState *s = ASPEED_WDT(opaque);
+ trace_aspeed_wdt_read(offset, size);
+
offset >>= 2;
switch (offset) {
@@ -80,6 +87,10 @@ static uint64_t aspeed_wdt_read(void *opaque, hwaddr offset, unsigned size)
return s->regs[WDT_RESET_MASK1];
case WDT_TIMEOUT_STATUS:
case WDT_TIMEOUT_CLEAR:
+ case WDT_RESET_MASK2:
+ case WDT_SW_RESET_CTRL:
+ case WDT_SW_RESET_MASK1:
+ case WDT_SW_RESET_MASK2:
qemu_log_mask(LOG_UNIMP,
"%s: uninmplemented read at offset 0x%" HWADDR_PRIx "\n",
__func__, offset);
@@ -140,6 +151,8 @@ static void aspeed_wdt_write(void *opaque, hwaddr offset, uint64_t data,
AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(s);
bool enable;
+ trace_aspeed_wdt_write(offset, size, data);
+
offset >>= 2;
switch (offset) {
@@ -185,6 +198,10 @@ static void aspeed_wdt_write(void *opaque, hwaddr offset, uint64_t data,
case WDT_TIMEOUT_STATUS:
case WDT_TIMEOUT_CLEAR:
+ case WDT_RESET_MASK2:
+ case WDT_SW_RESET_CTRL:
+ case WDT_SW_RESET_MASK1:
+ case WDT_SW_RESET_MASK2:
qemu_log_mask(LOG_UNIMP,
"%s: uninmplemented write at offset 0x%" HWADDR_PRIx "\n",
__func__, offset);
@@ -197,16 +214,11 @@ static void aspeed_wdt_write(void *opaque, hwaddr offset, uint64_t data,
return;
}
-static WatchdogTimerModel model = {
- .wdt_name = TYPE_ASPEED_WDT,
- .wdt_description = "Aspeed watchdog device",
-};
-
static const VMStateDescription vmstate_aspeed_wdt = {
.name = "vmstate_aspeed_wdt",
.version_id = 0,
.minimum_version_id = 0,
- .fields = (VMStateField[]) {
+ .fields = (const VMStateField[]) {
VMSTATE_TIMER_PTR(timer, AspeedWDTState),
VMSTATE_UINT32_ARRAY(regs, AspeedWDTState, ASPEED_WDT_REGS_MAX),
VMSTATE_END_OF_LIST()
@@ -227,8 +239,8 @@ 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_STATUS] = awc->default_status;
+ s->regs[WDT_RELOAD_VALUE] = awc->default_reload_value;
s->regs[WDT_RESTART] = 0;
s->regs[WDT_CTRL] = awc->sanitize_ctrl(0);
s->regs[WDT_RESET_WIDTH] = 0xFF;
@@ -260,6 +272,7 @@ static void aspeed_wdt_realize(DeviceState *dev, Error **errp)
{
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
AspeedWDTState *s = ASPEED_WDT(dev);
+ AspeedWDTClass *awc = ASPEED_WDT_GET_CLASS(dev);
assert(s->scu);
@@ -271,7 +284,7 @@ static void aspeed_wdt_realize(DeviceState *dev, Error **errp)
s->pclk_freq = PCLK_HZ;
memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_wdt_ops, s,
- TYPE_ASPEED_WDT, ASPEED_WDT_REGS_MAX * 4);
+ TYPE_ASPEED_WDT, awc->iosize);
sysbus_init_mmio(sbd, &s->iomem);
}
@@ -288,9 +301,10 @@ static void aspeed_wdt_class_init(ObjectClass *klass, void *data)
dc->desc = "ASPEED Watchdog Controller";
dc->realize = aspeed_wdt_realize;
dc->reset = aspeed_wdt_reset;
- set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+ set_bit(DEVICE_CATEGORY_WATCHDOG, dc->categories);
dc->vmsd = &vmstate_aspeed_wdt;
device_class_set_props(dc, aspeed_wdt_properties);
+ dc->desc = "Aspeed watchdog device";
}
static const TypeInfo aspeed_wdt_info = {
@@ -308,11 +322,13 @@ static void aspeed_2400_wdt_class_init(ObjectClass *klass, void *data)
AspeedWDTClass *awc = ASPEED_WDT_CLASS(klass);
dc->desc = "ASPEED 2400 Watchdog Controller";
- awc->offset = 0x20;
+ awc->iosize = 0x20;
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;
+ awc->default_status = 0x03EF1480;
+ awc->default_reload_value = 0x03EF1480;
}
static const TypeInfo aspeed_2400_wdt_info = {
@@ -343,12 +359,14 @@ static void aspeed_2500_wdt_class_init(ObjectClass *klass, void *data)
AspeedWDTClass *awc = ASPEED_WDT_CLASS(klass);
dc->desc = "ASPEED 2500 Watchdog Controller";
- awc->offset = 0x20;
+ awc->iosize = 0x20;
awc->ext_pulse_width_mask = 0xfffff;
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;
+ awc->default_status = 0x014FB180;
+ awc->default_reload_value = 0x014FB180;
}
static const TypeInfo aspeed_2500_wdt_info = {
@@ -364,12 +382,14 @@ static void aspeed_2600_wdt_class_init(ObjectClass *klass, void *data)
AspeedWDTClass *awc = ASPEED_WDT_CLASS(klass);
dc->desc = "ASPEED 2600 Watchdog Controller";
- awc->offset = 0x40;
+ awc->iosize = 0x40;
awc->ext_pulse_width_mask = 0xfffff; /* TODO */
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;
+ awc->default_status = 0x014FB180;
+ awc->default_reload_value = 0x014FB180;
}
static const TypeInfo aspeed_2600_wdt_info = {
@@ -379,13 +399,36 @@ static const TypeInfo aspeed_2600_wdt_info = {
.class_init = aspeed_2600_wdt_class_init,
};
+static void aspeed_1030_wdt_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ AspeedWDTClass *awc = ASPEED_WDT_CLASS(klass);
+
+ dc->desc = "ASPEED 1030 Watchdog Controller";
+ awc->iosize = 0x80;
+ awc->ext_pulse_width_mask = 0xfffff; /* TODO */
+ 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;
+ awc->default_status = 0x014FB180;
+ awc->default_reload_value = 0x014FB180;
+}
+
+static const TypeInfo aspeed_1030_wdt_info = {
+ .name = TYPE_ASPEED_1030_WDT,
+ .parent = TYPE_ASPEED_WDT,
+ .instance_size = sizeof(AspeedWDTState),
+ .class_init = aspeed_1030_wdt_class_init,
+};
+
static void wdt_aspeed_register_types(void)
{
- watchdog_add_model(&model);
type_register_static(&aspeed_wdt_info);
type_register_static(&aspeed_2400_wdt_info);
type_register_static(&aspeed_2500_wdt_info);
type_register_static(&aspeed_2600_wdt_info);
+ type_register_static(&aspeed_1030_wdt_info);
}
type_init(wdt_aspeed_register_types)