All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jamin Lin <jamin_lin@aspeedtech.com>
To: "Cédric Le Goater" <clg@kaod.org>,
	"Peter Maydell" <peter.maydell@linaro.org>,
	"Steven Lee" <steven_lee@aspeedtech.com>,
	"Troy Lee" <leetroy@gmail.com>,
	"Kane Chen" <kane_chen@aspeedtech.com>,
	"Andrew Jeffery" <andrew@codeconstruct.com.au>,
	"Joel Stanley" <joel@jms.id.au>,
	"Fabiano Rosas" <farosas@suse.de>,
	"Laurent Vivier" <lvivier@redhat.com>,
	"Paolo Bonzini" <pbonzini@redhat.com>,
	"open list:ASPEED BMCs" <qemu-arm@nongnu.org>,
	"open list:All patches CC here" <qemu-devel@nongnu.org>
Cc: Jamin Lin <jamin_lin@aspeedtech.com>, Troy Lee <troy_lee@aspeedtech.com>
Subject: [PATCH v1 1/5] hw/misc/aspeed_acry: Add ASPEED ACRY model
Date: Thu, 13 Aug 2026 06:24:02 +0000	[thread overview]
Message-ID: <20260813062359.425268-2-jamin_lin@aspeedtech.com> (raw)
In-Reply-To: <20260813062359.425268-1-jamin_lin@aspeedtech.com>

Introduce a ASPEED ACRY model, which performs RSA modular
exponentiation. The datasheet documents the engine as
supporting both RSA and ECDSA, but ECDSA is broken on this
hardware, so only RSA is modelled.

The engine DMAs its operands (data, exponent, modulus) from a guest
DRAM buffer and writes the result back into a memory-mapped SRAM
region. Both regions share the same interleaved byte/dword layout:
repeating 12-dword blocks of [4 dwords exponent][4 dwords modulus][4
dwords data], index 0 holding the least-significant word/byte of each
value.

The engine accesses DRAM by relative offset, so the CPU-visible
address written to the DMA source register has its top (base) bit
masked off.

The modular exponentiation itself is delegated to QEMU's generic
akcipher crypto API (crypto/akcipher.c) using raw (unpadded) RSA,
matching what the real hardware performs - PKCS1 padding is handled
by the guest's software crypto stack, not by this engine.

The RSA public-key operand DER encoding needed by that API is built with
crypto/der.h's generic encoder. Raw (unpadded) RSA is only implemented
by that API's libgcrypt backend (its nettle backend rejects raw
padding), so this device needs QEMU built with --enable-gcrypt.

When that support is missing, the engine still completes and raises its
completion IRQ as real hardware would, but produces an all-zero result
so that whatever signature check the guest performs on it fails cleanly
instead of the guest hanging forever waiting for an interrupt that
would otherwise never come.

Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
---
 include/hw/misc/aspeed_acry.h |  50 ++++
 hw/misc/aspeed_acry.c         | 447 ++++++++++++++++++++++++++++++++++
 hw/misc/meson.build           |   1 +
 hw/misc/trace-events          |   6 +
 4 files changed, 504 insertions(+)
 create mode 100644 include/hw/misc/aspeed_acry.h
 create mode 100644 hw/misc/aspeed_acry.c

