diff --git a/arch/arm/core/cortex_m/scb.c b/arch/arm/core/cortex_m/scb.c index 1ce219a9865..4959485394f 100644 --- a/arch/arm/core/cortex_m/scb.c +++ b/arch/arm/core/cortex_m/scb.c @@ -79,53 +79,3 @@ void sys_arch_reboot(int type) ARG_UNUSED(type); DO_REBOOT(); } - -#if defined(CONFIG_ARMV6_M) -#elif defined(CONFIG_ARMV7_M) -/** - * - * @brief Set the number of priority groups based on the number of exception - * priorities desired - * - * Exception priorities can be divided in priority groups, inside which there is - * no preemption. The priorities inside a group are only used to decide which - * exception will run when more than one is ready to be handled. - * - * The number of priorities has to be a power of two, from 1 to 128. - * - * @param n the number of priorities - * - * @return N/A - */ -void _ScbNumPriGroupSet(unsigned int n) -{ - unsigned int set; - union __aircr reg; - - __ASSERT(is_power_of_two(n) && (n <= 128), - "invalid number of priorities"); - - set = find_lsb_set(n); - - reg.val = __scs.scb.aircr.val; - - /* num pri bit set prigroup - * --------------------------------- - * 1 1 7 - * 2 2 6 - * 4 3 5 - * 8 4 4 - * 16 5 3 - * 32 6 2 - * 64 7 1 - * 128 8 0 - */ - - reg.bit.prigroup = 8 - set; - reg.bit.vectkey = SCB_AIRCR_VECTKEY_EN_W; - - __scs.scb.aircr.val = reg.val; -} -#else -#error Unknown ARM architecture -#endif /* CONFIG_ARMV6_M */ diff --git a/include/arch/arm/cortex_m/scb.h b/include/arch/arm/cortex_m/scb.h index f4c3bdbf19a..a138b8fa422 100644 --- a/include/arch/arm/cortex_m/scb.h +++ b/include/arch/arm/cortex_m/scb.h @@ -51,20 +51,6 @@ extern "C" { #include #include -extern void _ScbNumPriGroupSet(unsigned int n); - -/** - * - * @brief Find out if the NMI exception is pending - * - * @return 1 if it is pending, 0 otherwise - */ - -static inline int _ScbIsNmiPending(void) -{ - return !!__scs.scb.icsr.bit.nmipendset; -} - /** * * @brief Pend the NMI exception @@ -79,18 +65,6 @@ static inline void _ScbNmiPend(void) __scs.scb.icsr.bit.nmipendset = 1; } -/** - * - * @brief Find out if the PendSV exception is pending - * - * @return 1 if it is pending, 0 otherwise - */ - -static inline int _ScbIsPendsvPending(void) -{ - return __scs.scb.icsr.bit.pendsvset; -} - /** * * @brief Set the PendSV exception @@ -106,97 +80,6 @@ static inline void _ScbPendsvSet(void) __scs.scb.icsr.bit.pendsvset = 1; } -/** - * - * @brief Clear the PendSV exception - * - * This routine clears the PendSV exception. - * - * @return N/A - */ - -static inline void _ScbPendsvClear(void) -{ - __scs.scb.icsr.bit.pendsvclr = 1; -} - -/** - * - * @brief Find out if the SYSTICK exception is pending - * - * This routine determines if the SYSTICK exception is pending. - * - * @return 1 if it is pending, 0 otherwise - */ - -static inline int _ScbIsSystickPending(void) -{ - return __scs.scb.icsr.bit.pendstset; -} - -/** - * - * @brief Pend the SYSTICK exception - * - * Pend the SYSTICK exception: it will be handled when returning from a higher - * priority exception or immediately if in thread mode or handling a lower - * priority exception. - * - * @return N/A - */ - -static inline void _ScbSystickPendSet(void) -{ - __scs.scb.icsr.bit.pendstset = 1; -} - -/** - * - * @brief Clear the SYSTICK exception - * - * This routine clears the SYSTICK exception. - * - * @return N/A - */ - -static inline void _ScbSystickPendClear(void) -{ - __scs.scb.icsr.bit.pendstclr = 1; -} - -/** - * - * @brief Find out if an external interrupt is pending - * - * Find out if an external interrupt, generated by the NVIC, is pending. - * - * @return 1 if one or more interrupt is pending, 0 otherwise - */ - -static inline int _ScbIsIrqPending(void) -{ - return __scs.scb.icsr.bit.isrpending; -} - -/** - * - * @brief Find out the exception number of highest-priority - * pending exception (including interrupts) - * - * If one or more exceptions are pending, return the exception number of the - * highest-priority one; otherwise, return 0. - * - * @return the exception number if one is pending, 0 otherwise - */ - -static inline int _ScbHiPriVectorPendingGet(void) -{ - union __icsr reg; - - reg.val = __scs.scb.icsr.val; - return reg.bit.vectpending; -} - /** * * @brief Find out if running in thread mode @@ -212,34 +95,6 @@ static inline int _ScbIsInThreadMode(void) return !__scs.scb.icsr.bit.vectactive; } -/** - * - * @brief Find out if running in handler mode - * - * This routine determines if the current mode is handler mode. - * - * @return 1 if in handler mode, 0 otherwise - */ - -static inline int _ScbIsInHandlerMode(void) -{ - return !_ScbIsInThreadMode(); -} - -/** - * - * @brief Find out if handling an exception - * - * This routine determines if an exception is being handled (handler mode). - * - * @return 1 if handling an exception, 0 otherwise - */ - -static inline int _ScbIsInExc(void) -{ - return _ScbIsInHandlerMode(); -} - /** * * @brief Obtain the currently executing vector @@ -255,192 +110,6 @@ static inline uint32_t _ScbActiveVectorGet(void) return __scs.scb.icsr.bit.vectactive; } -/** - * - * @brief Find out if data regions are little endian - * - * Data regions on Cortex-M devices can be either little or big endian. Code - * regions are always little endian. - * - * @return 1 if little endian, 0 if big endian - */ - -static inline int _ScbIsDataLittleEndian(void) -{ - return !(__scs.scb.aircr.bit.endianness); -} - -/** - * - * @brief CPU goes to sleep after exiting an ISR - * - * CPU never runs in thread mode until this is cancelled. - * - * This enables the feature until it is cancelled. - * - * @return N/A - */ - -static inline void _ScbSleepOnExitSet(void) -{ - __scs.scb.scr.bit.sleeponexit = 1; -} - -/** - * - * @brief CPU does not go to sleep after exiting an ISR - * - * This routine prevents CPU sleep mode upon exiting an ISR. - * This is the normal operating mode. - * - * @return N/A - */ - -static inline void _ScbSleepOnExitClear(void) -{ - __scs.scb.scr.bit.sleeponexit = 0; -} - -/** - * - * @brief Do not put CPU to sleep if pending exception are present - * when invoking wfe instruction - * - * By default, when invoking wfi or wfe instructions, if PRIMASK is masking - * interrupts and if an interrupt is pending, the CPU will go to sleep, and - * another interrupt is needed to wake it up. By coupling the use of the - * SEVONPEND feature and the wfe instruction (NOT wfi), pending exception will - * prevent the CPU from sleeping. - * - * This enables the feature until it is cancelled. - * - * @return N/A - */ - -static inline void _ScbSevOnPendSet(void) -{ - __scs.scb.scr.bit.sevonpend = 1; -} - -/** - * - * @brief Clear SEVONPEND bit - * - * See _ScbSevOnPendSet(). - * - * @return N/A - */ - -static inline void _ScbSevOnPendClear(void) -{ - __scs.scb.scr.bit.sevonpend = 0; -} - -/** - * - * @brief When putting the CPU to sleep, put it in deep sleep - * - * When wfi/wfe is invoked, the CPU will go into a "deep sleep" mode, using less - * power than regular sleep mode, but with some possible side-effect. - * - * Behavior is processor-specific. - * - * @return N/A - */ - -static inline void _ScbSleepDeepSet(void) -{ - __scs.scb.scr.bit.sleepdeep = 1; -} - -/** - * - * @brief When putting the CPU to sleep, do not put it in deep sleep - * - * This routine prevents CPU deep sleep mode. - * - * @return N/A - */ - -static inline void _ScbSleepDeepClear(void) -{ - __scs.scb.scr.bit.sleepdeep = 0; -} - -/** - * - * @brief Enable faulting on unaligned access - * - * This routine enables the unaligned access fault. - * By default, the CPU ignores the error. - * - * @return N/A - */ - -static inline void _ScbUnalignedFaultEnable(void) -{ - __scs.scb.ccr.bit.unalign_trp = 1; -} - -/** - * - * @brief Ignore unaligned access errors - * - * This routine disables the unaligned fault. - * This is the default behavior. - * - * @return N/A - */ - -static inline void _ScbUnalignedFaultDisable(void) -{ - __scs.scb.ccr.bit.unalign_trp = 0; -} - -/** - * - * @brief Write the CCR all at once - * - * This routine writes the given value to the Configuration Control Register. - * - * @param val value to write to CCR - * @return N/A - */ - -static inline void ScbCcrSet(uint32_t val) -{ - __scs.scb.ccr.val = val; -} - -/** - * - * @brief Obtain priority of an exception - * - * Only works with exceptions; i.e. do not use this for interrupts, which - * are exceptions 16+. - * - * ARMv6-M: Exceptions 1 to 3 priorities are fixed (-3, -2, -1) and 4 to 9 are - * reserved exceptions. - * ARMv7-M: Exceptions 1 to 3 priorities are fixed (-3, -2, -1). - * - * @param exc exception number, 4 to 15 - * @return priority of exception @a exc - */ - -static inline uint8_t _ScbExcPrioGet(uint8_t exc) -{ -#if defined(CONFIG_ARMV6_M) - __ASSERT((exc > 10) && (exc < 16), ""); - return (__scs.scb.shpr[_PRIO_SHP_IDX(exc)] >> _PRIO_BIT_SHIFT(exc)); -#elif defined(CONFIG_ARMV7_M) - /* For priority exception handler 4-15 */ - __ASSERT((exc > 3) && (exc < 16), ""); - return __scs.scb.shpr[exc - 4]; -#else -#error Unknown ARM architecture -#endif /* CONFIG_ARMV6_M */ -} - /** * * @brief Set priority of an exception @@ -493,76 +162,6 @@ static inline int _ScbIsNestedExc(void) return !__scs.scb.icsr.bit.rettobase; } -/** - * - * @brief Find out if vector table is in SRAM or ROM - * - * This routine determines if the currently executing exception is nested. - * - * @return 1 if in SRAM, 0 if in ROM - */ - -static inline uint32_t _ScbIsVtableInSram(void) -{ - return !!__scs.scb.vtor.bit.tblbase; -} - -/** - * - * @brief Move vector table from SRAM to ROM and vice-versa - * - * This routine moves the vector table to the given memory region. - * - * @return 1 if in SRAM, 0 if in ROM - */ - -static inline void _ScbVtableLocationSet( - int sram /* 1 to move vector to SRAM, 0 to move it to ROM */ - ) -{ - __ASSERT(!(sram & 0xfffffffe), ""); - __scs.scb.vtor.bit.tblbase = sram; -} - -/** - * - * @brief Obtain base address of vector table - * - * This routine returns the vector table's base address. - * - * @return the base address of the vector table - */ - -static inline uint32_t _ScbVtableAddrGet(void) -{ - return __scs.scb.vtor.bit.tbloff; -} - -/** - * - * @brief Set base address of vector table - * - * @a addr must align to the number of exception entries in vector table: - * - * numException = 16 + num_interrupts where each entry is 4 Bytes - * - * As a minimum, @a addr must be a multiple of 128: - * - * 0 <= num_interrupts < 16: multiple 0x080 - * 16 <= num_interrupts < 48: multiple 0x100 - * 48 <= num_interrupts < 112: multiple 0x200 - * .... - * @param addr base address, aligned on 128 minimum - * - * @return N/A - */ - -static inline void _ScbVtableAddrSet(uint32_t addr) -{ - __ASSERT(!(addr & 0x7F), "invalid vtable base Addr"); - __scs.scb.vtor.bit.tbloff = addr; -} - /** * * @brief Enable faulting on division by zero @@ -578,37 +177,6 @@ static inline void _ScbDivByZeroFaultEnable(void) __scs.scb.ccr.bit.div_0_trp = 1; } -/** - * - * @brief Ignore division by zero errors - * - * This routine disables the divide by zero fault. - * This is the default behavior. - * - * @return N/A - */ - -static inline void _ScbDivByZeroFaultDisable(void) -{ - __scs.scb.ccr.bit.div_0_trp = 0; -} - -/** - * - * @brief Get the programmed number of priority groups - * - * Exception priorities can be sub-divided into groups, with sub-priorities. - * Within these groups, exceptions do not preempt each other. The sub-priorities - * are only used to decide which exception will run when several are pending. - * - * @return the number of priority groups - */ - -static inline int _ScbNumPriGroupGet(void) -{ - return 1 << (7 - __scs.scb.aircr.bit.prigroup); -} - /** * * @brief Enable usage fault exceptions @@ -624,21 +192,6 @@ static inline void _ScbUsageFaultEnable(void) __scs.scb.shcsr.bit.usgfaultena = 1; } -/** - * - * @brief Disable usage fault exceptions - * - * This routine disables usage faults. - * This is the default behavior. - * - * @return N/A - */ - -static inline void _ScbUsageFaultDisable(void) -{ - __scs.scb.shcsr.bit.usgfaultena = 0; -} - /** * * @brief Enable bus fault exceptions @@ -654,21 +207,6 @@ static inline void _ScbBusFaultEnable(void) __scs.scb.shcsr.bit.busfaultena = 1; } -/** - * - * @brief Disable bus fault exceptions - * - * This routine disables bus faults. - * This is the default behavior. - * - * @return N/A - */ - -static inline void _ScbBusFaultDisable(void) -{ - __scs.scb.shcsr.bit.busfaultena = 0; -} - /** * * @brief Enable MPU faults exceptions @@ -684,21 +222,6 @@ static inline void _ScbMemFaultEnable(void) __scs.scb.shcsr.bit.memfaultena = 1; } -/** - * - * @brief Disable MPU fault exceptions - * - * This routine disables MPU faults. - * This is the default behavior. - * - * @return N/A - */ - -static inline void _ScbMemFaultDisable(void) -{ - __scs.scb.shcsr.bit.memfaultena = 0; -} - /** * * @brief Find out if a hard fault is caused by a bus error on vector read @@ -1119,90 +642,6 @@ static inline int _ScbUsageFaultIsUndefinedInstr(void) return !!__scs.scb.cfsr.byte.ufsr.bit.undefinstr; } -/** - * - * @brief Clear the 'division by zero' fault - * - * CFSR/UFSR register is a 'write-one-to-clear' (W1C) register. - * - * @return N/A - */ - -static inline void _ScbUsageFaultDivByZeroReset(void) -{ - __scs.scb.cfsr.byte.ufsr.bit.divbyzero = 1; -} - -/** - * - * @brief Clear the 'unaligned access' fault - * - * CFSR/UFSR register is a 'write-one-to-clear' (W1C) register. - * - * @return N/A - */ - -static inline void _ScbUsageFaultUnalignedReset(void) -{ - __scs.scb.cfsr.byte.ufsr.bit.unaligned = 1; -} - -/** - * - * @brief Clear the 'no co-processor' fault - * - * CFSR/UFSR register is a 'write-one-to-clear' (W1C) register. - * - * @return N/A - */ - -static inline void _ScbUsageFaultNoCpReset(void) -{ - __scs.scb.cfsr.byte.ufsr.bit.nocp = 1; -} - -/** - * - * @brief Clear the 'invalid PC load ' fault - * - * CFSR/UFSR register is a 'write-one-to-clear' (W1C) register. - * - * @return N/A - */ - -static inline void _ScbUsageFaultInvalidPcLoadReset(void) -{ - __scs.scb.cfsr.byte.ufsr.bit.invpc = 1; -} - -/** - * - * @brief Clear the 'invalid state' fault - * - * CFSR/UFSR register is a 'write-one-to-clear' (W1C) register. - * - * @return N/A - */ - -static inline void _ScbUsageFaultInvalidStateReset(void) -{ - __scs.scb.cfsr.byte.ufsr.bit.invstate = 1; -} - -/** - * - * @brief Clear the 'undefined instruction' fault - * - * CFSR/UFSR register is a 'write-one-to-clear' (W1C) register. - * - * @return N/A - */ - -static inline void _ScbUsageFaultUndefinedInstrReset(void) -{ - __scs.scb.cfsr.byte.ufsr.bit.undefinstr = 1; -} - /** * * @brief Clear all usage faults (UFSR register) diff --git a/include/arch/arm/cortex_m/scs.h b/include/arch/arm/cortex_m/scs.h index 436a6807a97..0caf3b3a7df 100644 --- a/include/arch/arm/cortex_m/scs.h +++ b/include/arch/arm/cortex_m/scs.h @@ -592,117 +592,6 @@ extern volatile struct __scs __scs; /* API */ #if defined(CONFIG_ARMV6_M) #elif defined(CONFIG_ARMV7_M) -/** - * - * @brief Obtain the number of interrupt lines on the target - * - * @return the number of interrupts - */ - -static inline int _ScsNumIrqGet(void) -{ - return 32 * (__scs.ictr.bit.intlinesnum + 1); -} - -/** - * - * @brief Disable load/store multiple instructions - * - * From the ARM manuals: - * - * LDM/STM instructions increase the interrupt latency of the processor because - * they must complete before the processor can stack the current state and - * invoke the interrupt handler. - * - * @return N/A - */ - -static inline void _ScsIntMultiCycleInstDisable(void) -{ - __scs.actlr.bit.dismcycint = 1; -} - -/** - * - * @brief Enable load/store multiple instructions - * - * See _ScsIntMultiCycleInstDisable(). - * - * @return N/A - */ - -static inline void _ScsIntMultiCycleInstEnable(void) -{ - __scs.actlr.bit.dismcycint = 0; -} - -/** - * - * @brief Disable write buffer - * - * From the ARM manuals: - * - * Disables write buffer use during default memory map accesses. This causes all - * BusFaults to be precise BusFaults but decreases performance because any store - * to memory must complete before the processor can execute the next - * instruction. - * - * @return N/A - */ - -static inline void _ScsWriteBufDisable(void) -{ - __scs.actlr.bit.disdefwbuf = 1; -} - -/** - * - * @brief Enable write buffer - * - * See _ScsWriteBufDisable(). - * - * @return N/A - */ - -static inline void _ScsWriteBufEnable(void) -{ - __scs.actlr.bit.disdefwbuf = 0; -} - -/** - * - * @brief Disable IT folding - * - * From the ARM manuals: - * - * In some situations, the processor can start executing the first instruction - * in an IT block while it is still executing the IT instruction. This behavior - * is called IT folding, and improves performance, However, IT folding can cause - * jitter in looping. If a task must avoid jitter, set the DISFOLD bit to 1 - * before executing the task, to disable IT folding. - * - * @return N/A - */ - -static inline void _ScsFoldItDisable(void) -{ - __scs.actlr.bit.disfold = 1; -} - -/** - * - * @brief Enable IT folding - * - * See _ScsFoldItDisable(). - * - * @return N/A - */ - -static inline void _ScsFoldItEnable(void) -{ - __scs.actlr.bit.disfold = 0; -} - /** * * @brief Relocate the vector table