diff options
author | Aaron Lindsay <alindsay@codeaurora.org> | 2018-04-26 11:04:39 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2018-04-26 11:04:39 +0100 |
commit | 08267487c99e8150382420936ab72c1e0ad74ce3 (patch) | |
tree | 92ff492c7951003e73f853727e659bf176c3995d /target/arm/cpu.c | |
parent | d5a5e4c93dae0dc3feb402cf7ee78d846da1a7e1 (diff) |
target/arm: Support multiple EL change hooks
Signed-off-by: Aaron Lindsay <alindsay@codeaurora.org>
Message-id: 1523997485-1905-7-git-send-email-alindsay@codeaurora.org
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'target/arm/cpu.c')
-rw-r--r-- | target/arm/cpu.c | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 022d8c5787..1f689f6817 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -55,13 +55,15 @@ static bool arm_cpu_has_work(CPUState *cs) | CPU_INTERRUPT_EXITTB); } -void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHook *hook, +void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook, void *opaque) { - /* We currently only support registering a single hook function */ - assert(!cpu->el_change_hook); - cpu->el_change_hook = hook; - cpu->el_change_hook_opaque = opaque; + ARMELChangeHook *entry = g_new0(ARMELChangeHook, 1); + + entry->hook = hook; + entry->opaque = opaque; + + QLIST_INSERT_HEAD(&cpu->el_change_hooks, entry, node); } static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque) @@ -552,6 +554,8 @@ static void arm_cpu_initfn(Object *obj) cpu->cp_regs = g_hash_table_new_full(g_int_hash, g_int_equal, g_free, g_free); + QLIST_INIT(&cpu->el_change_hooks); + #ifndef CONFIG_USER_ONLY /* Our inbound IRQ and FIQ lines */ if (kvm_enabled()) { @@ -713,7 +717,14 @@ static void arm_cpu_post_init(Object *obj) static void arm_cpu_finalizefn(Object *obj) { ARMCPU *cpu = ARM_CPU(obj); + ARMELChangeHook *hook, *next; + g_hash_table_destroy(cpu->cp_regs); + + QLIST_FOREACH_SAFE(hook, &cpu->el_change_hooks, node, next) { + QLIST_REMOVE(hook, node); + g_free(hook); + } } static void arm_cpu_realizefn(DeviceState *dev, Error **errp) |