All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/8] hw/arm: Add Allwinner H618 SoC and Orange Pi Zero 2W machine
@ 2026-11-09 11:35 Khai Do
  2026-11-09 11:35 ` [PATCH v2 1/8] hw/arm/allwinner-h618: Add Allwinner H618 SoC emulation Khai Do
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Khai Do @ 2026-11-09 11:35 UTC (permalink / raw)
  To: qemu-devel, qemu-arm
  Cc: peter.maydell, pbonzini, strahinja.p.jankovic, Khai Do

This patch series adds emulation support for the Allwinner H618 SoC and
the Xunlong Orange Pi Zero 2W single-board computer (SBC).

The Allwinner H618 is a quad-core 64-bit ARM Cortex-A53 SoC. This series
follows the incremental skeleton design established for Allwinner SoCs:
- Patch 1: Introduces the basic H618 SoC model with 4x Cortex-A53 cores,
  GICv2, ARM Generic Timer PPIs, UART0/1, SRAM A1/A2, and stubbed unimp MMIO.
- Patch 2: Adds the Orange Pi Zero 2W machine with 1 GiB SDRAM and kernel loader.
- Patch 3: Separates the ALLWINNER_SID Kconfig symbol so other SoCs can reuse it.
- Patch 4: Extends the Allwinner SID eFuse controller to support configurable
  capacity up to 512 bytes (AW_SID_SIZE_MAX), preserving backward compatibility.
- Patch 5: Connects the SID controller into the H618 SoC (256 bytes capacity)
  and sets the default UID.
- Patch 6: Separates the ALLWINNER_SDHOST Kconfig symbol for independent reuse.
- Patch 7: Connects Allwinner SD/MMC host controller 0 (sun50i-a64 compatible)
  at 0x04020000 into the H618 SoC.
- Patch 8: Wires up the SD card bus to Orange Pi Zero 2W machine and supports
  loading bootloader firmware via -bios.

Changes since v1:
- hw/misc/allwinner-sid: Use extract32(s->control, 16, 9) to extract the
  9-bit PRCTL offset and return 0 on out-of-bounds eFuse reads.
- hw/arm/allwinner-h618: Set SID size property to 256 bytes (0x100) to
  match physical H618 eFuse capacity, consistent with Linux and Zephyr DTS.
- hw/sd/allwinner-sdhost: Separate CONFIG_ALLWINNER_SDHOST symbol from H3.
- hw/arm/allwinner-h618: Connect SD/MMC host controller 0.
- hw/arm/orangepi-zero2w: Wire up SD bus and support raw firmware loading
  via -bios (e.g. for U-Boot SPL).

Verification:
- The series has been tested using Zephyr RTOS (v4.5) running on the
  orangepi-zero2w target:
  * UART0 console & kernel boot: PASS
  * Multi-threading with ARM Generic Timer PPIs (k_msleep): PASS
  * HWINFO UID reading from SID eFuse: PASS (16 bytes UID)
  * SID OTP driver: PASS (Offset 0..15, Offset 240..255, and Offset 256
    returning -EINVAL out-of-bounds error)
- Tested raw firmware loading (-bios) with U-Boot SPL.
- All patches pass ./scripts/checkpatch.pl with 0 errors and 0 warnings.

Khai Do (8):
  hw/arm/allwinner-h618: Add Allwinner H618 SoC emulation
  hw/arm/orangepi-zero2w: Add Orange Pi Zero 2W machine
  hw/misc/allwinner-sid: Separate ALLWINNER_SID config symbol
  hw/misc/allwinner-sid: Support configurable eFuse capacity up to 512
    bytes
  hw/arm/allwinner-h618: Connect Allwinner SID controller
  hw/sd/allwinner-sdhost: Separate ALLWINNER_SDHOST config symbol
  hw/arm/allwinner-h618: Connect Allwinner SD/MMC host controller 0
  hw/arm/orangepi-zero2w: Wire up SD card and support firmware loading

 MAINTAINERS                     |   8 ++
 hw/arm/Kconfig                  |  11 ++
 hw/arm/allwinner-h618.c         | 247 ++++++++++++++++++++++++++++++++
 hw/arm/meson.build              |   1 +
 hw/arm/orangepi-zero2w.c        | 114 +++++++++++++++
 hw/misc/Kconfig                 |   3 +
 hw/misc/allwinner-sid.c         |  12 +-
 hw/misc/meson.build             |   2 +-
 hw/sd/Kconfig                   |   4 +
 hw/sd/meson.build               |   2 +-
 include/hw/arm/allwinner-h618.h |  63 ++++++++
 include/hw/misc/allwinner-sid.h |   8 ++
 12 files changed, 471 insertions(+), 4 deletions(-)
 create mode 100644 hw/arm/allwinner-h618.c
 create mode 100644 hw/arm/orangepi-zero2w.c
 create mode 100644 include/hw/arm/allwinner-h618.h

-- 
2.43.0



^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 1/8] hw/arm/allwinner-h618: Add Allwinner H618 SoC emulation
  2026-11-09 11:35 [PATCH v2 0/8] hw/arm: Add Allwinner H618 SoC and Orange Pi Zero 2W machine Khai Do
@ 2026-11-09 11:35 ` Khai Do
  2026-11-09 11:35 ` [PATCH v2 2/8] hw/arm/orangepi-zero2w: Add Orange Pi Zero 2W machine Khai Do
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Khai Do @ 2026-11-09 11:35 UTC (permalink / raw)
  To: qemu-devel, qemu-arm
  Cc: peter.maydell, pbonzini, strahinja.p.jankovic, Khai Do

The Allwinner H618 is a 64-bit quad-core Cortex-A53 SoC. This commit
adds baseline SoC emulation including:
- 4x Cortex-A53 cores with PSCI conduit for SMP
- ARM GICv2 interrupt controller and generic timer PPI connections
- SRAM A1, SRAM A2, and 16550 UART0/1 controllers
- Unimplemented memory regions for non-critical peripherals

Signed-off-by: Khai Do <dovankhai97@gmail.com>
---
 MAINTAINERS                     |   7 +
 hw/arm/Kconfig                  |   7 +
 hw/arm/allwinner-h618.c         | 224 ++++++++++++++++++++++++++++++++
 hw/arm/meson.build              |   1 +
 include/hw/arm/allwinner-h618.h |  57 ++++++++
 5 files changed, 296 insertions(+)
 create mode 100644 hw/arm/allwinner-h618.c
 create mode 100644 include/hw/arm/allwinner-h618.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 70e9fed776..68f1c31d60 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -779,6 +779,13 @@ F: hw/arm/orangepi.c
 F: docs/system/arm/orangepi.rst
 F: tests/functional/arm/test_orangepi.py
 
+Allwinner-h618
+M: Khai Do <dovankhai97@gmail.com>
+L: qemu-arm@nongnu.org
+S: Maintained
+F: hw/*/allwinner-h618*
+F: include/hw/*/allwinner-h618*
+
 ARM PrimeCell and CMSDK devices
 M: Peter Maydell <peter.maydell@linaro.org>
 L: qemu-arm@nongnu.org
diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index e9f796f718..616beae7bf 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -333,6 +333,13 @@ config ALLWINNER_R40
     select USB_EHCI_SYSBUS
     select SD
 
+config ALLWINNER_H618
+    bool
+    default y if TCG && AARCH64
+    select SERIAL_MM
+    select ARM_GIC
+    select UNIMP
+
 config MAX78000_SOC
     bool
     select ARM_V7M
diff --git a/hw/arm/allwinner-h618.c b/hw/arm/allwinner-h618.c
new file mode 100644
index 0000000000..59e0196fc6
--- /dev/null
+++ b/hw/arm/allwinner-h618.c
@@ -0,0 +1,224 @@
+/*
+ * Allwinner H618 System on Chip emulation
+ *
+ * Copyright (C) 2026 Khai Do <dovankhai97@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu/error-report.h"
+#include "qemu/module.h"
+#include "qemu/units.h"
+#include "hw/core/qdev.h"
+#include "hw/core/sysbus.h"
+#include "hw/char/serial-mm.h"
+#include "hw/misc/unimp.h"
+#include "system/system.h"
+#include "system/address-spaces.h"
+#include "hw/arm/allwinner-h618.h"
+#include "target/arm/cpu-qom.h"
+#include "target/arm/gtimer.h"
+
+/* Memory map */
+const hwaddr allwinner_h618_memmap[] = {
+    [AW_H618_DEV_SRAM_A1]  = 0x00020000,
+    [AW_H618_DEV_SRAM_A2]  = 0x00100000,
+    [AW_H618_DEV_GIC_DIST] = 0x03021000,
+    [AW_H618_DEV_GIC_CPU]  = 0x03022000,
+    [AW_H618_DEV_GIC_HYP]  = 0x03024000,
+    [AW_H618_DEV_GIC_VCPU] = 0x03026000,
+    [AW_H618_DEV_UART0]    = 0x05000000,
+    [AW_H618_DEV_UART1]    = 0x05000400,
+    [AW_H618_DEV_UART2]    = 0x05000800,
+    [AW_H618_DEV_UART3]    = 0x05000c00,
+    [AW_H618_DEV_SDRAM]    = 0x40000000,
+};
+
+/* List of unimplemented devices */
+static const struct AwH618Unimplemented {
+    const char *device_name;
+    hwaddr base;
+    hwaddr size;
+} unimplemented[] = {
+    { "ccu",       0x03001000, 4 * KiB },
+    { "dma",       0x03002000, 4 * KiB },
+    { "sid",       0x03006000, 4 * KiB },
+    { "smc",       0x03007000, 4 * KiB },
+    { "timer",     0x03009000, 4 * KiB },
+    { "pwm",       0x0300a000, 4 * KiB },
+    { "pio",       0x0300b000, 4 * KiB },
+    { "mmc0",      0x04020000, 4 * KiB },
+    { "mmc1",      0x04021000, 4 * KiB },
+    { "mmc2",      0x04022000, 4 * KiB },
+    { "rtc",       0x07000000, 4 * KiB },
+    { "prcm",      0x07010000, 4 * KiB },
+    { "r_pio",     0x07022000, 4 * KiB },
+    { "r_uart",    0x07080000, 4 * KiB },
+};
+
+/* Interrupt mapping */
+enum {
+    AW_H618_GIC_PPI_MAINT     =  9,
+    AW_H618_GIC_PPI_HYPTIMER  = 10,
+    AW_H618_GIC_PPI_VIRTTIMER = 11,
+    AW_H618_GIC_PPI_SECTIMER  = 13,
+    AW_H618_GIC_PPI_PHYSTIMER = 14
+};
+
+enum {
+    AW_H618_GIC_SPI_UART0 = 0,
+    AW_H618_GIC_SPI_UART1 = 1,
+    AW_H618_GIC_SPI_UART2 = 2,
+    AW_H618_GIC_SPI_UART3 = 3,
+};
+
+enum {
+    AW_H618_GIC_NUM_SPI = 128
+};
+
+static void allwinner_h618_init(Object *obj)
+{
+    AwH618State *s = AW_H618(obj);
+    int i;
+
+    s->memmap = allwinner_h618_memmap;
+
+    for (i = 0; i < AW_H618_NUM_CPUS; i++) {
+        object_initialize_child(obj, "cpu[*]", &s->cpus[i],
+                                ARM_CPU_TYPE_NAME("cortex-a53"));
+    }
+
+    object_initialize_child(obj, "gic", &s->gic, TYPE_ARM_GIC);
+}
+
+static void allwinner_h618_realize(DeviceState *dev, Error **errp)
+{
+    AwH618State *s = AW_H618(dev);
+    unsigned int i;
+
+    /* CPUs */
+    for (i = 0; i < AW_H618_NUM_CPUS; i++) {
+        /* Disable secondary CPUs until brought up by firmware/kernel */
+        qdev_prop_set_bit(DEVICE(&s->cpus[i]), "start-powered-off",
+                          i > 0);
+
+        /*
+         * Enable PSCI emulation with SMC calls so secondary CPUs
+         * can be brought up.
+         */
+        qdev_prop_set_uint32(DEVICE(&s->cpus[i]), "psci-conduit",
+                             QEMU_PSCI_CONDUIT_SMC);
+
+        /* Mark realized */
+        qdev_realize(DEVICE(&s->cpus[i]), NULL, &error_fatal);
+    }
+
+    /* Generic Interrupt Controller */
+    qdev_prop_set_uint32(DEVICE(&s->gic), "num-irq", AW_H618_GIC_NUM_SPI +
+                                                     GIC_INTERNAL);
+    qdev_prop_set_uint32(DEVICE(&s->gic), "revision", 2);
+    qdev_prop_set_uint32(DEVICE(&s->gic), "num-cpu", AW_H618_NUM_CPUS);
+    qdev_prop_set_bit(DEVICE(&s->gic), "has-security-extensions", false);
+    qdev_prop_set_bit(DEVICE(&s->gic), "has-virtualization-extensions", true);
+    sysbus_realize(SYS_BUS_DEVICE(&s->gic), &error_fatal);
+
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->gic), 0,
+                    s->memmap[AW_H618_DEV_GIC_DIST]);
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->gic), 1,
+                    s->memmap[AW_H618_DEV_GIC_CPU]);
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->gic), 2,
+                    s->memmap[AW_H618_DEV_GIC_VCPU]);
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->gic), 3,
+                    s->memmap[AW_H618_DEV_GIC_HYP]);
+
+    /* Connect GIC outputs to CPU interrupt inputs and CPU timer to GIC PPI */
+    for (i = 0; i < AW_H618_NUM_CPUS; i++) {
+        DeviceState *cpudev = DEVICE(&s->cpus[i]);
+        int ppibase = AW_H618_GIC_NUM_SPI + i * GIC_INTERNAL + GIC_NR_SGIS;
+        int irq;
+        /*
+         * Mapping from the output timer irq lines from the CPU to the
+         * GIC PPI inputs used for this board.
+         */
+        const int timer_irq[] = {
+            [GTIMER_PHYS] = AW_H618_GIC_PPI_PHYSTIMER,
+            [GTIMER_VIRT] = AW_H618_GIC_PPI_VIRTTIMER,
+            [GTIMER_HYP]  = AW_H618_GIC_PPI_HYPTIMER,
+            [GTIMER_SEC]  = AW_H618_GIC_PPI_SECTIMER,
+        };
+
+        /* Connect CPU timer outputs to GIC PPI inputs */
+        for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {
+            qdev_connect_gpio_out(cpudev, irq,
+                                  qdev_get_gpio_in(DEVICE(&s->gic),
+                                                   ppibase + timer_irq[irq]));
+        }
+
+        /* Connect GIC outputs to CPU interrupt inputs */
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), i,
+                           qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), i + AW_H618_NUM_CPUS,
+                           qdev_get_gpio_in(cpudev, ARM_CPU_FIQ));
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), i + (2 * AW_H618_NUM_CPUS),
+                           qdev_get_gpio_in(cpudev, ARM_CPU_VIRQ));
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), i + (3 * AW_H618_NUM_CPUS),
+                           qdev_get_gpio_in(cpudev, ARM_CPU_VFIQ));
+
+        /* GIC maintenance signal */
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->gic), i + (4 * AW_H618_NUM_CPUS),
+                           qdev_get_gpio_in(DEVICE(&s->gic),
+                                            ppibase + AW_H618_GIC_PPI_MAINT));
+    }
+
+    /* SRAM */
+    memory_region_init_ram(&s->sram_a1, OBJECT(dev), "sram A1",
+                           64 * KiB, &error_abort);
+    memory_region_init_ram(&s->sram_a2, OBJECT(dev), "sram A2",
+                           48 * KiB, &error_abort);
+    memory_region_add_subregion(get_system_memory(),
+                                s->memmap[AW_H618_DEV_SRAM_A1], &s->sram_a1);
+    memory_region_add_subregion(get_system_memory(),
+                                s->memmap[AW_H618_DEV_SRAM_A2], &s->sram_a2);
+
+    /* UART0 */
+    serial_mm_init(get_system_memory(), s->memmap[AW_H618_DEV_UART0], 2,
+                   qdev_get_gpio_in(DEVICE(&s->gic), AW_H618_GIC_SPI_UART0),
+                   115200, serial_hd(0), DEVICE_LITTLE_ENDIAN);
+    /* UART1 */
+    serial_mm_init(get_system_memory(), s->memmap[AW_H618_DEV_UART1], 2,
+                   qdev_get_gpio_in(DEVICE(&s->gic), AW_H618_GIC_SPI_UART1),
+                   115200, serial_hd(1), DEVICE_LITTLE_ENDIAN);
+
+    /* Unimplemented devices */
+    for (i = 0; i < ARRAY_SIZE(unimplemented); i++) {
+        create_unimplemented_device(unimplemented[i].device_name,
+                                    unimplemented[i].base,
+                                    unimplemented[i].size);
+    }
+}
+
+static void allwinner_h618_class_init(ObjectClass *oc, const void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+
+    dc->realize = allwinner_h618_realize;
+    /* Reason: uses serial_hd() in realize function */
+    dc->user_creatable = false;
+}
+
+static const TypeInfo allwinner_h618_type_info = {
+    .name = TYPE_AW_H618,
+    .parent = TYPE_DEVICE,
+    .instance_size = sizeof(AwH618State),
+    .instance_init = allwinner_h618_init,
+    .class_init = allwinner_h618_class_init,
+};
+
+static void allwinner_h618_register_types(void)
+{
+    type_register_static(&allwinner_h618_type_info);
+}
+
+type_init(allwinner_h618_register_types)
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
index bcc068de04..42ed065b17 100644
--- a/hw/arm/meson.build
+++ b/hw/arm/meson.build
@@ -24,6 +24,7 @@ arm_common_ss.add(when: 'CONFIG_OMAP', if_true: files('omap1.c'))
 arm_common_ss.add(when: 'CONFIG_ALLWINNER_A10', if_true: files('allwinner-a10.c', 'cubieboard.c'))
 arm_common_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-h3.c', 'orangepi.c'))
 arm_common_ss.add(when: 'CONFIG_ALLWINNER_R40', if_true: files('allwinner-r40.c', 'bananapi_m2u.c'))
+arm_common_ss.add(when: 'CONFIG_ALLWINNER_H618', if_true: files('allwinner-h618.c'))
 arm_common_ss.add(when: 'CONFIG_MAX78000_SOC', if_true: files('max78000_soc.c'))
 arm_common_ss.add(when: 'CONFIG_RASPI', if_true: files(
   'bcm2836.c',
diff --git a/include/hw/arm/allwinner-h618.h b/include/hw/arm/allwinner-h618.h
new file mode 100644
index 0000000000..e1b7162759
--- /dev/null
+++ b/include/hw/arm/allwinner-h618.h
@@ -0,0 +1,57 @@
+/*
+ * Allwinner H618 System on Chip emulation
+ *
+ * Copyright (C) 2026 Khai Do <dovankhai97@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef HW_ARM_ALLWINNER_H618_H
+#define HW_ARM_ALLWINNER_H618_H
+
+#include "qom/object.h"
+#include "hw/intc/arm_gic.h"
+#include "target/arm/cpu.h"
+
+/**
+ * Allwinner H618 device list
+ */
+enum {
+    AW_H618_DEV_SRAM_A1,
+    AW_H618_DEV_SRAM_A2,
+    AW_H618_DEV_GIC_DIST,
+    AW_H618_DEV_GIC_CPU,
+    AW_H618_DEV_GIC_HYP,
+    AW_H618_DEV_GIC_VCPU,
+    AW_H618_DEV_UART0,
+    AW_H618_DEV_UART1,
+    AW_H618_DEV_UART2,
+    AW_H618_DEV_UART3,
+    AW_H618_DEV_SDRAM
+};
+
+/** Total number of CPU cores in the H618 SoC */
+#define AW_H618_NUM_CPUS (4)
+
+/** Object type for the Allwinner H618 SoC */
+#define TYPE_AW_H618 "allwinner-h618"
+
+/** Convert input object to Allwinner H618 state object */
+OBJECT_DECLARE_SIMPLE_TYPE(AwH618State, AW_H618)
+
+/**
+ * Allwinner H618 object
+ */
+struct AwH618State {
+    /*< private >*/
+    DeviceState parent_obj;
+    /*< public >*/
+
+    ARMCPU cpus[AW_H618_NUM_CPUS];
+    const hwaddr *memmap;
+    GICState gic;
+    MemoryRegion sram_a1;
+    MemoryRegion sram_a2;
+};
+
+#endif /* HW_ARM_ALLWINNER_H618_H */
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 2/8] hw/arm/orangepi-zero2w: Add Orange Pi Zero 2W machine
  2026-11-09 11:35 [PATCH v2 0/8] hw/arm: Add Allwinner H618 SoC and Orange Pi Zero 2W machine Khai Do
  2026-11-09 11:35 ` [PATCH v2 1/8] hw/arm/allwinner-h618: Add Allwinner H618 SoC emulation Khai Do
