@@ -32,6 +32,7 @@ CONFIG_NETDUINO2=y
CONFIG_NETDUINOPLUS2=y
CONFIG_MPS2=y
CONFIG_RASPI=y
+CONFIG_RP2040=y
CONFIG_DIGIC=y
CONFIG_SABRELITE=y
CONFIG_EMCRAFT_SF2=y
new file mode 100644
@@ -0,0 +1,32 @@
+/*
+ * RP2040 SoC Emulation
+ *
+ * Copyright (c) 2021 Linaro Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef _RP2040_H_
+#define _RP2040_H_
+
+#include "target/arm/cpu.h"
+#include "hw/arm/armv7m.h"
+#include "qom/object.h"
+
+#define TYPE_RP2040 "rp2040"
+OBJECT_DECLARE_TYPE(RP2040State, RP2040Class, RP2040)
+
+#define RP2040_NCPUS 2
+
+struct RP2040State {
+ /*< private >*/
+ DeviceState parent_obj;
+ /*< public >*/
+
+ ARMv7MState armv7m[RP2040_NCPUS];
+
+ MemoryRegion container;
+};
+
+
+#endif /* _RP2040_H_ */
new file mode 100644
@@ -0,0 +1,79 @@
+/*
+ * RP2040 SoC Emulation
+ *
+ * Copyright (c) 2021 Linaro Ltd
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qemu/module.h"
+#include "hw/arm/armv7m.h"
+#include "hw/arm/rp2040.h"
+#include "hw/sysbus.h"
+#include "hw/qdev-properties.h"
+
+typedef struct RP2040Class {
+ /*< private >*/
+ DeviceClass parent_class;
+ /*< public >*/
+ const char *name;
+ const char *cpu_type;
+} RP2040Class;
+
+#define RP2040_CLASS(klass) \
+ OBJECT_CLASS_CHECK(RP2040Class, (klass), TYPE_RP2040)
+#define RP2040_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(RP2040Class, (obj), TYPE_RP2040)
+
+static void rp2040_init(Object *obj)
+{
+ RP2040State *s = RP2040(obj);
+ int n;
+
+ for (n = 0; n < RP2040_NCPUS; n++) {
+ g_autofree char *name = g_strdup_printf("cpu[%d]", n);
+ object_initialize_child(obj, name, &s->armv7m[n], TYPE_ARMV7M);
+ qdev_prop_set_string(DEVICE(&s->armv7m[n]), "cpu-type",
+ ARM_CPU_TYPE_NAME("cortex-m0"));
+ }
+}
+
+static void rp2040_realize(DeviceState *dev, Error **errp)
+{
+ RP2040State *s = RP2040(dev);
+ Object *obj = OBJECT(dev);
+ int n;
+
+ for (n = 0; n < RP2040_NCPUS; n++) {
+ Object *cpuobj = OBJECT(&s->armv7m[n]);
+ if (!sysbus_realize(SYS_BUS_DEVICE(cpuobj), errp)) {
+ return;
+ }
+ }
+}
+
+static void rp2040_class_init(ObjectClass *oc, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(oc);
+ RP2040Class *bc = RP2040_CLASS(oc);
+
+ bc->cpu_type = ARM_CPU_TYPE_NAME("cortex-m0");
+ dc->realize = rp2040_realize;
+ /* any props? */
+};
+
+static const TypeInfo rp2040_types[] = {
+ {
+ .name = TYPE_RP2040,
+ /* .parent = TYPE_SYS_BUS_DEVICE, */
+ .parent = TYPE_DEVICE,
+ .instance_size = sizeof(RP2040State),
+ .instance_init = rp2040_init,
+ .class_size = sizeof(RP2040Class),
+ .class_init = rp2040_class_init,
+ }
+};
+
+DEFINE_TYPES(rp2040_types)
@@ -203,6 +203,9 @@ config REALVIEW
select DS1338 # I2C RTC+NVRAM
select USB_OHCI
+config RP2040
+ bool
+
config SBSA_REF
bool
imply PCI_DEVICES
@@ -40,6 +40,7 @@ arm_ss.add(when: 'CONFIG_STRONGARM', if_true: files('strongarm.c'))
arm_ss.add(when: 'CONFIG_ALLWINNER_A10', if_true: files('allwinner-a10.c', 'cubieboard.c'))
arm_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-h3.c', 'orangepi.c'))
arm_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_peripherals.c', 'bcm2836.c', 'raspi.c'))
+arm_ss.add(when: 'CONFIG_RP2040', if_true: files('rp2040.c'))
arm_ss.add(when: 'CONFIG_STM32F100_SOC', if_true: files('stm32f100_soc.c'))
arm_ss.add(when: 'CONFIG_STM32F205_SOC', if_true: files('stm32f205_soc.c'))
arm_ss.add(when: 'CONFIG_STM32F405_SOC', if_true: files('stm32f405_soc.c'))
Signed-off-by: Alex Bennée <alex.bennee@linaro.org> --- configs/devices/arm-softmmu/default.mak | 1 + include/hw/arm/rp2040.h | 32 ++++++++++ hw/arm/rp2040.c | 79 +++++++++++++++++++++++++ hw/arm/Kconfig | 3 + hw/arm/meson.build | 1 + 5 files changed, 116 insertions(+) create mode 100644 include/hw/arm/rp2040.h create mode 100644 hw/arm/rp2040.c