diff --git a/include/hw/misc/aspeed_acry.h b/include/hw/misc/aspeed_acry.h
new file mode 100644
index 0000000000..5af2296830
--- /dev/null
+++ b/include/hw/misc/aspeed_acry.h
@@ -0,0 +1,50 @@
+/*
+ * ASPEED ACRY Engine
+ *
+ * Copyright (C) 2026 ASPEED Technology Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef ASPEED_ACRY_H
+#define ASPEED_ACRY_H
+
+#include "hw/core/sysbus.h"
+#include "system/memory.h"
+
+#define TYPE_ASPEED_ACRY "aspeed.acry"
+OBJECT_DECLARE_SIMPLE_TYPE(AspeedACRYState, ASPEED_ACRY)
+
+#define ASPEED_ACRY_NR_REGS     (0x400 >> 2)
+/* Max size of the "data" (message) field within the SRAM buffer. */
+#define ASPEED_ACRY_DATA_MAX_LEN 0x800
+#define ASPEED_ACRY_MAX_BITS     4096
+/* Max exponent/modulus size for a 4096-bit RSA key, in bytes. */
+#define ASPEED_ACRY_MAX_BYTES    (ASPEED_ACRY_MAX_BITS / 8)
+
+struct AspeedACRYState {
+    SysBusDevice parent_obj;
+
+    MemoryRegion iomem;
+    qemu_irq irq;
+
+    uint32_t regs[ASPEED_ACRY_NR_REGS];
+
+    /*
+     * Byte-position lookup tables: exp_map[k] / mod_map[k] / data_map[k]
+     * give the offset in the scattered buffer of byte k (k = 0 =
+     * least significant) of the exponent / modulus / data.
+     */
+    uint32_t exp_map[ASPEED_ACRY_MAX_BYTES];
+    uint32_t mod_map[ASPEED_ACRY_MAX_BYTES];
+    uint32_t data_map[ASPEED_ACRY_DATA_MAX_LEN];
+
+    MemoryRegion *dram_mr;
+    AddressSpace dram_as;
+
+    MemoryRegion *sram_mr;
+    AddressSpace sram_as;
+    uint64_t sram_base;
+};
+
+#endif /* ASPEED_ACRY_H */
diff --git a/hw/misc/aspeed_acry.c b/hw/misc/aspeed_acry.c
new file mode 100644
index 0000000000..53ef68d284
--- /dev/null
+++ b/hw/misc/aspeed_acry.c
@@ -0,0 +1,447 @@
+/*
+ * ASPEED ACRY Engine
+ *
+ * Copyright (C) 2026 ASPEED Technology Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * The datasheet documents the ACRY engine as supporting both RSA and
+ * ECDSA, but ECDSA is broken on this hardware, so only RSA is modelled
+ * here.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/cutils.h"
+#include "qemu/log.h"
+#include "hw/misc/aspeed_acry.h"
+#include "hw/core/qdev-properties.h"
+#include "hw/core/irq.h"
+#include "hw/core/registerfields.h"
+#include "qapi/error.h"
+#include "crypto/akcipher.h"
+#include "crypto/der.h"
+#include "trace.h"
+
+REG32(ACRY_TRIGGER, 0x000)
+    FIELD(ACRY_TRIGGER, RSA_DMA_DATA, 1, 1)
+    FIELD(ACRY_TRIGGER, RSA_START, 0, 1)
+REG32(ACRY_DMA_CMD, 0x048)
+REG32(ACRY_DMA_SRC, 0x04C)
+REG32(ACRY_DMA_LEN, 0x050)
+REG32(ACRY_RSA_KEY_LEN, 0x058)
+REG32(ACRY_INT_MASK, 0x3F8)
+    FIELD(ACRY_INT_MASK, RSA_DMA_MASK, 2, 1)
+    FIELD(ACRY_INT_MASK, RSA_ENG_MASK, 1, 1)
+REG32(ACRY_STATUS, 0x3FC)
+    FIELD(ACRY_STATUS, RSA_DMA_DONE, 2, 1)
+    FIELD(ACRY_STATUS, RSA_ENG_DONE, 1, 1)
+
+/*
+ * Total size of the interleaved SRAM buffer. Data is 4 of every 12
+ * dwords of a block (see aspeed_acry_init_mapping()), i.e. one third of
+ * the buffer, so the whole buffer is 3x the data region.
+ */
+#define ASPEED_ACRY_SRAM_SIZE   (3 * ASPEED_ACRY_DATA_MAX_LEN)
+
+static void aspeed_acry_hexdump(const char *desc, const uint8_t *buf,
+                                size_t size)
+{
+    g_autoptr(GString) str = g_string_sized_new(64);
+    size_t len;
+    size_t i;
+
+    for (i = 0; i < size; i += len) {
+        len = MIN(16, size - i);
+        g_string_truncate(str, 0);
+        qemu_hexdump_line(str, buf + i, len, 1, 4);
+        trace_aspeed_acry_hexdump(desc, i, str->str);
+    }
+}
+
+/*
+ * The SRAM buffer is a series of 12-dword blocks, each split into
+ * three 4-dword regions - exp, mod, data:
+ *
+ *   dword in block:  0    1    2    3    4    5    6    7    8    9   10   11
+ *   region:          \---- exp ----/    \---- mod ----/    \---- data ----/
+ *   lane:            0    1    2    3    0    1    2    3    0    1    2    3
+ *
+ * Successive blocks hold the next 4 dwords of each operand, so operand
+ * dword d is in block (d / 4), lane (d % 4). Dwords are little-endian, so
+ * byte b of the dword at SRAM dword D is at byte D * 4 + b.
+ *
+ * exp_map[op_byte] / mod_map[op_byte] / data_map[op_byte] give the buffer
+ * offset of operand byte op_byte (op_byte = 0 = least significant).
+ */
+static void aspeed_acry_init_mapping(AspeedACRYState *s)
+{
+    int byte_in_dword;
+    int block_base;
+    int op_dword;
+    int op_byte;
+    int block;
+    int lane;
+
+    for (op_byte = 0; op_byte < ASPEED_ACRY_DATA_MAX_LEN; op_byte++) {
+        op_dword = op_byte / 4;
+        byte_in_dword = op_byte % 4;
+        block = op_dword / 4;
+        lane = op_dword % 4;
+        block_base = block * 12;
+
+        /* exp starts each block; mod is +4 dwords, data +8 dwords. */
+        s->data_map[op_byte] = (block_base + 8 + lane) * 4 + byte_in_dword;
+        if (op_byte < ASPEED_ACRY_MAX_BYTES) {
+            s->exp_map[op_byte] = (block_base + 0 + lane) * 4 + byte_in_dword;
+            s->mod_map[op_byte] = (block_base + 4 + lane) * 4 + byte_in_dword;
+        }
+    }
+}
+
+/*
+ * Read one operand out of the buffer as a big-endian magnitude.
+ *
+ * The operand's bytes are scattered through buf: buf[map[k]] is the byte
+ * at significance level k (k = 0 is the least significant). Walk from the
+ * top down, drop leading zero bytes, and write the result most significant
+ * byte first into out[]. Returns the number of bytes written (the value 0
+ * yields a single 0x00 byte, so always >= 1).
+ */
+static int aspeed_acry_extract_be(const uint8_t *buf, const uint32_t *map,
+                                  int max_bytes, uint8_t *out)
+{
+    int msb;
+    int len;
+    int k;
+
+    /* Highest significance level holding a non-zero byte (skip leading 0s). */
+    msb = max_bytes - 1;
+    while (msb >= 0 && buf[map[msb]] == 0) {
+        msb--;
+    }
+
+    /* All bytes zero: the value is 0. */
+    if (msb < 0) {
+        out[0] = 0;
+        return 1;
+    }
+
+    /* Copy most significant byte first: level msb down to level 0. */
+    len = 0;
+    for (k = msb; k >= 0; k--) {
+        out[len++] = buf[map[k]];
+    }
+
+    return len;
+}
+
+/*
+ * Return a DER INTEGER body for the unsigned big-endian magnitude 'be'.
+ *
+ * DER INTEGERs are signed, so if the top byte has bit 7 set the value
+ * would decode as negative; prepend a 0x00 guard byte in that case.
+ *
+ * The padded copy is written into 'pad_buf' (caller-owned, sized len + 1)
+ * rather than a local, because qcrypto_der_encode_int() only stores the
+ * pointer we hand it - the bytes are not copied until
+ * qcrypto_der_encode_ctx_flush_and_free() - so the body must stay valid
+ * until then. Returns a pointer into 'be' or 'pad_buf' as appropriate,
+ * with the body length in *body_len.
+ */
+static const uint8_t *aspeed_acry_der_uint_body(const uint8_t *be, size_t len,
+                                                uint8_t *pad_buf,
+                                                size_t *body_len)
+{
+    if (be[0] & 0x80) {
+        pad_buf[0] = 0x00;
+        memcpy(pad_buf + 1, be, len);
+        *body_len = len + 1;
+        return pad_buf;
+    }
+
+    *body_len = len;
+    return be;
+}
+
+/*
+ * DER-encode a "RsaPubKey ::= SEQUENCE { n INTEGER, e INTEGER }" (see
+ * crypto/rsakey.h), the format expected by qcrypto_akcipher_new(). n and e
+ * are minimal big-endian magnitudes (as produced by
+ * aspeed_acry_extract_be()); the engine does a raw modexp, so the guest's
+ * exponent is always encoded here as the public 'e'.
+ */
+static uint8_t *aspeed_acry_der_encode_pubkey(const uint8_t *n, size_t n_len,
+                                              const uint8_t *e, size_t e_len,
+                                              size_t *out_len)
+{
+    QCryptoEncodeContext *ctx = qcrypto_der_encode_ctx_new();
+    uint8_t n_pad[ASPEED_ACRY_MAX_BYTES + 1];
+    uint8_t e_pad[ASPEED_ACRY_MAX_BYTES + 1];
+    const uint8_t *n_body;
+    const uint8_t *e_body;
+    size_t n_body_len;
+    size_t e_body_len;
+    uint8_t *buf;
+
+    n_body = aspeed_acry_der_uint_body(n, n_len, n_pad, &n_body_len);
+    e_body = aspeed_acry_der_uint_body(e, e_len, e_pad, &e_body_len);
+
+    qcrypto_der_encode_seq_begin(ctx);
+    qcrypto_der_encode_int(ctx, n_body, n_body_len);
+    qcrypto_der_encode_int(ctx, e_body, e_body_len);
+    qcrypto_der_encode_seq_end(ctx);
+
+    *out_len = qcrypto_der_encode_ctx_buffer_len(ctx);
+    buf = g_malloc(*out_len);
+    qcrypto_der_encode_ctx_flush_and_free(ctx, buf);
+
+    return buf;
+}
+
+/*
+ * Store the RSA result into the output SRAM, scattered through the data
+ * region via data_map[] (result_be is big-endian; the region above the
+ * result is zeroed).
+ *
+ * data_map[] holds SRAM-relative offsets, but sram_as is an AddressSpace
+ * over the SoC memory, where the SRAM is mapped at sram_base - so the
+ * absolute address is sram_base + data_map[k].
+ */
+static void aspeed_acry_store_result(AspeedACRYState *s,
+                                     const uint8_t *result_be, int result_len)
+{
+    uint8_t value;
+    int src;
+    int k;
+
+    /* result_be is MSB-first, so its last byte is the least significant. */
+    src = result_len - 1;
+    for (k = 0; k < ASPEED_ACRY_DATA_MAX_LEN; k++) {
+        value = 0;
+        if (src >= 0) {
+            value = result_be[src--];
+        }
+        address_space_write(&s->sram_as, s->sram_base + s->data_map[k],
+                            MEMTXATTRS_UNSPECIFIED, &value, 1);
+    }
+}
+
+static void aspeed_acry_do_rsa(AspeedACRYState *s)
+{
+    QCryptoAkCipherOptions opts = {
+        .alg = QCRYPTO_AK_CIPHER_ALGO_RSA,
+        .u.rsa = {
+            .padding_alg = QCRYPTO_RSA_PADDING_ALGO_RAW,
+        },
+    };
+    uint8_t result[ASPEED_ACRY_MAX_BYTES] = { 0 };
+    uint64_t src_addr = s->regs[R_ACRY_DMA_SRC];
+    uint8_t buf[ASPEED_ACRY_SRAM_SIZE] = { 0 };
+    uint8_t data[ASPEED_ACRY_DATA_MAX_LEN];
+    uint32_t len = s->regs[R_ACRY_DMA_LEN];
+    g_autofree uint8_t *der_key = NULL;
+    uint8_t n[ASPEED_ACRY_MAX_BYTES];
+    uint8_t e[ASPEED_ACRY_MAX_BYTES];
+    QCryptoAkCipher *cipher = NULL;
+    Error *local_err = NULL;
+    int result_len = 0;
+    size_t der_len;
+    int data_len;
+    int n_len;
+    int e_len;
+
+    if (len == 0 || len > ASPEED_ACRY_SRAM_SIZE) {
+        len = ASPEED_ACRY_SRAM_SIZE;
+    }
+
+    trace_aspeed_acry_rsa_trigger(src_addr, len);
+
+    if (address_space_read(&s->dram_as, src_addr, MEMTXATTRS_UNSPECIFIED,
+                           buf, len) != MEMTX_OK) {
+        qemu_log_mask(LOG_GUEST_ERROR,
+                     "%s: failed to read DMA buffer at 0x%" PRIx64 "\n",
+                     __func__, src_addr);
+    }
+
+    n_len = aspeed_acry_extract_be(buf, s->mod_map, ASPEED_ACRY_MAX_BYTES, n);
+    e_len = aspeed_acry_extract_be(buf, s->exp_map, ASPEED_ACRY_MAX_BYTES, e);
+    data_len = aspeed_acry_extract_be(buf, s->data_map,
+                                      ASPEED_ACRY_DATA_MAX_LEN, data);
+
+    if (trace_event_get_state_backends(TRACE_ASPEED_ACRY_HEXDUMP)) {
+        aspeed_acry_hexdump("buf", buf, len);
+        aspeed_acry_hexdump("n", n, n_len);
+        aspeed_acry_hexdump("e", e, e_len);
+        aspeed_acry_hexdump("data", data, data_len);
+    }
+
+    if (!qcrypto_akcipher_supports(&opts)) {
+        qemu_log_mask(LOG_UNIMP,
+                     "%s: RSA ModExp not supported by the crypto backend; "
+                     "completing with an invalid result\n", __func__);
+        return;
+    }
+
+    der_key = aspeed_acry_der_encode_pubkey(n, n_len, e, e_len, &der_len);
+    cipher = qcrypto_akcipher_new(&opts, QCRYPTO_AK_CIPHER_KEY_TYPE_PUBLIC,
+                                  der_key, der_len, &local_err);
+    if (!cipher) {
+        qemu_log_mask(LOG_GUEST_ERROR,
+                     "%s: failed to create RSA cipher: %s\n",
+                     __func__, error_get_pretty(local_err));
+        error_free(local_err);
+    } else {
+        result_len = qcrypto_akcipher_encrypt(cipher, data, data_len,
+                                              result, sizeof(result),
+                                              &local_err);
+        if (result_len < 0) {
+            qemu_log_mask(LOG_GUEST_ERROR, "%s: RSA modexp failed: %s\n",
+                         __func__, error_get_pretty(local_err));
+            error_free(local_err);
+            result_len = 0;
+        }
+
+        qcrypto_akcipher_free(cipher);
+    }
+
+    if (trace_event_get_state_backends(TRACE_ASPEED_ACRY_HEXDUMP)) {
+        aspeed_acry_hexdump("result", result, result_len);
+    }
+
+    aspeed_acry_store_result(s, result, result_len);
+}
+
+static uint64_t aspeed_acry_read(void *opaque, hwaddr addr, unsigned int size)
+{
+    AspeedACRYState *s = ASPEED_ACRY(opaque);
+
+    addr >>= 2;
+
+    trace_aspeed_acry_read(addr << 2, s->regs[addr]);
+
+    return s->regs[addr];
+}
+
+static void aspeed_acry_write(void *opaque, hwaddr addr, uint64_t data,
+                              unsigned int size)
+{
+    AspeedACRYState *s = ASPEED_ACRY(opaque);
+
+    addr >>= 2;
+
+    trace_aspeed_acry_write(addr << 2, data);
+
+    switch (addr) {
+    case R_ACRY_DMA_SRC:
+        /*
+         * The DMA source register holds a CPU-visible DRAM address (e.g.
+         * 0x8xxxxxxx on AST2600); the engine addresses DRAM from offset 0,
+         * so mask off the top bit to get the DRAM-relative offset.
+         */
+        data &= 0x7FFFFFFF;
+        break;
+    case R_ACRY_STATUS:
+        data = s->regs[R_ACRY_STATUS] & ~data;
+        if (!(data & (R_ACRY_STATUS_RSA_ENG_DONE_MASK |
+                      R_ACRY_STATUS_RSA_DMA_DONE_MASK))) {
+            qemu_irq_lower(s->irq);
+        }
+        break;
+    case R_ACRY_TRIGGER:
+        if (FIELD_EX32(data, ACRY_TRIGGER, RSA_START)) {
+            aspeed_acry_do_rsa(s);
+
+            s->regs[R_ACRY_STATUS] |= R_ACRY_STATUS_RSA_ENG_DONE_MASK |
+                                      R_ACRY_STATUS_RSA_DMA_DONE_MASK;
+            if (s->regs[R_ACRY_INT_MASK] &
+                (R_ACRY_INT_MASK_RSA_ENG_MASK_MASK |
+                 R_ACRY_INT_MASK_RSA_DMA_MASK_MASK)) {
+                qemu_irq_raise(s->irq);
+            }
+        }
+        break;
+    default:
+        break;
+    }
+
+    s->regs[addr] = data;
+}
+
+static const MemoryRegionOps aspeed_acry_ops = {
+    .read = aspeed_acry_read,
+    .write = aspeed_acry_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .valid = {
+        .min_access_size = 1,
+        .max_access_size = 4,
+    },
+};
+
+static void aspeed_acry_reset_hold(Object *obj, ResetType type)
+{
+    AspeedACRYState *s = ASPEED_ACRY(obj);
+
+    memset(s->regs, 0, sizeof(s->regs));
+}
+
+static void aspeed_acry_instance_init(Object *obj)
+{
+    AspeedACRYState *s = ASPEED_ACRY(obj);
+
+    aspeed_acry_init_mapping(s);
+}
+
+static void aspeed_acry_realize(DeviceState *dev, Error **errp)
+{
+    SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
+    AspeedACRYState *s = ASPEED_ACRY(dev);
+
+    sysbus_init_irq(sbd, &s->irq);
+
+    memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_acry_ops, s,
+                          TYPE_ASPEED_ACRY, ASPEED_ACRY_NR_REGS << 2);
+    sysbus_init_mmio(sbd, &s->iomem);
+
+    if (!s->dram_mr) {
+        error_setg(errp, TYPE_ASPEED_ACRY ": 'dram' link not set");
+        return;
+    }
+    address_space_init(&s->dram_as, s->dram_mr, "dram");
+
+    if (!s->sram_mr) {
+        error_setg(errp, TYPE_ASPEED_ACRY ": 'sram' link not set");
+        return;
+    }
+    address_space_init(&s->sram_as, s->sram_mr, "sram");
+}
+
+static const Property aspeed_acry_properties[] = {
+    DEFINE_PROP_LINK("dram", AspeedACRYState, dram_mr,
+                     TYPE_MEMORY_REGION, MemoryRegion *),
+    DEFINE_PROP_LINK("sram", AspeedACRYState, sram_mr,
+                     TYPE_MEMORY_REGION, MemoryRegion *),
+    DEFINE_PROP_UINT64("sram-base", AspeedACRYState, sram_base, 0),
+};
+
+static void aspeed_acry_class_init(ObjectClass *klass, const void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    ResettableClass *rc = RESETTABLE_CLASS(klass);
+
+    dc->desc = "ASPEED ACRY Engine";
+    dc->realize = aspeed_acry_realize;
+    rc->phases.hold = aspeed_acry_reset_hold;
+    device_class_set_props(dc, aspeed_acry_properties);
+}
+
+static const TypeInfo aspeed_acry_types[] = {
+    {
+        .name = TYPE_ASPEED_ACRY,
+        .parent = TYPE_SYS_BUS_DEVICE,
+        .instance_size = sizeof(AspeedACRYState),
+        .instance_init = aspeed_acry_instance_init,
+        .class_init = aspeed_acry_class_init,
+    },
+};
+
+DEFINE_TYPES(aspeed_acry_types)
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index e86d9ad6b3..3912dc2bce 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -137,6 +137,7 @@ system_ss.add(when: 'CONFIG_PVPANIC_PCI', if_true: files('pvpanic-pci.c'))
 system_ss.add(when: 'CONFIG_PVPANIC_MMIO', if_true: files('pvpanic-mmio.c'))
 system_ss.add(when: 'CONFIG_AUX', if_true: files('auxbus.c'))
 system_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files(
+  'aspeed_acry.c',
   'aspeed_hace.c',
   'aspeed_lpc.c',
   'aspeed_ltpi.c',
diff --git a/hw/misc/trace-events b/hw/misc/trace-events
index c9a868b3ef..bbec0d2178 100644
--- a/hw/misc/trace-events
+++ b/hw/misc/trace-events
@@ -331,6 +331,12 @@ aspeed_peci_read(uint64_t offset, uint64_t data) "offset 0x%" PRIx64 " data 0x%"
 aspeed_peci_write(uint64_t offset, uint64_t data) "offset 0x%" PRIx64 " data 0x%" PRIx64
 aspeed_peci_raise_interrupt(uint32_t ctrl, uint32_t status) "ctrl 0x%" PRIx32 " status 0x%" PRIx32
 
+# aspeed_acry.c
+aspeed_acry_read(uint64_t offset, uint64_t data) "offset 0x%" PRIx64 " data 0x%" PRIx64
+aspeed_acry_write(uint64_t offset, uint64_t data) "offset 0x%" PRIx64 " data 0x%" PRIx64
+aspeed_acry_rsa_trigger(uint64_t src_addr, uint32_t len) "src_addr 0x%" PRIx64 " len 0x%" PRIx32
+aspeed_acry_hexdump(const char *desc, uint32_t offset, const char *s) "%s: 0x%08x: %s"
+
 # aspeed_hace.c
 aspeed_hace_read(uint64_t offset, uint64_t data) "offset 0x%" PRIx64 " data 0x%" PRIx64
 aspeed_hace_write(uint64_t offset, uint64_t data) "offset 0x%" PRIx64 " data 0x%" PRIx64
-- 
2.43.0


  reply	other threads:[~2026-08-13  6:24 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-13  6:24 [PATCH v1 0/5] Add ASPEED ACRY RSA model for the AST2600 Jamin Lin
2026-08-13  6:24 ` Jamin Lin [this message]
2026-08-13  6:24 ` [PATCH v1 2/5] hw/arm/aspeed_ast2600: Introduce the ACRY SRAM Jamin Lin
2026-08-13  6:24 ` [PATCH v1 3/5] hw/arm/aspeed_soc: Add the ACRY model to AspeedSoCState Jamin Lin
2026-08-13  6:24 ` [PATCH v1 4/5] hw/arm/aspeed_ast2600: Wire up the ACRY model Jamin Lin
2026-08-13  6:24 ` [PATCH v1 5/5] tests/qtest/aspeed-acry-test: Add RSA ModExp tests Jamin Lin

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=20260813062359.425268-2-jamin_lin@aspeedtech.com \
    --to=jamin_lin@aspeedtech.com \
    --cc=andrew@codeconstruct.com.au \
    --cc=clg@kaod.org \
    --cc=farosas@suse.de \
    --cc=joel@jms.id.au \
    --cc=kane_chen@aspeedtech.com \
    --cc=leetroy@gmail.com \
    --cc=lvivier@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=steven_lee@aspeedtech.com \
    --cc=troy_lee@aspeedtech.com \
    /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.