@ 2026-11-09 11:35 ` Khai Do
  2026-11-09 11:35 ` [PATCH v2 3/8] hw/misc/allwinner-sid: Separate ALLWINNER_SID config symbol Khai Do
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Khai Do @ 2026-11-09 11:35 UTC (permalink / raw)
  To: qemu-devel, qemu-arm
  Cc: peter.maydell, pbonzini, strahinja.p.jankovic, Khai Do

The Orange Pi Zero 2W is a single-board computer powered by the
Allwinner H618 SoC. This commit adds machine emulation with:
- Allwinner H618 SoC instance
- 1 GiB default system SDRAM at 0x40000000
- Kernel and firmware loading via arm_load_kernel

Signed-off-by: Khai Do <dovankhai97@gmail.com>
---
 MAINTAINERS              |  1 +
 hw/arm/meson.build       |  2 +-
 hw/arm/orangepi-zero2w.c | 77 ++++++++++++++++++++++++++++++++++++++++
 3 files changed, 79 insertions(+), 1 deletion(-)
 create mode 100644 hw/arm/orangepi-zero2w.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 68f1c31d60..d5f60db054 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -785,6 +785,7 @@ L: qemu-arm@nongnu.org
 S: Maintained
 F: hw/*/allwinner-h618*
 F: include/hw/*/allwinner-h618*
+F: hw/arm/orangepi-zero2w.c
 
 ARM PrimeCell and CMSDK devices
 M: Peter Maydell <peter.maydell@linaro.org>
diff --git a/hw/arm/meson.build b/hw/arm/meson.build
index 42ed065b17..947ee2c7b4 100644
--- a/hw/arm/meson.build
+++ b/hw/arm/meson.build
@@ -24,7 +24,7 @@ arm_common_ss.add(when: 'CONFIG_OMAP', if_true: files('omap1.c'))
 arm_common_ss.add(when: 'CONFIG_ALLWINNER_A10', if_true: files('allwinner-a10.c', 'cubieboard.c'))
 arm_common_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-h3.c', 'orangepi.c'))
 arm_common_ss.add(when: 'CONFIG_ALLWINNER_R40', if_true: files('allwinner-r40.c', 'bananapi_m2u.c'))
-arm_common_ss.add(when: 'CONFIG_ALLWINNER_H618', if_true: files('allwinner-h618.c'))
+arm_common_ss.add(when: 'CONFIG_ALLWINNER_H618', if_true: files('allwinner-h618.c', 'orangepi-zero2w.c'))
 arm_common_ss.add(when: 'CONFIG_MAX78000_SOC', if_true: files('max78000_soc.c'))
 arm_common_ss.add(when: 'CONFIG_RASPI', if_true: files(
   'bcm2836.c',
diff --git a/hw/arm/orangepi-zero2w.c b/hw/arm/orangepi-zero2w.c
new file mode 100644
index 0000000000..fe87a98efc
--- /dev/null
+++ b/hw/arm/orangepi-zero2w.c
@@ -0,0 +1,77 @@
+/*
+ * Orange Pi Zero 2W machine emulation
+ *
+ * Copyright (C) 2026 Khai Do <dovankhai97@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/units.h"
+#include "system/address-spaces.h"
+#include "qapi/error.h"
+#include "qemu/error-report.h"
+#include "hw/core/boards.h"
+#include "hw/core/qdev-properties.h"
+#include "hw/arm/allwinner-h618.h"
+#include "hw/arm/boot.h"
+
+#define TYPE_ORANGEPI_ZERO2W_MACHINE MACHINE_TYPE_NAME("orangepi-zero2w")
+OBJECT_DECLARE_SIMPLE_TYPE(OrangePiZero2WMachineState, ORANGEPI_ZERO2W_MACHINE)
+
+struct OrangePiZero2WMachineState {
+    MachineState parent;
+
+    struct arm_boot_info bootinfo;
+};
+
+static void orangepi_zero2w_init(MachineState *machine)
+{
+    OrangePiZero2WMachineState *opms = ORANGEPI_ZERO2W_MACHINE(machine);
+    AwH618State *h618;
+
+    /* BIOS is not supported by this board */
+    if (machine->firmware) {
+        error_report("BIOS not supported for this machine");
+        exit(1);
+    }
+
+    h618 = AW_H618(object_new(TYPE_AW_H618));
+    object_property_add_child(OBJECT(machine), "soc", OBJECT(h618));
+    object_unref(OBJECT(h618));
+
+    /* Mark H618 object realized */
+    qdev_realize(DEVICE(h618), NULL, &error_abort);
+
+    /* SDRAM */
+    memory_region_add_subregion(get_system_memory(),
+                                h618->memmap[AW_H618_DEV_SDRAM],
+                                machine->ram);
+
+    opms->bootinfo.loader_start = h618->memmap[AW_H618_DEV_SDRAM];
+    opms->bootinfo.ram_size = machine->ram_size;
+    opms->bootinfo.psci_conduit = QEMU_PSCI_CONDUIT_SMC;
+    arm_load_kernel(&h618->cpus[0], machine, &opms->bootinfo);
+}
+
+static void orangepi_zero2w_machine_init(MachineClass *mc)
+{
+    static const char * const valid_cpu_types[] = {
+        ARM_CPU_TYPE_NAME("cortex-a53"),
+        NULL
+    };
+
+    mc->desc = "Orange Pi Zero 2W (Cortex-A53)";
+    mc->init = orangepi_zero2w_init;
+    mc->min_cpus = AW_H618_NUM_CPUS;
+    mc->max_cpus = AW_H618_NUM_CPUS;
+    mc->default_cpus = AW_H618_NUM_CPUS;
+    mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a53");
+    mc->valid_cpu_types = valid_cpu_types;
+    mc->default_ram_size = 1 * GiB;
+    mc->default_ram_id = "orangepi-zero2w.ram";
+}
+
+DEFINE_MACHINE_EXTENDED("orangepi-zero2w", MACHINE, OrangePiZero2WMachineState,
+                        orangepi_zero2w_machine_init, false, false,
+                        NULL)
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 3/8] hw/misc/allwinner-sid: Separate ALLWINNER_SID config symbol
  2026-11-09 11:35 [PATCH v2 0/8] hw/arm: Add Allwinner H618 SoC and Orange Pi Zero 2W machine Khai Do
  2026-11-09 11:35 ` [PATCH v2 1/8] hw/arm/allwinner-h618: Add Allwinner H618 SoC emulation Khai Do
  2026-11-09 11:35 ` [PATCH v2 2/8] hw/arm/orangepi-zero2w: Add Orange Pi Zero 2W machine Khai Do
