* [PATCH v4 0/5] ASPEED OTP QEMU model: block backend, machine alias, SoC integration
@ 2025-07-08 5:57 Kane Chen via
2025-07-08 5:57 ` [PATCH v4 1/5] hw/misc/aspeed_otp: Add ASPEED OTP memory device model Kane Chen via
` (5 more replies)
0 siblings, 6 replies; 15+ messages in thread
From: Kane Chen via @ 2025-07-08 5:57 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Jamin Lin, Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs,
open list:All patches CC here
Cc: troy_lee, Kane-Chen-AS
From: Kane-Chen-AS <kane_chen@aspeedtech.com>
This patch series extends the QEMU model for the ASPEED OTP (One-Time
Programmable) memory device with block backend support and tighter
integration with the SoC and machine configuration.
The OTP model simulates a simple fuse array, used in ASPEED SoCs
for secure boot and configuration purposes. The updated model now
supports loading initial OTP content from a file via the QEMU CLI.
Example usage:
./qemu-system-arm \
-machine ast2600-evb,otpmem=otp \
-blockdev driver=file,filename=otpmem.img,node-name=otp \
-global aspeed-otp.drive=otp \
...
ChangeLog
---------
v4:
- Add a 'drive' property to allow backing OTP data with a block device
- Expose a machine parameter (`-machine otpmem=XXX`) for convenient
aliasing of the OTP drive via QOM path
v3:
- Switched to object_property_set_int() for setting "size"
- Simplified qdev_realize() error handling by passing errp directly
- Added "drive" property to OTP model for future extensibility
v2:
- Rename device from 'aspeed_otpmem' to 'aspeed_otp' and move it to hw/nvram/
- Move OTP device realization from instance_init to the realize function
- Improve error logging with qemu_log_mask() and remove unused error propagation
v1:
- Initial version
---
Kane-Chen-AS (5):
hw/misc/aspeed_otp: Add ASPEED OTP memory device model
hw/misc/aspeed_sbc: Connect ASPEED OTP memory device to SBC
hw/arm: Integrate ASPEED OTP memory support into AST2600 SoCs
hw/misc/aspeed_otp: Add 'drive' property to support block backend
hw/misc/aspeed_sbc: Add machine parameter to alias OTP drive property
include/hw/misc/aspeed_sbc.h | 5 ++
include/hw/nvram/aspeed_otp.h | 33 ++++++++++
hw/arm/aspeed.c | 20 ++++++
hw/arm/aspeed_ast2600.c | 2 +-
hw/misc/aspeed_sbc.c | 121 ++++++++++++++++++++++++++++++++++
hw/nvram/aspeed_otp.c | 113 +++++++++++++++++++++++++++++++
hw/misc/trace-events | 5 ++
hw/nvram/meson.build | 4 ++
8 files changed, 302 insertions(+), 1 deletion(-)
create mode 100644 include/hw/nvram/aspeed_otp.h
create mode 100644 hw/nvram/aspeed_otp.c
--
2.43.0
^ permalink raw reply [flat|nested] 15+ messages in thread
* [PATCH v4 1/5] hw/misc/aspeed_otp: Add ASPEED OTP memory device model
2025-07-08 5:57 [PATCH v4 0/5] ASPEED OTP QEMU model: block backend, machine alias, SoC integration Kane Chen via
@ 2025-07-08 5:57 ` Kane Chen via
2025-07-22 9:30 ` [SPAM] " Cédric Le Goater
2025-07-22 9:54 ` Cédric Le Goater
2025-07-08 5:57 ` [PATCH v4 2/5] hw/misc/aspeed_sbc: Connect ASPEED OTP memory device to SBC Kane Chen via
` (4 subsequent siblings)
5 siblings, 2 replies; 15+ messages in thread
From: Kane Chen via @ 2025-07-08 5:57 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Jamin Lin, Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs,
open list:All patches CC here
Cc: troy_lee, Kane-Chen-AS
From: Kane-Chen-AS <kane_chen@aspeedtech.com>
Introduce a QEMU device model for ASPEED's One-Time Programmable (OTP)
memory.
This model simulates a word-addressable OTP region used for secure
fuse storage. The OTP memory can operate with an internal memory
buffer.
The OTP model provides a memory-like interface through a dedicated
AddressSpace, allowing other device models (e.g., SBC) to issue
transactions as if accessing a memory-mapped region.
Signed-off-by: Kane-Chen-AS <kane_chen@aspeedtech.com>
---
include/hw/nvram/aspeed_otp.h | 33 ++++++++++++
hw/nvram/aspeed_otp.c | 99 +++++++++++++++++++++++++++++++++++
hw/nvram/meson.build | 4 ++
3 files changed, 136 insertions(+)
create mode 100644 include/hw/nvram/aspeed_otp.h
create mode 100644 hw/nvram/aspeed_otp.c
diff --git a/include/hw/nvram/aspeed_otp.h b/include/hw/nvram/aspeed_otp.h
new file mode 100644
index 0000000000..3752353860
--- /dev/null
+++ b/include/hw/nvram/aspeed_otp.h
@@ -0,0 +1,33 @@
+/*
+ * ASPEED OTP (One-Time Programmable) memory
+ *
+ * Copyright (C) 2025 Aspeed
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef ASPEED_OTP_H
+#define ASPEED_OTP_H
+
+#include "system/memory.h"
+#include "hw/block/block.h"
+#include "system/address-spaces.h"
+
+#define TYPE_ASPEED_OTP "aspeed-otp"
+OBJECT_DECLARE_SIMPLE_TYPE(AspeedOTPState, ASPEED_OTP)
+
+typedef struct AspeedOTPState {
+ DeviceState parent_obj;
+
+ BlockBackend *blk;
+
+ uint64_t size;
+
+ AddressSpace as;
+
+ MemoryRegion mmio;
+
+ uint8_t *storage;
+} AspeedOTPState;
+
+#endif /* ASPEED_OTP_H */
diff --git a/hw/nvram/aspeed_otp.c b/hw/nvram/aspeed_otp.c
new file mode 100644
index 0000000000..e41481d9bb
--- /dev/null
+++ b/hw/nvram/aspeed_otp.c
@@ -0,0 +1,99 @@
+/*
+ * ASPEED OTP (One-Time Programmable) memory
+ *
+ * Copyright (C) 2025 Aspeed
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/log.h"
+#include "qapi/error.h"
+#include "system/block-backend-io.h"
+#include "hw/qdev-properties.h"
+#include "hw/nvram/aspeed_otp.h"
+
+static uint64_t aspeed_otp_read(void *opaque, hwaddr offset, unsigned size)
+{
+ AspeedOTPState *s = opaque;
+ uint64_t val = 0;
+
+ memcpy(&val, s->storage + offset, size);
+
+ return val;
+}
+
+static void aspeed_otp_write(void *opaque, hwaddr offset,
+ uint64_t val, unsigned size)
+{
+ AspeedOTPState *s = opaque;
+
+ memcpy(s->storage + offset, &val, size);
+}
+
+static bool aspeed_otp_init_storage(AspeedOTPState *s, Error **errp)
+{
+ uint32_t *p;
+ int i, num;
+
+ num = s->size / sizeof(uint32_t);
+ p = (uint32_t *)s->storage;
+ for (i = 0; i < num; i++) {
+ p[i] = (i % 2 == 0) ? 0x00000000 : 0xFFFFFFFF;
+ }
+
+ return true;
+}
+
+static const MemoryRegionOps aspeed_otp_ops = {
+ .read = aspeed_otp_read,
+ .write = aspeed_otp_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+ .valid.min_access_size = 1,
+ .valid.max_access_size = 4,
+};
+
+static void aspeed_otp_realize(DeviceState *dev, Error **errp)
+{
+ AspeedOTPState *s = ASPEED_OTP(dev);
+
+ if (s->size == 0) {
+ error_setg(errp, "aspeed.otp: 'size' property must be set");
+ return;
+ }
+
+ s->storage = blk_blockalign(s->blk, s->size);
+
+ if (!aspeed_otp_init_storage(s, errp)) {
+ return;
+ }
+
+ memory_region_init_io(&s->mmio, OBJECT(dev), &aspeed_otp_ops,
+ s, "aspeed.otp", s->size);
+ address_space_init(&s->as, &s->mmio, NULL);
+}
+
+static const Property aspeed_otp_properties[] = {
+ DEFINE_PROP_UINT64("size", AspeedOTPState, size, 0),
+};
+
+static void aspeed_otp_class_init(ObjectClass *klass, const void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+ dc->realize = aspeed_otp_realize;
+ device_class_set_props(dc, aspeed_otp_properties);
+}
+
+static const TypeInfo aspeed_otp_info = {
+ .name = TYPE_ASPEED_OTP,
+ .parent = TYPE_DEVICE,
+ .instance_size = sizeof(AspeedOTPState),
+ .class_init = aspeed_otp_class_init,
+};
+
+static void aspeed_otp_register_types(void)
+{
+ type_register_static(&aspeed_otp_info);
+}
+
+type_init(aspeed_otp_register_types)
diff --git a/hw/nvram/meson.build b/hw/nvram/meson.build
index 10f3639db6..b66f23605b 100644
--- a/hw/nvram/meson.build
+++ b/hw/nvram/meson.build
@@ -19,3 +19,7 @@ system_ss.add(when: 'CONFIG_XLNX_BBRAM', if_true: files('xlnx-bbram.c'))
specific_ss.add(when: 'CONFIG_PSERIES', if_true: files('spapr_nvram.c'))
specific_ss.add(when: 'CONFIG_ACPI', if_true: files('fw_cfg-acpi.c'))
+
+system_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files(
+ 'aspeed_otp.c',
+ ))
\ No newline at end of file
--
2.43.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v4 2/5] hw/misc/aspeed_sbc: Connect ASPEED OTP memory device to SBC
2025-07-08 5:57 [PATCH v4 0/5] ASPEED OTP QEMU model: block backend, machine alias, SoC integration Kane Chen via
2025-07-08 5:57 ` [PATCH v4 1/5] hw/misc/aspeed_otp: Add ASPEED OTP memory device model Kane Chen via
@ 2025-07-08 5:57 ` Kane Chen via
2025-07-08 5:57 ` [PATCH v4 3/5] hw/arm: Integrate ASPEED OTP memory support into AST2600 SoCs Kane Chen via
` (3 subsequent siblings)
5 siblings, 0 replies; 15+ messages in thread
From: Kane Chen via @ 2025-07-08 5:57 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Jamin Lin, Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs,
open list:All patches CC here
Cc: troy_lee, Kane-Chen-AS, Cédric Le Goater
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="y", Size: 7472 bytes --]
From: Kane-Chen-AS <kane_chen@aspeedtech.com>
This patch connects the aspeed.otp device to the ASPEED Secure Boot
Controller (SBC) model. It implements OTP memory access via the SBC's
command interface and enables emulation of secure fuse programming flows.
The following OTP commands are supported:
- READ: reads a 32-bit word from OTP memory into internal registers
- PROG: programs a 32-bit word value to the specified OTP address
Trace events are added to observe read/program operations and command
handling flow.
Signed-off-by: Kane-Chen-AS <kane_chen@aspeedtech.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
---
include/hw/misc/aspeed_sbc.h | 5 ++
hw/misc/aspeed_sbc.c | 111 +++++++++++++++++++++++++++++++++++
hw/misc/trace-events | 5 ++
3 files changed, 121 insertions(+)
diff --git a/include/hw/misc/aspeed_sbc.h b/include/hw/misc/aspeed_sbc.h
index 405e6782b9..0c2746d392 100644
--- a/include/hw/misc/aspeed_sbc.h
+++ b/include/hw/misc/aspeed_sbc.h
@@ -10,6 +10,7 @@
#define ASPEED_SBC_H
#include "hw/sysbus.h"
+#include "hw/nvram/aspeed_otp.h"
#define TYPE_ASPEED_SBC "aspeed.sbc"
#define TYPE_ASPEED_AST2600_SBC TYPE_ASPEED_SBC "-ast2600"
@@ -36,10 +37,14 @@ struct AspeedSBCState {
MemoryRegion iomem;
uint32_t regs[ASPEED_SBC_NR_REGS];
+
+ AspeedOTPState otp;
};
struct AspeedSBCClass {
SysBusDeviceClass parent_class;
+
+ bool has_otp;
};
#endif /* ASPEED_SBC_H */
diff --git a/hw/misc/aspeed_sbc.c b/hw/misc/aspeed_sbc.c
index a7d101ba71..46a038337c 100644
--- a/hw/misc/aspeed_sbc.c
+++ b/hw/misc/aspeed_sbc.c
@@ -15,9 +15,13 @@
#include "hw/misc/aspeed_sbc.h"
#include "qapi/error.h"
#include "migration/vmstate.h"
+#include "trace.h"
#define R_PROT (0x000 / 4)
+#define R_CMD (0x004 / 4)
+#define R_ADDR (0x010 / 4)
#define R_STATUS (0x014 / 4)
+#define R_CAMP1 (0x020 / 4)
#define R_QSR (0x040 / 4)
/* R_STATUS */
@@ -41,6 +45,11 @@
#define QSR_RSA_MASK (0x3 << 12)
#define QSR_HASH_MASK (0x3 << 10)
+#define OTP_MEMORY_SIZE 0x4000
+/* OTP command */
+#define SBC_OTP_CMD_READ 0x23b1e361
+#define SBC_OTP_CMD_PROG 0x23b1e364
+
static uint64_t aspeed_sbc_read(void *opaque, hwaddr addr, unsigned int size)
{
AspeedSBCState *s = ASPEED_SBC(opaque);
@@ -57,6 +66,84 @@ static uint64_t aspeed_sbc_read(void *opaque, hwaddr addr, unsigned int size)
return s->regs[addr];
}
+static bool aspeed_sbc_otp_read(AspeedSBCState *s,
+ uint32_t otp_addr)
+{
+ MemTxResult ret;
+ AspeedOTPState *otp = &s->otp;
+ uint32_t value, otp_offset;
+
+ otp_offset = otp_addr << 2;
+ ret = address_space_read(&otp->as, otp_offset, MEMTXATTRS_UNSPECIFIED,
+ &value, sizeof(value));
+ if (ret != MEMTX_OK) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "Failed to read OTP memory, addr = %x\n",
+ otp_addr);
+ return false;
+ }
+ s->regs[R_CAMP1] = value;
+ trace_aspeed_sbc_otp_read(otp_addr, value);
+
+ return true;
+}
+
+static bool aspeed_sbc_otp_prog(AspeedSBCState *s,
+ uint32_t otp_addr)
+{
+ MemTxResult ret;
+ AspeedOTPState *otp = &s->otp;
+ uint32_t value = s->regs[R_CAMP1];
+
+ ret = address_space_write(&otp->as, otp_addr, MEMTXATTRS_UNSPECIFIED,
+ &value, sizeof(value));
+ if (ret != MEMTX_OK) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "Failed to write OTP memory, addr = %x\n",
+ otp_addr);
+ return false;
+ }
+
+ trace_aspeed_sbc_otp_prog(otp_addr, value);
+
+ return true;
+}
+
+static void aspeed_sbc_handle_command(void *opaque, uint32_t cmd)
+{
+ AspeedSBCState *s = ASPEED_SBC(opaque);
+ AspeedSBCClass *sc = ASPEED_SBC_GET_CLASS(opaque);
+ bool ret = false;
+ uint32_t otp_addr;
+
+ if (!sc->has_otp) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: OTP memory is not supported\n",
+ __func__);
+ return;
+ }
+
+ s->regs[R_STATUS] &= ~(OTP_MEM_IDLE | OTP_IDLE);
+ otp_addr = s->regs[R_ADDR];
+
+ switch (cmd) {
+ case SBC_OTP_CMD_READ:
+ ret = aspeed_sbc_otp_read(s, otp_addr);
+ break;
+ case SBC_OTP_CMD_PROG:
+ ret = aspeed_sbc_otp_prog(s, otp_addr);
+ break;
+ default:
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: Unknown command 0x%x\n",
+ __func__, cmd);
+ break;
+ }
+
+ trace_aspeed_sbc_handle_cmd(cmd, otp_addr, ret);
+ s->regs[R_STATUS] |= (OTP_MEM_IDLE | OTP_IDLE);
+}
+
static void aspeed_sbc_write(void *opaque, hwaddr addr, uint64_t data,
unsigned int size)
{
@@ -78,6 +165,9 @@ static void aspeed_sbc_write(void *opaque, hwaddr addr, uint64_t data,
"%s: write to read only register 0x%" HWADDR_PRIx "\n",
__func__, addr << 2);
return;
+ case R_CMD:
+ aspeed_sbc_handle_command(opaque, data);
+ return;
default:
break;
}
@@ -115,10 +205,30 @@ static void aspeed_sbc_reset(DeviceState *dev)
s->regs[R_QSR] = s->signing_settings;
}
+static void aspeed_sbc_instance_init(Object *obj)
+{
+ AspeedSBCClass *sc = ASPEED_SBC_GET_CLASS(obj);
+ AspeedSBCState *s = ASPEED_SBC(obj);
+
+ if (sc->has_otp) {
+ object_initialize_child(OBJECT(s), "otp", &s->otp,
+ TYPE_ASPEED_OTP);
+ }
+}
+
static void aspeed_sbc_realize(DeviceState *dev, Error **errp)
{
AspeedSBCState *s = ASPEED_SBC(dev);
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+ AspeedSBCClass *sc = ASPEED_SBC_GET_CLASS(dev);
+
+ if (sc->has_otp) {
+ object_property_set_int(OBJECT(&s->otp), "size",
+ OTP_MEMORY_SIZE, &error_abort);
+ if (!qdev_realize(DEVICE(&s->otp), NULL, errp)) {
+ return;
+ }
+ }
memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_sbc_ops, s,
TYPE_ASPEED_SBC, 0x1000);
@@ -155,6 +265,7 @@ static const TypeInfo aspeed_sbc_info = {
.name = TYPE_ASPEED_SBC,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(AspeedSBCState),
+ .instance_init = aspeed_sbc_instance_init,
.class_init = aspeed_sbc_class_init,
.class_size = sizeof(AspeedSBCClass)
};
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
index e3f64c0ff6..9e05b82f37 100644
--- a/hw/misc/trace-events
+++ b/hw/misc/trace-events
@@ -90,6 +90,11 @@ slavio_sysctrl_mem_readl(uint32_t ret) "Read system control 0x%08x"
slavio_led_mem_writew(uint32_t val) "Write diagnostic LED 0x%04x"
slavio_led_mem_readw(uint32_t ret) "Read diagnostic LED 0x%04x"
+# aspeed_sbc.c
+aspeed_sbc_handle_cmd(uint32_t cmd, uint32_t addr, bool ret) "Handling command 0x%" PRIx32 " for OTP addr 0x%" PRIx32 " Result: %d"
+aspeed_sbc_otp_read(uint32_t addr, uint32_t value) "OTP Memory read: addr 0x%" PRIx32 " value 0x%" PRIx32
+aspeed_sbc_otp_prog(uint32_t addr, uint32_t value) "OTP Memory write: addr 0x%" PRIx32 " value 0x%" PRIx32
+
# aspeed_scu.c
aspeed_scu_write(uint64_t offset, unsigned size, uint32_t data) "To 0x%" PRIx64 " of size %u: 0x%" PRIx32
aspeed_scu_read(uint64_t offset, unsigned size, uint32_t data) "To 0x%" PRIx64 " of size %u: 0x%" PRIx32
--
2.43.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v4 3/5] hw/arm: Integrate ASPEED OTP memory support into AST2600 SoCs
2025-07-08 5:57 [PATCH v4 0/5] ASPEED OTP QEMU model: block backend, machine alias, SoC integration Kane Chen via
2025-07-08 5:57 ` [PATCH v4 1/5] hw/misc/aspeed_otp: Add ASPEED OTP memory device model Kane Chen via
2025-07-08 5:57 ` [PATCH v4 2/5] hw/misc/aspeed_sbc: Connect ASPEED OTP memory device to SBC Kane Chen via
@ 2025-07-08 5:57 ` Kane Chen via
2025-07-08 5:57 ` [PATCH v4 4/5] hw/misc/aspeed_otp: Add 'drive' property to support block backend Kane Chen via
` (2 subsequent siblings)
5 siblings, 0 replies; 15+ messages in thread
From: Kane Chen via @ 2025-07-08 5:57 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Jamin Lin, Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs,
open list:All patches CC here
Cc: troy_lee, Kane-Chen-AS, Cédric Le Goater
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="y", Size: 1537 bytes --]
From: Kane-Chen-AS <kane_chen@aspeedtech.com>
The has_otpmem attribute is enabled in the SBC subclasses for AST2600
to control the presence of OTP support per SoC type.
Signed-off-by: Kane-Chen-AS <kane_chen@aspeedtech.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
---
hw/arm/aspeed_ast2600.c | 2 +-
hw/misc/aspeed_sbc.c | 2 ++
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c
index d12707f0ab..59ffd41a4a 100644
--- a/hw/arm/aspeed_ast2600.c
+++ b/hw/arm/aspeed_ast2600.c
@@ -261,7 +261,7 @@ static void aspeed_soc_ast2600_init(Object *obj)
object_initialize_child(obj, "i3c", &s->i3c, TYPE_ASPEED_I3C);
- object_initialize_child(obj, "sbc", &s->sbc, TYPE_ASPEED_SBC);
+ object_initialize_child(obj, "sbc", &s->sbc, TYPE_ASPEED_AST2600_SBC);
object_initialize_child(obj, "iomem", &s->iomem, TYPE_UNIMPLEMENTED_DEVICE);
object_initialize_child(obj, "video", &s->video, TYPE_UNIMPLEMENTED_DEVICE);
diff --git a/hw/misc/aspeed_sbc.c b/hw/misc/aspeed_sbc.c
index 46a038337c..b56a8b7678 100644
--- a/hw/misc/aspeed_sbc.c
+++ b/hw/misc/aspeed_sbc.c
@@ -273,8 +273,10 @@ static const TypeInfo aspeed_sbc_info = {
static void aspeed_ast2600_sbc_class_init(ObjectClass *klass, const void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
+ AspeedSBCClass *sc = ASPEED_SBC_CLASS(klass);
dc->desc = "AST2600 Secure Boot Controller";
+ sc->has_otp = true;
}
static const TypeInfo aspeed_ast2600_sbc_info = {
--
2.43.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v4 4/5] hw/misc/aspeed_otp: Add 'drive' property to support block backend
2025-07-08 5:57 [PATCH v4 0/5] ASPEED OTP QEMU model: block backend, machine alias, SoC integration Kane Chen via
` (2 preceding siblings ...)
2025-07-08 5:57 ` [PATCH v4 3/5] hw/arm: Integrate ASPEED OTP memory support into AST2600 SoCs Kane Chen via
@ 2025-07-08 5:57 ` Kane Chen via
2025-07-22 9:30 ` [SPAM] " Cédric Le Goater
2025-07-08 5:57 ` [PATCH v4 5/5] hw/misc/aspeed_sbc: Add machine parameter to alias OTP drive property Kane Chen via
2025-07-22 9:41 ` [SPAM] [PATCH v4 0/5] ASPEED OTP QEMU model: block backend, machine alias, SoC integration Cédric Le Goater
5 siblings, 1 reply; 15+ messages in thread
From: Kane Chen via @ 2025-07-08 5:57 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Jamin Lin, Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs,
open list:All patches CC here
Cc: troy_lee, Kane-Chen-AS
From: Kane-Chen-AS <kane_chen@aspeedtech.com>
This patch introduces a 'drive' property to the Aspeed OTP device,
allowing it to be backed by a block device. Users can now preload
OTP data via QEMU CLI using a block backend.
Example usage:
./qemu-system-arm \
-blockdev driver=file,filename=otpmem.img,node-name=otp \
-global aspeed-otp.drive=otp \
...
If the drive is provided, its content will be loaded as the initial OTP state.
Otherwise, an internal memory buffer will be used.
Signed-off-by: Kane-Chen-AS <kane_chen@aspeedtech.com>
---
hw/nvram/aspeed_otp.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
diff --git a/hw/nvram/aspeed_otp.c b/hw/nvram/aspeed_otp.c
index e41481d9bb..f018c58713 100644
--- a/hw/nvram/aspeed_otp.c
+++ b/hw/nvram/aspeed_otp.c
@@ -9,6 +9,7 @@
#include "qemu/osdep.h"
#include "qemu/log.h"
#include "qapi/error.h"
+#include "system/block-backend-global-state.h"
#include "system/block-backend-io.h"
#include "hw/qdev-properties.h"
#include "hw/nvram/aspeed_otp.h"
@@ -35,13 +36,25 @@ static bool aspeed_otp_init_storage(AspeedOTPState *s, Error **errp)
{
uint32_t *p;
int i, num;
+ uint64_t perm;
+ if (s->blk) {
+ perm = BLK_PERM_CONSISTENT_READ |
+ (blk_supports_write_perm(s->blk) ? BLK_PERM_WRITE : 0);
+ if (blk_set_perm(s->blk, perm, BLK_PERM_ALL, errp) < 0) {
+ return false;
+ }
+ if (blk_pread(s->blk, 0, s->size, s->storage, 0) < 0) {
+ error_setg(errp, "Failed to read the initial flash content");
+ return false;
+ }
+ } else {
num = s->size / sizeof(uint32_t);
p = (uint32_t *)s->storage;
for (i = 0; i < num; i++) {
p[i] = (i % 2 == 0) ? 0x00000000 : 0xFFFFFFFF;
}
-
+ }
return true;
}
@@ -75,6 +88,7 @@ static void aspeed_otp_realize(DeviceState *dev, Error **errp)
static const Property aspeed_otp_properties[] = {
DEFINE_PROP_UINT64("size", AspeedOTPState, size, 0),
+ DEFINE_PROP_DRIVE("drive", AspeedOTPState, blk),
};
static void aspeed_otp_class_init(ObjectClass *klass, const void *data)
--
2.43.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* [PATCH v4 5/5] hw/misc/aspeed_sbc: Add machine parameter to alias OTP drive property
2025-07-08 5:57 [PATCH v4 0/5] ASPEED OTP QEMU model: block backend, machine alias, SoC integration Kane Chen via
` (3 preceding siblings ...)
2025-07-08 5:57 ` [PATCH v4 4/5] hw/misc/aspeed_otp: Add 'drive' property to support block backend Kane Chen via
@ 2025-07-08 5:57 ` Kane Chen via
2025-07-22 9:35 ` [SPAM] " Cédric Le Goater
2025-07-22 9:41 ` [SPAM] [PATCH v4 0/5] ASPEED OTP QEMU model: block backend, machine alias, SoC integration Cédric Le Goater
5 siblings, 1 reply; 15+ messages in thread
From: Kane Chen via @ 2025-07-08 5:57 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Jamin Lin, Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs,
open list:All patches CC here
Cc: troy_lee, Kane-Chen-AS
From: Kane-Chen-AS <kane_chen@aspeedtech.com>
This patch adds a new machine parameter `otpmem` which creates a QOM
property alias on the aspeed_sbc device for the OTP drive.
Example usage:
./qemu-system-arm \
-machine ast2600-evb,otpmem=otp-drive \
-blockdev driver=file,filename=otpmem.img,node-name=otp \
-global aspeed-otp.drive=otp \
...
With this change, the specified alias name (e.g. "otp-drive") becomes
available on the QOM path `/machine/soc/sbc/otp-drive`.
Signed-off-by: Kane-Chen-AS <kane_chen@aspeedtech.com>
---
hw/arm/aspeed.c | 20 ++++++++++++++++++++
hw/misc/aspeed_sbc.c | 8 ++++++++
2 files changed, 28 insertions(+)
diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
index c31bbe7701..8ec32369a6 100644
--- a/hw/arm/aspeed.c
+++ b/hw/arm/aspeed.c
@@ -48,6 +48,7 @@ struct AspeedMachineState {
uint32_t uart_chosen;
char *fmc_model;
char *spi_model;
+ char *otpmem;
uint32_t hw_strap1;
};
@@ -1424,6 +1425,21 @@ static void aspeed_set_bmc_console(Object *obj, const char *value, Error **errp)
bmc->uart_chosen = val + ASPEED_DEV_UART0;
}
+static char *aspeed_get_otpmem(Object *obj, Error **errp)
+{
+ AspeedMachineState *bmc = ASPEED_MACHINE(obj);
+
+ return g_strdup(bmc->otpmem);
+}
+
+static void aspeed_set_otpmem(Object *obj, const char *value, Error **errp)
+{
+ AspeedMachineState *bmc = ASPEED_MACHINE(obj);
+
+ g_free(bmc->otpmem);
+ bmc->otpmem = g_strdup(value);
+}
+
static void aspeed_machine_class_props_init(ObjectClass *oc)
{
object_class_property_add_bool(oc, "execute-in-place",
@@ -1445,6 +1461,10 @@ static void aspeed_machine_class_props_init(ObjectClass *oc)
aspeed_set_spi_model);
object_class_property_set_description(oc, "spi-model",
"Change the SPI Flash model");
+ object_class_property_add_str(oc, "otpmem", aspeed_get_otpmem,
+ aspeed_set_otpmem);
+ object_class_property_set_description(oc, "otpmem",
+ "Set OTP Memory type");
}
static void aspeed_machine_class_init_cpus_defaults(MachineClass *mc)
diff --git a/hw/misc/aspeed_sbc.c b/hw/misc/aspeed_sbc.c
index b56a8b7678..b82c5e37cc 100644
--- a/hw/misc/aspeed_sbc.c
+++ b/hw/misc/aspeed_sbc.c
@@ -209,10 +209,18 @@ static void aspeed_sbc_instance_init(Object *obj)
{
AspeedSBCClass *sc = ASPEED_SBC_GET_CLASS(obj);
AspeedSBCState *s = ASPEED_SBC(obj);
+ char *otpname;
if (sc->has_otp) {
object_initialize_child(OBJECT(s), "otp", &s->otp,
TYPE_ASPEED_OTP);
+ otpname = object_property_get_str(qdev_get_machine(),
+ "otpmem",
+ &error_abort);
+ if (strlen(otpname)) {
+ object_property_add_alias(obj, otpname,
+ OBJECT(&s->otp), "drive");
+ }
}
}
--
2.43.0
^ permalink raw reply related [flat|nested] 15+ messages in thread
* Re: [SPAM] [PATCH v4 1/5] hw/misc/aspeed_otp: Add ASPEED OTP memory device model
2025-07-08 5:57 ` [PATCH v4 1/5] hw/misc/aspeed_otp: Add ASPEED OTP memory device model Kane Chen via
@ 2025-07-22 9:30 ` Cédric Le Goater
2025-07-22 9:54 ` Cédric Le Goater
1 sibling, 0 replies; 15+ messages in thread
From: Cédric Le Goater @ 2025-07-22 9:30 UTC (permalink / raw)
To: Kane Chen, Peter Maydell, Steven Lee, Troy Lee, Jamin Lin,
Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs,
open list:All patches CC here
Cc: troy_lee
On 7/8/25 07:57, Kane Chen wrote:
> From: Kane-Chen-AS <kane_chen@aspeedtech.com>
>
> Introduce a QEMU device model for ASPEED's One-Time Programmable (OTP)
> memory.
>
> This model simulates a word-addressable OTP region used for secure
> fuse storage. The OTP memory can operate with an internal memory
> buffer.
>
> The OTP model provides a memory-like interface through a dedicated
> AddressSpace, allowing other device models (e.g., SBC) to issue
> transactions as if accessing a memory-mapped region.
>
> Signed-off-by: Kane-Chen-AS <kane_chen@aspeedtech.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Thanks,
C.
> ---
> include/hw/nvram/aspeed_otp.h | 33 ++++++++++++
> hw/nvram/aspeed_otp.c | 99 +++++++++++++++++++++++++++++++++++
> hw/nvram/meson.build | 4 ++
> 3 files changed, 136 insertions(+)
> create mode 100644 include/hw/nvram/aspeed_otp.h
> create mode 100644 hw/nvram/aspeed_otp.c
>
> diff --git a/include/hw/nvram/aspeed_otp.h b/include/hw/nvram/aspeed_otp.h
> new file mode 100644
> index 0000000000..3752353860
> --- /dev/null
> +++ b/include/hw/nvram/aspeed_otp.h
> @@ -0,0 +1,33 @@
> +/*
> + * ASPEED OTP (One-Time Programmable) memory
> + *
> + * Copyright (C) 2025 Aspeed
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#ifndef ASPEED_OTP_H
> +#define ASPEED_OTP_H
> +
> +#include "system/memory.h"
> +#include "hw/block/block.h"
> +#include "system/address-spaces.h"
> +
> +#define TYPE_ASPEED_OTP "aspeed-otp"
> +OBJECT_DECLARE_SIMPLE_TYPE(AspeedOTPState, ASPEED_OTP)
> +
> +typedef struct AspeedOTPState {
> + DeviceState parent_obj;
> +
> + BlockBackend *blk;
> +
> + uint64_t size;
> +
> + AddressSpace as;
> +
> + MemoryRegion mmio;
> +
> + uint8_t *storage;
> +} AspeedOTPState;
> +
> +#endif /* ASPEED_OTP_H */
> diff --git a/hw/nvram/aspeed_otp.c b/hw/nvram/aspeed_otp.c
> new file mode 100644
> index 0000000000..e41481d9bb
> --- /dev/null
> +++ b/hw/nvram/aspeed_otp.c
> @@ -0,0 +1,99 @@
> +/*
> + * ASPEED OTP (One-Time Programmable) memory
> + *
> + * Copyright (C) 2025 Aspeed
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/log.h"
> +#include "qapi/error.h"
> +#include "system/block-backend-io.h"
> +#include "hw/qdev-properties.h"
> +#include "hw/nvram/aspeed_otp.h"
> +
> +static uint64_t aspeed_otp_read(void *opaque, hwaddr offset, unsigned size)
> +{
> + AspeedOTPState *s = opaque;
> + uint64_t val = 0;
> +
> + memcpy(&val, s->storage + offset, size);
> +
> + return val;
> +}
> +
> +static void aspeed_otp_write(void *opaque, hwaddr offset,
> + uint64_t val, unsigned size)
> +{
> + AspeedOTPState *s = opaque;
> +
> + memcpy(s->storage + offset, &val, size);
> +}
> +
> +static bool aspeed_otp_init_storage(AspeedOTPState *s, Error **errp)
> +{
> + uint32_t *p;
> + int i, num;
> +
> + num = s->size / sizeof(uint32_t);
> + p = (uint32_t *)s->storage;
> + for (i = 0; i < num; i++) {
> + p[i] = (i % 2 == 0) ? 0x00000000 : 0xFFFFFFFF;
> + }
> +
> + return true;
> +}
> +
> +static const MemoryRegionOps aspeed_otp_ops = {
> + .read = aspeed_otp_read,
> + .write = aspeed_otp_write,
> + .endianness = DEVICE_LITTLE_ENDIAN,
> + .valid.min_access_size = 1,
> + .valid.max_access_size = 4,
> +};
> +
> +static void aspeed_otp_realize(DeviceState *dev, Error **errp)
> +{
> + AspeedOTPState *s = ASPEED_OTP(dev);
> +
> + if (s->size == 0) {
> + error_setg(errp, "aspeed.otp: 'size' property must be set");
> + return;
> + }
> +
> + s->storage = blk_blockalign(s->blk, s->size);
> +
> + if (!aspeed_otp_init_storage(s, errp)) {
> + return;
> + }
> +
> + memory_region_init_io(&s->mmio, OBJECT(dev), &aspeed_otp_ops,
> + s, "aspeed.otp", s->size);
> + address_space_init(&s->as, &s->mmio, NULL);
> +}
> +
> +static const Property aspeed_otp_properties[] = {
> + DEFINE_PROP_UINT64("size", AspeedOTPState, size, 0),
> +};
> +
> +static void aspeed_otp_class_init(ObjectClass *klass, const void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(klass);
> + dc->realize = aspeed_otp_realize;
> + device_class_set_props(dc, aspeed_otp_properties);
> +}
> +
> +static const TypeInfo aspeed_otp_info = {
> + .name = TYPE_ASPEED_OTP,
> + .parent = TYPE_DEVICE,
> + .instance_size = sizeof(AspeedOTPState),
> + .class_init = aspeed_otp_class_init,
> +};
> +
> +static void aspeed_otp_register_types(void)
> +{
> + type_register_static(&aspeed_otp_info);
> +}
> +
> +type_init(aspeed_otp_register_types)
> diff --git a/hw/nvram/meson.build b/hw/nvram/meson.build
> index 10f3639db6..b66f23605b 100644
> --- a/hw/nvram/meson.build
> +++ b/hw/nvram/meson.build
> @@ -19,3 +19,7 @@ system_ss.add(when: 'CONFIG_XLNX_BBRAM', if_true: files('xlnx-bbram.c'))
>
> specific_ss.add(when: 'CONFIG_PSERIES', if_true: files('spapr_nvram.c'))
> specific_ss.add(when: 'CONFIG_ACPI', if_true: files('fw_cfg-acpi.c'))
> +
> +system_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files(
> + 'aspeed_otp.c',
> + ))
> \ No newline at end of file
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [SPAM] [PATCH v4 4/5] hw/misc/aspeed_otp: Add 'drive' property to support block backend
2025-07-08 5:57 ` [PATCH v4 4/5] hw/misc/aspeed_otp: Add 'drive' property to support block backend Kane Chen via
@ 2025-07-22 9:30 ` Cédric Le Goater
2025-07-22 10:27 ` Alex Bennée
0 siblings, 1 reply; 15+ messages in thread
From: Cédric Le Goater @ 2025-07-22 9:30 UTC (permalink / raw)
To: Kane Chen, Peter Maydell, Steven Lee, Troy Lee, Jamin Lin,
Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs,
open list:All patches CC here
Cc: troy_lee
On 7/8/25 07:57, Kane Chen wrote:
> From: Kane-Chen-AS <kane_chen@aspeedtech.com>
>
> This patch introduces a 'drive' property to the Aspeed OTP device,
> allowing it to be backed by a block device. Users can now preload
> OTP data via QEMU CLI using a block backend.
>
> Example usage:
> ./qemu-system-arm \
> -blockdev driver=file,filename=otpmem.img,node-name=otp \
> -global aspeed-otp.drive=otp \
> ...
>
> If the drive is provided, its content will be loaded as the initial OTP state.
> Otherwise, an internal memory buffer will be used.
>
> Signed-off-by: Kane-Chen-AS <kane_chen@aspeedtech.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Thanks,
C.
> ---
> hw/nvram/aspeed_otp.c | 16 +++++++++++++++-
> 1 file changed, 15 insertions(+), 1 deletion(-)
>
> diff --git a/hw/nvram/aspeed_otp.c b/hw/nvram/aspeed_otp.c
> index e41481d9bb..f018c58713 100644
> --- a/hw/nvram/aspeed_otp.c
> +++ b/hw/nvram/aspeed_otp.c
> @@ -9,6 +9,7 @@
> #include "qemu/osdep.h"
> #include "qemu/log.h"
> #include "qapi/error.h"
> +#include "system/block-backend-global-state.h"
> #include "system/block-backend-io.h"
> #include "hw/qdev-properties.h"
> #include "hw/nvram/aspeed_otp.h"
> @@ -35,13 +36,25 @@ static bool aspeed_otp_init_storage(AspeedOTPState *s, Error **errp)
> {
> uint32_t *p;
> int i, num;
> + uint64_t perm;
>
> + if (s->blk) {
> + perm = BLK_PERM_CONSISTENT_READ |
> + (blk_supports_write_perm(s->blk) ? BLK_PERM_WRITE : 0);
> + if (blk_set_perm(s->blk, perm, BLK_PERM_ALL, errp) < 0) {
> + return false;
> + }
> + if (blk_pread(s->blk, 0, s->size, s->storage, 0) < 0) {
> + error_setg(errp, "Failed to read the initial flash content");
> + return false;
> + }
> + } else {
> num = s->size / sizeof(uint32_t);
> p = (uint32_t *)s->storage;
> for (i = 0; i < num; i++) {
> p[i] = (i % 2 == 0) ? 0x00000000 : 0xFFFFFFFF;
> }
> -
> + }
> return true;
> }
>
> @@ -75,6 +88,7 @@ static void aspeed_otp_realize(DeviceState *dev, Error **errp)
>
> static const Property aspeed_otp_properties[] = {
> DEFINE_PROP_UINT64("size", AspeedOTPState, size, 0),
> + DEFINE_PROP_DRIVE("drive", AspeedOTPState, blk),
> };
>
> static void aspeed_otp_class_init(ObjectClass *klass, const void *data)
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [SPAM] [PATCH v4 5/5] hw/misc/aspeed_sbc: Add machine parameter to alias OTP drive property
2025-07-08 5:57 ` [PATCH v4 5/5] hw/misc/aspeed_sbc: Add machine parameter to alias OTP drive property Kane Chen via
@ 2025-07-22 9:35 ` Cédric Le Goater
0 siblings, 0 replies; 15+ messages in thread
From: Cédric Le Goater @ 2025-07-22 9:35 UTC (permalink / raw)
To: Kane Chen, Peter Maydell, Steven Lee, Troy Lee, Jamin Lin,
Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs,
open list:All patches CC here
Cc: troy_lee
On 7/8/25 07:57, Kane Chen wrote:
> From: Kane-Chen-AS <kane_chen@aspeedtech.com>
>
> This patch adds a new machine parameter `otpmem` which creates a QOM
> property alias on the aspeed_sbc device for the OTP drive.
>
> Example usage:
>
> ./qemu-system-arm \
> -machine ast2600-evb,otpmem=otp-drive \
> -blockdev driver=file,filename=otpmem.img,node-name=otp \
> -global aspeed-otp.drive=otp \
> ...
>
> With this change, the specified alias name (e.g. "otp-drive") becomes
> available on the QOM path `/machine/soc/sbc/otp-drive`.
>
> Signed-off-by: Kane-Chen-AS <kane_chen@aspeedtech.com>
> ---
> hw/arm/aspeed.c | 20 ++++++++++++++++++++
> hw/misc/aspeed_sbc.c | 8 ++++++++
> 2 files changed, 28 insertions(+)
>
> diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c
> index c31bbe7701..8ec32369a6 100644
> --- a/hw/arm/aspeed.c
> +++ b/hw/arm/aspeed.c
> @@ -48,6 +48,7 @@ struct AspeedMachineState {
> uint32_t uart_chosen;
> char *fmc_model;
> char *spi_model;
> + char *otpmem;
> uint32_t hw_strap1;
> };
>
> @@ -1424,6 +1425,21 @@ static void aspeed_set_bmc_console(Object *obj, const char *value, Error **errp)
> bmc->uart_chosen = val + ASPEED_DEV_UART0;
> }
>
> +static char *aspeed_get_otpmem(Object *obj, Error **errp)
> +{
> + AspeedMachineState *bmc = ASPEED_MACHINE(obj);
> +
> + return g_strdup(bmc->otpmem);
> +}
> +
> +static void aspeed_set_otpmem(Object *obj, const char *value, Error **errp)
> +{
> + AspeedMachineState *bmc = ASPEED_MACHINE(obj);
> +
> + g_free(bmc->otpmem);
> + bmc->otpmem = g_strdup(value);
> +}
> +
> static void aspeed_machine_class_props_init(ObjectClass *oc)
> {
> object_class_property_add_bool(oc, "execute-in-place",
> @@ -1445,6 +1461,10 @@ static void aspeed_machine_class_props_init(ObjectClass *oc)
> aspeed_set_spi_model);
> object_class_property_set_description(oc, "spi-model",
> "Change the SPI Flash model");
> + object_class_property_add_str(oc, "otpmem", aspeed_get_otpmem,
> + aspeed_set_otpmem);
> + object_class_property_set_description(oc, "otpmem",
> + "Set OTP Memory type");
> }
>
> static void aspeed_machine_class_init_cpus_defaults(MachineClass *mc)
> diff --git a/hw/misc/aspeed_sbc.c b/hw/misc/aspeed_sbc.c
> index b56a8b7678..b82c5e37cc 100644
> --- a/hw/misc/aspeed_sbc.c
> +++ b/hw/misc/aspeed_sbc.c
> @@ -209,10 +209,18 @@ static void aspeed_sbc_instance_init(Object *obj)
> {
> AspeedSBCClass *sc = ASPEED_SBC_GET_CLASS(obj);
> AspeedSBCState *s = ASPEED_SBC(obj);
> + char *otpname;
>
> if (sc->has_otp) {
> object_initialize_child(OBJECT(s), "otp", &s->otp,
> TYPE_ASPEED_OTP);
> + otpname = object_property_get_str(qdev_get_machine(),
> + "otpmem",> + &error_abort);
This is a hack and I would prefer to prevent device models from
accessing directly the machine.
It would have been nice to have a machine option, but since the
user can specify a file for the OTP backend from the command line,
let's leave it as is.
Thanks,
C.
> + if (strlen(otpname)) {
> + object_property_add_alias(obj, otpname,
> + OBJECT(&s->otp), "drive");
> + }
> }
> }
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [SPAM] [PATCH v4 0/5] ASPEED OTP QEMU model: block backend, machine alias, SoC integration
2025-07-08 5:57 [PATCH v4 0/5] ASPEED OTP QEMU model: block backend, machine alias, SoC integration Kane Chen via
` (4 preceding siblings ...)
2025-07-08 5:57 ` [PATCH v4 5/5] hw/misc/aspeed_sbc: Add machine parameter to alias OTP drive property Kane Chen via
@ 2025-07-22 9:41 ` Cédric Le Goater
2025-07-22 10:03 ` Kane Chen
5 siblings, 1 reply; 15+ messages in thread
From: Cédric Le Goater @ 2025-07-22 9:41 UTC (permalink / raw)
To: Kane Chen, Peter Maydell, Steven Lee, Troy Lee, Jamin Lin,
Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs,
open list:All patches CC here
Cc: troy_lee
On 7/8/25 07:57, Kane Chen wrote:
> From: Kane-Chen-AS <kane_chen@aspeedtech.com>
>
> This patch series extends the QEMU model for the ASPEED OTP (One-Time
> Programmable) memory device with block backend support and tighter
> integration with the SoC and machine configuration.
>
> The OTP model simulates a simple fuse array, used in ASPEED SoCs
> for secure boot and configuration purposes. The updated model now
> supports loading initial OTP content from a file via the QEMU CLI.
>
> Example usage:
> ./qemu-system-arm \
> -machine ast2600-evb,otpmem=otp \
> -blockdev driver=file,filename=otpmem.img,node-name=otp \
> -global aspeed-otp.drive=otp \
> ...
>
> ChangeLog
> ---------
> v4:
> - Add a 'drive' property to allow backing OTP data with a block device
> - Expose a machine parameter (`-machine otpmem=XXX`) for convenient
> aliasing of the OTP drive via QOM path
Patch 1-4 are fine. Patch 5 is too complex to address and its
value is limited as explained.
Could you please send a documentation update :
https://gitlab.com/qemu-project/qemu/-/blob/master/docs/system/arm/aspeed.rst ?
An extra section after "Other booting options" explaining the OTP backend
for the AST2600 SoC would be welcome.
Please make sure --enable-docs is configured.
Thanks,
C.
>
> v3:
> - Switched to object_property_set_int() for setting "size"
> - Simplified qdev_realize() error handling by passing errp directly
> - Added "drive" property to OTP model for future extensibility
>
> v2:
> - Rename device from 'aspeed_otpmem' to 'aspeed_otp' and move it to hw/nvram/
> - Move OTP device realization from instance_init to the realize function
> - Improve error logging with qemu_log_mask() and remove unused error propagation
>
> v1:
> - Initial version
>
> ---
>
> Kane-Chen-AS (5):
> hw/misc/aspeed_otp: Add ASPEED OTP memory device model
> hw/misc/aspeed_sbc: Connect ASPEED OTP memory device to SBC
> hw/arm: Integrate ASPEED OTP memory support into AST2600 SoCs
> hw/misc/aspeed_otp: Add 'drive' property to support block backend
> hw/misc/aspeed_sbc: Add machine parameter to alias OTP drive property
>
> include/hw/misc/aspeed_sbc.h | 5 ++
> include/hw/nvram/aspeed_otp.h | 33 ++++++++++
> hw/arm/aspeed.c | 20 ++++++
> hw/arm/aspeed_ast2600.c | 2 +-
> hw/misc/aspeed_sbc.c | 121 ++++++++++++++++++++++++++++++++++
> hw/nvram/aspeed_otp.c | 113 +++++++++++++++++++++++++++++++
> hw/misc/trace-events | 5 ++
> hw/nvram/meson.build | 4 ++
> 8 files changed, 302 insertions(+), 1 deletion(-)
> create mode 100644 include/hw/nvram/aspeed_otp.h
> create mode 100644 hw/nvram/aspeed_otp.c
>
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [SPAM] [PATCH v4 1/5] hw/misc/aspeed_otp: Add ASPEED OTP memory device model
2025-07-08 5:57 ` [PATCH v4 1/5] hw/misc/aspeed_otp: Add ASPEED OTP memory device model Kane Chen via
2025-07-22 9:30 ` [SPAM] " Cédric Le Goater
@ 2025-07-22 9:54 ` Cédric Le Goater
2025-07-22 9:59 ` Kane Chen
1 sibling, 1 reply; 15+ messages in thread
From: Cédric Le Goater @ 2025-07-22 9:54 UTC (permalink / raw)
To: Kane Chen, Peter Maydell, Steven Lee, Troy Lee, Jamin Lin,
Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs,
open list:All patches CC here
Cc: troy_lee
On 7/8/25 07:57, Kane Chen wrote:
> From: Kane-Chen-AS <kane_chen@aspeedtech.com>
>
> Introduce a QEMU device model for ASPEED's One-Time Programmable (OTP)
> memory.
>
> This model simulates a word-addressable OTP region used for secure
> fuse storage. The OTP memory can operate with an internal memory
> buffer.
>
> The OTP model provides a memory-like interface through a dedicated
> AddressSpace, allowing other device models (e.g., SBC) to issue
> transactions as if accessing a memory-mapped region.
>
> Signed-off-by: Kane-Chen-AS <kane_chen@aspeedtech.com>
> ---
> include/hw/nvram/aspeed_otp.h | 33 ++++++++++++
> hw/nvram/aspeed_otp.c | 99 +++++++++++++++++++++++++++++++++++
> hw/nvram/meson.build | 4 ++
> 3 files changed, 136 insertions(+)
> create mode 100644 include/hw/nvram/aspeed_otp.h
> create mode 100644 hw/nvram/aspeed_otp.c
>
> diff --git a/include/hw/nvram/aspeed_otp.h b/include/hw/nvram/aspeed_otp.h
> new file mode 100644
> index 0000000000..3752353860
> --- /dev/null
> +++ b/include/hw/nvram/aspeed_otp.h
> @@ -0,0 +1,33 @@
> +/*
> + * ASPEED OTP (One-Time Programmable) memory
> + *
> + * Copyright (C) 2025 Aspeed
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#ifndef ASPEED_OTP_H
> +#define ASPEED_OTP_H
> +
> +#include "system/memory.h"
> +#include "hw/block/block.h"
> +#include "system/address-spaces.h"
> +
> +#define TYPE_ASPEED_OTP "aspeed-otp"
> +OBJECT_DECLARE_SIMPLE_TYPE(AspeedOTPState, ASPEED_OTP)
> +
> +typedef struct AspeedOTPState {
> + DeviceState parent_obj;
> +
> + BlockBackend *blk;
> +
> + uint64_t size;
> +
> + AddressSpace as;
> +
> + MemoryRegion mmio;
> +
> + uint8_t *storage;
> +} AspeedOTPState;
> +
> +#endif /* ASPEED_OTP_H */
> diff --git a/hw/nvram/aspeed_otp.c b/hw/nvram/aspeed_otp.c
> new file mode 100644
> index 0000000000..e41481d9bb
> --- /dev/null
> +++ b/hw/nvram/aspeed_otp.c
> @@ -0,0 +1,99 @@
> +/*
> + * ASPEED OTP (One-Time Programmable) memory
> + *
> + * Copyright (C) 2025 Aspeed
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/log.h"
> +#include "qapi/error.h"
> +#include "system/block-backend-io.h"
Please replace with :
#include "system/block-backend.h"
Thanks,
C.
> +#include "hw/qdev-properties.h"
> +#include "hw/nvram/aspeed_otp.h"
> +
> +static uint64_t aspeed_otp_read(void *opaque, hwaddr offset, unsigned size)
> +{
> + AspeedOTPState *s = opaque;
> + uint64_t val = 0;
> +
> + memcpy(&val, s->storage + offset, size);
> +
> + return val;
> +}
> +
> +static void aspeed_otp_write(void *opaque, hwaddr offset,
> + uint64_t val, unsigned size)
> +{
> + AspeedOTPState *s = opaque;
> +
> + memcpy(s->storage + offset, &val, size);
> +}
> +
> +static bool aspeed_otp_init_storage(AspeedOTPState *s, Error **errp)
> +{
> + uint32_t *p;
> + int i, num;
> +
> + num = s->size / sizeof(uint32_t);
> + p = (uint32_t *)s->storage;
> + for (i = 0; i < num; i++) {
> + p[i] = (i % 2 == 0) ? 0x00000000 : 0xFFFFFFFF;
> + }
> +
> + return true;
> +}
> +
> +static const MemoryRegionOps aspeed_otp_ops = {
> + .read = aspeed_otp_read,
> + .write = aspeed_otp_write,
> + .endianness = DEVICE_LITTLE_ENDIAN,
> + .valid.min_access_size = 1,
> + .valid.max_access_size = 4,
> +};
> +
> +static void aspeed_otp_realize(DeviceState *dev, Error **errp)
> +{
> + AspeedOTPState *s = ASPEED_OTP(dev);
> +
> + if (s->size == 0) {
> + error_setg(errp, "aspeed.otp: 'size' property must be set");
> + return;
> + }
> +
> + s->storage = blk_blockalign(s->blk, s->size);
> +
> + if (!aspeed_otp_init_storage(s, errp)) {
> + return;
> + }
> +
> + memory_region_init_io(&s->mmio, OBJECT(dev), &aspeed_otp_ops,
> + s, "aspeed.otp", s->size);
> + address_space_init(&s->as, &s->mmio, NULL);
> +}
> +
> +static const Property aspeed_otp_properties[] = {
> + DEFINE_PROP_UINT64("size", AspeedOTPState, size, 0),
> +};
> +
> +static void aspeed_otp_class_init(ObjectClass *klass, const void *data)
> +{
> + DeviceClass *dc = DEVICE_CLASS(klass);
> + dc->realize = aspeed_otp_realize;
> + device_class_set_props(dc, aspeed_otp_properties);
> +}
> +
> +static const TypeInfo aspeed_otp_info = {
> + .name = TYPE_ASPEED_OTP,
> + .parent = TYPE_DEVICE,
> + .instance_size = sizeof(AspeedOTPState),
> + .class_init = aspeed_otp_class_init,
> +};
> +
> +static void aspeed_otp_register_types(void)
> +{
> + type_register_static(&aspeed_otp_info);
> +}
> +
> +type_init(aspeed_otp_register_types)
> diff --git a/hw/nvram/meson.build b/hw/nvram/meson.build
> index 10f3639db6..b66f23605b 100644
> --- a/hw/nvram/meson.build
> +++ b/hw/nvram/meson.build
> @@ -19,3 +19,7 @@ system_ss.add(when: 'CONFIG_XLNX_BBRAM', if_true: files('xlnx-bbram.c'))
>
> specific_ss.add(when: 'CONFIG_PSERIES', if_true: files('spapr_nvram.c'))
> specific_ss.add(when: 'CONFIG_ACPI', if_true: files('fw_cfg-acpi.c'))
> +
> +system_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files(
> + 'aspeed_otp.c',
> + ))
> \ No newline at end of file
^ permalink raw reply [flat|nested] 15+ messages in thread
* RE: [SPAM] [PATCH v4 1/5] hw/misc/aspeed_otp: Add ASPEED OTP memory device model
2025-07-22 9:54 ` Cédric Le Goater
@ 2025-07-22 9:59 ` Kane Chen
0 siblings, 0 replies; 15+ messages in thread
From: Kane Chen @ 2025-07-22 9:59 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Jamin Lin, Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs,
open list:All patches CC here
Cc: Troy Lee
Hi Cédric,
Thanks for the feedback.
I will update the code accordingly in the next version of the patch series.
Best Regards,
Kane
> -----Original Message-----
> From: Cédric Le Goater <clg@kaod.org>
> Sent: Tuesday, July 22, 2025 5:55 PM
> To: Kane Chen <kane_chen@aspeedtech.com>; Peter Maydell
> <peter.maydell@linaro.org>; Steven Lee <steven_lee@aspeedtech.com>; Troy
> Lee <leetroy@gmail.com>; Jamin Lin <jamin_lin@aspeedtech.com>; Andrew
> Jeffery <andrew@codeconstruct.com.au>; Joel Stanley <joel@jms.id.au>;
> open list:ASPEED BMCs <qemu-arm@nongnu.org>; open list:All patches CC
> here <qemu-devel@nongnu.org>
> Cc: Troy Lee <troy_lee@aspeedtech.com>
> Subject: Re: [SPAM] [PATCH v4 1/5] hw/misc/aspeed_otp: Add ASPEED OTP
> memory device model
>
> On 7/8/25 07:57, Kane Chen wrote:
> > From: Kane-Chen-AS <kane_chen@aspeedtech.com>
> >
> > Introduce a QEMU device model for ASPEED's One-Time Programmable
> (OTP)
> > memory.
> >
> > This model simulates a word-addressable OTP region used for secure
> > fuse storage. The OTP memory can operate with an internal memory
> > buffer.
> >
> > The OTP model provides a memory-like interface through a dedicated
> > AddressSpace, allowing other device models (e.g., SBC) to issue
> > transactions as if accessing a memory-mapped region.
> >
> > Signed-off-by: Kane-Chen-AS <kane_chen@aspeedtech.com>
> > ---
> > include/hw/nvram/aspeed_otp.h | 33 ++++++++++++
> > hw/nvram/aspeed_otp.c | 99
> +++++++++++++++++++++++++++++++++++
> > hw/nvram/meson.build | 4 ++
> > 3 files changed, 136 insertions(+)
> > create mode 100644 include/hw/nvram/aspeed_otp.h
> > create mode 100644 hw/nvram/aspeed_otp.c
> >
> > diff --git a/include/hw/nvram/aspeed_otp.h
> > b/include/hw/nvram/aspeed_otp.h new file mode 100644 index
> > 0000000000..3752353860
> > --- /dev/null
> > +++ b/include/hw/nvram/aspeed_otp.h
> > @@ -0,0 +1,33 @@
> > +/*
> > + * ASPEED OTP (One-Time Programmable) memory
> > + *
> > + * Copyright (C) 2025 Aspeed
> > + *
> > + * SPDX-License-Identifier: GPL-2.0-or-later */
> > +
> > +#ifndef ASPEED_OTP_H
> > +#define ASPEED_OTP_H
> > +
> > +#include "system/memory.h"
> > +#include "hw/block/block.h"
> > +#include "system/address-spaces.h"
> > +
> > +#define TYPE_ASPEED_OTP "aspeed-otp"
> > +OBJECT_DECLARE_SIMPLE_TYPE(AspeedOTPState, ASPEED_OTP)
> > +
> > +typedef struct AspeedOTPState {
> > + DeviceState parent_obj;
> > +
> > + BlockBackend *blk;
> > +
> > + uint64_t size;
> > +
> > + AddressSpace as;
> > +
> > + MemoryRegion mmio;
> > +
> > + uint8_t *storage;
> > +} AspeedOTPState;
> > +
> > +#endif /* ASPEED_OTP_H */
> > diff --git a/hw/nvram/aspeed_otp.c b/hw/nvram/aspeed_otp.c new file
> > mode 100644 index 0000000000..e41481d9bb
> > --- /dev/null
> > +++ b/hw/nvram/aspeed_otp.c
> > @@ -0,0 +1,99 @@
> > +/*
> > + * ASPEED OTP (One-Time Programmable) memory
> > + *
> > + * Copyright (C) 2025 Aspeed
> > + *
> > + * SPDX-License-Identifier: GPL-2.0-or-later */
> > +
> > +#include "qemu/osdep.h"
> > +#include "qemu/log.h"
> > +#include "qapi/error.h"
> > +#include "system/block-backend-io.h"
>
> Please replace with :
>
> #include "system/block-backend.h"
>
>
> Thanks,
>
> C.
>
>
>
> > +#include "hw/qdev-properties.h"
> > +#include "hw/nvram/aspeed_otp.h"
> > +
> > +static uint64_t aspeed_otp_read(void *opaque, hwaddr offset, unsigned
> > +size) {
> > + AspeedOTPState *s = opaque;
> > + uint64_t val = 0;
> > +
> > + memcpy(&val, s->storage + offset, size);
> > +
> > + return val;
> > +}
> > +
> > +static void aspeed_otp_write(void *opaque, hwaddr offset,
> > + uint64_t val, unsigned size) {
> > + AspeedOTPState *s = opaque;
> > +
> > + memcpy(s->storage + offset, &val, size); }
> > +
> > +static bool aspeed_otp_init_storage(AspeedOTPState *s, Error **errp)
> > +{
> > + uint32_t *p;
> > + int i, num;
> > +
> > + num = s->size / sizeof(uint32_t);
> > + p = (uint32_t *)s->storage;
> > + for (i = 0; i < num; i++) {
> > + p[i] = (i % 2 == 0) ? 0x00000000 : 0xFFFFFFFF;
> > + }
> > +
> > + return true;
> > +}
> > +
> > +static const MemoryRegionOps aspeed_otp_ops = {
> > + .read = aspeed_otp_read,
> > + .write = aspeed_otp_write,
> > + .endianness = DEVICE_LITTLE_ENDIAN,
> > + .valid.min_access_size = 1,
> > + .valid.max_access_size = 4,
> > +};
> > +
> > +static void aspeed_otp_realize(DeviceState *dev, Error **errp) {
> > + AspeedOTPState *s = ASPEED_OTP(dev);
> > +
> > + if (s->size == 0) {
> > + error_setg(errp, "aspeed.otp: 'size' property must be set");
> > + return;
> > + }
> > +
> > + s->storage = blk_blockalign(s->blk, s->size);
> > +
> > + if (!aspeed_otp_init_storage(s, errp)) {
> > + return;
> > + }
> > +
> > + memory_region_init_io(&s->mmio, OBJECT(dev), &aspeed_otp_ops,
> > + s, "aspeed.otp", s->size);
> > + address_space_init(&s->as, &s->mmio, NULL); }
> > +
> > +static const Property aspeed_otp_properties[] = {
> > + DEFINE_PROP_UINT64("size", AspeedOTPState, size, 0), };
> > +
> > +static void aspeed_otp_class_init(ObjectClass *klass, const void
> > +*data) {
> > + DeviceClass *dc = DEVICE_CLASS(klass);
> > + dc->realize = aspeed_otp_realize;
> > + device_class_set_props(dc, aspeed_otp_properties); }
> > +
> > +static const TypeInfo aspeed_otp_info = {
> > + .name = TYPE_ASPEED_OTP,
> > + .parent = TYPE_DEVICE,
> > + .instance_size = sizeof(AspeedOTPState),
> > + .class_init = aspeed_otp_class_init,
> > +};
> > +
> > +static void aspeed_otp_register_types(void) {
> > + type_register_static(&aspeed_otp_info);
> > +}
> > +
> > +type_init(aspeed_otp_register_types)
> > diff --git a/hw/nvram/meson.build b/hw/nvram/meson.build index
> > 10f3639db6..b66f23605b 100644
> > --- a/hw/nvram/meson.build
> > +++ b/hw/nvram/meson.build
> > @@ -19,3 +19,7 @@ system_ss.add(when: 'CONFIG_XLNX_BBRAM',
> if_true:
> > files('xlnx-bbram.c'))
> >
> > specific_ss.add(when: 'CONFIG_PSERIES', if_true: files('spapr_nvram.c'))
> > specific_ss.add(when: 'CONFIG_ACPI', if_true:
> > files('fw_cfg-acpi.c'))
> > +
> > +system_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files(
> > + 'aspeed_otp.c',
> > + ))
> > \ No newline at end of file
^ permalink raw reply [flat|nested] 15+ messages in thread
* RE: [SPAM] [PATCH v4 0/5] ASPEED OTP QEMU model: block backend, machine alias, SoC integration
2025-07-22 9:41 ` [SPAM] [PATCH v4 0/5] ASPEED OTP QEMU model: block backend, machine alias, SoC integration Cédric Le Goater
@ 2025-07-22 10:03 ` Kane Chen
0 siblings, 0 replies; 15+ messages in thread
From: Kane Chen @ 2025-07-22 10:03 UTC (permalink / raw)
To: Cédric Le Goater, Peter Maydell, Steven Lee, Troy Lee,
Jamin Lin, Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs,
open list:All patches CC here
Cc: Troy Lee
Hi Cédric,
Thanks for your review.
I will drop patch 5 and include a documentation update in the next version.
Best Regards,
Kane
> -----Original Message-----
> From: Cédric Le Goater <clg@kaod.org>
> Sent: Tuesday, July 22, 2025 5:41 PM
> To: Kane Chen <kane_chen@aspeedtech.com>; Peter Maydell
> <peter.maydell@linaro.org>; Steven Lee <steven_lee@aspeedtech.com>; Troy
> Lee <leetroy@gmail.com>; Jamin Lin <jamin_lin@aspeedtech.com>; Andrew
> Jeffery <andrew@codeconstruct.com.au>; Joel Stanley <joel@jms.id.au>;
> open list:ASPEED BMCs <qemu-arm@nongnu.org>; open list:All patches CC
> here <qemu-devel@nongnu.org>
> Cc: Troy Lee <troy_lee@aspeedtech.com>
> Subject: Re: [SPAM] [PATCH v4 0/5] ASPEED OTP QEMU model: block backend,
> machine alias, SoC integration
>
> On 7/8/25 07:57, Kane Chen wrote:
> > From: Kane-Chen-AS <kane_chen@aspeedtech.com>
> >
> > This patch series extends the QEMU model for the ASPEED OTP (One-Time
> > Programmable) memory device with block backend support and tighter
> > integration with the SoC and machine configuration.
> >
> > The OTP model simulates a simple fuse array, used in ASPEED SoCs for
> > secure boot and configuration purposes. The updated model now supports
> > loading initial OTP content from a file via the QEMU CLI.
> >
> > Example usage:
> > ./qemu-system-arm \
> > -machine ast2600-evb,otpmem=otp \
> > -blockdev driver=file,filename=otpmem.img,node-name=otp \
> > -global aspeed-otp.drive=otp \
> > ...
> >
> > ChangeLog
> > ---------
> > v4:
> > - Add a 'drive' property to allow backing OTP data with a block device
> > - Expose a machine parameter (`-machine otpmem=XXX`) for convenient
> > aliasing of the OTP drive via QOM path
>
>
> Patch 1-4 are fine. Patch 5 is too complex to address and its value is limited as
> explained.
>
> Could you please send a documentation update :
>
>
> https://gitlab.com/qemu-project/qemu/-/blob/master/docs/system/arm/asp
> eed.rst ?
>
> An extra section after "Other booting options" explaining the OTP backend for
> the AST2600 SoC would be welcome.
>
> Please make sure --enable-docs is configured.
>
> Thanks,
>
> C.
>
>
>
>
> >
> > v3:
> > - Switched to object_property_set_int() for setting "size"
> > - Simplified qdev_realize() error handling by passing errp directly
> > - Added "drive" property to OTP model for future extensibility
> >
> > v2:
> > - Rename device from 'aspeed_otpmem' to 'aspeed_otp' and move it to
> > hw/nvram/
> > - Move OTP device realization from instance_init to the realize
> > function
> > - Improve error logging with qemu_log_mask() and remove unused error
> > propagation
> >
> > v1:
> > - Initial version
> >
> > ---
> >
> > Kane-Chen-AS (5):
> > hw/misc/aspeed_otp: Add ASPEED OTP memory device model
> > hw/misc/aspeed_sbc: Connect ASPEED OTP memory device to SBC
> > hw/arm: Integrate ASPEED OTP memory support into AST2600 SoCs
> > hw/misc/aspeed_otp: Add 'drive' property to support block backend
> > hw/misc/aspeed_sbc: Add machine parameter to alias OTP drive
> > property
> >
> > include/hw/misc/aspeed_sbc.h | 5 ++
> > include/hw/nvram/aspeed_otp.h | 33 ++++++++++
> > hw/arm/aspeed.c | 20 ++++++
> > hw/arm/aspeed_ast2600.c | 2 +-
> > hw/misc/aspeed_sbc.c | 121
> ++++++++++++++++++++++++++++++++++
> > hw/nvram/aspeed_otp.c | 113
> +++++++++++++++++++++++++++++++
> > hw/misc/trace-events | 5 ++
> > hw/nvram/meson.build | 4 ++
> > 8 files changed, 302 insertions(+), 1 deletion(-)
> > create mode 100644 include/hw/nvram/aspeed_otp.h
> > create mode 100644 hw/nvram/aspeed_otp.c
> >
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [SPAM] [PATCH v4 4/5] hw/misc/aspeed_otp: Add 'drive' property to support block backend
2025-07-22 9:30 ` [SPAM] " Cédric Le Goater
@ 2025-07-22 10:27 ` Alex Bennée
2025-07-22 11:27 ` Cédric Le Goater
0 siblings, 1 reply; 15+ messages in thread
From: Alex Bennée @ 2025-07-22 10:27 UTC (permalink / raw)
To: Cédric Le Goater
Cc: Kane Chen, Peter Maydell, Steven Lee, Troy Lee, Jamin Lin,
Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs,
open list:All patches CC here, troy_lee
Cédric Le Goater <clg@kaod.org> writes:
> On 7/8/25 07:57, Kane Chen wrote:
>> From: Kane-Chen-AS <kane_chen@aspeedtech.com>
>> This patch introduces a 'drive' property to the Aspeed OTP device,
>> allowing it to be backed by a block device. Users can now preload
>> OTP data via QEMU CLI using a block backend.
>> Example usage:
>> ./qemu-system-arm \
>> -blockdev driver=file,filename=otpmem.img,node-name=otp \
>> -global aspeed-otp.drive=otp \
>> ...
>> If the drive is provided, its content will be loaded as the initial
>> OTP state.
>> Otherwise, an internal memory buffer will be used.
>> Signed-off-by: Kane-Chen-AS <kane_chen@aspeedtech.com>
>
>
> Reviewed-by: Cédric Le Goater <clg@redhat.com>
Erm where is this email getting tagged as SPAM? The headers seem to
indicate its clear:
X-Spam_score_int: -39
X-Spam_score: -4.0
X-Spam_bar: ----
X-Spam_report: (-4.0 / 5.0 requ) BAYES_00=-1.9,
HEADER_FROM_DIFFERENT_DOMAINS=0.157, RCVD_IN_DNSWL_MED=-2.3,
SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no
X-Spam_action: no action
X-BeenThere: qemu-arm@nongnu.org
X-Mailman-Version: 2.1.29
>
> Thanks,
>
> C.
>
>
>> ---
>> hw/nvram/aspeed_otp.c | 16 +++++++++++++++-
>> 1 file changed, 15 insertions(+), 1 deletion(-)
>> diff --git a/hw/nvram/aspeed_otp.c b/hw/nvram/aspeed_otp.c
>> index e41481d9bb..f018c58713 100644
>> --- a/hw/nvram/aspeed_otp.c
>> +++ b/hw/nvram/aspeed_otp.c
>> @@ -9,6 +9,7 @@
>> #include "qemu/osdep.h"
>> #include "qemu/log.h"
>> #include "qapi/error.h"
>> +#include "system/block-backend-global-state.h"
>> #include "system/block-backend-io.h"
>> #include "hw/qdev-properties.h"
>> #include "hw/nvram/aspeed_otp.h"
>> @@ -35,13 +36,25 @@ static bool aspeed_otp_init_storage(AspeedOTPState *s, Error **errp)
>> {
>> uint32_t *p;
>> int i, num;
>> + uint64_t perm;
>> + if (s->blk) {
>> + perm = BLK_PERM_CONSISTENT_READ |
>> + (blk_supports_write_perm(s->blk) ? BLK_PERM_WRITE : 0);
>> + if (blk_set_perm(s->blk, perm, BLK_PERM_ALL, errp) < 0) {
>> + return false;
>> + }
>> + if (blk_pread(s->blk, 0, s->size, s->storage, 0) < 0) {
>> + error_setg(errp, "Failed to read the initial flash content");
>> + return false;
>> + }
>> + } else {
>> num = s->size / sizeof(uint32_t);
>> p = (uint32_t *)s->storage;
>> for (i = 0; i < num; i++) {
>> p[i] = (i % 2 == 0) ? 0x00000000 : 0xFFFFFFFF;
>> }
>> -
>> + }
>> return true;
>> }
>> @@ -75,6 +88,7 @@ static void aspeed_otp_realize(DeviceState *dev,
>> Error **errp)
>> static const Property aspeed_otp_properties[] = {
>> DEFINE_PROP_UINT64("size", AspeedOTPState, size, 0),
>> + DEFINE_PROP_DRIVE("drive", AspeedOTPState, blk),
>> };
>> static void aspeed_otp_class_init(ObjectClass *klass, const void
>> *data)
--
Alex Bennée
Virtualisation Tech Lead @ Linaro
^ permalink raw reply [flat|nested] 15+ messages in thread
* Re: [SPAM] [PATCH v4 4/5] hw/misc/aspeed_otp: Add 'drive' property to support block backend
2025-07-22 10:27 ` Alex Bennée
@ 2025-07-22 11:27 ` Cédric Le Goater
0 siblings, 0 replies; 15+ messages in thread
From: Cédric Le Goater @ 2025-07-22 11:27 UTC (permalink / raw)
To: Alex Bennée
Cc: Kane Chen, Peter Maydell, Steven Lee, Troy Lee, Jamin Lin,
Andrew Jeffery, Joel Stanley, open list:ASPEED BMCs,
open list:All patches CC here, troy_lee
On 7/22/25 12:27, Alex Bennée wrote:
> Cédric Le Goater <clg@kaod.org> writes:
>
>> On 7/8/25 07:57, Kane Chen wrote:
>>> From: Kane-Chen-AS <kane_chen@aspeedtech.com>
>>> This patch introduces a 'drive' property to the Aspeed OTP device,
>>> allowing it to be backed by a block device. Users can now preload
>>> OTP data via QEMU CLI using a block backend.
>>> Example usage:
>>> ./qemu-system-arm \
>>> -blockdev driver=file,filename=otpmem.img,node-name=otp \
>>> -global aspeed-otp.drive=otp \
>>> ...
>>> If the drive is provided, its content will be loaded as the initial
>>> OTP state.
>>> Otherwise, an internal memory buffer will be used.
>>> Signed-off-by: Kane-Chen-AS <kane_chen@aspeedtech.com>
>>
>>
>> Reviewed-by: Cédric Le Goater <clg@redhat.com>
>
> Erm where is this email getting tagged as SPAM? The headers seem to
> indicate its clear:
>
> X-Spam_score_int: -39
> X-Spam_score: -4.0
> X-Spam_bar: ----
> X-Spam_report: (-4.0 / 5.0 requ) BAYES_00=-1.9,
> HEADER_FROM_DIFFERENT_DOMAINS=0.157, RCVD_IN_DNSWL_MED=-2.3,
> SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no
> X-Spam_action: no action
> X-BeenThere: qemu-arm@nongnu.org
> X-Mailman-Version: 2.1.29
I guess it's my provider (OVH). See below what I received.
C.
X-Mozilla-Status: 0001
X-Mozilla-Status2: 00000000
Received: from DAG8EX1.mxp5.local (172.16.2.71) by DAG8EX2.mxp5.local
(172.16.2.72) with Microsoft SMTP Server (version=TLS1_2,
cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.44 via Mailbox
Transport; Tue, 8 Jul 2025 07:58:23 +0200
Received: from DAG9EX2.mxp5.local (172.16.2.82) by DAG8EX1.mxp5.local
(172.16.2.71) with Microsoft SMTP Server (version=TLS1_2,
cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.44; Tue, 8 Jul
2025 07:58:23 +0200
Received: from output47.mail.ovh.net (164.132.34.47) by mxplan5.mail.ovh.net
(172.16.2.82) with Microsoft SMTP Server (version=TLS1_2,
cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.44 via Frontend
Transport; Tue, 8 Jul 2025 07:58:23 +0200
Received: from vr27.mail.ovh.net (unknown [10.101.8.27])
by out47.mail.ovh.net (Postfix) with ESMTP id 4bbr4v1fkDz1K9FR
for <clg@kaod.org>; Tue, 8 Jul 2025 05:58:23 +0000 (UTC)
Received: from in79.mail.ovh.net (unknown [10.101.4.79])
by vr27.mail.ovh.net (Postfix) with ESMTP id 4bbr4t0F45zFpd7
for <clg@kaod.org>; Tue, 8 Jul 2025 05:58:22 +0000 (UTC)
Received: from TWMBX01.aspeed.com (mail.aspeedtech.com [211.20.114.72])
by in79.mail.ovh.net (Postfix) with ESMTPS id 4bbr4s4RcFz6dtBC
for <clg@kaod.org>; Tue, 8 Jul 2025 05:58:21 +0000 (UTC)
Authentication-Results: mx.mail.ovh.net;
arc=none (no signatures found);
dkim=none (no signatures found);
dmarc=pass policy.published-domain-policy=quarantine policy.applied-disposition=none policy.evaluated-disposition=none (p=quarantine,d=none,d.eval=none) policy.policy-from=p header.from=aspeedtech.com;
spf=pass smtp.mailfrom=kane_chen@aspeedtech.com smtp.helo=TWMBX01.aspeed.com;
x-tls=pass smtp.version=TLSv1.2 smtp.cipher=ECDHE-RSA-AES256-GCM-SHA384 smtp.bits=256
Received-SPF: Fail (DAG8EX1.mxp5.local: domain of kane_chen@aspeedtech.com
does not designate 164.132.34.47 as permitted sender)
receiver=DAG8EX1.mxp5.local; client-ip=164.132.34.47;
helo=output47.mail.ovh.net;
Received-SPF: pass
(aspeedtech.com: 211.20.114.72 is authorized to use 'kane_chen@aspeedtech.com' in 'mfrom' identity (mechanism 'ip4:211.20.114.72' matched))
receiver=in79.mail.ovh.net;
identity=mailfrom;
envelope-from="kane_chen@aspeedtech.com";
helo=TWMBX01.aspeed.com;
client-ip=211.20.114.72
Received: from TWMBX01.aspeed.com (192.168.0.62) by TWMBX01.aspeed.com
(192.168.0.62) with Microsoft SMTP Server (version=TLS1_2,
cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.10; Tue, 8 Jul
2025 13:58:10 +0800
Received: from mail.aspeedtech.com (192.168.10.10) by TWMBX01.aspeed.com
(192.168.0.62) with Microsoft SMTP Server id 15.2.1748.10 via Frontend
Transport; Tue, 8 Jul 2025 13:58:10 +0800
From: Kane Chen <kane_chen@aspeedtech.com>
To: =?UTF-8?q?C=C3=A9dric=20Le=20Goater?= <clg@kaod.org>, Peter Maydell
<peter.maydell@linaro.org>, Steven Lee <steven_lee@aspeedtech.com>, Troy Lee
<leetroy@gmail.com>, Jamin Lin <jamin_lin@aspeedtech.com>, Andrew Jeffery
<andrew@codeconstruct.com.au>, Joel Stanley <joel@jms.id.au>, "open
list:ASPEED BMCs" <qemu-arm@nongnu.org>, "open list:All patches CC here"
<qemu-devel@nongnu.org>
CC: <troy_lee@aspeedtech.com>, Kane-Chen-AS <kane_chen@aspeedtech.com>
Subject: [SPAM] [PATCH v4 0/5] ASPEED OTP QEMU model: block backend, machine alias, SoC integration
Date: Tue, 8 Jul 2025 13:57:52 +0800
Message-ID: <20250708055810.2868680-1-kane_chen@aspeedtech.com>
X-Mailer: git-send-email 2.43.0
Content-Transfer-Encoding: 8bit
Content-Type: text/plain
X-OVH-Remote: 211.20.114.72 (mail.aspeedtech.com)
X-Ovh-Tracer-Id: 12933493708818734458
X-VR-SPAMSTATE: SPAM
X-VR-SPAMSCORE: 200
X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgeeffedrtdefgdeffeeklecutefuodetggdotefrodftvfcurfhrohhfihhlvgemucfqggfjpdevjffgvefmvefgnecuuegrihhlohhuthemucehtddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenogfuphgrmhfkphculdeftddtmdenucfjughrpefhvfevufffkffoggfgtgesthekredtredttdenucfhrhhomhepmfgrnhgvucevhhgvnhcuoehkrghnvggptghhvghnsegrshhpvggvughtvggthhdrtghomheqnecuggftrfgrthhtvghrnhepgeeggfdvuddtgfegkefhudetjefftdefkefhhedtkeekffegveehgfeiheevvefhnecukfhppedvuddurddvtddruddugedrjedvnecuufhprghmkfhppedvuddurddvtddruddugedrjedvnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehinhgvthepvdduuddrvddtrdduudegrdejvddphhgvlhhopehtfihmsgigtddurdgrshhpvggvugdrtghomhdpmhgrihhlfhhrohhmpehkrghnvggptghhvghnsegrshhpvggvughtvggthhdrtghomhdpnhgspghrtghpthhtohepuddprhgtphhtthhopegtlhhgsehkrghougdrohhrghdpoffvtefjohhsthepvhhrvdejmgdpughkihhmpehnohhnvggmpdhsphhfpehprghsshgmpdgumhgrrhgtpehprghsshgmpdhrvghvkffrpehmrghilhdrrghsphgvvgguthgvtghhrdgtohhmmgdpghgvohfkrfepvfgh
X-Ovh-Spam-Status: SPAM
X-Ovh-Spam-Reason: vr: SPAM; dkim: disabled; spf: disabled
X-Ovh-Message-Type: SPAM
X-Ovh-Exchange-Junk: True
X-Spam-Tag: YES
Return-Path: kane_chen@aspeedtech.com
X-MS-Exchange-Organization-Network-Message-Id: 126a28f3-a563-4c49-b5da-08ddbde472e1
X-MS-Exchange-Organization-PRD: aspeedtech.com
X-MS-Exchange-Organization-SenderIdResult: Fail
X-MS-Exchange-Organization-AVStamp-Enterprise: 1.0
X-MS-Exchange-ABP-GUID: bd2a0b77-ce4f-4d81-a151-b15427a5e809
X-Ovh-Tracer-GUID: 51d3ce0b-f2d1-4f5a-a08a-a00eb1ad14da
X-MS-Exchange-Organization-SCL: 9
X-MS-Exchange-Organization-AuthSource: DAG9EX2.mxp5.local
X-MS-Exchange-Organization-AuthAs: Anonymous
X-MS-Exchange-Transport-EndToEndLatency: 00:00:00.5736284
X-MS-Exchange-Processed-By-BccFoldering: 15.01.2507.044
MIME-Version: 1.0
From: Kane-Chen-AS <kane_chen@aspeedtech.com>
^ permalink raw reply [flat|nested] 15+ messages in thread
end of thread, other threads:[~2025-07-22 11:29 UTC | newest]
Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-08 5:57 [PATCH v4 0/5] ASPEED OTP QEMU model: block backend, machine alias, SoC integration Kane Chen via
2025-07-08 5:57 ` [PATCH v4 1/5] hw/misc/aspeed_otp: Add ASPEED OTP memory device model Kane Chen via
2025-07-22 9:30 ` [SPAM] " Cédric Le Goater
2025-07-22 9:54 ` Cédric Le Goater
2025-07-22 9:59 ` Kane Chen
2025-07-08 5:57 ` [PATCH v4 2/5] hw/misc/aspeed_sbc: Connect ASPEED OTP memory device to SBC Kane Chen via
2025-07-08 5:57 ` [PATCH v4 3/5] hw/arm: Integrate ASPEED OTP memory support into AST2600 SoCs Kane Chen via
2025-07-08 5:57 ` [PATCH v4 4/5] hw/misc/aspeed_otp: Add 'drive' property to support block backend Kane Chen via
2025-07-22 9:30 ` [SPAM] " Cédric Le Goater
2025-07-22 10:27 ` Alex Bennée
2025-07-22 11:27 ` Cédric Le Goater
2025-07-08 5:57 ` [PATCH v4 5/5] hw/misc/aspeed_sbc: Add machine parameter to alias OTP drive property Kane Chen via
2025-07-22 9:35 ` [SPAM] " Cédric Le Goater
2025-07-22 9:41 ` [SPAM] [PATCH v4 0/5] ASPEED OTP QEMU model: block backend, machine alias, SoC integration Cédric Le Goater
2025-07-22 10:03 ` Kane Chen
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).