From: gilles grimaud <[email protected]>

Replace the TBMAN and VREG/chip-reset placeholders with the RP2040 register 
models from the development tree. Expose the ASIC platform indication, 
documented reset values, write masks, regulator status, and APB atomic 
aliases.\n\nAdd focused qtests for both blocks.

Signed-off-by: gilles grimaud <[email protected]>
---
 hw/arm/Kconfig                  |   2 +
 hw/arm/rp2040.c                 |  14 ++-
 hw/misc/Kconfig                 |   6 ++
 hw/misc/meson.build             |   2 +
 hw/misc/rp2040_tbman.c          |  92 +++++++++++++++++
 hw/misc/rp2040_vreg.c           | 178 ++++++++++++++++++++++++++++++++
 include/hw/arm/rp2040.h         |   4 +
 include/hw/misc/rp2040_tbman.h  |  25 +++++
 include/hw/misc/rp2040_vreg.h   |  28 +++++
 tests/qtest/meson.build         |   4 +-
 tests/qtest/rp2040-tbman-test.c |  32 ++++++
 tests/qtest/rp2040-vreg-test.c  |  79 ++++++++++++++
 12 files changed, 463 insertions(+), 3 deletions(-)
 create mode 100644 hw/misc/rp2040_tbman.c
 create mode 100644 hw/misc/rp2040_vreg.c
 create mode 100644 include/hw/misc/rp2040_tbman.h
 create mode 100644 include/hw/misc/rp2040_vreg.h
 create mode 100644 tests/qtest/rp2040-tbman-test.c
 create mode 100644 tests/qtest/rp2040-vreg-test.c

diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index 5d55ca06fd..89c479ab6d 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -381,6 +381,8 @@ config RP2040
     select RP2040_NYI
     select RP2040_SYSCFG
     select RP2040_SYSINFO
+    select RP2040_TBMAN
+    select RP2040_VREG
     select UNIMP
 
 config STM32F100_SOC