@ 2026-11-09 11:35 ` Khai Do
  2026-11-09 11:35 ` [PATCH v2 4/8] hw/misc/allwinner-sid: Support configurable eFuse capacity up to 512 bytes Khai Do
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Khai Do @ 2026-11-09 11:35 UTC (permalink / raw)
  To: qemu-devel, qemu-arm
  Cc: peter.maydell, pbonzini, strahinja.p.jankovic, Khai Do

Introduce a dedicated CONFIG_ALLWINNER_SID Kconfig symbol and select
it from CONFIG_ALLWINNER_H3 so the SID controller can be reused by
other Allwinner SoCs.

Signed-off-by: Khai Do <dovankhai97@gmail.com>
---
 hw/arm/Kconfig      | 1 +
 hw/misc/Kconfig     | 3 +++
 hw/misc/meson.build | 2 +-
 3 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 616beae7bf..21480e277d 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -309,6 +309,7 @@ config ALLWINNER_H3
     select ALLWINNER_SUN8I_EMAC
     select ALLWINNER_I2C
     select ALLWINNER_WDT
+    select ALLWINNER_SID
     select SERIAL_MM
     select ARM_TIMER
     select ARM_GIC
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index 685b7ff1e7..1639978874 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -268,6 +268,9 @@ config LASI
 config ALLWINNER_SRAMC
     bool
 
