Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/2228707/?format=api
{ "id": 2228707, "url": "http://patchwork.ozlabs.org/api/patches/2228707/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260427084055.2246089-2-steven_lee@aspeedtech.com/", "project": { "id": 14, "url": "http://patchwork.ozlabs.org/api/projects/14/?format=api", "name": "QEMU Development", "link_name": "qemu-devel", "list_id": "qemu-devel.nongnu.org", "list_email": "qemu-devel@nongnu.org", "web_url": "", "scm_url": "", "webscm_url": "", "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20260427084055.2246089-2-steven_lee@aspeedtech.com>", "list_archive_url": null, "date": "2026-04-27T08:40:54", "name": "[RFC,v1,1/1] hw/arm: aspeed: Add PoC integration for Caliptra Root of Trust", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "657c3f743c7c29d429fffd64bbc330216cefdbd2", "submitter": { "id": 81516, "url": "http://patchwork.ozlabs.org/api/people/81516/?format=api", "name": "Steven Lee", "email": "steven_lee@aspeedtech.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20260427084055.2246089-2-steven_lee@aspeedtech.com/mbox/", "series": [ { "id": 501606, "url": "http://patchwork.ozlabs.org/api/series/501606/?format=api", "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/list/?series=501606", "date": "2026-04-27T08:40:53", "name": "hw/arm: aspeed: PoC integration for Caliptra Root of Trust", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/501606/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2228707/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2228707/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org\n (client-ip=209.51.188.17; helo=lists1p.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)", "Received": [ "from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17])\n\t(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g3xyN2z48z1yJs\n\tfor <incoming@patchwork.ozlabs.org>; Mon, 27 Apr 2026 18:47:06 +1000 (AEST)", "from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists1p.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1wHHbd-0005pL-QV; Mon, 27 Apr 2026 04:46:18 -0400", "from eggs.gnu.org ([2001:470:142:3::10])\n by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <steven_lee@aspeedtech.com>)\n id 1wHHbb-0005oz-5N; Mon, 27 Apr 2026 04:46:15 -0400", "from mail.aspeedtech.com ([211.20.114.72]\n helo=twmbx01.aspeedtech.com)\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <steven_lee@aspeedtech.com>)\n id 1wHHbY-0001C8-D2; Mon, 27 Apr 2026 04:46:14 -0400", "from TWMBX01.aspeed.com (192.168.0.62) by TWMBX01.aspeed.com\n (192.168.0.62) with Microsoft SMTP Server (version=TLS1_2,\n cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1748.10; Mon, 27 Apr\n 2026 16:40:55 +0800", "from mail.aspeedtech.com (192.168.10.10) by TWMBX01.aspeed.com\n (192.168.0.62) with Microsoft SMTP Server id 15.2.1748.10 via Frontend\n Transport; Mon, 27 Apr 2026 16:40:55 +0800" ], "To": "=?utf-8?q?C=C3=A9dric_Le_Goater?= <clg@kaod.org>,\n Peter Maydell <peter.maydell@linaro.org>, Troy Lee <leetroy@gmail.com>,\n Jamin Lin <jamin_lin@aspeedtech.com>, Kane Chen <kane_chen@aspeedtech.com>,\n \"Andrew Jeffery\" <andrew@codeconstruct.com.au>,\n Joel Stanley <joel@jms.id.au>,\n Pierrick Bouvier <pierrick.bouvier@linaro.org>,\n \"open list:All patches CC here\" <qemu-devel@nongnu.org>,\n \"open list:ASPEED BMCs\" <qemu-arm@nongnu.org>", "CC": "<troy_lee@aspeedtech.com>, <longzl2@lenovo.com>,\n <yunlin.tang@aspeedtech.com>, <steven_lee@aspeedtech.com>", "Subject": "[RFC PATCH v1 1/1] hw/arm: aspeed: Add PoC integration for Caliptra\n Root of Trust", "Date": "Mon, 27 Apr 2026 16:40:54 +0800", "Message-ID": "<20260427084055.2246089-2-steven_lee@aspeedtech.com>", "X-Mailer": "git-send-email 2.43.0", "In-Reply-To": "<20260427084055.2246089-1-steven_lee@aspeedtech.com>", "References": "<20260427084055.2246089-1-steven_lee@aspeedtech.com>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "Content-Type": "text/plain", "Received-SPF": "pass client-ip=211.20.114.72;\n envelope-from=steven_lee@aspeedtech.com; helo=twmbx01.aspeedtech.com", "X-Spam_score_int": "-18", "X-Spam_score": "-1.9", "X-Spam_bar": "-", "X-Spam_report": "(-1.9 / 5.0 requ) BAYES_00=-1.9, SPF_HELO_NONE=0.001,\n SPF_PASS=-0.001 autolearn=ham autolearn_force=no", "X-Spam_action": "no action", "X-BeenThere": "qemu-devel@nongnu.org", "X-Mailman-Version": "2.1.29", "Precedence": "list", "List-Id": "qemu development <qemu-devel.nongnu.org>", "List-Unsubscribe": "<https://lists.nongnu.org/mailman/options/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>", "List-Archive": "<https://lists.nongnu.org/archive/html/qemu-devel>", "List-Post": "<mailto:qemu-devel@nongnu.org>", "List-Help": "<mailto:qemu-devel-request@nongnu.org?subject=help>", "List-Subscribe": "<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=subscribe>", "Reply-to": "Steven Lee <steven_lee@aspeedtech.com>", "From": "Steven Lee via qemu development <qemu-devel@nongnu.org>", "Errors-To": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org", "Sender": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org" }, "content": "The ASPEED AST2700fc SoC integrates the Caliptra Root of Trust\n(Caliptra 1.2 core). Moving forward, we expect more SoCs to adopt\nCaliptra cores (e.g., Caliptra 2.x). Currently, QEMU does not have\na native Caliptra emulator.\n\nThe official `caliptra-sw` project provides a fully functional\nemulator with C-bindings. As a Proof of Concept, this RFC integrates\nthe external `caliptra-sw` C-binding model into QEMU to enable booting\nthe AST2700fc machine.\n\nThis RFC does not propose merging the current PoC design as-is.\nInstead, it is intended to explore possible approaches for adding\nCaliptra support in QEMU and to gather early feedback from the\ncommunity on architecture and integration strategy.\n\nIn this PoC, the `caliptra-sw` emulator is used as a reference model\nto enable early bring-up and validation of the AST2700fc secure boot\nflow, rather than as a final implementation choice. The integration is\nbased on the `caliptra-1.2` branch of the official repository:\nhttps://github.com/chipsalliance/caliptra-sw/tree/caliptra-1.2\n\nTo avoid making normal ASPEED/AArch64 builds depend on a local external\ncheckout, the c-binding backend is compiled only when the PoC detects\nthe generated `caliptra-sw` c-binding header and static library in the\nexpected sibling source tree. A mergeable version would need an\nexplicit configure option and a proper dependency integration.\n\nFor context, the actual hardware boot flow on the AST2700fc relies on a\ndedicated RISC-V core (bootmcu) to orchestrate the secure boot:\n\n 1. bootmcu executes its ROM code.\n 2. bootmcu releases the Caliptra core from reset.\n 3. Caliptra requests its FMC and Runtime (RT) firmware.\n 4. bootmcu loads the Caliptra FMC/RT images into Caliptra's mailbox.\n 5. Caliptra ROM verifies the signature of the Caliptra FMC/RT images.\n 6. Caliptra boots into its FMC and RT environments.\n 7. bootmcu requests Caliptra RT to verify the bootmcu's own FMC.\n 8. bootmcu executes its FMC.\n 9. bootmcu requests Caliptra to verify the BMC (Cortex-A35) firmware.\n 10. BMC (Cortex-A35) firmware begins execution.\n\nSince QEMU currently lacks a `bootmcu` model and the associated mailbox\ninteractions with Caliptra, this PoC simplifies the boot flow by using\na background thread and the `caliptra_model_boot_default` C-binding to\nsimulate steps 1 through 6.\n\nTo approximate the hardware behavior where the Cortex-A35 CPUs remain\nin reset until secure boot is completed, this PoC uses\n`vm_stop_force_state()` as a temporary approximation.\n\nThis approach is intentionally simplified and not intended to reflect\nthe final QEMU design. In particular, the use of a background thread\nand global VM control APIs may not align with QEMU device model\nexpectations, and alternative approaches are encouraged.\n\nSigned-off-by: Steven Lee <steven_lee@aspeedtech.com>\n---\n MAINTAINERS | 2 +\n docs/system/arm/aspeed.rst | 20 +++\n include/hw/arm/aspeed_caliptra_emu.h | 17 ++\n hw/arm/aspeed_ast27x0-fc.c | 60 +++++++\n hw/arm/aspeed_caliptra_emu.c | 259 +++++++++++++++++++++++++++\n hw/arm/meson.build | 31 +++-\n 6 files changed, 388 insertions(+), 1 deletion(-)\n create mode 100644 include/hw/arm/aspeed_caliptra_emu.h\n create mode 100644 hw/arm/aspeed_caliptra_emu.c", "diff": "diff --git a/MAINTAINERS b/MAINTAINERS\nindex ad215eced8..376959dfd2 100644\n--- a/MAINTAINERS\n+++ b/MAINTAINERS\n@@ -1254,6 +1254,8 @@ L: qemu-arm@nongnu.org\n S: Maintained\n F: hw/*/*aspeed*\n F: include/hw/*/*aspeed*\n+F: hw/arm/aspeed_caliptra_emu.c\n+F: include/hw/arm/aspeed_caliptra_emu.h\n F: hw/net/ftgmac100.c\n F: include/hw/net/ftgmac100.h\n F: docs/system/arm/aspeed.rst\ndiff --git a/docs/system/arm/aspeed.rst b/docs/system/arm/aspeed.rst\nindex d0054a7dbb..656924262b 100644\n--- a/docs/system/arm/aspeed.rst\n+++ b/docs/system/arm/aspeed.rst\n@@ -423,6 +423,26 @@ Steps to boot the AST2700fc machine:\n -snapshot \\\n -S -nographic\n \n+The ``ast2700fc`` machine can also boot a Caliptra emulator through the\n+``caliptra-sw`` c-binding before starting the Cortex-A35 processors. The ROM\n+and firmware bundle are configured with the ``caliptra-rom`` and\n+``caliptra-firmware`` machine properties.\n+\n+This RFC PoC backend is built only when a local ``../caliptra-sw`` checkout\n+contains the generated c-binding header and static library.\n+\n+For example, to run Caliptra firmware from ``caliptra-sw``:\n+\n+.. code-block:: bash\n+\n+ $ qemu-system-aarch64 \\\n+ -M ast2700fc,caliptra-rom=images/caliptra-rom-with-log.bin,caliptra-firmware=images/caliptra-fw.bundle \\\n+ ...\n+\n+QEMU boots the c-binding model to the Caliptra runtime-ready boot status before\n+starting the Cortex-A35 CPUs. If these properties are omitted, no Caliptra\n+backend is launched.\n+\n After launching QEMU, serial devices will be automatically redirected.\n Example output:\n \ndiff --git a/include/hw/arm/aspeed_caliptra_emu.h b/include/hw/arm/aspeed_caliptra_emu.h\nnew file mode 100644\nindex 0000000000..136e327d11\n--- /dev/null\n+++ b/include/hw/arm/aspeed_caliptra_emu.h\n@@ -0,0 +1,17 @@\n+/*\n+ * ASPEED Caliptra emulator backend\n+ *\n+ * Copyright (C) 2026 ASPEED Technology Inc.\n+ *\n+ * SPDX-License-Identifier: GPL-2.0-or-later\n+ */\n+\n+#ifndef ASPEED_CALIPTRA_EMU_H\n+#define ASPEED_CALIPTRA_EMU_H\n+\n+#include \"chardev/char.h\"\n+\n+void aspeed_caliptra_emu_start(Chardev *console, const char *rom_path,\n+ const char *firmware_path);\n+\n+#endif /* ASPEED_CALIPTRA_EMU_H */\ndiff --git a/hw/arm/aspeed_ast27x0-fc.c b/hw/arm/aspeed_ast27x0-fc.c\nindex 5eb6680da9..84aedef815 100644\n--- a/hw/arm/aspeed_ast27x0-fc.c\n+++ b/hw/arm/aspeed_ast27x0-fc.c\n@@ -22,6 +22,7 @@\n #include \"hw/arm/boot.h\"\n #include \"hw/block/flash.h\"\n #include \"hw/arm/aspeed_coprocessor.h\"\n+#include \"hw/arm/aspeed_caliptra_emu.h\"\n #include \"hw/arm/machines-qom.h\"\n \n #define TYPE_AST2700FC MACHINE_TYPE_NAME(\"ast2700fc\")\n@@ -34,6 +35,9 @@ static struct arm_boot_info ast2700fc_board_info = {\n struct Ast2700FCState {\n MachineState parent_obj;\n \n+ char *caliptra_rom;\n+ char *caliptra_firmware;\n+\n MemoryRegion ca35_memory;\n MemoryRegion ca35_dram;\n MemoryRegion ca35_boot_rom;\n@@ -198,9 +202,53 @@ static bool ast2700fc_tsp_init(MachineState *machine, Error **errp)\n \n static void ast2700fc_init(MachineState *machine)\n {\n+ Ast2700FCState *s = AST2700FC(machine);\n+\n ast2700fc_ca35_init(machine, &error_abort);\n ast2700fc_ssp_init(machine, &error_abort);\n ast2700fc_tsp_init(machine, &error_abort);\n+ aspeed_caliptra_emu_start(serial_hd(0), s->caliptra_rom,\n+ s->caliptra_firmware);\n+}\n+\n+static char *ast2700fc_get_caliptra_rom(Object *obj, Error **errp)\n+{\n+ Ast2700FCState *s = AST2700FC(obj);\n+\n+ return g_strdup(s->caliptra_rom ? s->caliptra_rom : \"\");\n+}\n+\n+static void ast2700fc_set_caliptra_rom(Object *obj, const char *value,\n+ Error **errp)\n+{\n+ Ast2700FCState *s = AST2700FC(obj);\n+\n+ g_free(s->caliptra_rom);\n+ s->caliptra_rom = g_strdup(value);\n+}\n+\n+static char *ast2700fc_get_caliptra_firmware(Object *obj, Error **errp)\n+{\n+ Ast2700FCState *s = AST2700FC(obj);\n+\n+ return g_strdup(s->caliptra_firmware ? s->caliptra_firmware : \"\");\n+}\n+\n+static void ast2700fc_set_caliptra_firmware(Object *obj, const char *value,\n+ Error **errp)\n+{\n+ Ast2700FCState *s = AST2700FC(obj);\n+\n+ g_free(s->caliptra_firmware);\n+ s->caliptra_firmware = g_strdup(value);\n+}\n+\n+static void ast2700fc_instance_finalize(Object *obj)\n+{\n+ Ast2700FCState *s = AST2700FC(obj);\n+\n+ g_free(s->caliptra_rom);\n+ g_free(s->caliptra_firmware);\n }\n \n static void ast2700fc_class_init(ObjectClass *oc, const void *data)\n@@ -212,6 +260,17 @@ static void ast2700fc_class_init(ObjectClass *oc, const void *data)\n mc->no_floppy = 1;\n mc->no_cdrom = 1;\n mc->min_cpus = mc->max_cpus = mc->default_cpus = 6;\n+\n+ object_class_property_add_str(oc, \"caliptra-rom\",\n+ ast2700fc_get_caliptra_rom,\n+ ast2700fc_set_caliptra_rom);\n+ object_class_property_set_description(oc, \"caliptra-rom\",\n+ \"Caliptra ROM image used by the c-binding emulator backend\");\n+ object_class_property_add_str(oc, \"caliptra-firmware\",\n+ ast2700fc_get_caliptra_firmware,\n+ ast2700fc_set_caliptra_firmware);\n+ object_class_property_set_description(oc, \"caliptra-firmware\",\n+ \"Caliptra firmware bundle used by the c-binding emulator backend\");\n }\n \n static const TypeInfo ast2700fc_types[] = {\n@@ -220,6 +279,7 @@ static const TypeInfo ast2700fc_types[] = {\n .parent = TYPE_MACHINE,\n .class_init = ast2700fc_class_init,\n .instance_size = sizeof(Ast2700FCState),\n+ .instance_finalize = ast2700fc_instance_finalize,\n .interfaces = aarch64_machine_interfaces,\n },\n };\ndiff --git a/hw/arm/aspeed_caliptra_emu.c b/hw/arm/aspeed_caliptra_emu.c\nnew file mode 100644\nindex 0000000000..c5dfbc786f\n--- /dev/null\n+++ b/hw/arm/aspeed_caliptra_emu.c\n@@ -0,0 +1,259 @@\n+/*\n+ * ASPEED Caliptra emulator backend\n+ *\n+ * Copyright (C) 2026 ASPEED Technology Inc.\n+ *\n+ * SPDX-License-Identifier: GPL-2.0-or-later\n+ */\n+\n+#include \"qemu/osdep.h\"\n+#include \"chardev/char.h\"\n+#include \"hw/arm/aspeed_caliptra_emu.h\"\n+#include \"qemu/error-report.h\"\n+\n+#ifdef CONFIG_ASPEED_CALIPTRA_CBINDING\n+#include \"qemu/main-loop.h\"\n+#include \"qemu/thread.h\"\n+#include \"system/runstate.h\"\n+\n+#include \"caliptra_model.h\"\n+#endif\n+\n+#define CALIPTRA_EMU_PREFIX \"[caliptra] \"\n+\n+#ifdef CONFIG_ASPEED_CALIPTRA_CBINDING\n+#define CALIPTRA_RUNTIME_READY_BOOT_STATUS 0x600\n+\n+typedef struct AspeedCaliptraEmuState {\n+ QemuThread thread;\n+ VMChangeStateEntry *vmstate;\n+ struct caliptra_model *model;\n+ Chardev *console;\n+ char *rom_path;\n+ char *firmware_path;\n+ char *error;\n+ bool at_start_of_line;\n+ bool waiting_for_runtime;\n+ bool startup_pause_done;\n+} AspeedCaliptraEmuState;\n+\n+static void caliptra_emu_write(AspeedCaliptraEmuState *s,\n+ const uint8_t *buf, size_t len)\n+{\n+ g_autofree uint8_t *out = NULL;\n+ size_t prefix_len = strlen(CALIPTRA_EMU_PREFIX);\n+ size_t extra = 0;\n+ size_t i;\n+ size_t out_pos = 0;\n+\n+ if (!s->console || len == 0) {\n+ return;\n+ }\n+\n+ for (i = 0; i < len; i++) {\n+ if (s->at_start_of_line || (i > 0 && buf[i - 1] == '\\n')) {\n+ extra += prefix_len;\n+ }\n+ }\n+\n+ out = g_malloc(len + extra);\n+ for (i = 0; i < len; i++) {\n+ if (s->at_start_of_line) {\n+ memcpy(out + out_pos, CALIPTRA_EMU_PREFIX, prefix_len);\n+ out_pos += prefix_len;\n+ s->at_start_of_line = false;\n+ }\n+\n+ out[out_pos++] = buf[i];\n+ if (buf[i] == '\\n') {\n+ s->at_start_of_line = true;\n+ }\n+ }\n+\n+ qemu_chr_write_all(s->console, out, out_pos);\n+}\n+\n+static void caliptra_emu_note(AspeedCaliptraEmuState *s, const char *msg)\n+{\n+ if (!s->at_start_of_line) {\n+ static const uint8_t newline = '\\n';\n+ qemu_chr_write_all(s->console, &newline, 1);\n+ s->at_start_of_line = true;\n+ }\n+ caliptra_emu_write(s, (const uint8_t *)msg, strlen(msg));\n+}\n+\n+static bool caliptra_emu_read_file(const char *path, const char *name,\n+ gchar **contents, gsize *len, char **error)\n+{\n+ g_autoptr(GError) err = NULL;\n+\n+ if (!g_file_get_contents(path, contents, len, &err)) {\n+ *error = g_strdup_printf(\"Failed to read Caliptra %s image '%s': %s\",\n+ name, path, err->message);\n+ return false;\n+ }\n+\n+ return true;\n+}\n+\n+static void caliptra_emu_release_vm(AspeedCaliptraEmuState *s,\n+ const char *reason)\n+{\n+ if (!s->waiting_for_runtime) {\n+ return;\n+ }\n+\n+ s->waiting_for_runtime = false;\n+ caliptra_emu_note(s, reason);\n+ if (s->startup_pause_done) {\n+ vm_start();\n+ }\n+}\n+\n+static void caliptra_emu_vm_state_change(void *opaque, bool running,\n+ RunState state)\n+{\n+ AspeedCaliptraEmuState *s = opaque;\n+\n+ if (!running || !s->waiting_for_runtime || s->startup_pause_done) {\n+ return;\n+ }\n+\n+ s->startup_pause_done = true;\n+ /*\n+ * FIXME: RFC ONLY - Using vm_stop_force_state is a hack.\n+ * We need advice on the proper way to hold main CPUs in reset\n+ * until the Caliptra thread finishes booting.\n+ */\n+ vm_stop_force_state(RUN_STATE_PAUSED);\n+}\n+\n+static void caliptra_emu_boot_done_bh(void *opaque)\n+{\n+ AspeedCaliptraEmuState *s = opaque;\n+\n+ if (s->error) {\n+ error_report(\"%s\", s->error);\n+ caliptra_emu_release_vm(s,\n+ \"runtime boot failed, releasing CA35\\n\");\n+ } else {\n+ caliptra_emu_release_vm(s, \"runtime ready, releasing CA35\\n\");\n+ }\n+\n+ qemu_del_vm_change_state_handler(s->vmstate);\n+ if (s->model) {\n+ caliptra_model_destroy(s->model);\n+ }\n+ g_free(s->rom_path);\n+ g_free(s->firmware_path);\n+ g_free(s->error);\n+ g_free(s);\n+}\n+\n+static void *caliptra_emu_thread(void *opaque)\n+{\n+ AspeedCaliptraEmuState *s = opaque;\n+ g_autofree gchar *rom = NULL;\n+ g_autofree gchar *firmware = NULL;\n+ gsize rom_len = 0;\n+ gsize firmware_len = 0;\n+ static const uint8_t empty;\n+ struct caliptra_model_init_params params;\n+ int rc;\n+\n+ if (!caliptra_emu_read_file(s->rom_path, \"ROM\", &rom, &rom_len,\n+ &s->error) ||\n+ !caliptra_emu_read_file(s->firmware_path, \"firmware\", &firmware,\n+ &firmware_len, &s->error)) {\n+ goto out;\n+ }\n+\n+ params = (struct caliptra_model_init_params) {\n+ .rom = {\n+ .data = (const uint8_t *)rom,\n+ .len = rom_len,\n+ },\n+ .dccm = {\n+ .data = &empty,\n+ .len = 0,\n+ },\n+ .iccm = {\n+ .data = &empty,\n+ .len = 0,\n+ },\n+ .security_state = CALIPTRA_SEC_STATE_DBG_UNLOCKED_UNPROVISIONED,\n+ };\n+\n+ rc = caliptra_model_init_default(params, &s->model);\n+ if (rc != CALIPTRA_MODEL_STATUS_OK) {\n+ s->error = g_strdup_printf(\n+ \"Failed to initialize Caliptra c-binding model: %d\", rc);\n+ goto out;\n+ }\n+\n+ rc = caliptra_model_boot_default(s->model,\n+ (struct caliptra_buffer) {\n+ .data = (const uint8_t *)firmware,\n+ .len = firmware_len,\n+ },\n+ CALIPTRA_RUNTIME_READY_BOOT_STATUS);\n+ if (rc != CALIPTRA_MODEL_STATUS_OK) {\n+ s->error = g_strdup_printf(\"Failed to boot Caliptra runtime: %d\", rc);\n+ goto out;\n+ }\n+\n+out:\n+ aio_bh_schedule_oneshot(qemu_get_aio_context(), caliptra_emu_boot_done_bh,\n+ s);\n+ return NULL;\n+}\n+\n+void aspeed_caliptra_emu_start(Chardev *console, const char *rom_path,\n+ const char *firmware_path)\n+{\n+ AspeedCaliptraEmuState *s;\n+\n+ if (!rom_path && !firmware_path) {\n+ return;\n+ }\n+\n+ if (!rom_path || !rom_path[0] || !firmware_path || !firmware_path[0]) {\n+ error_report(\"Both caliptra-rom and caliptra-firmware must be set\");\n+ return;\n+ }\n+\n+ if (!console) {\n+ error_report(\"Caliptra emulator backend is set \"\n+ \"but serial0 is unavailable\");\n+ return;\n+ }\n+\n+ s = g_new0(AspeedCaliptraEmuState, 1);\n+ s->console = console;\n+ s->rom_path = g_strdup(rom_path);\n+ s->firmware_path = g_strdup(firmware_path);\n+ s->at_start_of_line = true;\n+ s->waiting_for_runtime = true;\n+\n+ s->vmstate = qemu_add_vm_change_state_handler(caliptra_emu_vm_state_change,\n+ s);\n+ caliptra_emu_note(s, \"starting c-binding model thread\\n\");\n+ caliptra_emu_note(s, \"waiting for runtime ready before starting CA35\\n\");\n+\n+ qemu_thread_create(&s->thread, \"caliptra-emu\", caliptra_emu_thread, s,\n+ QEMU_THREAD_DETACHED);\n+}\n+#else\n+void aspeed_caliptra_emu_start(Chardev *console, const char *rom_path,\n+ const char *firmware_path)\n+{\n+ (void)console;\n+\n+ if (!rom_path && !firmware_path) {\n+ return;\n+ }\n+\n+ error_report(\"Caliptra c-binding backend was not compiled in\");\n+}\n+#endif\ndiff --git a/hw/arm/meson.build b/hw/arm/meson.build\nindex b187b946f0..e37df51a48 100644\n--- a/hw/arm/meson.build\n+++ b/hw/arm/meson.build\n@@ -1,5 +1,33 @@\n arm_ss = ss.source_set()\n arm_common_ss = ss.source_set()\n+\n+# RFC ONLY: this local-tree probe is for PoC discussion. A mergeable version\n+# needs an explicit configure option and a proper dependency integration.\n+caliptra_cbinding_root = meson.project_source_root() / '..' / 'caliptra-sw'\n+caliptra_cbinding_inc = caliptra_cbinding_root / 'hw-model/c-binding/out'\n+caliptra_cbinding_header = caliptra_cbinding_inc / 'caliptra_model.h'\n+caliptra_cbinding_incdir = include_directories(\n+ '../../../caliptra-sw/hw-model/c-binding/out')\n+caliptra_cbinding_lib = caliptra_cbinding_root / 'target' / 'debug'\n+caliptra_cbinding_lib_name = 'libcaliptra_hw_model_c_binding.a'\n+caliptra_cbinding_lib = caliptra_cbinding_lib / caliptra_cbinding_lib_name\n+caliptra_cbinding_dep = []\n+caliptra_cbinding_found = fs.exists(caliptra_cbinding_header)\n+if caliptra_cbinding_found\n+ caliptra_cbinding_found = fs.exists(caliptra_cbinding_lib)\n+endif\n+if caliptra_cbinding_found\n+ caliptra_cbinding_dep = declare_dependency(\n+ compile_args: ['-DCONFIG_ASPEED_CALIPTRA_CBINDING'],\n+ include_directories: caliptra_cbinding_incdir,\n+ link_args: [\n+ caliptra_cbinding_lib,\n+ '-lstdc++',\n+ '-ldl',\n+ '-lrt',\n+ '-lm',\n+ ])\n+endif\n arm_common_ss.add(when: 'CONFIG_ARM_VIRT', if_true: files('virt.c'))\n arm_common_ss.add(when: 'CONFIG_ACPI', if_true: files('virt-acpi-build.c'))\n arm_common_ss.add(when: 'CONFIG_DIGIC', if_true: files('digic_boards.c'))\n@@ -72,10 +100,11 @@ arm_common_ss.add(when: ['CONFIG_ASPEED_SOC', 'TARGET_AARCH64'], if_true: files(\n 'aspeed_ast1700.c',\n 'aspeed_ast27x0.c',\n 'aspeed_ast27x0_evb.c',\n+ 'aspeed_caliptra_emu.c',\n 'aspeed_ast27x0-fc.c',\n 'aspeed_ast27x0-ssp.c',\n 'aspeed_ast27x0-tsp.c',\n- 'aspeed_coprocessor_common.c'))\n+ 'aspeed_coprocessor_common.c') + [caliptra_cbinding_dep])\n arm_common_ss.add(when: 'CONFIG_MPS2', if_true: files('mps2.c'))\n arm_common_ss.add(when: 'CONFIG_MPS2', if_true: files('mps2-tz.c'))\n arm_common_ss.add(when: 'CONFIG_MSF2', if_true: files('msf2-soc.c'))\n", "prefixes": [ "RFC", "v1", "1/1" ] }