From: "Cédric Le Goater" <clg@kaod.org>
To: Peter Maydell <peter.maydell@linaro.org>
Cc: "Andrew Jeffery" <andrew@aj.id.au>,
qemu-devel@nongnu.org, qemu-arm@nongnu.org,
"Cédric Le Goater" <clg@kaod.org>,
"Peter Delevoryas" <pdel@fb.com>, "Joel Stanley" <joel@jms.id.au>
Subject: [PATCH 4/4] aspeed/smc: Improve support for the alternate boot function
Date: Mon, 4 Oct 2021 17:46:35 +0200 [thread overview]
Message-ID: <20211004154635.394258-5-clg@kaod.org> (raw)
In-Reply-To: <20211004154635.394258-1-clg@kaod.org>
Map the WDT2 registers in the AST2600 FMC memory region by creating a
local address space on top of WDT2 memory region.
The model only implements the enable bit of the control register. The
reload register uses a 0.1s unit instead of a 1us. Values are
converted on the fly when doing the accesses. The restart register is
the same.
Cc: Peter Delevoryas <pdel@fb.com>
Signed-off-by: Cédric Le Goater <clg@kaod.org>
---
include/hw/ssi/aspeed_smc.h | 3 ++
hw/arm/aspeed_ast2600.c | 2 +
hw/ssi/aspeed_smc.c | 78 ++++++++++++++++++++++++++++++++++++-
hw/ssi/trace-events | 1 +
4 files changed, 82 insertions(+), 2 deletions(-)
diff --git a/include/hw/ssi/aspeed_smc.h b/include/hw/ssi/aspeed_smc.h
index 75bc793bd269..ad3c80f2d809 100644
--- a/include/hw/ssi/aspeed_smc.h
+++ b/include/hw/ssi/aspeed_smc.h
@@ -76,6 +76,9 @@ struct AspeedSMCState {
MemoryRegion *dram_mr;
AddressSpace dram_as;
+ AddressSpace wdt2_as;
+ MemoryRegion *wdt2_mr;
+
AspeedSMCFlash flashes[ASPEED_SMC_CS_MAX];
uint8_t snoop_index;
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
index 0384357a9510..2c53d77899a8 100644
--- a/hw/arm/aspeed_ast2600.c
+++ b/hw/arm/aspeed_ast2600.c
@@ -353,6 +353,8 @@ static void aspeed_soc_ast2600_realize(DeviceState *dev, Error **errp)
}
/* FMC, The number of CS is set at the board level */
+ object_property_set_link(OBJECT(&s->fmc), "wdt2", OBJECT(&s->wdt[2].iomem),
+ &error_abort);
object_property_set_link(OBJECT(&s->fmc), "dram", OBJECT(s->dram_mr),
&error_abort);
if (!sysbus_realize(SYS_BUS_DEVICE(&s->fmc), errp)) {
diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c
index 8a988c167604..1770985230b0 100644
--- a/hw/ssi/aspeed_smc.c
+++ b/hw/ssi/aspeed_smc.c
@@ -130,6 +130,8 @@
#define FMC_WDT2_CTRL_SINGLE_BOOT_MODE BIT(5)
#define FMC_WDT2_CTRL_BOOT_SOURCE BIT(4) /* O: primary 1: alternate */
#define FMC_WDT2_CTRL_EN BIT(0)
+#define R_FMC_WDT2_RELOAD (0x68 / 4)
+#define R_FMC_WDT2_RESTART (0x6C / 4)
/* DMA Control/Status Register */
#define R_DMA_CTRL (0x80 / 4)
@@ -704,6 +706,54 @@ static void aspeed_smc_reset(DeviceState *d)
s->snoop_dummies = 0;
}
+#define ASPEED_WDT_RELOAD 0x04
+#define ASPEED_WDT_RESTART 0x08
+#define ASPEED_WDT_CTRL 0x0C
+
+static void aspeed_smc_wdt2_write(AspeedSMCState *s, uint32_t offset,
+ uint32_t value)
+{
+ MemTxResult result;
+
+ address_space_stl_le(&s->wdt2_as, offset, value, MEMTXATTRS_UNSPECIFIED,
+ &result);
+ if (result != MEMTX_OK) {
+ aspeed_smc_error("WDT2 write failed @%08x", offset);
+ return;
+ }
+}
+
+static uint64_t aspeed_smc_wdt2_read(AspeedSMCState *s, uint32_t offset)
+{
+ MemTxResult result;
+ uint32_t value;
+
+ value = address_space_ldl_le(&s->wdt2_as, offset, MEMTXATTRS_UNSPECIFIED,
+ &result);
+ if (result != MEMTX_OK) {
+ aspeed_smc_error("WDT2 read failed @%08x", offset);
+ return -1;
+ }
+ return value;
+}
+
+static void aspeed_smc_wdt2_enable(AspeedSMCState *s, bool enable)
+{
+ uint32_t value;
+
+ value = aspeed_smc_wdt2_read(s, ASPEED_WDT_CTRL);
+ if (value == -1) {
+ return;
+ }
+
+ value &= ~BIT(0);
+ value |= enable;
+
+ aspeed_smc_wdt2_write(s, ASPEED_WDT_CTRL, value);
+
+ trace_aspeed_smc_wdt2_enable(enable ? "en" : "dis");
+}
+
static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, unsigned int size)
{
AspeedSMCState *s = ASPEED_SMC(opaque);
@@ -718,7 +768,6 @@ static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, unsigned int size)
addr == R_CE_CMD_CTRL ||
addr == R_INTR_CTRL ||
addr == R_DUMMY_DATA ||
- (aspeed_smc_has_wdt_control(asc) && addr == R_FMC_WDT2_CTRL) ||
(aspeed_smc_has_dma(asc) && addr == R_DMA_CTRL) ||
(aspeed_smc_has_dma(asc) && addr == R_DMA_FLASH_ADDR) ||
(aspeed_smc_has_dma(asc) && addr == R_DMA_DRAM_ADDR) ||
@@ -731,6 +780,10 @@ static uint64_t aspeed_smc_read(void *opaque, hwaddr addr, unsigned int size)
trace_aspeed_smc_read(addr << 2, size, s->regs[addr]);
return s->regs[addr];
+ } else if (aspeed_smc_has_wdt_control(asc) && addr == R_FMC_WDT2_CTRL) {
+ return aspeed_smc_wdt2_read(s, ASPEED_WDT_CTRL);
+ } else if (aspeed_smc_has_wdt_control(asc) && addr == R_FMC_WDT2_RELOAD) {
+ return aspeed_smc_wdt2_read(s, ASPEED_WDT_RELOAD) / 100000;
} else {
qemu_log_mask(LOG_UNIMP, "%s: not implemented: 0x%" HWADDR_PRIx "\n",
__func__, addr);
@@ -1053,7 +1106,11 @@ static void aspeed_smc_write(void *opaque, hwaddr addr, uint64_t data,
} else if (addr == R_DUMMY_DATA) {
s->regs[addr] = value & 0xff;
} else if (aspeed_smc_has_wdt_control(asc) && addr == R_FMC_WDT2_CTRL) {
- s->regs[addr] = value & FMC_WDT2_CTRL_EN;
+ aspeed_smc_wdt2_enable(s, !!(value & FMC_WDT2_CTRL_EN));
+ } else if (aspeed_smc_has_wdt_control(asc) && addr == R_FMC_WDT2_RELOAD) {
+ aspeed_smc_wdt2_write(s, ASPEED_WDT_RELOAD, value * 100000);
+ } else if (aspeed_smc_has_wdt_control(asc) && addr == R_FMC_WDT2_RESTART) {
+ aspeed_smc_wdt2_write(s, ASPEED_WDT_RESTART, value);
} else if (addr == R_INTR_CTRL) {
s->regs[addr] = value;
} else if (aspeed_smc_has_dma(asc) && addr == R_DMA_CTRL) {
@@ -1108,6 +1165,16 @@ static void aspeed_smc_dma_setup(AspeedSMCState *s, Error **errp)
TYPE_ASPEED_SMC ".dma-dram");
}
+static void aspeed_smc_wdt_setup(AspeedSMCState *s, Error **errp)
+{
+ if (!s->wdt2_mr) {
+ error_setg(errp, TYPE_ASPEED_SMC ": 'wdt2' link not set");
+ return;
+ }
+
+ address_space_init(&s->wdt2_as, s->wdt2_mr, TYPE_ASPEED_SMC ".wdt2");
+}
+
static void aspeed_smc_realize(DeviceState *dev, Error **errp)
{
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
@@ -1189,6 +1256,11 @@ static void aspeed_smc_realize(DeviceState *dev, Error **errp)
if (aspeed_smc_has_dma(asc)) {
aspeed_smc_dma_setup(s, errp);
}
+
+ /* WDT2 support */
+ if (aspeed_smc_has_wdt_control(asc)) {
+ aspeed_smc_wdt_setup(s, errp);
+ }
}
static const VMStateDescription vmstate_aspeed_smc = {
@@ -1208,6 +1280,8 @@ static Property aspeed_smc_properties[] = {
DEFINE_PROP_BOOL("inject-failure", AspeedSMCState, inject_failure, false),
DEFINE_PROP_LINK("dram", AspeedSMCState, dram_mr,
TYPE_MEMORY_REGION, MemoryRegion *),
+ DEFINE_PROP_LINK("wdt2", AspeedSMCState, wdt2_mr,
+ TYPE_MEMORY_REGION, MemoryRegion *),
DEFINE_PROP_END_OF_LIST(),
};
diff --git a/hw/ssi/trace-events b/hw/ssi/trace-events
index 612d3d6087aa..0de79bf9c6a5 100644
--- a/hw/ssi/trace-events
+++ b/hw/ssi/trace-events
@@ -9,6 +9,7 @@ aspeed_smc_dma_checksum(uint32_t addr, uint32_t data) "0x%08x: 0x%08x"
aspeed_smc_dma_rw(const char *dir, uint32_t flash_addr, uint32_t dram_addr, uint32_t size) "%s flash:@0x%08x dram:@0x%08x size:0x%08x"
aspeed_smc_write(uint64_t addr, uint32_t size, uint64_t data) "@0x%" PRIx64 " size %u: 0x%" PRIx64
aspeed_smc_flash_select(int cs, const char *prefix) "CS%d %sselect"
+aspeed_smc_wdt2_enable(const char *prefix) "WDT2 is %sabled"
# npcm7xx_fiu.c
--
2.31.1
next prev parent reply other threads:[~2021-10-04 15:56 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-10-04 15:46 [PATCH 0/4] aspeed/smc: Improve support for the alternate boot function Cédric Le Goater
2021-10-04 15:46 ` [PATCH 1/4] aspeed/wdt: Add trace events Cédric Le Goater
2021-10-05 9:16 ` Francisco Iglesias
2021-10-18 8:57 ` Philippe Mathieu-Daudé
2021-10-04 15:46 ` [PATCH 2/4] aspeed/smc: Dump address offset in " Cédric Le Goater
2021-10-05 8:55 ` Francisco Iglesias
2021-10-18 8:58 ` Philippe Mathieu-Daudé
2021-10-04 15:46 ` [PATCH 3/4] aspeed/wdt: Add an alias for the MMIO region Cédric Le Goater
2021-10-18 9:04 ` Philippe Mathieu-Daudé
2021-10-18 13:07 ` Cédric Le Goater
2021-10-04 15:46 ` Cédric Le Goater [this message]
2021-10-18 8:54 ` [PATCH 0/4] aspeed/smc: Improve support for the alternate boot function Cédric Le Goater
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=20211004154635.394258-5-clg@kaod.org \
--to=clg@kaod.org \
--cc=andrew@aj.id.au \
--cc=joel@jms.id.au \
--cc=pdel@fb.com \
--cc=peter.maydell@linaro.org \
--cc=qemu-arm@nongnu.org \
--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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.