+config ALLWINNER_SID
+    bool
+
 config ALLWINNER_A10_CCM
     bool
 
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index fc3800baec..059d4c01a1 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -55,7 +55,7 @@ system_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-h3-ccu.c'))
 system_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-cpucfg.c'))
 system_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-h3-dramc.c'))
 system_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-h3-sysctrl.c'))
-system_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-sid.c'))
+system_ss.add(when: 'CONFIG_ALLWINNER_SID', if_true: files('allwinner-sid.c'))
 system_ss.add(when: 'CONFIG_ALLWINNER_R40', if_true: files('allwinner-r40-ccu.c'))
 system_ss.add(when: 'CONFIG_ALLWINNER_R40', if_true: files('allwinner-r40-dramc.c'))
 system_ss.add(when: 'CONFIG_AXP2XX_PMU', if_true: files('axp2xx.c'))
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 4/8] hw/misc/allwinner-sid: Support configurable eFuse capacity up to 512 bytes
  2026-11-09 11:35 [PATCH v2 0/8] hw/arm: Add Allwinner H618 SoC and Orange Pi Zero 2W machine Khai Do
                   ` (2 preceding siblings ...)
  2026-11-09 11:35 ` [PATCH v2 3/8] hw/misc/allwinner-sid: Separate ALLWINNER_SID config symbol Khai Do
@ 2026-11-09 11:35 ` Khai Do
  2026-11-09 11:35 ` [PATCH v2 5/8] hw/arm/allwinner-h618: Connect Allwinner SID controller Khai Do
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Khai Do @ 2026-11-09 11:35 UTC (permalink / raw)
  To: qemu-devel, qemu-arm
  Cc: peter.maydell, pbonzini, strahinja.p.jankovic, Khai Do

Allwinner SoCs provide different eFuse capacities: older SoCs have
16 to 256 bytes, while newer 64-bit SoCs (e.g. H618) provide up to 512
bytes of eFuse storage.

Add a "size" property (defaulting to 16 bytes for backward compatibility)
and an internal storage buffer up to 512 bytes (AW_SID_SIZE_MAX).

Signed-off-by: Khai Do <dovankhai97@gmail.com>
---
 hw/misc/allwinner-sid.c         | 12 ++++++++++--
 include/hw/misc/allwinner-sid.h |  8 ++++++++
 2 files changed, 18 insertions(+), 2 deletions(-)

diff --git a/hw/misc/allwinner-sid.c b/hw/misc/allwinner-sid.c
index b5f827d4bd..afe5132c93 100644
--- a/hw/misc/allwinner-sid.c
+++ b/hw/misc/allwinner-sid.c
@@ -79,10 +79,15 @@ static void allwinner_sid_write(void *opaque, hwaddr offset,
 
         if ((s->control & REG_PRCTL_OP_LOCK) &&
             (s->control & REG_PRCTL_WRITE)) {
-            uint32_t id = s->control >> 16;
+            uint32_t id = extract32(s->control, 16, 9);
 
             if (id <= sizeof(QemuUUID) - sizeof(s->rdkey)) {
                 s->rdkey = ldl_be_p(&s->identifier.data[id]);
+            } else if (s->size >= sizeof(s->rdkey) &&
+                       id <= s->size - sizeof(s->rdkey)) {
+                s->rdkey = ldl_be_p(&s->storage[id]);
+            } else {
+                s->rdkey = 0;
             }
         }
         s->control &= ~REG_PRCTL_WRITE;
@@ -129,16 +134,19 @@ static void allwinner_sid_init(Object *obj)
 
 static const Property allwinner_sid_properties[] = {
     DEFINE_PROP_UUID_NODEFAULT("identifier", AwSidState, identifier),
+    DEFINE_PROP_UINT32("size", AwSidState, size, sizeof(QemuUUID)),
 };
 
 static const VMStateDescription allwinner_sid_vmstate = {
     .name = "allwinner-sid",
-    .version_id = 1,
+    .version_id = 2,
     .minimum_version_id = 1,
     .fields = (const VMStateField[]) {
         VMSTATE_UINT32(control, AwSidState),
         VMSTATE_UINT32(rdkey, AwSidState),
         VMSTATE_UINT8_ARRAY_V(identifier.data, AwSidState, sizeof(QemuUUID), 1),
+        VMSTATE_UINT32_V(size, AwSidState, 2),
+        VMSTATE_UINT8_ARRAY_V(storage, AwSidState, AW_SID_SIZE_MAX, 2),
         VMSTATE_END_OF_LIST()
     }
 };
diff --git a/include/hw/misc/allwinner-sid.h b/include/hw/misc/allwinner-sid.h
index cfa22a4d7f..da8c235c5d 100644
--- a/include/hw/misc/allwinner-sid.h
+++ b/include/hw/misc/allwinner-sid.h
@@ -24,6 +24,9 @@
 #include "hw/core/sysbus.h"
 #include "qemu/uuid.h"
 
+/** Maximum eFuse storage size supported */
+#define AW_SID_SIZE_MAX (512)
+
 /**
  * Object model
  * @{
@@ -54,6 +57,11 @@ struct AwSidState {
     /** Stores the emulated device identifier */
     QemuUUID identifier;
 
+    /** Size of eFuse storage */
+    uint32_t size;
+
+    /** eFuse storage buffer */
+    uint8_t storage[AW_SID_SIZE_MAX];
 };
 
 #endif /* HW_MISC_ALLWINNER_SID_H */
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 5/8] hw/arm/allwinner-h618: Connect Allwinner SID controller
  2026-11-09 11:35 [PATCH v2 0/8] hw/arm: Add Allwinner H618 SoC and Orange Pi Zero 2W machine Khai Do
                   ` (3 preceding siblings ...)
  2026-11-09 11:35 ` [PATCH v2 4/8] hw/misc/allwinner-sid: Support configurable eFuse capacity up to 512 bytes Khai Do
@ 2026-11-09 11:35 ` Khai Do
  2026-11-09 11:35 ` [PATCH v2 6/8] hw/sd/allwinner-sdhost: Separate ALLWINNER_SDHOST config symbol Khai Do
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Khai Do @ 2026-11-09 11:35 UTC (permalink / raw)
  To: qemu-devel, qemu-arm
  Cc: peter.maydell, pbonzini, strahinja.p.jankovic, Khai Do

