From: Bin Meng <bin.meng@processmission.com>
To: QEMU <qemu-devel@nongnu.org>
Cc: Alistair Francis <alistair@alistair23.me>,
Paolo Bonzini <pbonzini@redhat.com>,
qemu-arm@nongnu.org
Subject: [PATCH v2 12/32] hw/ssi: Add Phytium E2000 QSPI controller
Date: Tue, 8 Sep 2026 18:41:21 +0800 [thread overview]
Message-ID: <20260908104159.1621764-13-bin.meng@processmission.com> (raw)
In-Reply-To: <20260908104159.1621764-1-bin.meng@processmission.com>
Phytium E2000Q integrates a QSPI controller which seems to be an
in-house IP. This adds a model for it with command-port and
direct-map paths, and exposes an SSI bus and chip-select output.
Signed-off-by: Bin Meng <bin.meng@processmission.com>
---
(no changes since v1)
include/hw/ssi/phytium_qspi.h | 23 ++
hw/ssi/phytium_qspi.c | 398 ++++++++++++++++++++++++++++++++++
hw/ssi/Kconfig | 5 +
hw/ssi/meson.build | 1 +
4 files changed, 427 insertions(+)
create mode 100644 include/hw/ssi/phytium_qspi.h
create mode 100644 hw/ssi/phytium_qspi.c
diff --git a/include/hw/ssi/phytium_qspi.h b/include/hw/ssi/phytium_qspi.h
new file mode 100644
index 0000000000..c6534af16d
--- /dev/null
+++ b/include/hw/ssi/phytium_qspi.h
@@ -0,0 +1,23 @@
+/*
+ * Phytium E2000 QSPI controller
+ *
+ * Copyright (c) 2026 Process Mission
+ *
+ * Author:
+ * Bin Meng <bin.meng@processmission.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef HW_SSI_PHYTIUM_QSPI_H
+#define HW_SSI_PHYTIUM_QSPI_H
+
+#include "hw/core/sysbus.h"
+
+#define TYPE_PHYTIUM_E2000_QSPI "phytium-e2000-qspi"
+OBJECT_DECLARE_SIMPLE_TYPE(PhytiumE2000QSPIState, PHYTIUM_E2000_QSPI)
+
+#define PHYTIUM_E2000_QSPI_REG_SIZE 0x1000
+#define PHYTIUM_E2000_QSPI_DIRECT_SIZE 0x10000000
+
+#endif
diff --git a/hw/ssi/phytium_qspi.c b/hw/ssi/phytium_qspi.c
new file mode 100644
index 0000000000..da7dce1d46
--- /dev/null
+++ b/hw/ssi/phytium_qspi.c
@@ -0,0 +1,398 @@
+/*
+ * Phytium E2000 QSPI controller
+ *
+ * Copyright (c) 2026 Process Mission
+ *
+ * Author:
+ * Bin Meng <bin.meng@processmission.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "hw/ssi/phytium_qspi.h"
+
+#include "hw/core/register.h"
+#include "hw/core/irq.h"
+#include "hw/ssi/ssi.h"
+#include "migration/vmstate.h"
+#include "qemu/log.h"
+#include "qemu/module.h"
+
+REG32(FLASH_CAP, 0x00)
+REG32(RD_CFG, 0x04)
+ FIELD(RD_CFG, CMD, 24, 8)
+ FIELD(RD_CFG, ADDR_SEL, 19, 1)
+ FIELD(RD_CFG, LATENCY, 18, 1)
+ FIELD(RD_CFG, DUMMY, 4, 5)
+REG32(WR_CFG, 0x08)
+ FIELD(WR_CFG, CMD, 24, 8)
+ FIELD(WR_CFG, ADDR_SEL, 4, 1)
+ FIELD(WR_CFG, MODE, 3, 1)
+REG32(FLUSH, 0x0c)
+REG32(CMD_PORT, 0x10)
+ FIELD(CMD_PORT, CMD, 24, 8)
+ FIELD(CMD_PORT, CS, 19, 2)
+ FIELD(CMD_PORT, CMD_ADDR, 15, 1)
+ FIELD(CMD_PORT, LATENCY, 14, 1)
+ FIELD(CMD_PORT, DATA_XFER, 13, 1)
+ FIELD(CMD_PORT, ADDR_SEL, 12, 1)
+ FIELD(CMD_PORT, DUMMY, 7, 5)
+ FIELD(CMD_PORT, RW_NUM, 3, 3)
+REG32(ADDR_PORT, 0x14)
+REG32(HD_PORT, 0x18)
+REG32(LD_PORT, 0x1c)
+REG32(FUN_SET, 0x20)
+REG32(WIP, 0x24)
+REG32(WP, 0x28)
+REG32(MODE, 0x2c)
+REG32(LEGACY_CTRL, 0x30)
+
+#define PHYTIUM_E2000_QSPI_R_MAX (A_LEGACY_CTRL / sizeof(uint32_t) + 1)
+#define PHYTIUM_E2000_QSPI_PAGE_SIZE 256
+
+struct PhytiumE2000QSPIState {
+ SysBusDevice parent_obj;
+
+ uint32_t regs[PHYTIUM_E2000_QSPI_R_MAX];
+ RegisterInfo regs_info[PHYTIUM_E2000_QSPI_R_MAX];
+ MemoryRegion direct_mr;
+ SSIBus *spi;
+ qemu_irq cs;
+ uint8_t write_buffer[PHYTIUM_E2000_QSPI_PAGE_SIZE];
+ uint32_t write_address;
+ uint16_t write_len;
+ bool write_pending;
+ bool resetting;
+};
+
+static void phytium_e2000_qspi_select(PhytiumE2000QSPIState *s)
+{
+ qemu_irq_lower(s->cs);
+}
+
+static void phytium_e2000_qspi_deselect(PhytiumE2000QSPIState *s)
+{
+ qemu_irq_raise(s->cs);
+}
+
+static void phytium_e2000_qspi_send_address(PhytiumE2000QSPIState *s,
+ uint32_t address,
+ unsigned int length)
+{
+ int shift;
+
+ for (shift = (length - 1) * 8; shift >= 0; shift -= 8) {
+ ssi_transfer(s->spi, extract32(address, shift, 8));
+ }
+}
+
+static void phytium_e2000_qspi_send_dummy(PhytiumE2000QSPIState *s,
+ unsigned int cycles)
+{
+ unsigned int i;
+
+ for (i = 0; i < DIV_ROUND_UP(cycles, 8); i++) {
+ ssi_transfer(s->spi, 0);
+ }
+}
+
+static void phytium_e2000_qspi_exec_port(PhytiumE2000QSPIState *s)
+{
+ uint32_t cfg = s->regs[R_CMD_PORT];
+ uint64_t tx = s->regs[R_LD_PORT] |
+ ((uint64_t)s->regs[R_HD_PORT] << 32);
+ uint64_t rx = 0;
+ unsigned int cs = FIELD_EX32(cfg, CMD_PORT, CS);
+ unsigned int length;
+ unsigned int i;
+
+ if (cs != 0) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: command selects unwired CS%u\n",
+ TYPE_PHYTIUM_E2000_QSPI, cs);
+ s->regs[R_LD_PORT] = 0;
+ s->regs[R_HD_PORT] = 0;
+ return;
+ }
+
+ phytium_e2000_qspi_select(s);
+ ssi_transfer(s->spi, FIELD_EX32(cfg, CMD_PORT, CMD));
+
+ if (FIELD_EX32(cfg, CMD_PORT, CMD_ADDR)) {
+ length = FIELD_EX32(cfg, CMD_PORT, ADDR_SEL) ? 4 : 3;
+ phytium_e2000_qspi_send_address(s, s->regs[R_ADDR_PORT], length);
+ }
+
+ if (FIELD_EX32(cfg, CMD_PORT, LATENCY)) {
+ phytium_e2000_qspi_send_dummy(
+ s, FIELD_EX32(cfg, CMD_PORT, DUMMY) + 1);
+ }
+
+ if (FIELD_EX32(cfg, CMD_PORT, DATA_XFER)) {
+ length = FIELD_EX32(cfg, CMD_PORT, RW_NUM) + 1;
+ for (i = 0; i < length; i++) {
+ rx = deposit64(rx, i * 8, 8,
+ ssi_transfer(s->spi, extract64(tx, i * 8, 8)));
+ }
+ }
+
+ phytium_e2000_qspi_deselect(s);
+ s->regs[R_LD_PORT] = extract64(rx, 0, 32);
+ s->regs[R_HD_PORT] = extract64(rx, 32, 32);
+}
+
+static void phytium_e2000_qspi_ld_post_write(RegisterInfo *reg,
+ uint64_t value)
+{
+ PhytiumE2000QSPIState *s = PHYTIUM_E2000_QSPI(reg->opaque);
+
+ /*
+ * LD_PORT is the final staging write and commits the command assembled in
+ * CMD_PORT, ADDR_PORT, HD_PORT, and LD_PORT. register_reset() invokes the
+ * same callback, so suppress SPI side effects while installing defaults.
+ */
+ if (!s->resetting) {
+ phytium_e2000_qspi_exec_port(s);
+ }
+}
+
+static void phytium_e2000_qspi_flush_write_buffer(PhytiumE2000QSPIState *s)
+{
+ uint32_t cfg = s->regs[R_WR_CFG];
+ unsigned int address_len;
+ unsigned int i;
+
+ if (!s->write_pending) {
+ return;
+ }
+ if (!FIELD_EX32(cfg, WR_CFG, MODE)) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: FLUSH with direct writes disabled\n",
+ TYPE_PHYTIUM_E2000_QSPI);
+ return;
+ }
+
+ phytium_e2000_qspi_select(s);
+ ssi_transfer(s->spi, FIELD_EX32(cfg, WR_CFG, CMD));
+ address_len = FIELD_EX32(cfg, WR_CFG, ADDR_SEL) ? 4 : 3;
+ phytium_e2000_qspi_send_address(s, s->write_address, address_len);
+ for (i = 0; i < s->write_len; i++) {
+ ssi_transfer(s->spi, s->write_buffer[i]);
+ }
+ phytium_e2000_qspi_deselect(s);
+
+ s->write_pending = false;
+ s->write_address = 0;
+ s->write_len = 0;
+}
+
+static uint64_t phytium_e2000_qspi_flush_pre_write(RegisterInfo *reg,
+ uint64_t value)
+{
+ PhytiumE2000QSPIState *s = PHYTIUM_E2000_QSPI(reg->opaque);
+
+ if (value & BIT(0)) {
+ phytium_e2000_qspi_flush_write_buffer(s);
+ }
+ return 0;
+}
+
+static const RegisterAccessInfo phytium_e2000_qspi_regs_info[] = {
+ { .name = "FLASH_CAP", .addr = A_FLASH_CAP,
+ .rsvd = 0xfffc0000 },
+ { .name = "RD_CFG", .addr = A_RD_CFG },
+ { .name = "WR_CFG", .addr = A_WR_CFG,
+ .rsvd = 0x00fffc00 },
+ { .name = "FLUSH", .addr = A_FLUSH,
+ .rsvd = 0xfffffffe,
+ .pre_write = phytium_e2000_qspi_flush_pre_write },
+ { .name = "CMD_PORT", .addr = A_CMD_PORT,
+ .rsvd = BIT(23) },
+ { .name = "ADDR_PORT", .addr = A_ADDR_PORT },
+ { .name = "HD_PORT", .addr = A_HD_PORT },
+ { .name = "LD_PORT", .addr = A_LD_PORT,
+ .post_write = phytium_e2000_qspi_ld_post_write },
+ { .name = "FUN_SET", .addr = A_FUN_SET },
+ { .name = "WIP", .addr = A_WIP,
+ .rsvd = 0x00ffffe0 },
+ { .name = "WP", .addr = A_WP,
+ .rsvd = 0xfffc0000 },
+ { .name = "MODE", .addr = A_MODE,
+ .rsvd = 0xffff0000 },
+ { .name = "LEGACY_CTRL", .addr = A_LEGACY_CTRL,
+ .rsvd = 0xfffffeff },
+};
+
+static const MemoryRegionOps phytium_e2000_qspi_regs_ops = {
+ .read = register_read_memory,
+ .write = register_write_memory,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+ .valid = {
+ .min_access_size = 4,
+ .max_access_size = 4,
+ .unaligned = false,
+ },
+};
+
+static uint64_t phytium_e2000_qspi_direct_read(void *opaque, hwaddr address,
+ unsigned int size)
+{
+ PhytiumE2000QSPIState *s = opaque;
+ uint32_t cfg = s->regs[R_RD_CFG];
+ uint64_t value = 0;
+ unsigned int address_len;
+ unsigned int i;
+
+ phytium_e2000_qspi_select(s);
+ ssi_transfer(s->spi, FIELD_EX32(cfg, RD_CFG, CMD));
+ address_len = FIELD_EX32(cfg, RD_CFG, ADDR_SEL) ? 4 : 3;
+ phytium_e2000_qspi_send_address(s, address, address_len);
+
+ if (FIELD_EX32(cfg, RD_CFG, LATENCY)) {
+ phytium_e2000_qspi_send_dummy(
+ s, FIELD_EX32(cfg, RD_CFG, DUMMY) + 1);
+ }
+
+ for (i = 0; i < size; i++) {
+ value = deposit64(value, i * 8, 8, ssi_transfer(s->spi, 0));
+ }
+ phytium_e2000_qspi_deselect(s);
+
+ return value;
+}
+
+static void phytium_e2000_qspi_direct_write(void *opaque, hwaddr address,
+ uint64_t value,
+ unsigned int size)
+{
+ PhytiumE2000QSPIState *s = opaque;
+ uint32_t cfg = s->regs[R_WR_CFG];
+ unsigned int i;
+
+ if (!FIELD_EX32(cfg, WR_CFG, MODE)) {
+ return;
+ }
+
+ /*
+ * The direct aperture accepts multiple CPU stores for one page program.
+ * Buffer them until FLUSH supplies the transaction boundary required by
+ * the flash command.
+ */
+ if (!s->write_pending) {
+ if ((address & ~(PHYTIUM_E2000_QSPI_PAGE_SIZE - 1)) !=
+ ((address + size - 1) &
+ ~(PHYTIUM_E2000_QSPI_PAGE_SIZE - 1))) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: direct write crosses a flash page\n",
+ TYPE_PHYTIUM_E2000_QSPI);
+ return;
+ }
+ s->write_pending = true;
+ s->write_address = address;
+ s->write_len = 0;
+ } else if (address != s->write_address + s->write_len ||
+ (s->write_address &
+ (PHYTIUM_E2000_QSPI_PAGE_SIZE - 1)) +
+ s->write_len + size > PHYTIUM_E2000_QSPI_PAGE_SIZE) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: non-contiguous direct writes before FLUSH\n",
+ TYPE_PHYTIUM_E2000_QSPI);
+ return;
+ }
+
+ for (i = 0; i < size; i++) {
+ s->write_buffer[s->write_len++] = extract64(value, i * 8, 8);
+ }
+}
+
+static const MemoryRegionOps phytium_e2000_qspi_direct_ops = {
+ .read = phytium_e2000_qspi_direct_read,
+ .write = phytium_e2000_qspi_direct_write,
+ .endianness = DEVICE_LITTLE_ENDIAN,
+ .valid = {
+ .min_access_size = 1,
+ .max_access_size = 8,
+ .unaligned = true,
+ },
+};
+
+static void phytium_e2000_qspi_reset(DeviceState *dev)
+{
+ PhytiumE2000QSPIState *s = PHYTIUM_E2000_QSPI(dev);
+ size_t i;
+
+ s->resetting = true;
+ for (i = 0; i < ARRAY_SIZE(phytium_e2000_qspi_regs_info); i++) {
+ register_reset(&s->regs_info[
+ phytium_e2000_qspi_regs_info[i].addr / sizeof(uint32_t)]);
+ }
+ memset(s->write_buffer, 0, sizeof(s->write_buffer));
+ s->write_address = 0;
+ s->write_len = 0;
+ s->write_pending = false;
+ s->resetting = false;
+ phytium_e2000_qspi_deselect(s);
+}
+
+static void phytium_e2000_qspi_init(Object *obj)
+{
+ PhytiumE2000QSPIState *s = PHYTIUM_E2000_QSPI(obj);
+ RegisterInfoArray *reg_array;
+
+ s->spi = ssi_create_bus(DEVICE(obj), "spi");
+ qdev_init_gpio_out_named(DEVICE(obj), &s->cs, "cs", 1);
+
+ reg_array = register_init_block32(
+ DEVICE(obj), phytium_e2000_qspi_regs_info,
+ ARRAY_SIZE(phytium_e2000_qspi_regs_info), s->regs_info, s->regs,
+ &phytium_e2000_qspi_regs_ops, false,
+ PHYTIUM_E2000_QSPI_REG_SIZE);
+ sysbus_init_mmio(SYS_BUS_DEVICE(obj), ®_array->mem);
+
+ memory_region_init_io(&s->direct_mr, obj,
+ &phytium_e2000_qspi_direct_ops, s,
+ TYPE_PHYTIUM_E2000_QSPI ".direct",
+ PHYTIUM_E2000_QSPI_DIRECT_SIZE);
+ sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->direct_mr);
+}
+
+static const VMStateDescription phytium_e2000_qspi_vmsd = {
+ .name = TYPE_PHYTIUM_E2000_QSPI,
+ .version_id = 1,
+ .minimum_version_id = 1,
+ .fields = (const VMStateField[]) {
+ VMSTATE_UINT32_ARRAY(regs, PhytiumE2000QSPIState,
+ PHYTIUM_E2000_QSPI_R_MAX),
+ VMSTATE_UINT8_ARRAY(write_buffer, PhytiumE2000QSPIState,
+ PHYTIUM_E2000_QSPI_PAGE_SIZE),
+ VMSTATE_UINT32(write_address, PhytiumE2000QSPIState),
+ VMSTATE_UINT16(write_len, PhytiumE2000QSPIState),
+ VMSTATE_BOOL(write_pending, PhytiumE2000QSPIState),
+ VMSTATE_END_OF_LIST()
+ },
+};
+
+static void phytium_e2000_qspi_class_init(ObjectClass *klass,
+ const void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ dc->vmsd = &phytium_e2000_qspi_vmsd;
+ device_class_set_legacy_reset(dc, phytium_e2000_qspi_reset);
+}
+
+static const TypeInfo phytium_e2000_qspi_info = {
+ .name = TYPE_PHYTIUM_E2000_QSPI,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(PhytiumE2000QSPIState),
+ .instance_init = phytium_e2000_qspi_init,
+ .class_init = phytium_e2000_qspi_class_init,
+};
+
+static void phytium_e2000_qspi_register_types(void)
+{
+ type_register_static(&phytium_e2000_qspi_info);
+}
+
+type_init(phytium_e2000_qspi_register_types)
diff --git a/hw/ssi/Kconfig b/hw/ssi/Kconfig
index 1bd56463c1..202c81c5ac 100644
--- a/hw/ssi/Kconfig
+++ b/hw/ssi/Kconfig
@@ -9,6 +9,11 @@ config SIFIVE_SPI
config SSI
bool
+config PHYTIUM_E2000_QSPI
+ bool
+ select REGISTER
+ select SSI
+
config XILINX_SPI
bool
select SSI
diff --git a/hw/ssi/meson.build b/hw/ssi/meson.build
index 6afb1ea200..c76945ddf4 100644
--- a/hw/ssi/meson.build
+++ b/hw/ssi/meson.build
@@ -13,3 +13,4 @@ system_ss.add(when: 'CONFIG_IMX', if_true: files('imx_spi.c'))
system_ss.add(when: 'CONFIG_IBEX', if_true: files('ibex_spi_host.c'))
system_ss.add(when: 'CONFIG_BCM2835_SPI', if_true: files('bcm2835_spi.c'))
system_ss.add(when: 'CONFIG_PNV_SPI', if_true: files('pnv_spi.c'))
+system_ss.add(when: 'CONFIG_PHYTIUM_E2000_QSPI', if_true: files('phytium_qspi.c'))
--
2.53.0
next prev parent reply other threads:[~2026-09-08 10:44 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-08 10:41 [PATCH v2 00/32] hw/arm: Add Phytium E2000Q SoC and board support Bin Meng
2026-09-08 10:41 ` [PATCH v2 01/32] hw/arm: Add Phytium E2000 SoC and Phytium Pi machine Bin Meng
2026-09-08 10:41 ` [PATCH v2 02/32] hw/arm: phytium: Add Phytium E2000 PCIe host Bin Meng
2026-09-08 10:41 ` [PATCH v2 04/32] hw/sd: Add Phytium E2000 MCI controller Bin Meng
2026-09-08 10:41 ` [PATCH v2 05/32] hw/arm: phytium: Connect Phytium E2000 MCI controllers Bin Meng
2026-09-08 10:41 ` [PATCH v2 07/32] hw/arm: phytium: Connect Phytium E2000 GEM controllers Bin Meng
2026-09-08 10:41 ` [PATCH v2 08/32] hw/misc: Add Phytium E2000 DDR controller Bin Meng
2026-09-08 10:41 ` [PATCH v2 09/32] hw/arm: phytium: Connect the " Bin Meng
2026-09-08 10:41 ` [PATCH v2 10/32] hw/misc: Add Phytium E2000 MHU doorbell Bin Meng
2026-09-08 10:41 ` [PATCH v2 11/32] hw/arm: phytium: Connect the Phytium E2000 MHU Bin Meng
2026-09-08 10:41 ` Bin Meng [this message]
2026-09-08 10:41 ` [PATCH v2 13/32] hw/arm: phytium: Connect the Phytium E2000 QSPI controller Bin Meng
2026-09-08 10:41 ` [PATCH v2 14/32] hw/misc: Add Phytium E2000 PBR model Bin Meng
2026-09-08 10:41 ` [PATCH v2 15/32] hw/arm: phytium: Integrate the Phytium E2000 PBR Bin Meng
2026-09-08 10:41 ` [PATCH v2 16/32] hw/arm: phytium: Add Phytium E2000 control region placeholders Bin Meng
2026-09-08 10:41 ` [PATCH v2 17/32] hw/misc: Support Phytium E2000 SCMI CPU power control Bin Meng
2026-09-08 10:41 ` [PATCH v2 18/32] hw/arm: phytium: Select the Phytium E2000 PBR boot medium Bin Meng
2026-09-08 10:41 ` [PATCH v2 19/32] hw/arm: phytium: Connect the Phytium E2000 I2C controller Bin Meng
2026-09-08 10:41 ` [PATCH v2 20/32] hw/arm: phytium: Add Phytium E2000 xHCI controllers Bin Meng
2026-09-08 10:41 ` [PATCH v2 21/32] hw/misc: Model the Phytium E2000 random generator Bin Meng
2026-09-08 10:41 ` [PATCH v2 22/32] hw/arm: phytium: Connect " Bin Meng
2026-09-08 10:41 ` [PATCH v2 23/32] hw/arm: phytium: Support Phytium E2000 direct Linux boot Bin Meng
2026-09-08 10:41 ` [PATCH v2 24/32] hw/arm: phytium: Add Phytium E2000Q COMe machine Bin Meng
2026-09-08 10:41 ` [PATCH v2 26/32] hw/arm: phytium: Connect the Phytium E2000Q COMe QSPI flash Bin Meng
2026-09-08 10:41 ` [PATCH v2 27/32] hw/arm: phytium: Add Phytium E2000 AHCI controllers Bin Meng
2026-09-08 10:41 ` [PATCH v2 28/32] hw/arm: Add Phytium E2000 Linux SCMI channel Bin Meng
2026-09-08 10:41 ` [PATCH v2 29/32] hw/arm: phytium: Connect the Phytium E2000 SMMUv3 Bin Meng
2026-09-08 10:41 ` [PATCH v2 30/32] docs/system/arm: Document Phytium E2000 machines Bin Meng
2026-09-08 10:41 ` [PATCH v2 31/32] tests/functional/aarch64: Add Phytium Pi boot tests Bin Meng
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=20260908104159.1621764-13-bin.meng@processmission.com \
--to=bin.meng@processmission.com \
--cc=alistair@alistair23.me \
--cc=pbonzini@redhat.com \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox