diff options
Diffstat (limited to 'target/arm/cpu.h')
| -rw-r--r-- | target/arm/cpu.h | 228 |
1 files changed, 8 insertions, 220 deletions
diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 7bc97fece9..12b1082537 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -227,6 +227,8 @@ typedef struct CPUARMTBFlags { typedef struct ARMMMUFaultInfo ARMMMUFaultInfo; +typedef struct NVICState NVICState; + typedef struct CPUArchState { /* Regs for current mode. */ uint32_t regs[16]; @@ -721,11 +723,6 @@ typedef struct CPUArchState { ARMVectorReg zarray[ARM_MAX_VQ * 16]; #endif -#if defined(CONFIG_USER_ONLY) - /* For usermode syscall translation. */ - int eabi; -#endif - struct CPUBreakpoint *cpu_breakpoint[16]; struct CPUWatchpoint *cpu_watchpoint[16]; @@ -772,10 +769,15 @@ typedef struct CPUArchState { uint32_t ctrl; } sau; - void *nvic; +#if !defined(CONFIG_USER_ONLY) + NVICState *nvic; const struct arm_boot_info *boot_info; /* Store GICv3CPUState to access from this struct */ void *gicv3state; +#else /* CONFIG_USER_ONLY */ + /* For usermode syscall translation. */ + bool eabi; +#endif /* CONFIG_USER_ONLY */ #ifdef TARGET_TAGGED_ADDRESSES /* Linux syscall tagged address support */ @@ -2557,220 +2559,6 @@ void arm_cpu_list(void); uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx, uint32_t cur_el, bool secure); -/* Interface between CPU and Interrupt controller. */ -#ifndef CONFIG_USER_ONLY -bool armv7m_nvic_can_take_pending_exception(void *opaque); -#else -static inline bool armv7m_nvic_can_take_pending_exception(void *opaque) -{ - return true; -} -#endif -/** - * armv7m_nvic_set_pending: mark the specified exception as pending - * @opaque: the NVIC - * @irq: the exception number to mark pending - * @secure: false for non-banked exceptions or for the nonsecure - * version of a banked exception, true for the secure version of a banked - * exception. - * - * Marks the specified exception as pending. Note that we will assert() - * if @secure is true and @irq does not specify one of the fixed set - * of architecturally banked exceptions. - */ -void armv7m_nvic_set_pending(void *opaque, int irq, bool secure); -/** - * armv7m_nvic_set_pending_derived: mark this derived exception as pending - * @opaque: the NVIC - * @irq: the exception number to mark pending - * @secure: false for non-banked exceptions or for the nonsecure - * version of a banked exception, true for the secure version of a banked - * exception. - * - * Similar to armv7m_nvic_set_pending(), but specifically for derived - * exceptions (exceptions generated in the course of trying to take - * a different exception). - */ -void armv7m_nvic_set_pending_derived(void *opaque, int irq, bool secure); -/** - * armv7m_nvic_set_pending_lazyfp: mark this lazy FP exception as pending - * @opaque: the NVIC - * @irq: the exception number to mark pending - * @secure: false for non-banked exceptions or for the nonsecure - * version of a banked exception, true for the secure version of a banked - * exception. - * - * Similar to armv7m_nvic_set_pending(), but specifically for exceptions - * generated in the course of lazy stacking of FP registers. - */ -void armv7m_nvic_set_pending_lazyfp(void *opaque, int irq, bool secure); -/** - * armv7m_nvic_get_pending_irq_info: return highest priority pending - * exception, and whether it targets Secure state - * @opaque: the NVIC - * @pirq: set to pending exception number - * @ptargets_secure: set to whether pending exception targets Secure - * - * This function writes the number of the highest priority pending - * exception (the one which would be made active by - * armv7m_nvic_acknowledge_irq()) to @pirq, and sets @ptargets_secure - * to true if the current highest priority pending exception should - * be taken to Secure state, false for NS. - */ -void armv7m_nvic_get_pending_irq_info(void *opaque, int *pirq, - bool *ptargets_secure); -/** - * armv7m_nvic_acknowledge_irq: make highest priority pending exception active - * @opaque: the NVIC - * - * Move the current highest priority pending exception from the pending - * state to the active state, and update v7m.exception to indicate that - * it is the exception currently being handled. - */ -void armv7m_nvic_acknowledge_irq(void *opaque); -/** - * armv7m_nvic_complete_irq: complete specified interrupt or exception - * @opaque: the NVIC - * @irq: the exception number to complete - * @secure: true if this exception was secure - * - * Returns: -1 if the irq was not active - * 1 if completing this irq brought us back to base (no active irqs) - * 0 if there is still an irq active after this one was completed - * (Ignoring -1, this is the same as the RETTOBASE value before completion.) - */ -int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure); -/** - * armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure) - * @opaque: the NVIC - * @irq: the exception number to mark pending - * @secure: false for non-banked exceptions or for the nonsecure - * version of a banked exception, true for the secure version of a banked - * exception. - * - * Return whether an exception is "ready", i.e. whether the exception is - * enabled and is configured at a priority which would allow it to - * interrupt the current execution priority. This controls whether the - * RDY bit for it in the FPCCR is set. - */ -bool armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure); -/** - * armv7m_nvic_raw_execution_priority: return the raw execution priority - * @opaque: the NVIC - * - * Returns: the raw execution priority as defined by the v8M architecture. - * This is the execution priority minus the effects of AIRCR.PRIS, - * and minus any PRIMASK/FAULTMASK/BASEPRI priority boosting. - * (v8M ARM ARM I_PKLD.) - */ -int armv7m_nvic_raw_execution_priority(void *opaque); -/** - * armv7m_nvic_neg_prio_requested: return true if the requested execution - * priority is negative for the specified security state. - * @opaque: the NVIC - * @secure: the security state to test - * This corresponds to the pseudocode IsReqExecPriNeg(). - */ -#ifndef CONFIG_USER_ONLY -bool armv7m_nvic_neg_prio_requested(void *opaque, bool secure); -#else -static inline bool armv7m_nvic_neg_prio_requested(void *opaque, bool secure) -{ - return false; -} -#endif - -/* Interface for defining coprocessor registers. - * Registers are defined in tables of arm_cp_reginfo structs - * which are passed to define_arm_cp_regs(). - */ - -/* When looking up a coprocessor register we look for it - * via an integer which encodes all of: - * coprocessor number - * Crn, Crm, opc1, opc2 fields - * 32 or 64 bit register (ie is it accessed via MRC/MCR - * or via MRRC/MCRR?) - * non-secure/secure bank (AArch32 only) - * We allow 4 bits for opc1 because MRRC/MCRR have a 4 bit field. - * (In this case crn and opc2 should be zero.) - * For AArch64, there is no 32/64 bit size distinction; - * instead all registers have a 2 bit op0, 3 bit op1 and op2, - * and 4 bit CRn and CRm. The encoding patterns are chosen - * to be easy to convert to and from the KVM encodings, and also - * so that the hashtable can contain both AArch32 and AArch64 - * registers (to allow for interprocessing where we might run - * 32 bit code on a 64 bit core). - */ -/* This bit is private to our hashtable cpreg; in KVM register - * IDs the AArch64/32 distinction is the KVM_REG_ARM/ARM64 - * in the upper bits of the 64 bit ID. - */ -#define CP_REG_AA64_SHIFT 28 -#define CP_REG_AA64_MASK (1 << CP_REG_AA64_SHIFT) - -/* To enable banking of coprocessor registers depending on ns-bit we - * add a bit to distinguish between secure and non-secure cpregs in the - * hashtable. - */ -#define CP_REG_NS_SHIFT 29 -#define CP_REG_NS_MASK (1 << CP_REG_NS_SHIFT) - -#define ENCODE_CP_REG(cp, is64, ns, crn, crm, opc1, opc2) \ - ((ns) << CP_REG_NS_SHIFT | ((cp) << 16) | ((is64) << 15) | \ - ((crn) << 11) | ((crm) << 7) | ((opc1) << 3) | (opc2)) - -#define ENCODE_AA64_CP_REG(cp, crn, crm, op0, op1, op2) \ - (CP_REG_AA64_MASK | \ - ((cp) << CP_REG_ARM_COPROC_SHIFT) | \ - ((op0) << CP_REG_ARM64_SYSREG_OP0_SHIFT) | \ - ((op1) << CP_REG_ARM64_SYSREG_OP1_SHIFT) | \ - ((crn) << CP_REG_ARM64_SYSREG_CRN_SHIFT) | \ - ((crm) << CP_REG_ARM64_SYSREG_CRM_SHIFT) | \ - ((op2) << CP_REG_ARM64_SYSREG_OP2_SHIFT)) - -/* Convert a full 64 bit KVM register ID to the truncated 32 bit - * version used as a key for the coprocessor register hashtable - */ -static inline uint32_t kvm_to_cpreg_id(uint64_t kvmid) -{ - uint32_t cpregid = kvmid; - if ((kvmid & CP_REG_ARCH_MASK) == CP_REG_ARM64) { - cpregid |= CP_REG_AA64_MASK; - } else { - if ((kvmid & CP_REG_SIZE_MASK) == CP_REG_SIZE_U64) { - cpregid |= (1 << 15); - } - - /* KVM is always non-secure so add the NS flag on AArch32 register - * entries. - */ - cpregid |= 1 << CP_REG_NS_SHIFT; - } - return cpregid; -} - -/* Convert a truncated 32 bit hashtable key into the full - * 64 bit KVM register ID. - */ -static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid) -{ - uint64_t kvmid; - - if (cpregid & CP_REG_AA64_MASK) { - kvmid = cpregid & ~CP_REG_AA64_MASK; - kvmid |= CP_REG_SIZE_U64 | CP_REG_ARM64; - } else { - kvmid = cpregid & ~(1 << 15); - if (cpregid & (1 << 15)) { - kvmid |= CP_REG_SIZE_U64 | CP_REG_ARM; - } else { - kvmid |= CP_REG_SIZE_U32 | CP_REG_ARM; - } - } - return kvmid; -} - /* Return the highest implemented Exception Level */ static inline int arm_highest_el(CPUARMState *env) { |