From nobody Wed Dec 17 21:51:18 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1488302254301740.4607293959098; Tue, 28 Feb 2017 09:17:34 -0800 (PST) Received: from localhost ([::1]:35775 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cilP0-0001hC-Va for importer@patchew.org; Tue, 28 Feb 2017 12:17:31 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43161) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cilNt-0001fH-RQ for qemu-devel@nongnu.org; Tue, 28 Feb 2017 12:16:23 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cilNs-0002yT-Ei for qemu-devel@nongnu.org; Tue, 28 Feb 2017 12:16:21 -0500 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:48710) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1cilNs-0002wj-6m for qemu-devel@nongnu.org; Tue, 28 Feb 2017 12:16:20 -0500 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.84_2) (envelope-from ) id 1cilNr-0003Pj-Bk for qemu-devel@nongnu.org; Tue, 28 Feb 2017 17:16:19 +0000 From: Peter Maydell To: qemu-devel@nongnu.org Date: Tue, 28 Feb 2017 17:15:58 +0000 Message-Id: <1488302176-19463-4-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1488302176-19463-1-git-send-email-peter.maydell@linaro.org> References: <1488302176-19463-1-git-send-email-peter.maydell@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 03/21] armv7m: QOMify the armv7m container X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Create a proper QOM object for the armv7m container, which holds the CPU, the NVIC and the bitband regions. Signed-off-by: Peter Maydell Reviewed-by: Alex Benn=C3=A9e Message-id: 1487604965-23220-4-git-send-email-peter.maydell@linaro.org --- include/hw/arm/armv7m.h | 51 ++++++++++++++++++ hw/arm/armv7m.c | 139 +++++++++++++++++++++++++++++++++++++++++++-= ---- 2 files changed, 178 insertions(+), 12 deletions(-) create mode 100644 include/hw/arm/armv7m.h diff --git a/include/hw/arm/armv7m.h b/include/hw/arm/armv7m.h new file mode 100644 index 0000000..193ad71 --- /dev/null +++ b/include/hw/arm/armv7m.h @@ -0,0 +1,51 @@ +/* + * ARMv7M CPU object + * + * Copyright (c) 2017 Linaro Ltd + * Written by Peter Maydell + * + * This code is licensed under the GPL version 2 or later. + */ + +#ifndef HW_ARM_ARMV7M_H +#define HW_ARM_ARMV7M_H + +#include "hw/sysbus.h" +#include "hw/arm/armv7m_nvic.h" + +#define TYPE_BITBAND "ARM,bitband-memory" +#define BITBAND(obj) OBJECT_CHECK(BitBandState, (obj), TYPE_BITBAND) + +typedef struct { + /*< private >*/ + SysBusDevice parent_obj; + /*< public >*/ + + MemoryRegion iomem; + uint32_t base; +} BitBandState; + +#define TYPE_ARMV7M "armv7m" +#define ARMV7M(obj) OBJECT_CHECK(ARMv7MState, (obj), TYPE_ARMV7M) + +#define ARMV7M_NUM_BITBANDS 2 + +/* ARMv7M container object. + * + Unnamed GPIO input lines: external IRQ lines for the NVIC + * + Named GPIO output SYSRESETREQ: signalled for guest AIRCR.SYSRESETREQ + * + Property "cpu-model": CPU model to instantiate + * + Property "num-irq": number of external IRQ lines + */ +typedef struct ARMv7MState { + /*< private >*/ + SysBusDevice parent_obj; + /*< public >*/ + NVICState nvic; + BitBandState bitband[ARMV7M_NUM_BITBANDS]; + ARMCPU *cpu; + + /* Properties */ + char *cpu_model; +} ARMv7MState; + +#endif diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c index b2cc6e9..fca85b2 100644 --- a/hw/arm/armv7m.c +++ b/hw/arm/armv7m.c @@ -8,6 +8,7 @@ */ =20 #include "qemu/osdep.h" +#include "hw/arm/armv7m.h" #include "qapi/error.h" #include "qemu-common.h" #include "cpu.h" @@ -120,18 +121,6 @@ static const MemoryRegionOps bitband_ops =3D { .endianness =3D DEVICE_NATIVE_ENDIAN, }; =20 -#define TYPE_BITBAND "ARM,bitband-memory" -#define BITBAND(obj) OBJECT_CHECK(BitBandState, (obj), TYPE_BITBAND) - -typedef struct { - /*< private >*/ - SysBusDevice parent_obj; - /*< public >*/ - - MemoryRegion iomem; - uint32_t base; -} BitBandState; - static void bitband_init(Object *obj) { BitBandState *s =3D BITBAND(obj); @@ -159,6 +148,131 @@ static void armv7m_bitband_init(void) =20 /* Board init. */ =20 +static const hwaddr bitband_input_addr[ARMV7M_NUM_BITBANDS] =3D { + 0x20000000, 0x40000000 +}; + +static const hwaddr bitband_output_addr[ARMV7M_NUM_BITBANDS] =3D { + 0x22000000, 0x42000000 +}; + +static void armv7m_instance_init(Object *obj) +{ + ARMv7MState *s =3D ARMV7M(obj); + int i; + + /* Can't init the cpu here, we don't yet know which model to use */ + + object_initialize(&s->nvic, sizeof(s->nvic), "armv7m_nvic"); + qdev_set_parent_bus(DEVICE(&s->nvic), sysbus_get_default()); + object_property_add_alias(obj, "num-irq", + OBJECT(&s->nvic), "num-irq", &error_abort); + + for (i =3D 0; i < ARRAY_SIZE(s->bitband); i++) { + object_initialize(&s->bitband[i], sizeof(s->bitband[i]), TYPE_BITB= AND); + qdev_set_parent_bus(DEVICE(&s->bitband[i]), sysbus_get_default()); + } +} + +static void armv7m_realize(DeviceState *dev, Error **errp) +{ + ARMv7MState *s =3D ARMV7M(dev); + Error *err =3D NULL; + int i; + char **cpustr; + ObjectClass *oc; + const char *typename; + CPUClass *cc; + + cpustr =3D g_strsplit(s->cpu_model, ",", 2); + + oc =3D cpu_class_by_name(TYPE_ARM_CPU, cpustr[0]); + if (!oc) { + error_setg(errp, "Unknown CPU model %s", cpustr[0]); + g_strfreev(cpustr); + return; + } + + cc =3D CPU_CLASS(oc); + typename =3D object_class_get_name(oc); + cc->parse_features(typename, cpustr[1], &err); + g_strfreev(cpustr); + if (err) { + error_propagate(errp, err); + return; + } + + s->cpu =3D ARM_CPU(object_new(typename)); + if (!s->cpu) { + error_setg(errp, "Unknown CPU model %s", s->cpu_model); + return; + } + + object_property_set_bool(OBJECT(s->cpu), true, "realized", &err); + if (err !=3D NULL) { + error_propagate(errp, err); + return; + } + + /* Note that we must realize the NVIC after the CPU */ + object_property_set_bool(OBJECT(&s->nvic), true, "realized", &err); + if (err !=3D NULL) { + error_propagate(errp, err); + return; + } + + /* Alias the NVIC's input and output GPIOs as our own so the board + * code can wire them up. (We do this in realize because the + * NVIC doesn't create the input GPIO array until realize.) + */ + qdev_pass_gpios(DEVICE(&s->nvic), dev, NULL); + qdev_pass_gpios(DEVICE(&s->nvic), dev, "SYSRESETREQ"); + + /* Wire the NVIC up to the CPU */ + sysbus_connect_irq(SYS_BUS_DEVICE(&s->nvic), 0, + qdev_get_gpio_in(DEVICE(s->cpu), ARM_CPU_IRQ)); + s->cpu->env.nvic =3D &s->nvic; + + for (i =3D 0; i < ARRAY_SIZE(s->bitband); i++) { + Object *obj =3D OBJECT(&s->bitband[i]); + SysBusDevice *sbd =3D SYS_BUS_DEVICE(&s->bitband[i]); + + object_property_set_int(obj, bitband_input_addr[i], "base", &err); + if (err !=3D NULL) { + error_propagate(errp, err); + return; + } + object_property_set_bool(obj, true, "realized", &err); + if (err !=3D NULL) { + error_propagate(errp, err); + return; + } + + sysbus_mmio_map(sbd, 0, bitband_output_addr[i]); + } +} + +static Property armv7m_properties[] =3D { + DEFINE_PROP_STRING("cpu-model", ARMv7MState, cpu_model), + DEFINE_PROP_END_OF_LIST(), +}; + +static void armv7m_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + + dc->realize =3D armv7m_realize; + dc->props =3D armv7m_properties; +} + +static const TypeInfo armv7m_info =3D { + .name =3D TYPE_ARMV7M, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(ARMv7MState), + .instance_init =3D armv7m_instance_init, + .class_init =3D armv7m_class_init, +}; + static void armv7m_reset(void *opaque) { ARMCPU *cpu =3D opaque; @@ -264,6 +378,7 @@ static const TypeInfo bitband_info =3D { static void armv7m_register_types(void) { type_register_static(&bitband_info); + type_register_static(&armv7m_info); } =20 type_init(armv7m_register_types) --=20 2.7.4