/* * ARMv7M NVIC object * * Copyright (c) 2017 Linaro Ltd * Written by Peter Maydell * * This code is licensed under the GPL version 2 or later. */ #ifndef HW_ARM_ARMV7M_NVIC_H #define HW_ARM_ARMV7M_NVIC_H #include "target/arm/cpu.h" #include "hw/sysbus.h" #include "hw/timer/armv7m_systick.h" #define TYPE_NVIC "armv7m_nvic" #define NVIC(obj) \ OBJECT_CHECK(NVICState, (obj), TYPE_NVIC) /* Highest permitted number of exceptions (architectural limit) */ #define NVIC_MAX_VECTORS 512 /* Number of internal exceptions */ #define NVIC_INTERNAL_VECTORS 16 typedef struct VecInfo { /* Exception priorities can range from -3 to 255; only the unmodifiable * priority values for RESET, NMI and HardFault can be negative. */ int16_t prio; uint8_t enabled; uint8_t pending; uint8_t active; uint8_t level; /* exceptions <=15 never set level */ } VecInfo; typedef struct NVICState { /*< private >*/ SysBusDevice parent_obj; /*< public >*/ ARMCPU *cpu; VecInfo vectors[NVIC_MAX_VECTORS]; /* If the v8M security extension is implemented, some of the internal * exceptions are banked between security states (ie there exists both * a Secure and a NonSecure version of the exception and its state): * HardFault, MemManage, UsageFault, SVCall, PendSV, SysTick (R_PJHV) * The rest (including all the external exceptions) are not banked, though * they may be configurable to target either Secure or NonSecure state. * We store the secure exception state in sec_vectors[] for the banked * exceptions, and otherwise use only vectors[] (including for exceptions * like SecureFault that unconditionally target Secure state). * Entries in sec_vectors[] for non-banked exception numbers are unused. */ VecInfo sec_vectors[NVIC_INTERNAL_VECTORS]; /* The PRIGROUP field in AIRCR is banked */ uint32_t prigroup[M_REG_NUM_BANKS]; /* v8M NVIC_ITNS state (stored as a bool per bit) */ bool itns[NVIC_MAX_VECTORS]; /* The following fields are all cached state that can be recalculated * from the vectors[] and sec_vectors[] arrays and the prigroup field: * - vectpending * - vectpending_is_secure * - exception_prio * - vectpending_prio */ unsigned int vectpending; /* highest prio pending enabled exception */ /* true if vectpending is a banked secure exception, ie it is in * sec_vectors[] rather than vectors[] */ bool vectpending_is_s_banked; int exception_prio; /* group prio of the highest prio active exception */ int vectpending_prio; /* group prio of the exeception in vectpending */ MemoryRegion sysregmem; MemoryRegion sysreg_ns_mem; MemoryRegion systickmem; MemoryRegion systick_ns_mem; MemoryRegion container; uint32_t num_irq; qemu_irq excpout; qemu_irq sysresetreq; SysTickState systick[M_REG_NUM_BANKS]; } NVICState; #endif