diff options
Diffstat (limited to 'target/arm/cpu.h')
-rw-r--r-- | target/arm/cpu.h | 48 |
1 files changed, 27 insertions, 21 deletions
diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 19a0c03f9b..44e6b77151 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -367,8 +367,8 @@ typedef struct CPUARMState { uint32_t c9_data; uint64_t c9_pmcr; /* performance monitor control register */ uint64_t c9_pmcnten; /* perf monitor counter enables */ - uint32_t c9_pmovsr; /* perf monitor overflow status */ - uint32_t c9_pmuserenr; /* perf monitor user enable */ + uint64_t c9_pmovsr; /* perf monitor overflow status */ + uint64_t c9_pmuserenr; /* perf monitor user enable */ uint64_t c9_pmselr; /* perf monitor counter selection register */ uint64_t c9_pminten; /* perf monitor interrupt enables */ union { /* Memory attribute redirection */ @@ -632,12 +632,17 @@ typedef struct CPUARMState { } CPUARMState; /** - * ARMELChangeHook: + * ARMELChangeHookFn: * type of a function which can be registered via arm_register_el_change_hook() * to get callbacks when the CPU changes its exception level or mode. */ -typedef void ARMELChangeHook(ARMCPU *cpu, void *opaque); - +typedef void ARMELChangeHookFn(ARMCPU *cpu, void *opaque); +typedef struct ARMELChangeHook ARMELChangeHook; +struct ARMELChangeHook { + ARMELChangeHookFn *hook; + void *opaque; + QLIST_ENTRY(ARMELChangeHook) node; +}; /* These values map onto the return values for * QEMU_PSCI_0_2_FN_AFFINITY_INFO */ @@ -826,8 +831,8 @@ struct ARMCPU { */ bool cfgend; - ARMELChangeHook *el_change_hook; - void *el_change_hook_opaque; + QLIST_HEAD(, ARMELChangeHook) pre_el_change_hooks; + QLIST_HEAD(, ARMELChangeHook) el_change_hooks; int32_t node_id; /* NUMA node this CPU belongs to */ @@ -2889,28 +2894,29 @@ static inline AddressSpace *arm_addressspace(CPUState *cs, MemTxAttrs attrs) #endif /** - * arm_register_el_change_hook: - * Register a hook function which will be called back whenever this + * arm_register_pre_el_change_hook: + * Register a hook function which will be called immediately before this * CPU changes exception level or mode. The hook function will be * passed a pointer to the ARMCPU and the opaque data pointer passed * to this function when the hook was registered. * - * Note that we currently only support registering a single hook function, - * and will assert if this function is called twice. - * This facility is intended for the use of the GICv3 emulation. + * Note that if a pre-change hook is called, any registered post-change hooks + * are guaranteed to subsequently be called. */ -void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHook *hook, +void arm_register_pre_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook, void *opaque); - /** - * arm_get_el_change_hook_opaque: - * Return the opaque data that will be used by the el_change_hook - * for this CPU. + * arm_register_el_change_hook: + * Register a hook function which will be called immediately after this + * CPU changes exception level or mode. The hook function will be + * passed a pointer to the ARMCPU and the opaque data pointer passed + * to this function when the hook was registered. + * + * Note that any registered hooks registered here are guaranteed to be called + * if pre-change hooks have been. */ -static inline void *arm_get_el_change_hook_opaque(ARMCPU *cpu) -{ - return cpu->el_change_hook_opaque; -} +void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook, void + *opaque); /** * aa32_vfp_dreg: |