Commit 005460f7ab for qemu.org
commit 005460f7ab0d3befb365aab9ce37d3a019a29970
Author: Kane Chen <kane_chen@aspeedtech.com>
Date: Fri Sep 18 06:53:49 2026 +0000
hw/nvram/aspeed_otp, hw/misc/aspeed_sbc: Consolidate OTP layout definitions
Move the OTP address-space layout definitions from aspeed_sbc.c to
aspeed_otp.h, as they describe the OTP device layout.
Add an aspeed_otp_read() helper to reduce duplicated OTP read code.
Remove the redundant OTP address bounds checks, as invalid accesses
are already handled by the OTP address space.
No functional change.
Signed-off-by: Kane-Chen-AS <kane_chen@aspeedtech.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Link: https://lore.kernel.org/qemu-devel/20260918065347.3713868-2-kane_chen@aspeedtech.com
Signed-off-by: Cédric Le Goater <clg@redhat.com>
diff --git a/hw/misc/aspeed_sbc.c b/hw/misc/aspeed_sbc.c
index 5c193d9086..3402cef5c3 100644
--- a/hw/misc/aspeed_sbc.c
+++ b/hw/misc/aspeed_sbc.c
@@ -66,15 +66,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_WRITE 0x23b1e362
#define SBC_OTP_CMD_PROG 0x23b1e364
-#define OTP_DATA_DWORD_COUNT (0x800)
-#define OTP_TOTAL_DWORD_COUNT (0x1000)
-
/* Voltage mode */
#define MODE_REGISTER (0x1000)
#define MODE_REGISTER_A (0x3000)
@@ -96,43 +92,34 @@ 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)
+static bool aspeed_otp_read(AspeedSBCState *s, uint32_t otp_addr,
+ uint32_t *value)
{
- MemTxResult ret;
- AspeedOTPState *otp = &s->otp;
- uint32_t value, otp_offset;
- bool is_data = false;
-
- if (otp_addr < OTP_DATA_DWORD_COUNT) {
- is_data = true;
- } else if (otp_addr >= OTP_TOTAL_DWORD_COUNT) {
+ if (address_space_read(&s->otp.as, otp_addr << 2, MEMTXATTRS_UNSPECIFIED,
+ value, sizeof(*value)) != MEMTX_OK) {
qemu_log_mask(LOG_GUEST_ERROR,
- "Invalid OTP addr 0x%x\n",
+ "Failed to read OTP memory, addr = %x\n",
otp_addr);
return false;
}
- 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 true;
+}
+
+static bool aspeed_sbc_otp_read(AspeedSBCState *s,
+ uint32_t otp_addr)
+{
+ uint32_t value;
+ bool is_data = otp_addr < OTP_DATA_DWORD_COUNT;
+
+ if (!aspeed_otp_read(s, otp_addr, &value)) {
return false;
}
s->regs[R_CAMP1] = value;
trace_aspeed_sbc_otp_read(otp_addr, value);
if (is_data) {
- ret = address_space_read(&otp->as, otp_offset + 4,
- 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);
+ if (!aspeed_otp_read(s, otp_addr + 1, &value)) {
return false;
}
s->regs[R_CAMP2] = value;
@@ -181,13 +168,6 @@ static bool aspeed_sbc_otp_prog(AspeedSBCState *s,
uint32_t value = s->regs[R_CAMP1];
uint32_t otp_offset = otp_addr << 2;
- if (otp_addr >= OTP_TOTAL_DWORD_COUNT) {
- qemu_log_mask(LOG_GUEST_ERROR,
- "Invalid OTP addr 0x%x\n",
- otp_addr);
- return false;
- }
-
ret = address_space_write(&otp->as, otp_offset, MEMTXATTRS_UNSPECIFIED,
&value, sizeof(value));
if (ret != MEMTX_OK) {
diff --git a/include/hw/nvram/aspeed_otp.h b/include/hw/nvram/aspeed_otp.h
index 3752353860..2b6c2eaaa3 100644
--- a/include/hw/nvram/aspeed_otp.h
+++ b/include/hw/nvram/aspeed_otp.h
@@ -16,6 +16,19 @@
#define TYPE_ASPEED_OTP "aspeed-otp"
OBJECT_DECLARE_SIMPLE_TYPE(AspeedOTPState, ASPEED_OTP)
+#define OTP_MEMORY_SIZE 0x4000
+
+/*
+ * The OTP address space is indexed by dword address and is split into
+ * two regions:
+ *
+ * - [0, OTP_DATA_DWORD_COUNT]: the data region. Each address contains
+ * 64 bits of data.
+ * - [OTP_DATA_DWORD_COUNT, OTP_MEMORY_SIZE / 4]: the configuration
+ * region. Each address contains 32 bits of data.
+ */
+#define OTP_DATA_DWORD_COUNT (0x800)
+
typedef struct AspeedOTPState {
DeviceState parent_obj;