diff --git a/hw/arm/rp2040.c b/hw/arm/rp2040.c
index a184d527e1..f2a6613aa3 100644
--- a/hw/arm/rp2040.c
+++ b/hw/arm/rp2040.c
@@ -73,8 +73,6 @@ static const struct {
     { "rp2040.watchdog", 0x40058000, 0x4000 },
     { "rp2040.rtc",      0x4005c000, 0x4000 },
     { "rp2040.rosc",     0x40060000, 0x4000 },
-    { "rp2040.vreg_and_chip_reset", 0x40064000, 0x4000 },
-    { "rp2040.tbman",    0x4006c000, 0x4000 },
     { "rp2040.dma",      0x50000000, 0x1000 },
     { "rp2040.usbctrl_dpram", 0x50100000, 0x10000 },
     { "rp2040.usbctrl_regs",  0x50110000, 0x10000 },
@@ -179,6 +177,8 @@ static void rp2040_soc_init(Object *obj)
 
     object_initialize_child(obj, "syscfg", &s->syscfg, TYPE_RP2040_SYSCFG);
     object_initialize_child(obj, "sysinfo", &s->sysinfo, TYPE_RP2040_SYSINFO);
+    object_initialize_child(obj, "tbman", &s->tbman, TYPE_RP2040_TBMAN);
+    object_initialize_child(obj, "vreg", &s->vreg, TYPE_RP2040_VREG);
 
     s->irq = qemu_allocate_irqs(rp2040_set_irq, s, RP2040_NUM_IRQS);
     s->sysclk = clock_new(obj, "sysclk");
@@ -325,6 +325,16 @@ static void rp2040_soc_realize(DeviceState *dev, Error 
**errp)
     sysbus_mmio_map(SYS_BUS_DEVICE(&s->sysinfo), 0, RP2040_SYSINFO_BASE);
     rp2040_syscfg_update(s);
 
+    if (!sysbus_realize(SYS_BUS_DEVICE(&s->tbman), errp)) {
+        return;
+    }
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->tbman), 0, RP2040_TBMAN_BASE);
+
+    if (!sysbus_realize(SYS_BUS_DEVICE(&s->vreg), errp)) {
+        return;
+    }
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->vreg), 0, RP2040_VREG_BASE);
+
     for (i = 0; i < ARRAY_SIZE(s->uart); i++) {
         qdev_connect_clock_in(DEVICE(&s->uart[i]), "clk", s->sysclk);
         if (!sysbus_realize(SYS_BUS_DEVICE(&s->uart[i]), errp)) {
diff --git a/hw/misc/Kconfig b/hw/misc/Kconfig
index f6f344ab51..597559186f 100644
--- a/hw/misc/Kconfig
+++ b/hw/misc/Kconfig
@@ -110,6 +110,12 @@ config RP2040_SYSCFG
 config RP2040_SYSINFO
     bool
 
+config RP2040_TBMAN
+    bool
+
+config RP2040_VREG
+    bool
+
 config STM32_RCC
     bool
 
diff --git a/hw/misc/meson.build b/hw/misc/meson.build
index 7be9f45c78..9191b16360 100644
--- a/hw/misc/meson.build
+++ b/hw/misc/meson.build
@@ -101,6 +101,8 @@ system_ss.add(when: 'CONFIG_RASPI', if_true: files(
 system_ss.add(when: 'CONFIG_RP2040_NYI', if_true: files('rp2040_nyi.c'))
 system_ss.add(when: 'CONFIG_RP2040_SYSCFG', if_true: files('rp2040_syscfg.c'))
 system_ss.add(when: 'CONFIG_RP2040_SYSINFO', if_true: 
files('rp2040_sysinfo.c'))
+system_ss.add(when: 'CONFIG_RP2040_TBMAN', if_true: files('rp2040_tbman.c'))
+system_ss.add(when: 'CONFIG_RP2040_VREG', if_true: files('rp2040_vreg.c'))
 system_ss.add(when: 'CONFIG_SLAVIO', if_true: files('slavio_misc.c'))
 system_ss.add(when: 'CONFIG_ZYNQ', if_true: files('zynq_slcr.c'))
 system_ss.add(when: 'CONFIG_XLNX_ZYNQ_DDRC', if_true: 
files('xlnx-zynq-ddrc.c'))
diff --git a/hw/misc/rp2040_tbman.c b/hw/misc/rp2040_tbman.c
new file mode 100644
index 0000000000..a60dd83848
--- /dev/null
+++ b/hw/misc/rp2040_tbman.c
@@ -0,0 +1,92 @@
+/*
+ * RP2040 testbench manager emulation
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "hw/misc/rp2040_nyi.h"
+#include "hw/misc/rp2040_tbman.h"
+#include "migration/vmstate.h"
+#include "qemu/module.h"
+
+#define TBMAN_PLATFORM      0x00
+#define TBMAN_PLATFORM_ASIC BIT(0)
+
+static uint64_t rp2040_tbman_read(void *opaque, hwaddr addr, unsigned size)
+{
+    hwaddr offset = addr & 0xfff;
+    uint64_t value;
+
+    switch (offset) {
+    case TBMAN_PLATFORM:
+        value = TBMAN_PLATFORM_ASIC;
+        break;
+    default:
+        value = 0;
+        rp2040_log_unimplemented_read("tbman", size,
+                                      RP2040_TBMAN_BASE + addr, offset,
+                                      value);
+        break;
+    }
+
+    return value;
+}
+
+static void rp2040_tbman_write(void *opaque, hwaddr addr,
+                               uint64_t value64, unsigned size)
+{
+    hwaddr offset = addr & 0xfff;
+
+    rp2040_log_unimplemented_write("tbman", size, RP2040_TBMAN_BASE + addr,
+                                   offset, value64);
+}
+
+static const MemoryRegionOps rp2040_tbman_ops = {
+    .read = rp2040_tbman_read,
+    .write = rp2040_tbman_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .valid = {
+        .min_access_size = 4,
+        .max_access_size = 4,
+    },
+};
+
+static void rp2040_tbman_init(Object *obj)
+{
+    RP2040TbmanState *s = RP2040_TBMAN(obj);
+
+    memory_region_init_io(&s->iomem, obj, &rp2040_tbman_ops, s,
+                          "rp2040.tbman", RP2040_TBMAN_SIZE);
+    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem);
+}
+
+static const VMStateDescription rp2040_tbman_vmstate = {
+    .name = TYPE_RP2040_TBMAN,
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (const VMStateField[]) {
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static void rp2040_tbman_class_init(ObjectClass *klass, const void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    dc->vmsd = &rp2040_tbman_vmstate;
+}
+
+static const TypeInfo rp2040_tbman_info = {
+    .name          = TYPE_RP2040_TBMAN,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(RP2040TbmanState),
+    .instance_init = rp2040_tbman_init,
+    .class_init    = rp2040_tbman_class_init,
+};
+
+static void rp2040_tbman_register_types(void)
+{
+    type_register_static(&rp2040_tbman_info);
+}
+type_init(rp2040_tbman_register_types)
diff --git a/hw/misc/rp2040_vreg.c b/hw/misc/rp2040_vreg.c
new file mode 100644
index 0000000000..e8480fc258
--- /dev/null
+++ b/hw/misc/rp2040_vreg.c
@@ -0,0 +1,178 @@
+/*
+ * RP2040 voltage regulator and chip reset emulation
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "hw/misc/rp2040_nyi.h"
+#include "hw/misc/rp2040_vreg.h"
+#include "migration/vmstate.h"
+#include "qemu/module.h"
+
+#define VREG_VREG          0x00
+#define VREG_BOD           0x04
+#define VREG_CHIP_RESET    0x08
+
+#define VREG_ROK           BIT(12)
+#define VREG_VSEL_MASK     0x000000f0
+#define VREG_HIZ           BIT(1)
+#define VREG_EN            BIT(0)
+#define VREG_RW_MASK       (VREG_VSEL_MASK | VREG_HIZ | VREG_EN)
+#define VREG_RESET         0x000000b1
+
+#define BOD_VSEL_MASK      0x000000f0
+#define BOD_EN             BIT(0)
+#define BOD_RW_MASK        (BOD_VSEL_MASK | BOD_EN)
+#define BOD_RESET          0x00000091
+
+#define CHIP_RESET_RW_MASK 0x01000000
+
+#define ATOMIC_ALIAS_MASK  0x3000
+#define ATOMIC_XOR         0x1000
+#define ATOMIC_SET         0x2000
+#define ATOMIC_CLR         0x3000
+
+static uint32_t rp2040_vreg_apply_alias(uint32_t old, uint32_t value,
+                                        hwaddr alias)
+{
+    switch (alias) {
+    case ATOMIC_XOR:
+        return old ^ value;
+    case ATOMIC_SET:
+        return old | value;
+    case ATOMIC_CLR:
+        return old & ~value;
+    default:
+        return value;
+    }
+}
+
+static uint32_t rp2040_vreg_read_vreg(RP2040VregState *s)
+{
+    uint32_t value = s->vreg;
+
+    if ((value & VREG_EN) && !(value & VREG_HIZ)) {
+        value |= VREG_ROK;
+    }
+
+    return value;
+}
+
+static uint64_t rp2040_vreg_read(void *opaque, hwaddr addr, unsigned size)
+{
+    RP2040VregState *s = opaque;
+    hwaddr offset = addr & 0xfff;
+    uint64_t value;
+
+    switch (offset) {
+    case VREG_VREG:
+        value = rp2040_vreg_read_vreg(s);
+        break;
+    case VREG_BOD:
+        value = s->bod;
+        break;
+    case VREG_CHIP_RESET:
+        value = s->chip_reset;
+        break;
+    default:
+        value = 0;
+        rp2040_log_unimplemented_read("vreg_and_chip_reset", size,
+                                      RP2040_VREG_BASE + addr, offset,
+                                      value);
+        break;
+    }
+
+    return value;
+}
+
+static void rp2040_vreg_write(void *opaque, hwaddr addr,
+                              uint64_t value64, unsigned size)
+{
+    RP2040VregState *s = opaque;
+    hwaddr alias = addr & ATOMIC_ALIAS_MASK;
+    hwaddr offset = addr & 0xfff;
+    uint32_t value = value64;
+
+    switch (offset) {
+    case VREG_VREG:
+        s->vreg = rp2040_vreg_apply_alias(s->vreg, value, alias) &
+                  VREG_RW_MASK;
+        break;
+    case VREG_BOD:
+        s->bod = rp2040_vreg_apply_alias(s->bod, value, alias) & BOD_RW_MASK;
+        break;
+    case VREG_CHIP_RESET:
+        s->chip_reset =
+            rp2040_vreg_apply_alias(s->chip_reset, value, alias) &
+            CHIP_RESET_RW_MASK;
+        break;
+    default:
+        rp2040_log_unimplemented_write("vreg_and_chip_reset", size,
+                                       RP2040_VREG_BASE + addr, offset,
+                                       value64);
+        break;
+    }
+}
+
+static const MemoryRegionOps rp2040_vreg_ops = {
+    .read = rp2040_vreg_read,
+    .write = rp2040_vreg_write,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+    .valid = {
+        .min_access_size = 4,
+        .max_access_size = 4,
+    },
+};
+
+static void rp2040_vreg_reset(DeviceState *dev)
+{
+    RP2040VregState *s = RP2040_VREG(dev);
+
+    s->vreg = VREG_RESET;
+    s->bod = BOD_RESET;
+    s->chip_reset = 0;
+}
+
+static void rp2040_vreg_init(Object *obj)
+{
+    RP2040VregState *s = RP2040_VREG(obj);
+
+    memory_region_init_io(&s->iomem, obj, &rp2040_vreg_ops, s,
+                          "rp2040.vreg_and_chip_reset", RP2040_VREG_SIZE);
+    sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->iomem);
+}
+
+static const VMStateDescription rp2040_vreg_vmstate = {
+    .name = TYPE_RP2040_VREG,
+    .version_id = 1,
+    .minimum_version_id = 1,
+    .fields = (const VMStateField[]) {
+        VMSTATE_UINT32(vreg, RP2040VregState),
+        VMSTATE_UINT32(bod, RP2040VregState),
+        VMSTATE_UINT32(chip_reset, RP2040VregState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static void rp2040_vreg_class_init(ObjectClass *klass, const void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+
+    device_class_set_legacy_reset(dc, rp2040_vreg_reset);
+    dc->vmsd = &rp2040_vreg_vmstate;
+}
+
+static const TypeInfo rp2040_vreg_info = {
+    .name          = TYPE_RP2040_VREG,
+    .parent        = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(RP2040VregState),
+    .instance_init = rp2040_vreg_init,
+    .class_init    = rp2040_vreg_class_init,
+};
+
+static void rp2040_vreg_register_types(void)
+{
+    type_register_static(&rp2040_vreg_info);
+}
+type_init(rp2040_vreg_register_types)
diff --git a/include/hw/arm/rp2040.h b/include/hw/arm/rp2040.h
index caa1f9127f..86037dd0d7 100644
--- a/include/hw/arm/rp2040.h
+++ b/include/hw/arm/rp2040.h
@@ -15,6 +15,8 @@
 #include "hw/core/sysbus.h"
 #include "hw/misc/rp2040_syscfg.h"
 #include "hw/misc/rp2040_sysinfo.h"
+#include "hw/misc/rp2040_tbman.h"
+#include "hw/misc/rp2040_vreg.h"
 #include "qom/object.h"
 
 #define TYPE_RP2040 "rp2040"
@@ -38,6 +40,8 @@ struct RP2040State {
     PL011State uart[2];
     RP2040SysCfgState syscfg;
     RP2040SysInfoState sysinfo;
+    RP2040TbmanState tbman;
+    RP2040VregState vreg;
 
     MemoryRegion *board_memory;
     MemoryRegion rom;
diff --git a/include/hw/misc/rp2040_tbman.h b/include/hw/misc/rp2040_tbman.h
new file mode 100644
index 0000000000..50b55039ce
--- /dev/null
+++ b/include/hw/misc/rp2040_tbman.h
@@ -0,0 +1,25 @@
+/*
+ * RP2040 testbench manager emulation
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef HW_MISC_RP2040_TBMAN_H
+#define HW_MISC_RP2040_TBMAN_H
+
+#include "hw/core/sysbus.h"
+#include "qom/object.h"
+
+#define TYPE_RP2040_TBMAN "rp2040-tbman"
+OBJECT_DECLARE_SIMPLE_TYPE(RP2040TbmanState, RP2040_TBMAN)
+
+#define RP2040_TBMAN_BASE 0x4006c000
+#define RP2040_TBMAN_SIZE 0x4000
+
+struct RP2040TbmanState {
+    SysBusDevice parent_obj;
+
+    MemoryRegion iomem;
+};
+
+#endif
diff --git a/include/hw/misc/rp2040_vreg.h b/include/hw/misc/rp2040_vreg.h
new file mode 100644
index 0000000000..9f1723b7d5
--- /dev/null
+++ b/include/hw/misc/rp2040_vreg.h
@@ -0,0 +1,28 @@
+/*
+ * RP2040 voltage regulator and chip reset emulation
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef HW_MISC_RP2040_VREG_H
+#define HW_MISC_RP2040_VREG_H
+
+#include "hw/core/sysbus.h"
+#include "qom/object.h"
+
+#define TYPE_RP2040_VREG "rp2040-vreg"
+OBJECT_DECLARE_SIMPLE_TYPE(RP2040VregState, RP2040_VREG)
+
+#define RP2040_VREG_BASE 0x40064000
+#define RP2040_VREG_SIZE 0x4000
+
+struct RP2040VregState {
+    SysBusDevice parent_obj;
+
+    MemoryRegion iomem;
+    uint32_t vreg;
+    uint32_t bod;
+    uint32_t chip_reset;
+};
+
+#endif
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 692d51a78a..8916f68bad 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -255,7 +255,9 @@ qtests_arm = \
   (config_all_devices.has_key('CONFIG_TPM_TIS_I2C') ? ['tpm-tis-i2c-test', 
'tpm-tis-i2c-swtpm-test'] : []) + \
   (config_all_devices.has_key('CONFIG_VEXPRESS') ? ['test-arm-mptimer'] : []) 
+ \
   (config_all_devices.has_key('CONFIG_MICROBIT') ? ['microbit-test'] : []) + \
-  (config_all_devices.has_key('CONFIG_RASPI_PICO') ? 
['rp2040-sysinfo-syscfg-test'] : []) + \
+  (config_all_devices.has_key('CONFIG_RASPI_PICO') ? 
['rp2040-sysinfo-syscfg-test',
+                                                       'rp2040-tbman-test',
+                                                       'rp2040-vreg-test'] : 
[]) + \
   (config_all_devices.has_key('CONFIG_STM32L4X5_SOC') ? qtests_stm32l4x5 : []) 
+ \
   (config_all_devices.has_key('CONFIG_FSI_APB2OPB_ASPEED') ? 
['aspeed_fsi-test'] : []) + \
   (config_all_devices.has_key('CONFIG_CAN_FLEXCAN') ? ['flexcan-test'] : []) + 
\
diff --git a/tests/qtest/rp2040-tbman-test.c b/tests/qtest/rp2040-tbman-test.c
new file mode 100644
index 0000000000..a05eb3c3e2
--- /dev/null
+++ b/tests/qtest/rp2040-tbman-test.c
@@ -0,0 +1,32 @@
+/*
+ * QTest testcase for the RP2040 testbench manager block.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "libqtest.h"
+#include "qemu/bitops.h"
+
+#define TBMAN_BASE          0x4006c000
+#define TBMAN_PLATFORM      0x00
+#define TBMAN_PLATFORM_ASIC BIT(0)
+
+static void test_tbman_platform(void)
+{
+    QTestState *qts = qtest_init("-machine raspi-pico");
+
+    g_assert_cmphex(qtest_readl(qts, TBMAN_BASE + TBMAN_PLATFORM), ==,
+                    TBMAN_PLATFORM_ASIC);
+
+    qtest_quit(qts);
+}
+
+int main(int argc, char **argv)
+{
+    g_test_init(&argc, &argv, NULL);
+
+    qtest_add_func("/rp2040-tbman/platform", test_tbman_platform);
+
+    return g_test_run();
+}
diff --git a/tests/qtest/rp2040-vreg-test.c b/tests/qtest/rp2040-vreg-test.c
new file mode 100644
index 0000000000..b08bb16765
--- /dev/null
+++ b/tests/qtest/rp2040-vreg-test.c
@@ -0,0 +1,79 @@
+/*
+ * QTest testcase for the RP2040 vreg_and_chip_reset block.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "libqtest.h"
+#include "qemu/bitops.h"
+
+#define VREG_BASE           0x40064000
+#define VREG_VREG           0x00
+#define VREG_BOD            0x04
+#define VREG_CHIP_RESET     0x08
+
+#define VREG_ROK            BIT(12)
+#define VREG_RESET          0x000000b1
+#define BOD_RESET           0x00000091
+#define CHIP_RESET_RESCUE   BIT(24)
+
+#define ATOMIC_SET_ALIAS    0x2000
+#define ATOMIC_CLR_ALIAS    0x3000
+
+static QTestState *rp2040_start(void)
+{
+    return qtest_init("-machine raspi-pico");
+}
+
+static void test_vreg_reset_values(void)
+{
+    QTestState *qts = rp2040_start();
+
+    g_assert_cmphex(qtest_readl(qts, VREG_BASE + VREG_VREG), ==,
+                    VREG_RESET | VREG_ROK);
+    g_assert_cmphex(qtest_readl(qts, VREG_BASE + VREG_BOD), ==, BOD_RESET);
+    g_assert_cmphex(qtest_readl(qts, VREG_BASE + VREG_CHIP_RESET), ==, 0);
+
+    qtest_quit(qts);
+}
+
+static void test_vreg_rw_masks(void)
+{
+    QTestState *qts = rp2040_start();
+
+    qtest_writel(qts, VREG_BASE + VREG_VREG, 0xffffffff);
+    qtest_writel(qts, VREG_BASE + VREG_BOD, 0xffffffff);
+    qtest_writel(qts, VREG_BASE + VREG_CHIP_RESET, 0xffffffff);
+
+    g_assert_cmphex(qtest_readl(qts, VREG_BASE + VREG_VREG), ==, 0x000000f3);
+    g_assert_cmphex(qtest_readl(qts, VREG_BASE + VREG_BOD), ==, 0x000000f1);
+    g_assert_cmphex(qtest_readl(qts, VREG_BASE + VREG_CHIP_RESET), ==,
+                    CHIP_RESET_RESCUE);
+
+    qtest_quit(qts);
+}
+
+static void test_vreg_atomic_aliases(void)
+{
+    QTestState *qts = rp2040_start();
+
+    qtest_writel(qts, VREG_BASE + VREG_BOD, 0);
+    qtest_writel(qts, VREG_BASE + ATOMIC_SET_ALIAS + VREG_BOD, 0x00000011);
+    qtest_writel(qts, VREG_BASE + ATOMIC_CLR_ALIAS + VREG_BOD, 0x00000010);
+
+    g_assert_cmphex(qtest_readl(qts, VREG_BASE + VREG_BOD), ==, 0x00000001);
+
+    qtest_quit(qts);
+}
+
+int main(int argc, char **argv)
+{
+    g_test_init(&argc, &argv, NULL);
+
+    qtest_add_func("/rp2040-vreg/reset-values", test_vreg_reset_values);
+    qtest_add_func("/rp2040-vreg/rw-masks", test_vreg_rw_masks);
+    qtest_add_func("/rp2040-vreg/atomic-aliases", test_vreg_atomic_aliases);
+
+    return g_test_run();
+}
-- 
2.55.0


Reply via email to