Skip to contentSkip to conversation

cpu_arm: Implement irqchip property for ARM CPU

PATCH Superseded Pavel Fedin 1 participant 3 messages Aug 19, 2015

v1 of 2 Superseded Latest is v2 →

lore
Share & tools
lore
#0 lore raw

cover cpu_arm: Implement irqchip property for ARM CPU

ARMv7m CPU needs a link to NVIC instance for processing interrupts. Similarly ARMv8 needs a link to GICv3 for its CPU interface.

This series builds upon existing mechanism for linking irqchip and CPU, bringing the code up to date and making it reusable.

Pavel Fedin (2):
cpu_arm: Rename 'nvic' to 'irqchip'
cpu_arm: Use irqchip property instead of direct assignment

 hw/arm/armv7m.c     |  5 ++---
 target-arm/cpu.c    |  6 ++++++
 target-arm/cpu.h    |  5 ++++-
 target-arm/helper.c | 12 ++++++------
 4 files changed, 18 insertions(+), 10 deletions(-)
Signature · 1 line
1.9.5.msysgit.0
#1 lore raw

PATCH 1/2 cpu_arm: Rename 'nvic' to 'irqchip'

This name seems to be more appropriate because ARMv8 also needs a link with GICv3 for its CPU interface.

---
 hw/arm/armv7m.c     |  2 +-
 target-arm/cpu.h    |  5 ++++-
 target-arm/helper.c | 12 ++++++------
 3 files changed, 11 insertions(+), 8 deletions(-)
hw/arm/armv7m.c +1 -1
index c6eab6d..19742b7 100644
@@ -194,7 +194,7 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq,
 
     nvic = qdev_create(NULL, "armv7m_nvic");
     qdev_prop_set_uint32(nvic, "num-irq", num_irq);
-    env->nvic = nvic;
+    env->irqchip = nvic;
     qdev_init_nofail(nvic);
     sysbus_connect_irq(SYS_BUS_DEVICE(nvic), 0,
                        qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ));
target-arm/cpu.h +4 -1
index 2e680da..7021b87 100644
@@ -496,7 +496,10 @@ typedef struct CPUARMState {
         uint32_t *dracr;
     } pmsav7;
 
-    void *nvic;
+    /* Some CPUs have an internal link to their interrupt controller.
+     * Examples are ARMv7m (NVIC) and ARMv8 (GICv3 CPU interface)
+     */
+    DeviceState *irqchip;
     const struct arm_boot_info *boot_info;
 } CPUARMState;
 
target-arm/helper.c +6 -6
index 1568aa6..104ac4b 100644
@@ -4785,7 +4785,7 @@ static void do_v7m_exception_exit(CPUARMState *env)
 
     type = env->regs[15];
     if (env->v7m.exception != 0)
-        armv7m_nvic_complete_irq(env->nvic, env->v7m.exception);
+        armv7m_nvic_complete_irq(env->irqchip, env->v7m.exception);
 
     /* Switch to the target stack.  */
     switch_v7m_sp(env, (type & 4) != 0);
@@ -4841,18 +4841,18 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
        one we're raising.  */
     switch (cs->exception_index) {
     case EXCP_UDEF:
-        armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE);
+        armv7m_nvic_set_pending(env->irqchip, ARMV7M_EXCP_USAGE);
         return;
     case EXCP_SWI:
         /* The PC already points to the next instruction.  */
-        armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SVC);
+        armv7m_nvic_set_pending(env->irqchip, ARMV7M_EXCP_SVC);
         return;
     case EXCP_PREFETCH_ABORT:
     case EXCP_DATA_ABORT:
         /* TODO: if we implemented the MPU registers, this is where we
          * should set the MMFAR, etc from exception.fsr and exception.vaddress.
          */
-        armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_MEM);
+        armv7m_nvic_set_pending(env->irqchip, ARMV7M_EXCP_MEM);
         return;
     case EXCP_BKPT:
         if (semihosting_enabled()) {
@@ -4865,10 +4865,10 @@ void arm_v7m_cpu_do_interrupt(CPUState *cs)
                 return;
             }
         }
-        armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_DEBUG);
+        armv7m_nvic_set_pending(env->irqchip, ARMV7M_EXCP_DEBUG);
         return;
     case EXCP_IRQ:
-        env->v7m.exception = armv7m_nvic_acknowledge_irq(env->nvic);
+        env->v7m.exception = armv7m_nvic_acknowledge_irq(env->irqchip);
         break;
     case EXCP_EXCEPTION_EXIT:
         do_v7m_exception_exit(env);
Signature · 1 line
1.9.5.msysgit.0
#2 lore raw

PATCH 2/2 cpu_arm: Use irqchip property instead of direct assignment

In reply to Pavel Fedin

Implement property instead of direct assignment of cpu->env.irqchip

---
 hw/arm/armv7m.c  | 5 ++---
 target-arm/cpu.c | 6 ++++++
 2 files changed, 8 insertions(+), 3 deletions(-)
hw/arm/armv7m.c +2 -3
index 19742b7..782fd3e 100644
@@ -170,7 +170,6 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq,
                       const char *kernel_filename, const char *cpu_model)
 {
     ARMCPU *cpu;
-    CPUARMState *env;
     DeviceState *nvic;
     qemu_irq *pic = g_new(qemu_irq, num_irq);
     int image_size;
@@ -188,13 +187,13 @@ qemu_irq *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq,
         fprintf(stderr, "Unable to find CPU definition\n");
         exit(1);
     }
-    env = &cpu->env;
 
     armv7m_bitband_init();
 
     nvic = qdev_create(NULL, "armv7m_nvic");
     qdev_prop_set_uint32(nvic, "num-irq", num_irq);
-    env->irqchip = nvic;
+    object_property_set_link(OBJECT(cpu), OBJECT(nvic), "irqchip",
+                             &error_abort);
     qdev_init_nofail(nvic);
     sysbus_connect_irq(SYS_BUS_DEVICE(nvic), 0,
                        qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ));
target-arm/cpu.c +6 -0
index cc6c6f3..aed58bc 100644
@@ -447,6 +447,12 @@ static void arm_cpu_initfn(Object *obj)
     static bool inited;
     uint32_t Aff1, Aff0;
 
+    object_property_add_link(obj, "irqchip",
+                             "arm_gic_common", (Object **)&cpu->env.irqchip,
+                             object_property_allow_set_link,
+                             OBJ_PROP_LINK_UNREF_ON_RELEASE,
+                             &error_abort);
+
     cs->env_ptr = &cpu->env;
     cpu_exec_init(cs, &error_abort);
     cpu->cp_regs = g_hash_table_new_full(g_int_hash, g_int_equal,
Signature · 1 line
1.9.5.msysgit.0