From: Peter Maydell <peter.maydell@linaro.org>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PULL 03/21] armv7m: QOMify the armv7m container
Date: Tue, 28 Feb 2017 17:15:58 +0000 [thread overview]
Message-ID: <1488302176-19463-4-git-send-email-peter.maydell@linaro.org> (raw)
In-Reply-To: <1488302176-19463-1-git-send-email-peter.maydell@linaro.org>
Create a proper QOM object for the armv7m container, which
holds the CPU, the NVIC and the bitband regions.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
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 <peter.maydell@linaro.org>
+ *
+ * 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 @@
*/
#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 = {
.endianness = DEVICE_NATIVE_ENDIAN,
};
-#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 = BITBAND(obj);
@@ -159,6 +148,131 @@ static void armv7m_bitband_init(void)
/* Board init. */
+static const hwaddr bitband_input_addr[ARMV7M_NUM_BITBANDS] = {
+ 0x20000000, 0x40000000
+};
+
+static const hwaddr bitband_output_addr[ARMV7M_NUM_BITBANDS] = {
+ 0x22000000, 0x42000000
+};
+
+static void armv7m_instance_init(Object *obj)
+{
+ ARMv7MState *s = 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 = 0; i < ARRAY_SIZE(s->bitband); i++) {
+ object_initialize(&s->bitband[i], sizeof(s->bitband[i]), TYPE_BITBAND);
+ qdev_set_parent_bus(DEVICE(&s->bitband[i]), sysbus_get_default());
+ }
+}
+
+static void armv7m_realize(DeviceState *dev, Error **errp)
+{
+ ARMv7MState *s = ARMV7M(dev);
+ Error *err = NULL;
+ int i;
+ char **cpustr;
+ ObjectClass *oc;
+ const char *typename;
+ CPUClass *cc;
+
+ cpustr = g_strsplit(s->cpu_model, ",", 2);
+
+ oc = 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 = CPU_CLASS(oc);
+ typename = object_class_get_name(oc);
+ cc->parse_features(typename, cpustr[1], &err);
+ g_strfreev(cpustr);
+ if (err) {
+ error_propagate(errp, err);
+ return;
+ }
+
+ s->cpu = 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 != 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 != 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 = &s->nvic;
+
+ for (i = 0; i < ARRAY_SIZE(s->bitband); i++) {
+ Object *obj = OBJECT(&s->bitband[i]);
+ SysBusDevice *sbd = SYS_BUS_DEVICE(&s->bitband[i]);
+
+ object_property_set_int(obj, bitband_input_addr[i], "base", &err);
+ if (err != NULL) {
+ error_propagate(errp, err);
+ return;
+ }
+ object_property_set_bool(obj, true, "realized", &err);
+ if (err != NULL) {
+ error_propagate(errp, err);
+ return;
+ }
+
+ sysbus_mmio_map(sbd, 0, bitband_output_addr[i]);
+ }
+}
+
+static Property armv7m_properties[] = {
+ DEFINE_PROP_STRING("cpu-model", ARMv7MState, cpu_model),
+ DEFINE_PROP_END_OF_LIST(),
+};
+
+static void armv7m_class_init(ObjectClass *klass, void *data)
+{
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ dc->realize = armv7m_realize;
+ dc->props = armv7m_properties;
+}
+
+static const TypeInfo armv7m_info = {
+ .name = TYPE_ARMV7M,
+ .parent = TYPE_SYS_BUS_DEVICE,
+ .instance_size = sizeof(ARMv7MState),
+ .instance_init = armv7m_instance_init,
+ .class_init = armv7m_class_init,
+};
+
static void armv7m_reset(void *opaque)
{
ARMCPU *cpu = opaque;
@@ -264,6 +378,7 @@ static const TypeInfo bitband_info = {
static void armv7m_register_types(void)
{
type_register_static(&bitband_info);
+ type_register_static(&armv7m_info);
}
type_init(armv7m_register_types)
--
2.7.4
next prev parent reply other threads:[~2017-02-28 17:16 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-02-28 17:15 [Qemu-devel] [PULL 00/21] target-arm queue Peter Maydell
2017-02-28 17:15 ` [Qemu-devel] [PULL 01/21] armv7m: Abstract out the "load kernel" code Peter Maydell
2017-02-28 17:15 ` [Qemu-devel] [PULL 02/21] armv7m: Move NVICState struct definition into header Peter Maydell
2017-02-28 17:15 ` Peter Maydell [this message]
2017-02-28 17:15 ` [Qemu-devel] [PULL 04/21] armv7m: Use QOMified armv7m object in armv7m_init() Peter Maydell
2017-02-28 17:16 ` [Qemu-devel] [PULL 05/21] armv7m: Make ARMv7M object take memory region link Peter Maydell
2017-02-28 17:16 ` [Qemu-devel] [PULL 06/21] armv7m: Make NVIC expose a memory region rather than mapping itself Peter Maydell
2017-02-28 17:16 ` [Qemu-devel] [PULL 07/21] armv7m: Make bitband device take the address space to access Peter Maydell
2017-02-28 17:16 ` [Qemu-devel] [PULL 08/21] armv7m: Don't put core v7M devices under CONFIG_STELLARIS Peter Maydell
2017-02-28 17:16 ` [Qemu-devel] [PULL 09/21] armv7m: Split systick out from NVIC Peter Maydell
2017-02-28 17:16 ` [Qemu-devel] [PULL 10/21] stm32f205: Create armv7m object without using armv7m_init() Peter Maydell
2017-02-28 17:16 ` [Qemu-devel] [PULL 11/21] stm32f205: Rename 'nvic' local to 'armv7m' Peter Maydell
2017-02-28 17:16 ` [Qemu-devel] [PULL 12/21] update-linux-headers: update for 4.11 Peter Maydell
2017-02-28 17:16 ` [Qemu-devel] [PULL 13/21] update Linux headers to 4.11 Peter Maydell
2017-02-28 17:16 ` [Qemu-devel] [PULL 14/21] hw/intc/arm_gicv3_kvm: Add ICC_SRE_EL1 register to vmstate Peter Maydell
2017-02-28 17:16 ` [Qemu-devel] [PULL 15/21] hw/intc/arm_gicv3_kvm: Implement get/put functions Peter Maydell
2017-02-28 17:16 ` [Qemu-devel] [PULL 16/21] target-arm: Add GICv3CPUState in CPUARMState struct Peter Maydell
2017-02-28 17:16 ` [Qemu-devel] [PULL 17/21] hw/intc/arm_gicv3_kvm: Reset GICv3 cpu interface registers Peter Maydell
2017-02-28 17:16 ` [Qemu-devel] [PULL 18/21] qdev: Have qdev_set_parent_bus() handle devices already on a bus Peter Maydell
2017-02-28 17:16 ` [Qemu-devel] [PULL 19/21] hw/sd: add card-reparenting function Peter Maydell
2017-02-28 17:16 ` [Qemu-devel] [PULL 20/21] bcm2835_gpio: add bcm2835 gpio controller Peter Maydell
2017-02-28 17:16 ` [Qemu-devel] [PULL 21/21] bcm2835: add sdhost and gpio controllers Peter Maydell
2017-03-01 19:28 ` [Qemu-devel] [PULL 00/21] target-arm queue Peter Maydell
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=1488302176-19463-4-git-send-email-peter.maydell@linaro.org \
--to=peter.maydell@linaro.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;
as well as URLs for NNTP newsgroup(s).