cpu_arm: Implement irqchip property for ARM CPU
v2 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. Another small step towards complete GICv3 implementation.
v1 => v2:
- Set link to nvic after it has been initialized
- Changed object type to "sys-bus-device" because GICv2 and GICv3 do not share common ancestors above that.
Pavel Fedin (2):
cpu_arm: Rename 'nvic' to 'irqchip'
armv7m: 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
PATCH v2 1/2 cpu_arm: Rename 'nvic' to 'irqchip'
This name seems to be more appropriate because ARMv8 also needs a link with GICv3 for CPU interface to work
--- 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
@@ -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
@@ -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
@@ -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
PATCH v2 2/2 armv7m: Use irqchip property instead of direct assignment
In reply to Pavel FedinImplement 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
@@ -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,14 +187,14 @@ 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;qdev_init_nofail (nvic); +object_property_set_link (OBJECT (cpu),OBJECT (nvic),"irqchip" , + &error_abort);sysbus_connect_irq (SYS_BUS_DEVICE (nvic),0 ,qdev_get_gpio_in (DEVICE (cpu),ARM_CPU_IRQ ));for (i =0 ; i < num_irq; i++) {
target-arm/cpu.c +6 -0
@@ -447,6 +447,12 @@ static void arm_cpu_initfn(Object *obj)static bool inited;uint32_t Aff1, Aff0; +object_property_add_link (obj,"irqchip" , +"sys-bus-device" , (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