Wire up the Allwinner Security ID (SID) eFuse controller into the
H618 SoC model:
- Map SID MMIO registers at 0x03006000 with 256 bytes capacity
- Remove sid from unimplemented peripheral list
- Configure default fixed SID identifier in Orange Pi Zero 2W machine
- Select ALLWINNER_SID in Kconfig

Signed-off-by: Khai Do <dovankhai97@gmail.com>
---
 hw/arm/Kconfig                  |  1 +
 hw/arm/allwinner-h618.c         | 11 ++++++++++-
 hw/arm/orangepi-zero2w.c        |  8 ++++++++
 include/hw/arm/allwinner-h618.h |  3 +++
 4 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 21480e277d..a1c09272fd 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -339,6 +339,7 @@ config ALLWINNER_H618
     default y if TCG && AARCH64
     select SERIAL_MM
     select ARM_GIC
+    select ALLWINNER_SID
     select UNIMP
 
 config MAX78000_SOC
diff --git a/hw/arm/allwinner-h618.c b/hw/arm/allwinner-h618.c
index 59e0196fc6..19e9c3f0a3 100644
--- a/hw/arm/allwinner-h618.c
+++ b/hw/arm/allwinner-h618.c
@@ -29,6 +29,7 @@ const hwaddr allwinner_h618_memmap[] = {
     [AW_H618_DEV_GIC_CPU]  = 0x03022000,
     [AW_H618_DEV_GIC_HYP]  = 0x03024000,
     [AW_H618_DEV_GIC_VCPU] = 0x03026000,
+    [AW_H618_DEV_SID]      = 0x03006000,
     [AW_H618_DEV_UART0]    = 0x05000000,
     [AW_H618_DEV_UART1]    = 0x05000400,
     [AW_H618_DEV_UART2]    = 0x05000800,
@@ -44,7 +45,6 @@ static const struct AwH618Unimplemented {
 } unimplemented[] = {
     { "ccu",       0x03001000, 4 * KiB },
     { "dma",       0x03002000, 4 * KiB },
-    { "sid",       0x03006000, 4 * KiB },
     { "smc",       0x03007000, 4 * KiB },
     { "timer",     0x03009000, 4 * KiB },
     { "pwm",       0x0300a000, 4 * KiB },
@@ -91,6 +91,10 @@ static void allwinner_h618_init(Object *obj)
     }
 
     object_initialize_child(obj, "gic", &s->gic, TYPE_ARM_GIC);
+
+    object_initialize_child(obj, "sid", &s->sid, TYPE_AW_SID);
+    object_property_add_alias(obj, "identifier", OBJECT(&s->sid),
+                              "identifier");
 }
 
 static void allwinner_h618_realize(DeviceState *dev, Error **errp)
@@ -172,6 +176,11 @@ static void allwinner_h618_realize(DeviceState *dev, Error **errp)
                                             ppibase + AW_H618_GIC_PPI_MAINT));
     }
 
+    /* Security Identifier */
+    qdev_prop_set_uint32(DEVICE(&s->sid), "size", 256);
+    sysbus_realize(SYS_BUS_DEVICE(&s->sid), &error_fatal);
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->sid), 0, s->memmap[AW_H618_DEV_SID]);
+
     /* SRAM */
     memory_region_init_ram(&s->sram_a1, OBJECT(dev), "sram A1",
                            64 * KiB, &error_abort);
diff --git a/hw/arm/orangepi-zero2w.c b/hw/arm/orangepi-zero2w.c
index fe87a98efc..1cc9ad7ba6 100644
--- a/hw/arm/orangepi-zero2w.c
+++ b/hw/arm/orangepi-zero2w.c
@@ -40,6 +40,14 @@ static void orangepi_zero2w_init(MachineState *machine)
     object_property_add_child(OBJECT(machine), "soc", OBJECT(h618));
     object_unref(OBJECT(h618));
 
+    /* Setup SID properties. Currently using a default fixed SID identifier. */
+    if (qemu_uuid_is_null(&h618->sid.identifier)) {
+        qdev_prop_set_string(DEVICE(h618), "identifier",
+                             "03006180-1111-2222-3333-000044556677");
+    } else if (ldl_be_p(&h618->sid.identifier.data[0]) != 0x03006180) {
+        warn_report("Security Identifier value does not include H618 prefix");
+    }
+
     /* Mark H618 object realized */
     qdev_realize(DEVICE(h618), NULL, &error_abort);
 
diff --git a/include/hw/arm/allwinner-h618.h b/include/hw/arm/allwinner-h618.h
index e1b7162759..d4c3d19725 100644
--- a/include/hw/arm/allwinner-h618.h
+++ b/include/hw/arm/allwinner-h618.h
@@ -11,6 +11,7 @@
 
 #include "qom/object.h"
 #include "hw/intc/arm_gic.h"
+#include "hw/misc/allwinner-sid.h"
 #include "target/arm/cpu.h"
 
 /**
@@ -23,6 +24,7 @@ enum {
     AW_H618_DEV_GIC_CPU,
     AW_H618_DEV_GIC_HYP,
     AW_H618_DEV_GIC_VCPU,
+    AW_H618_DEV_SID,
     AW_H618_DEV_UART0,
     AW_H618_DEV_UART1,
     AW_H618_DEV_UART2,
@@ -50,6 +52,7 @@ struct AwH618State {
     ARMCPU cpus[AW_H618_NUM_CPUS];
     const hwaddr *memmap;
     GICState gic;
+    AwSidState sid;
     MemoryRegion sram_a1;
     MemoryRegion sram_a2;
 };
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 6/8] hw/sd/allwinner-sdhost: Separate ALLWINNER_SDHOST config symbol
  2026-11-09 11:35 [PATCH v2 0/8] hw/arm: Add Allwinner H618 SoC and Orange Pi Zero 2W machine Khai Do
                   ` (4 preceding siblings ...)
  2026-11-09 11:35 ` [PATCH v2 5/8] hw/arm/allwinner-h618: Connect Allwinner SID controller Khai Do
@ 2026-11-09 11:35 ` Khai Do
  2026-11-09 11:35 ` [PATCH v2 7/8] hw/arm/allwinner-h618: Connect Allwinner SD/MMC host controller 0 Khai Do
  2026-11-09 11:35 ` [PATCH v2 8/8] hw/arm/orangepi-zero2w: Wire up SD card and support firmware loading Khai Do
  7 siblings, 0 replies; 9+ messages in thread
From: Khai Do @ 2026-11-09 11:35 UTC (permalink / raw)
  To: qemu-devel, qemu-arm
  Cc: peter.maydell, pbonzini, strahinja.p.jankovic, Khai Do

Introduce a dedicated Kconfig symbol ALLWINNER_SDHOST for the Allwinner
SD/MMC host controller. Previously it was conditionally built only when
CONFIG_ALLWINNER_H3 was enabled.

Select ALLWINNER_SDHOST in ALLWINNER_H3.

Signed-off-by: Khai Do <dovankhai97@gmail.com>
---
 hw/arm/Kconfig    | 1 +
 hw/sd/Kconfig     | 4 ++++
 hw/sd/meson.build | 2 +-
 3 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index a1c09272fd..18c45bc9e4 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -310,6 +310,7 @@ config ALLWINNER_H3
     select ALLWINNER_I2C
     select ALLWINNER_WDT
     select ALLWINNER_SID
+    select ALLWINNER_SDHOST
     select SERIAL_MM
     select ARM_TIMER
     select ARM_GIC
diff --git a/hw/sd/Kconfig b/hw/sd/Kconfig
index c69bf24f8d..5078fd4fab 100644
--- a/hw/sd/Kconfig
+++ b/hw/sd/Kconfig
@@ -1,3 +1,7 @@
+config ALLWINNER_SDHOST
+    bool
+    select SD
+
 config PL181
     bool
     select SD
diff --git a/hw/sd/meson.build b/hw/sd/meson.build
index ebf09e30a4..d15baaaf12 100644
--- a/hw/sd/meson.build
+++ b/hw/sd/meson.build
@@ -7,7 +7,7 @@ system_ss.add(when: 'CONFIG_SSI_SD', if_true: files('ssi-sd.c'))
 system_ss.add(when: 'CONFIG_OMAP', if_true: files('omap_mmc.c'))
 system_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_sdhost.c'))
 system_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files('aspeed_sdhci.c'))
-system_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-sdhost.c'))
+system_ss.add(when: 'CONFIG_ALLWINNER_SDHOST', if_true: files('allwinner-sdhost.c'))
 system_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx_sdhci.c'))
 system_ss.add(when: 'CONFIG_CADENCE_SDHCI', if_true: files('cadence_sdhci.c'))
 system_ss.add(when: 'CONFIG_AXIADO_SDHCI', if_true: files('axiado_sdhci.c'))
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 7/8] hw/arm/allwinner-h618: Connect Allwinner SD/MMC host controller 0
  2026-11-09 11:35 [PATCH v2 0/8] hw/arm: Add Allwinner H618 SoC and Orange Pi Zero 2W machine Khai Do
                   ` (5 preceding siblings ...)
  2026-11-09 11:35 ` [PATCH v2 6/8] hw/sd/allwinner-sdhost: Separate ALLWINNER_SDHOST config symbol Khai Do
@ 2026-11-09 11:35 ` Khai Do
  2026-11-09 11:35 ` [PATCH v2 8/8] hw/arm/orangepi-zero2w: Wire up SD card and support firmware loading Khai Do
  7 siblings, 0 replies; 9+ messages in thread
From: Khai Do @ 2026-11-09 11:35 UTC (permalink / raw)
  To: qemu-devel, qemu-arm
  Cc: peter.maydell, pbonzini, strahinja.p.jankovic, Khai Do

Wire up the Allwinner SD/MMC host controller 0 (SMHC0) into the
Allwinner H618 SoC model:
- Map MMC0 MMIO registers at 0x04020000
- Connect GIC interrupt SPI 35 (AW_H618_GIC_SPI_MMC0)
- Remove mmc0 from unimplemented peripheral list
- Alias "sd-bus" property from mmc0
- Select ALLWINNER_SDHOST in ALLWINNER_H618 Kconfig

Signed-off-by: Khai Do <dovankhai97@gmail.com>
---
 hw/arm/Kconfig                  |  1 +
 hw/arm/allwinner-h618.c         | 16 +++++++++++++++-
 include/hw/arm/allwinner-h618.h |  3 +++
 3 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 18c45bc9e4..655047fc47 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -341,6 +341,7 @@ config ALLWINNER_H618
     select SERIAL_MM
     select ARM_GIC
     select ALLWINNER_SID
+    select ALLWINNER_SDHOST
     select UNIMP
 
 config MAX78000_SOC
diff --git a/hw/arm/allwinner-h618.c b/hw/arm/allwinner-h618.c
index 19e9c3f0a3..9083e478d5 100644
--- a/hw/arm/allwinner-h618.c
+++ b/hw/arm/allwinner-h618.c
@@ -29,6 +29,7 @@ const hwaddr allwinner_h618_memmap[] = {
     [AW_H618_DEV_GIC_CPU]  = 0x03022000,
     [AW_H618_DEV_GIC_HYP]  = 0x03024000,
     [AW_H618_DEV_GIC_VCPU] = 0x03026000,
+    [AW_H618_DEV_MMC0]     = 0x04020000,
     [AW_H618_DEV_SID]      = 0x03006000,
     [AW_H618_DEV_UART0]    = 0x05000000,
     [AW_H618_DEV_UART1]    = 0x05000400,
@@ -49,7 +50,6 @@ static const struct AwH618Unimplemented {
     { "timer",     0x03009000, 4 * KiB },
     { "pwm",       0x0300a000, 4 * KiB },
     { "pio",       0x0300b000, 4 * KiB },
-    { "mmc0",      0x04020000, 4 * KiB },
     { "mmc1",      0x04021000, 4 * KiB },
     { "mmc2",      0x04022000, 4 * KiB },
     { "rtc",       0x07000000, 4 * KiB },
@@ -72,6 +72,7 @@ enum {
     AW_H618_GIC_SPI_UART1 = 1,
     AW_H618_GIC_SPI_UART2 = 2,
     AW_H618_GIC_SPI_UART3 = 3,
+    AW_H618_GIC_SPI_MMC0  = 35,
 };
 
 enum {
@@ -95,6 +96,8 @@ static void allwinner_h618_init(Object *obj)
     object_initialize_child(obj, "sid", &s->sid, TYPE_AW_SID);
     object_property_add_alias(obj, "identifier", OBJECT(&s->sid),
                               "identifier");
+
+    object_initialize_child(obj, "mmc0", &s->mmc0, TYPE_AW_SDHOST_SUN50I_A64);
 }
 
 static void allwinner_h618_realize(DeviceState *dev, Error **errp)
@@ -181,6 +184,17 @@ static void allwinner_h618_realize(DeviceState *dev, Error **errp)
     sysbus_realize(SYS_BUS_DEVICE(&s->sid), &error_fatal);
     sysbus_mmio_map(SYS_BUS_DEVICE(&s->sid), 0, s->memmap[AW_H618_DEV_SID]);
 
+    /* SD/MMC 0 */
+    object_property_set_link(OBJECT(&s->mmc0), "dma-memory",
+                             OBJECT(get_system_memory()), &error_fatal);
+    sysbus_realize(SYS_BUS_DEVICE(&s->mmc0), &error_fatal);
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->mmc0), 0, s->memmap[AW_H618_DEV_MMC0]);
+    sysbus_connect_irq(SYS_BUS_DEVICE(&s->mmc0), 0,
+                       qdev_get_gpio_in(DEVICE(&s->gic), AW_H618_GIC_SPI_MMC0));
+
+    object_property_add_alias(OBJECT(s), "sd-bus", OBJECT(&s->mmc0),
+                              "sd-bus");
+
     /* SRAM */
     memory_region_init_ram(&s->sram_a1, OBJECT(dev), "sram A1",
                            64 * KiB, &error_abort);
diff --git a/include/hw/arm/allwinner-h618.h b/include/hw/arm/allwinner-h618.h
index d4c3d19725..ea2ec205c8 100644
--- a/include/hw/arm/allwinner-h618.h
+++ b/include/hw/arm/allwinner-h618.h
@@ -12,6 +12,7 @@
 #include "qom/object.h"
 #include "hw/intc/arm_gic.h"
 #include "hw/misc/allwinner-sid.h"
+#include "hw/sd/allwinner-sdhost.h"
 #include "target/arm/cpu.h"
 
 /**
@@ -24,6 +25,7 @@ enum {
     AW_H618_DEV_GIC_CPU,
     AW_H618_DEV_GIC_HYP,
     AW_H618_DEV_GIC_VCPU,
+    AW_H618_DEV_MMC0,
     AW_H618_DEV_SID,
     AW_H618_DEV_UART0,
     AW_H618_DEV_UART1,
@@ -53,6 +55,7 @@ struct AwH618State {
     const hwaddr *memmap;
     GICState gic;
     AwSidState sid;
+    AwSdHostState mmc0;
     MemoryRegion sram_a1;
     MemoryRegion sram_a2;
 };
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH v2 8/8] hw/arm/orangepi-zero2w: Wire up SD card and support firmware loading
  2026-11-09 11:35 [PATCH v2 0/8] hw/arm: Add Allwinner H618 SoC and Orange Pi Zero 2W machine Khai Do
                   ` (6 preceding siblings ...)
  2026-11-09 11:35 ` [PATCH v2 7/8] hw/arm/allwinner-h618: Connect Allwinner SD/MMC host controller 0 Khai Do
@ 2026-11-09 11:35 ` Khai Do
  7 siblings, 0 replies; 9+ messages in thread
From: Khai Do @ 2026-11-09 11:35 UTC (permalink / raw)
  To: qemu-devel, qemu-arm
  Cc: peter.maydell, pbonzini, strahinja.p.jankovic, Khai Do

Connect the SD card block backend to the H618 "sd-bus", allowing
booting from MicroSD card images via `-drive if=sd,format=raw,file=...`.

In addition, support loading raw firmware binaries (such as EDK2 UEFI or
U-Boot) at 0x40080000 via the `-bios` command-line option.

Signed-off-by: Khai Do <dovankhai97@gmail.com>
---
 hw/arm/orangepi-zero2w.c | 41 ++++++++++++++++++++++++++++++++++------
 1 file changed, 35 insertions(+), 6 deletions(-)

diff --git a/hw/arm/orangepi-zero2w.c b/hw/arm/orangepi-zero2w.c
index 1cc9ad7ba6..5b0e64cff4 100644
--- a/hw/arm/orangepi-zero2w.c
+++ b/hw/arm/orangepi-zero2w.c
@@ -13,8 +13,12 @@
 #include "qemu/error-report.h"
 #include "hw/core/boards.h"
 #include "hw/core/qdev-properties.h"
+#include "hw/core/qdev-properties-system.h"
 #include "hw/arm/allwinner-h618.h"
 #include "hw/arm/boot.h"
+#include "hw/core/loader.h"
+#include "hw/sd/sd.h"
+#include "system/blockdev.h"
 
 #define TYPE_ORANGEPI_ZERO2W_MACHINE MACHINE_TYPE_NAME("orangepi-zero2w")
 OBJECT_DECLARE_SIMPLE_TYPE(OrangePiZero2WMachineState, ORANGEPI_ZERO2W_MACHINE)
@@ -29,12 +33,10 @@ static void orangepi_zero2w_init(MachineState *machine)
 {
     OrangePiZero2WMachineState *opms = ORANGEPI_ZERO2W_MACHINE(machine);
     AwH618State *h618;
-
-    /* BIOS is not supported by this board */
-    if (machine->firmware) {
-        error_report("BIOS not supported for this machine");
-        exit(1);
-    }
+    DriveInfo *di;
+    BlockBackend *blk;
+    BusState *bus;
+    DeviceState *carddev;
 
     h618 = AW_H618(object_new(TYPE_AW_H618));
     object_property_add_child(OBJECT(machine), "soc", OBJECT(h618));
@@ -51,6 +53,15 @@ static void orangepi_zero2w_init(MachineState *machine)
     /* Mark H618 object realized */
     qdev_realize(DEVICE(h618), NULL, &error_abort);
 
+    /* Retrieve SD bus and plug in SD card */
+    di = drive_get(IF_SD, 0, 0);
+    blk = di ? blk_by_legacy_dinfo(di) : NULL;
+    bus = qdev_get_child_bus(DEVICE(h618), "sd-bus");
+
+    carddev = qdev_new(TYPE_SD_CARD);
+    qdev_prop_set_drive_err(carddev, "drive", blk, &error_fatal);
+    qdev_realize_and_unref(carddev, bus, &error_fatal);
+
     /* SDRAM */
     memory_region_add_subregion(get_system_memory(),
                                 h618->memmap[AW_H618_DEV_SDRAM],
@@ -59,6 +70,24 @@ static void orangepi_zero2w_init(MachineState *machine)
     opms->bootinfo.loader_start = h618->memmap[AW_H618_DEV_SDRAM];
     opms->bootinfo.ram_size = machine->ram_size;
     opms->bootinfo.psci_conduit = QEMU_PSCI_CONDUIT_SMC;
+
+    /* Load firmware if specified (-bios) */
+    if (machine->firmware) {
+        hwaddr firmware_addr = 0x40080000;
+        int r;
+
+        r = load_image_targphys(machine->firmware, firmware_addr,
+                                machine->ram_size -
+                                (firmware_addr - 0x40000000), NULL);
+        if (r < 0) {
+            error_report("Failed to load firmware from %s", machine->firmware);
+            exit(1);
+        }
+
+        opms->bootinfo.entry = firmware_addr;
+        opms->bootinfo.firmware_loaded = true;
+    }
+
     arm_load_kernel(&h618->cpus[0], machine, &opms->bootinfo);
 }
 
-- 
2.43.0



^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2026-11-09 11:37 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-09 11:35 [PATCH v2 0/8] hw/arm: Add Allwinner H618 SoC and Orange Pi Zero 2W machine Khai Do
2026-11-09 11:35 ` [PATCH v2 1/8] hw/arm/allwinner-h618: Add Allwinner H618 SoC emulation Khai Do
2026-11-09 11:35 ` [PATCH v2 2/8] hw/arm/orangepi-zero2w: Add Orange Pi Zero 2W machine Khai Do
2026-11-09 11:35 ` [PATCH v2 3/8] hw/misc/allwinner-sid: Separate ALLWINNER_SID config symbol Khai Do
2026-11-09 11:35 ` [PATCH v2 4/8] hw/misc/allwinner-sid: Support configurable eFuse capacity up to 512 bytes Khai Do
2026-11-09 11:35 ` [PATCH v2 5/8] hw/arm/allwinner-h618: Connect Allwinner SID controller Khai Do
2026-11-09 11:35 ` [PATCH v2 6/8] hw/sd/allwinner-sdhost: Separate ALLWINNER_SDHOST config symbol Khai Do
2026-11-09 11:35 ` [PATCH v2 7/8] hw/arm/allwinner-h618: Connect Allwinner SD/MMC host controller 0 Khai Do
2026-11-09 11:35 ` [PATCH v2 8/8] hw/arm/orangepi-zero2w: Wire up SD card and support firmware loading Khai Do

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.