mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #5342 from ARMmbed/feature_cortex_a
Update CMSIS/RTX with Cortex-A supportpull/5497/merge
commit
41eb565d9c
|
@ -14,6 +14,11 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#if defined(TARGET_CORTEX_A)
|
||||
#error [NOT_SUPPORTED] This function not supported for this target
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
/**************************************************************************//**
|
||||
* @file cmsis_armcc.h
|
||||
* @brief CMSIS compiler specific macros, functions, instructions
|
||||
* @version V1.00
|
||||
* @date 22. Feb 2017
|
||||
* @version V1.0.1
|
||||
* @date 07. Sep 2017
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2017 ARM Limited. All rights reserved.
|
||||
|
@ -36,68 +36,53 @@
|
|||
|
||||
/* CMSIS compiler specific defines */
|
||||
#ifndef __ASM
|
||||
#define __ASM __asm
|
||||
#endif
|
||||
#ifndef __INLINE
|
||||
#define __INLINE __inline
|
||||
#endif
|
||||
#ifndef __STATIC_INLINE
|
||||
#define __STATIC_INLINE static __inline
|
||||
#endif
|
||||
#ifndef __STATIC_ASM
|
||||
#define __STATIC_ASM static __asm
|
||||
#endif
|
||||
#ifndef __NO_RETURN
|
||||
#define __NO_RETURN __declspec(noreturn)
|
||||
#endif
|
||||
#ifndef __USED
|
||||
#define __USED __attribute__((used))
|
||||
#endif
|
||||
#ifndef __WEAK
|
||||
#define __WEAK __attribute__((weak))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32
|
||||
#define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x)))
|
||||
#endif
|
||||
#ifndef __ALIGNED
|
||||
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||
#define __ASM __asm
|
||||
#endif
|
||||
#ifndef __INLINE
|
||||
#define __INLINE __inline
|
||||
#endif
|
||||
#ifndef __FORCEINLINE
|
||||
#define __FORCEINLINE __forceinline
|
||||
#endif
|
||||
#ifndef __STATIC_INLINE
|
||||
#define __STATIC_INLINE static __inline
|
||||
#endif
|
||||
#ifndef __STATIC_FORCEINLINE
|
||||
#define __STATIC_FORCEINLINE static __forceinline
|
||||
#endif
|
||||
#ifndef __NO_RETURN
|
||||
#define __NO_RETURN __declspec(noreturn)
|
||||
#endif
|
||||
#ifndef __USED
|
||||
#define __USED __attribute__((used))
|
||||
#endif
|
||||
#ifndef __WEAK
|
||||
#define __WEAK __attribute__((weak))
|
||||
#endif
|
||||
#ifndef __PACKED
|
||||
#define __PACKED __attribute__((packed))
|
||||
#define __PACKED __attribute__((packed))
|
||||
#endif
|
||||
|
||||
|
||||
/* ########################### Core Function Access ########################### */
|
||||
|
||||
/**
|
||||
\brief Get FPSCR
|
||||
\return Floating Point Status/Control register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_FPSCR(void)
|
||||
{
|
||||
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
|
||||
register uint32_t __regfpscr __ASM("fpscr");
|
||||
return(__regfpscr);
|
||||
#else
|
||||
return(0U);
|
||||
#ifndef __PACKED_STRUCT
|
||||
#define __PACKED_STRUCT __packed struct
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Set FPSCR
|
||||
\param [in] fpscr Floating Point Status/Control value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
|
||||
{
|
||||
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
|
||||
register uint32_t __regfpscr __ASM("fpscr");
|
||||
__regfpscr = (fpscr);
|
||||
#else
|
||||
(void)fpscr;
|
||||
#ifndef __UNALIGNED_UINT16_WRITE
|
||||
#define __UNALIGNED_UINT16_WRITE(addr, val) ((*((__packed uint16_t *)(addr))) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT16_READ
|
||||
#define __UNALIGNED_UINT16_READ(addr) (*((const __packed uint16_t *)(addr)))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_WRITE
|
||||
#define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_READ
|
||||
#define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr)))
|
||||
#endif
|
||||
#ifndef __ALIGNED
|
||||
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||
#endif
|
||||
#ifndef __PACKED
|
||||
#define __PACKED __attribute__((packed))
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ########################## Core Instruction Access ######################### */
|
||||
/**
|
||||
|
@ -209,7 +194,142 @@ __attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(in
|
|||
*/
|
||||
#define __CLZ __clz
|
||||
|
||||
/** \brief Get CPSR Register
|
||||
/**
|
||||
\brief LDR Exclusive (8 bit)
|
||||
\details Executes a exclusive LDR instruction for 8 bit value.
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint8_t at (*ptr)
|
||||
*/
|
||||
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
|
||||
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
|
||||
#else
|
||||
#define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop")
|
||||
#endif
|
||||
|
||||
/**
|
||||
\brief LDR Exclusive (16 bit)
|
||||
\details Executes a exclusive LDR instruction for 16 bit values.
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint16_t at (*ptr)
|
||||
*/
|
||||
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
|
||||
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
|
||||
#else
|
||||
#define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop")
|
||||
#endif
|
||||
|
||||
/**
|
||||
\brief LDR Exclusive (32 bit)
|
||||
\details Executes a exclusive LDR instruction for 32 bit values.
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint32_t at (*ptr)
|
||||
*/
|
||||
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
|
||||
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
|
||||
#else
|
||||
#define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop")
|
||||
#endif
|
||||
|
||||
/**
|
||||
\brief STR Exclusive (8 bit)
|
||||
\details Executes a exclusive STR instruction for 8 bit values.
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
|
||||
#define __STREXB(value, ptr) __strex(value, ptr)
|
||||
#else
|
||||
#define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
|
||||
#endif
|
||||
|
||||
/**
|
||||
\brief STR Exclusive (16 bit)
|
||||
\details Executes a exclusive STR instruction for 16 bit values.
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
|
||||
#define __STREXH(value, ptr) __strex(value, ptr)
|
||||
#else
|
||||
#define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
|
||||
#endif
|
||||
|
||||
/**
|
||||
\brief STR Exclusive (32 bit)
|
||||
\details Executes a exclusive STR instruction for 32 bit values.
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020)
|
||||
#define __STREXW(value, ptr) __strex(value, ptr)
|
||||
#else
|
||||
#define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop")
|
||||
#endif
|
||||
|
||||
/**
|
||||
\brief Remove the exclusive lock
|
||||
\details Removes the exclusive lock which is created by LDREX.
|
||||
*/
|
||||
#define __CLREX __clrex
|
||||
|
||||
|
||||
/**
|
||||
\brief Signed Saturate
|
||||
\details Saturates a signed value.
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (1..32)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __SSAT __ssat
|
||||
|
||||
/**
|
||||
\brief Unsigned Saturate
|
||||
\details Saturates an unsigned value.
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (0..31)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __USAT __usat
|
||||
|
||||
/* ########################### Core Function Access ########################### */
|
||||
|
||||
/**
|
||||
\brief Get FPSCR (Floating Point Status/Control)
|
||||
\return Floating Point Status/Control register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_FPSCR(void)
|
||||
{
|
||||
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
|
||||
register uint32_t __regfpscr __ASM("fpscr");
|
||||
return(__regfpscr);
|
||||
#else
|
||||
return(0U);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Set FPSCR (Floating Point Status/Control)
|
||||
\param [in] fpscr Floating Point Status/Control value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
|
||||
{
|
||||
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
|
||||
register uint32_t __regfpscr __ASM("fpscr");
|
||||
__regfpscr = (fpscr);
|
||||
#else
|
||||
(void)fpscr;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** \brief Get CPSR (Current Program Status Register)
|
||||
\return CPSR Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_CPSR(void)
|
||||
|
@ -219,7 +339,7 @@ __STATIC_INLINE uint32_t __get_CPSR(void)
|
|||
}
|
||||
|
||||
|
||||
/** \brief Set CPSR Register
|
||||
/** \brief Set CPSR (Current Program Status Register)
|
||||
\param [in] cpsr CPSR value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_CPSR(uint32_t cpsr)
|
||||
|
@ -244,7 +364,16 @@ __STATIC_INLINE __ASM void __set_mode(uint32_t mode) {
|
|||
BX r1
|
||||
}
|
||||
|
||||
/** \brief Set Stack Pointer
|
||||
/** \brief Get Stack Pointer
|
||||
\return Stack Pointer
|
||||
*/
|
||||
__STATIC_INLINE __ASM uint32_t __get_SP(void)
|
||||
{
|
||||
MOV r0, sp
|
||||
BX lr
|
||||
}
|
||||
|
||||
/** \brief Set Stack Pointer
|
||||
\param [in] stack Stack Pointer value to set
|
||||
*/
|
||||
__STATIC_INLINE __ASM void __set_SP(uint32_t stack)
|
||||
|
@ -253,15 +382,31 @@ __STATIC_INLINE __ASM void __set_SP(uint32_t stack)
|
|||
BX lr
|
||||
}
|
||||
|
||||
/** \brief Set Process Stack Pointer
|
||||
\param [in] topOfProcStack USR/SYS Stack Pointer value to set
|
||||
|
||||
/** \brief Get USR/SYS Stack Pointer
|
||||
\return USR/SYSStack Pointer
|
||||
*/
|
||||
__STATIC_INLINE __ASM void __set_PSP(uint32_t topOfProcStack)
|
||||
__STATIC_INLINE __ASM uint32_t __get_SP_usr(void)
|
||||
{
|
||||
ARM
|
||||
PRESERVE8
|
||||
|
||||
MRS R1, CPSR
|
||||
CPS #0x1F ;no effect in USR mode
|
||||
MOV R0, SP
|
||||
MSR CPSR_c, R1 ;no effect in USR mode
|
||||
ISB
|
||||
BX LR
|
||||
}
|
||||
|
||||
/** \brief Set USR/SYS Stack Pointer
|
||||
\param [in] topOfProcStack USR/SYS Stack Pointer value to set
|
||||
*/
|
||||
__STATIC_INLINE __ASM void __set_SP_usr(uint32_t topOfProcStack)
|
||||
{
|
||||
ARM
|
||||
PRESERVE8
|
||||
|
||||
BIC R0, R0, #7 ;ensure stack is 8-byte aligned
|
||||
MRS R1, CPSR
|
||||
CPS #0x1F ;no effect in USR mode
|
||||
MOV SP, R0
|
||||
|
@ -270,18 +415,8 @@ __STATIC_INLINE __ASM void __set_PSP(uint32_t topOfProcStack)
|
|||
BX LR
|
||||
}
|
||||
|
||||
/** \brief Set User Mode
|
||||
*/
|
||||
__STATIC_INLINE __ASM void __set_CPS_USR(void)
|
||||
{
|
||||
ARM
|
||||
|
||||
CPS #0x10
|
||||
BX LR
|
||||
}
|
||||
|
||||
/** \brief Get FPEXC
|
||||
\return Floating Point Exception Control register value
|
||||
/** \brief Get FPEXC (Floating Point Exception Control Register)
|
||||
\return Floating Point Exception Control Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_FPEXC(void)
|
||||
{
|
||||
|
@ -293,7 +428,7 @@ __STATIC_INLINE uint32_t __get_FPEXC(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
/** \brief Set FPEXC
|
||||
/** \brief Set FPEXC (Floating Point Exception Control Register)
|
||||
\param [in] fpexc Floating Point Exception Control value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_FPEXC(uint32_t fpexc)
|
||||
|
@ -304,243 +439,18 @@ __STATIC_INLINE void __set_FPEXC(uint32_t fpexc)
|
|||
#endif
|
||||
}
|
||||
|
||||
/** \brief Get CPACR
|
||||
\return Coprocessor Access Control register value
|
||||
/*
|
||||
* Include common core functions to access Coprocessor 15 registers
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_CPACR(void)
|
||||
{
|
||||
register uint32_t __regCPACR __ASM("cp15:0:c1:c0:2");
|
||||
return __regCPACR;
|
||||
}
|
||||
|
||||
#define __get_CP(cp, op1, Rt, CRn, CRm, op2) do { register uint32_t tmp __ASM("cp" # cp ":" # op1 ":c" # CRn ":c" # CRm ":" # op2); Rt = tmp; } while(0)
|
||||
#define __set_CP(cp, op1, Rt, CRn, CRm, op2) do { register uint32_t tmp __ASM("cp" # cp ":" # op1 ":c" # CRn ":c" # CRm ":" # op2); tmp = Rt; } while(0)
|
||||
|
||||
/** \brief Set CPACR
|
||||
\param [in] cpacr Coprocessor Acccess Control value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_CPACR(uint32_t cpacr)
|
||||
{
|
||||
register uint32_t __regCPACR __ASM("cp15:0:c1:c0:2");
|
||||
__regCPACR = cpacr;
|
||||
}
|
||||
|
||||
/** \brief Get CBAR
|
||||
\return Configuration Base Address register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_CBAR() {
|
||||
register uint32_t __regCBAR __ASM("cp15:4:c15:c0:0");
|
||||
return(__regCBAR);
|
||||
}
|
||||
|
||||
/** \brief Get TTBR0
|
||||
|
||||
This function returns the value of the Translation Table Base Register 0.
|
||||
|
||||
\return Translation Table Base Register 0 value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_TTBR0() {
|
||||
register uint32_t __regTTBR0 __ASM("cp15:0:c2:c0:0");
|
||||
return(__regTTBR0);
|
||||
}
|
||||
|
||||
/** \brief Set TTBR0
|
||||
|
||||
This function assigns the given value to the Translation Table Base Register 0.
|
||||
|
||||
\param [in] ttbr0 Translation Table Base Register 0 value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_TTBR0(uint32_t ttbr0) {
|
||||
register uint32_t __regTTBR0 __ASM("cp15:0:c2:c0:0");
|
||||
__regTTBR0 = ttbr0;
|
||||
}
|
||||
|
||||
/** \brief Get DACR
|
||||
|
||||
This function returns the value of the Domain Access Control Register.
|
||||
|
||||
\return Domain Access Control Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_DACR() {
|
||||
register uint32_t __regDACR __ASM("cp15:0:c3:c0:0");
|
||||
return(__regDACR);
|
||||
}
|
||||
|
||||
/** \brief Set DACR
|
||||
|
||||
This function assigns the given value to the Domain Access Control Register.
|
||||
|
||||
\param [in] dacr Domain Access Control Register value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_DACR(uint32_t dacr) {
|
||||
register uint32_t __regDACR __ASM("cp15:0:c3:c0:0");
|
||||
__regDACR = dacr;
|
||||
}
|
||||
|
||||
/** \brief Set SCTLR
|
||||
|
||||
This function assigns the given value to the System Control Register.
|
||||
|
||||
\param [in] sctlr System Control Register value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_SCTLR(uint32_t sctlr)
|
||||
{
|
||||
register uint32_t __regSCTLR __ASM("cp15:0:c1:c0:0");
|
||||
__regSCTLR = sctlr;
|
||||
}
|
||||
|
||||
/** \brief Get SCTLR
|
||||
\return System Control Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_SCTLR() {
|
||||
register uint32_t __regSCTLR __ASM("cp15:0:c1:c0:0");
|
||||
return(__regSCTLR);
|
||||
}
|
||||
|
||||
/** \brief Set ACTRL
|
||||
\param [in] actrl Auxiliary Control Register value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_ACTRL(uint32_t actrl)
|
||||
{
|
||||
register uint32_t __regACTRL __ASM("cp15:0:c1:c0:1");
|
||||
__regACTRL = actrl;
|
||||
}
|
||||
|
||||
/** \brief Get ACTRL
|
||||
\return Auxiliary Control Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_ACTRL(void)
|
||||
{
|
||||
register uint32_t __regACTRL __ASM("cp15:0:c1:c0:1");
|
||||
return(__regACTRL);
|
||||
}
|
||||
|
||||
/** \brief Get MPIDR
|
||||
|
||||
This function returns the value of the Multiprocessor Affinity Register.
|
||||
|
||||
\return Multiprocessor Affinity Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_MPIDR(void)
|
||||
{
|
||||
register uint32_t __regMPIDR __ASM("cp15:0:c0:c0:5");
|
||||
return(__regMPIDR);
|
||||
}
|
||||
|
||||
/** \brief Get VBAR
|
||||
|
||||
This function returns the value of the Vector Base Address Register.
|
||||
|
||||
\return Vector Base Address Register
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_VBAR(void)
|
||||
{
|
||||
register uint32_t __regVBAR __ASM("cp15:0:c12:c0:0");
|
||||
return(__regVBAR);
|
||||
}
|
||||
|
||||
/** \brief Set VBAR
|
||||
|
||||
This function assigns the given value to the Vector Base Address Register.
|
||||
|
||||
\param [in] vbar Vector Base Address Register value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_VBAR(uint32_t vbar)
|
||||
{
|
||||
register uint32_t __regVBAR __ASM("cp15:0:c12:c0:0");
|
||||
__regVBAR = vbar;
|
||||
}
|
||||
|
||||
/** \brief Set CNTP_TVAL
|
||||
|
||||
This function assigns the given value to PL1 Physical Timer Value Register (CNTP_TVAL).
|
||||
|
||||
\param [in] value CNTP_TVAL Register value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_CNTP_TVAL(uint32_t value) {
|
||||
register uint32_t __regCNTP_TVAL __ASM("cp15:0:c14:c2:0");
|
||||
__regCNTP_TVAL = value;
|
||||
}
|
||||
|
||||
/** \brief Get CNTP_TVAL
|
||||
|
||||
This function returns the value of the PL1 Physical Timer Value Register (CNTP_TVAL).
|
||||
|
||||
\return CNTP_TVAL Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_CNTP_TVAL() {
|
||||
register uint32_t __regCNTP_TVAL __ASM("cp15:0:c14:c2:0");
|
||||
return(__regCNTP_TVAL);
|
||||
}
|
||||
|
||||
/** \brief Set CNTP_CTL
|
||||
|
||||
This function assigns the given value to PL1 Physical Timer Control Register (CNTP_CTL).
|
||||
|
||||
\param [in] value CNTP_CTL Register value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_CNTP_CTL(uint32_t value) {
|
||||
register uint32_t __regCNTP_CTL __ASM("cp15:0:c14:c2:1");
|
||||
__regCNTP_CTL = value;
|
||||
}
|
||||
|
||||
/** \brief Set TLBIALL
|
||||
|
||||
TLB Invalidate All
|
||||
*/
|
||||
__STATIC_INLINE void __set_TLBIALL(uint32_t value) {
|
||||
register uint32_t __TLBIALL __ASM("cp15:0:c8:c7:0");
|
||||
__TLBIALL = value;
|
||||
}
|
||||
|
||||
/** \brief Set BPIALL.
|
||||
|
||||
Branch Predictor Invalidate All
|
||||
*/
|
||||
__STATIC_INLINE void __set_BPIALL(uint32_t value) {
|
||||
register uint32_t __BPIALL __ASM("cp15:0:c7:c5:6");
|
||||
__BPIALL = value;
|
||||
}
|
||||
|
||||
/** \brief Set ICIALLU
|
||||
|
||||
Instruction Cache Invalidate All
|
||||
*/
|
||||
__STATIC_INLINE void __set_ICIALLU(uint32_t value) {
|
||||
register uint32_t __ICIALLU __ASM("cp15:0:c7:c5:0");
|
||||
__ICIALLU = value;
|
||||
}
|
||||
|
||||
/** \brief Set DCCMVAC
|
||||
|
||||
Data cache clean
|
||||
*/
|
||||
__STATIC_INLINE void __set_DCCMVAC(uint32_t value) {
|
||||
register uint32_t __DCCMVAC __ASM("cp15:0:c7:c10:1");
|
||||
__DCCMVAC = value;
|
||||
}
|
||||
|
||||
/** \brief Set DCIMVAC
|
||||
|
||||
Data cache invalidate
|
||||
*/
|
||||
__STATIC_INLINE void __set_DCIMVAC(uint32_t value) {
|
||||
register uint32_t __DCIMVAC __ASM("cp15:0:c7:c6:1");
|
||||
__DCIMVAC = value;
|
||||
}
|
||||
|
||||
/** \brief Set DCCIMVAC
|
||||
|
||||
Data cache clean and invalidate
|
||||
*/
|
||||
__STATIC_INLINE void __set_DCCIMVAC(uint32_t value) {
|
||||
register uint32_t __DCCIMVAC __ASM("cp15:0:c7:c14:1");
|
||||
__DCCIMVAC = value;
|
||||
}
|
||||
#include "cmsis_cp15.h"
|
||||
|
||||
/** \brief Clean and Invalidate the entire data or unified cache
|
||||
|
||||
Generic mechanism for cleaning/invalidating the entire data or unified cache to the point of coherency
|
||||
* \param [in] op 0 - invalidate, 1 - clean, otherwise - invalidate and clean
|
||||
*/
|
||||
#pragma push
|
||||
#pragma arm
|
||||
__STATIC_INLINE __ASM void __L1C_CleanInvalidateCache(uint32_t op) {
|
||||
ARM
|
||||
|
||||
|
@ -595,14 +505,11 @@ Finished
|
|||
POP {R4-R11}
|
||||
BX lr
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
/** \brief Enable Floating Point Unit
|
||||
|
||||
Critical section, called from undef handler, so systick is disabled
|
||||
*/
|
||||
#pragma push
|
||||
#pragma arm
|
||||
__STATIC_INLINE __ASM void __FPU_Enable(void) {
|
||||
ARM
|
||||
|
||||
|
@ -668,6 +575,5 @@ __STATIC_INLINE __ASM void __FPU_Enable(void) {
|
|||
|
||||
BX LR
|
||||
}
|
||||
#pragma pop
|
||||
|
||||
#endif /* __CMSIS_ARMCC_H */
|
|
@ -1,8 +1,8 @@
|
|||
/**************************************************************************//**
|
||||
* @file cmsis_armclang.h
|
||||
* @brief CMSIS compiler specific macros, functions, instructions
|
||||
* @version V1.00
|
||||
* @date 05. Apr 2017
|
||||
* @version V1.0.1
|
||||
* @date 07. Sep 2017
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2017 ARM Limited. All rights reserved.
|
||||
|
@ -31,68 +31,72 @@
|
|||
|
||||
/* CMSIS compiler specific defines */
|
||||
#ifndef __ASM
|
||||
#define __ASM __asm
|
||||
#endif
|
||||
#ifndef __INLINE
|
||||
#define __INLINE __inline
|
||||
#endif
|
||||
#ifndef __STATIC_INLINE
|
||||
#define __STATIC_INLINE static __inline
|
||||
#endif
|
||||
#ifndef __STATIC_ASM
|
||||
#define __STATIC_ASM static __asm
|
||||
#endif
|
||||
#ifndef __NO_RETURN
|
||||
#define __NO_RETURN __declspec(noreturn)
|
||||
#endif
|
||||
#ifndef __USED
|
||||
#define __USED __attribute__((used))
|
||||
#endif
|
||||
#ifndef __WEAK
|
||||
#define __WEAK __attribute__((weak))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32
|
||||
#define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x)))
|
||||
#endif
|
||||
#ifndef __ALIGNED
|
||||
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||
#define __ASM __asm
|
||||
#endif
|
||||
#ifndef __INLINE
|
||||
#define __INLINE __inline
|
||||
#endif
|
||||
#ifndef __FORCEINLINE
|
||||
#define __FORCEINLINE __attribute__((always_inline))
|
||||
#endif
|
||||
#ifndef __STATIC_INLINE
|
||||
#define __STATIC_INLINE static __inline
|
||||
#endif
|
||||
#ifndef __STATIC_FORCEINLINE
|
||||
#define __STATIC_FORCEINLINE __attribute__((always_inline)) static __inline
|
||||
#endif
|
||||
#ifndef __NO_RETURN
|
||||
#define __NO_RETURN __declspec(noreturn)
|
||||
#endif
|
||||
#ifndef __USED
|
||||
#define __USED __attribute__((used))
|
||||
#endif
|
||||
#ifndef __WEAK
|
||||
#define __WEAK __attribute__((weak))
|
||||
#endif
|
||||
#ifndef __PACKED
|
||||
#define __PACKED __attribute__((packed))
|
||||
#define __PACKED __attribute__((packed, aligned(1)))
|
||||
#endif
|
||||
|
||||
|
||||
/* ########################### Core Function Access ########################### */
|
||||
|
||||
/**
|
||||
\brief Get FPSCR
|
||||
\return Floating Point Status/Control register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_FPSCR(void)
|
||||
{
|
||||
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
|
||||
uint32_t result;
|
||||
__ASM volatile("MRS %0, fpscr" : "=r" (result) );
|
||||
return(result);
|
||||
#else
|
||||
return(0U);
|
||||
#ifndef __PACKED_STRUCT
|
||||
#define __PACKED_STRUCT struct __attribute__((packed, aligned(1)))
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Set FPSCR
|
||||
\param [in] fpscr Floating Point Status/Control value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
|
||||
{
|
||||
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
|
||||
__ASM volatile ("MSR fpscr, %0" : : "r" (fpscr) : "memory");
|
||||
#else
|
||||
(void)fpscr;
|
||||
#ifndef __UNALIGNED_UINT16_WRITE
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wpacked"
|
||||
/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */
|
||||
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
|
||||
#pragma clang diagnostic pop
|
||||
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT16_READ
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wpacked"
|
||||
/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */
|
||||
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
|
||||
#pragma clang diagnostic pop
|
||||
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_WRITE
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wpacked"
|
||||
/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */
|
||||
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
|
||||
#pragma clang diagnostic pop
|
||||
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_READ
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wpacked"
|
||||
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
|
||||
#pragma clang diagnostic pop
|
||||
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
|
||||
#endif
|
||||
#ifndef __ALIGNED
|
||||
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||
#endif
|
||||
#ifndef __PACKED
|
||||
#define __PACKED __attribute__((packed))
|
||||
#endif
|
||||
}
|
||||
|
||||
/* ########################## Core Instruction Access ######################### */
|
||||
/**
|
||||
|
@ -210,69 +214,194 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint
|
|||
*/
|
||||
#define __CLZ __builtin_clz
|
||||
|
||||
/**
|
||||
\brief LDR Exclusive (8 bit)
|
||||
\details Executes a exclusive LDR instruction for 8 bit value.
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint8_t at (*ptr)
|
||||
*/
|
||||
#define __LDREXB (uint8_t)__builtin_arm_ldrex
|
||||
|
||||
|
||||
/**
|
||||
\brief LDR Exclusive (16 bit)
|
||||
\details Executes a exclusive LDR instruction for 16 bit values.
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint16_t at (*ptr)
|
||||
*/
|
||||
#define __LDREXH (uint16_t)__builtin_arm_ldrex
|
||||
|
||||
/**
|
||||
\brief LDR Exclusive (32 bit)
|
||||
\details Executes a exclusive LDR instruction for 32 bit values.
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint32_t at (*ptr)
|
||||
*/
|
||||
#define __LDREXW (uint32_t)__builtin_arm_ldrex
|
||||
|
||||
/**
|
||||
\brief STR Exclusive (8 bit)
|
||||
\details Executes a exclusive STR instruction for 8 bit values.
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
#define __STREXB (uint32_t)__builtin_arm_strex
|
||||
|
||||
/**
|
||||
\brief STR Exclusive (16 bit)
|
||||
\details Executes a exclusive STR instruction for 16 bit values.
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
#define __STREXH (uint32_t)__builtin_arm_strex
|
||||
|
||||
/**
|
||||
\brief STR Exclusive (32 bit)
|
||||
\details Executes a exclusive STR instruction for 32 bit values.
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
#define __STREXW (uint32_t)__builtin_arm_strex
|
||||
|
||||
/**
|
||||
\brief Remove the exclusive lock
|
||||
\details Removes the exclusive lock which is created by LDREX.
|
||||
*/
|
||||
#define __CLREX __builtin_arm_clrex
|
||||
|
||||
/**
|
||||
\brief Signed Saturate
|
||||
\details Saturates a signed value.
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (1..32)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __SSAT __builtin_arm_ssat
|
||||
|
||||
/**
|
||||
\brief Unsigned Saturate
|
||||
\details Saturates an unsigned value.
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (0..31)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __USAT __builtin_arm_usat
|
||||
|
||||
|
||||
/* ########################### Core Function Access ########################### */
|
||||
|
||||
/**
|
||||
\brief Get FPSCR
|
||||
\details Returns the current value of the Floating Point Status/Control register.
|
||||
\return Floating Point Status/Control register value
|
||||
*/
|
||||
#define __get_FPSCR __builtin_arm_get_fpscr
|
||||
|
||||
/**
|
||||
\brief Set FPSCR
|
||||
\details Assigns the given value to the Floating Point Status/Control register.
|
||||
\param [in] fpscr Floating Point Status/Control value to set
|
||||
*/
|
||||
#define __set_FPSCR __builtin_arm_set_fpscr
|
||||
|
||||
/** \brief Get CPSR Register
|
||||
\return CPSR Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_CPSR(void)
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_CPSR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
__ASM volatile("MRS %0, cpsr" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
/** \brief Set CPSR Register
|
||||
\param [in] cpsr CPSR value to set
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE void __set_CPSR(uint32_t cpsr)
|
||||
{
|
||||
__ASM volatile ("MSR cpsr, %0" : : "r" (cpsr) : "memory");
|
||||
}
|
||||
|
||||
/** \brief Get Mode
|
||||
\return Processor Mode
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_mode(void) {
|
||||
return (__get_CPSR() & 0x1FU);
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_mode(void)
|
||||
{
|
||||
return (__get_CPSR() & 0x1FU);
|
||||
}
|
||||
|
||||
/** \brief Set Mode
|
||||
\param [in] mode Mode value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_mode(uint32_t mode) {
|
||||
__attribute__((always_inline)) __STATIC_INLINE void __set_mode(uint32_t mode)
|
||||
{
|
||||
__ASM volatile("MSR cpsr_c, %0" : : "r" (mode) : "memory");
|
||||
}
|
||||
|
||||
/** \brief Get Stack Pointer
|
||||
\return Stack Pointer value
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_SP()
|
||||
{
|
||||
uint32_t result;
|
||||
__ASM volatile("MOV %0, sp" : "=r" (result) : : "memory");
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Set Stack Pointer
|
||||
\param [in] stack Stack Pointer value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_SP(uint32_t stack)
|
||||
__attribute__((always_inline)) __STATIC_INLINE void __set_SP(uint32_t stack)
|
||||
{
|
||||
__ASM volatile("MOV sp, %0" : : "r" (stack) : "memory");
|
||||
}
|
||||
|
||||
/** \brief Set Process Stack Pointer
|
||||
\param [in] topOfProcStack USR/SYS Stack Pointer value to set
|
||||
/** \brief Get USR/SYS Stack Pointer
|
||||
\return USR/SYS Stack Pointer value
|
||||
*/
|
||||
__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_SP_usr()
|
||||
{
|
||||
uint32_t cpsr;
|
||||
uint32_t result;
|
||||
__ASM volatile(
|
||||
".preserve8 \n"
|
||||
"BIC r0, r0, #7 \n" // ensure stack is 8-byte aligned
|
||||
"MRS r1, cpsr \n"
|
||||
"MRS %0, cpsr \n"
|
||||
"CPS #0x1F \n" // no effect in USR mode
|
||||
"MOV sp, r0 \n"
|
||||
"MSR cpsr_c, r1 \n" // no effect in USR mode
|
||||
"ISB"
|
||||
"MOV %1, sp \n"
|
||||
"MSR cpsr_c, %2 \n" // no effect in USR mode
|
||||
"ISB" : "=r"(cpsr), "=r"(result) : "r"(cpsr) : "memory"
|
||||
);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Set User Mode
|
||||
/** \brief Set USR/SYS Stack Pointer
|
||||
\param [in] topOfProcStack USR/SYS Stack Pointer value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_CPS_USR(void)
|
||||
__attribute__((always_inline)) __STATIC_INLINE void __set_SP_usr(uint32_t topOfProcStack)
|
||||
{
|
||||
__ASM volatile("CPS #0x10");
|
||||
uint32_t cpsr;
|
||||
__ASM volatile(
|
||||
"MRS %0, cpsr \n"
|
||||
"CPS #0x1F \n" // no effect in USR mode
|
||||
"MOV sp, %1 \n"
|
||||
"MSR cpsr_c, %2 \n" // no effect in USR mode
|
||||
"ISB" : "=r"(cpsr) : "r" (topOfProcStack), "r"(cpsr) : "memory"
|
||||
);
|
||||
}
|
||||
|
||||
/** \brief Get FPEXC
|
||||
\return Floating Point Exception Control register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_FPEXC(void)
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_FPEXC(void)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1)
|
||||
uint32_t result;
|
||||
__ASM volatile("MRS %0, fpexc" : "=r" (result) );
|
||||
__ASM volatile("VMRS %0, fpexc" : "=r" (result) : : "memory");
|
||||
return(result);
|
||||
#else
|
||||
return(0);
|
||||
|
@ -282,244 +411,29 @@ __STATIC_INLINE uint32_t __get_FPEXC(void)
|
|||
/** \brief Set FPEXC
|
||||
\param [in] fpexc Floating Point Exception Control value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_FPEXC(uint32_t fpexc)
|
||||
__attribute__((always_inline)) __STATIC_INLINE void __set_FPEXC(uint32_t fpexc)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1)
|
||||
__ASM volatile ("MSR fpexc, %0" : : "r" (fpexc) : "memory");
|
||||
__ASM volatile ("VMSR fpexc, %0" : : "r" (fpexc) : "memory");
|
||||
#endif
|
||||
}
|
||||
|
||||
/** \brief Get CPACR
|
||||
\return Coprocessor Access Control register value
|
||||
/*
|
||||
* Include common core functions to access Coprocessor 15 registers
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_CPACR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
__ASM volatile("MRC p15, 0, %0, c1, c0, 2" : "=r"(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Set CPACR
|
||||
\param [in] cpacr Coprocessor Acccess Control value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_CPACR(uint32_t cpacr)
|
||||
{
|
||||
__ASM volatile("MCR p15, 0, %0, c1, c0, 2" : : "r"(cpacr) : "memory");
|
||||
}
|
||||
#define __get_CP(cp, op1, Rt, CRn, CRm, op2) __ASM volatile("MRC p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : "=r" (Rt) : : "memory" )
|
||||
#define __set_CP(cp, op1, Rt, CRn, CRm, op2) __ASM volatile("MCR p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : : "r" (Rt) : "memory" )
|
||||
|
||||
/** \brief Get CBAR
|
||||
\return Configuration Base Address register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_CBAR() {
|
||||
uint32_t result;
|
||||
__ASM volatile("MRC p15, 4, %0, c15, c0, 0" : "=r"(result));
|
||||
return result;
|
||||
}
|
||||
#include "cmsis_cp15.h"
|
||||
|
||||
/** \brief Get TTBR0
|
||||
|
||||
This function returns the value of the Translation Table Base Register 0.
|
||||
|
||||
\return Translation Table Base Register 0 value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_TTBR0() {
|
||||
uint32_t result;
|
||||
__ASM volatile("MRC p15, 0, %0, c2, c0, 0" : "=r"(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Set TTBR0
|
||||
|
||||
This function assigns the given value to the Translation Table Base Register 0.
|
||||
|
||||
\param [in] ttbr0 Translation Table Base Register 0 value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_TTBR0(uint32_t ttbr0) {
|
||||
__ASM volatile("MCR p15, 0, %0, c2, c0, 0" : : "r"(ttbr0) : "memory");
|
||||
}
|
||||
|
||||
/** \brief Get DACR
|
||||
|
||||
This function returns the value of the Domain Access Control Register.
|
||||
|
||||
\return Domain Access Control Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_DACR() {
|
||||
uint32_t result;
|
||||
__ASM volatile("MRC p15, 0, %0, c3, c0, 0" : "=r"(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Set DACR
|
||||
|
||||
This function assigns the given value to the Domain Access Control Register.
|
||||
|
||||
\param [in] dacr Domain Access Control Register value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_DACR(uint32_t dacr) {
|
||||
__ASM volatile("MCR p15, 0, %0, c3, c0, 0" : : "r"(dacr) : "memory");
|
||||
}
|
||||
|
||||
/** \brief Set SCTLR
|
||||
|
||||
This function assigns the given value to the System Control Register.
|
||||
|
||||
\param [in] sctlr System Control Register value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_SCTLR(uint32_t sctlr)
|
||||
{
|
||||
__ASM volatile("MCR p15, 0, %0, c1, c0, 0" : : "r"(sctlr) : "memory");
|
||||
}
|
||||
|
||||
/** \brief Get SCTLR
|
||||
\return System Control Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_SCTLR() {
|
||||
uint32_t result;
|
||||
__ASM volatile("MRC p15, 0, %0, c1, c0, 0" : "=r"(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Set ACTRL
|
||||
\param [in] actrl Auxiliary Control Register value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_ACTRL(uint32_t actrl)
|
||||
{
|
||||
__ASM volatile("MCR p15, 0, %0, c1, c0, 1" : : "r"(actrl) : "memory");
|
||||
}
|
||||
|
||||
/** \brief Get ACTRL
|
||||
\return Auxiliary Control Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_ACTRL(void)
|
||||
{
|
||||
uint32_t result;
|
||||
__ASM volatile("MRC p15, 0, %0, c1, c0, 1" : "=r"(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Get MPIDR
|
||||
|
||||
This function returns the value of the Multiprocessor Affinity Register.
|
||||
|
||||
\return Multiprocessor Affinity Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_MPIDR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
__ASM volatile("MRC p15, 0, %0, c0, c0, 5" : "=r"(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Get VBAR
|
||||
|
||||
This function returns the value of the Vector Base Address Register.
|
||||
|
||||
\return Vector Base Address Register
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_VBAR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
__ASM volatile("MRC p15, 0, %0, c12, c0, 0" : "=r"(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Set VBAR
|
||||
|
||||
This function assigns the given value to the Vector Base Address Register.
|
||||
|
||||
\param [in] vbar Vector Base Address Register value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_VBAR(uint32_t vbar)
|
||||
{
|
||||
__ASM volatile("MCR p15, 0, %0, c12, c0, 1" : : "r"(vbar) : "memory");
|
||||
}
|
||||
|
||||
/** \brief Set CNTP_TVAL
|
||||
|
||||
This function assigns the given value to PL1 Physical Timer Value Register (CNTP_TVAL).
|
||||
|
||||
\param [in] value CNTP_TVAL Register value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_CNTP_TVAL(uint32_t value) {
|
||||
__ASM volatile("MCR p15, 0, %0, c14, c2, 0" : : "r"(value) : "memory");
|
||||
}
|
||||
|
||||
/** \brief Get CNTP_TVAL
|
||||
|
||||
This function returns the value of the PL1 Physical Timer Value Register (CNTP_TVAL).
|
||||
|
||||
\return CNTP_TVAL Register value
|
||||
*/
|
||||
__STATIC_INLINE uint32_t __get_CNTP_TVAL() {
|
||||
uint32_t result;
|
||||
__ASM volatile("MRC p15, 0, %0, c14, c2, 0" : "=r"(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Set CNTP_CTL
|
||||
|
||||
This function assigns the given value to PL1 Physical Timer Control Register (CNTP_CTL).
|
||||
|
||||
\param [in] value CNTP_CTL Register value to set
|
||||
*/
|
||||
__STATIC_INLINE void __set_CNTP_CTL(uint32_t value) {
|
||||
__ASM volatile("MCR p15, 0, %0, c14, c2, 1" : : "r"(value) : "memory");
|
||||
}
|
||||
|
||||
/** \brief Set TLBIALL
|
||||
|
||||
TLB Invalidate All
|
||||
*/
|
||||
__STATIC_INLINE void __set_TLBIALL(uint32_t value) {
|
||||
__ASM volatile("MCR p15, 0, %0, c8, c7, 0" : : "r"(value) : "memory");
|
||||
}
|
||||
|
||||
/** \brief Set BPIALL.
|
||||
|
||||
Branch Predictor Invalidate All
|
||||
*/
|
||||
__STATIC_INLINE void __set_BPIALL(uint32_t value) {
|
||||
__ASM volatile("MCR p15, 0, %0, c7, c5, 6" : : "r"(value) : "memory");
|
||||
}
|
||||
|
||||
/** \brief Set ICIALLU
|
||||
|
||||
Instruction Cache Invalidate All
|
||||
*/
|
||||
__STATIC_INLINE void __set_ICIALLU(uint32_t value) {
|
||||
__ASM volatile("MCR p15, 0, %0, c7, c5, 0" : : "r"(value) : "memory");
|
||||
}
|
||||
|
||||
/** \brief Set DCCMVAC
|
||||
|
||||
Data cache clean
|
||||
*/
|
||||
__STATIC_INLINE void __set_DCCMVAC(uint32_t value) {
|
||||
__ASM volatile("MCR p15, 0, %0, c7, c10, 1" : : "r"(value) : "memory");
|
||||
}
|
||||
|
||||
/** \brief Set DCIMVAC
|
||||
|
||||
Data cache invalidate
|
||||
*/
|
||||
__STATIC_INLINE void __set_DCIMVAC(uint32_t value) {
|
||||
__ASM volatile("MCR p15, 0, %0, c7, c6, 1" : : "r"(value) : "memory");
|
||||
}
|
||||
|
||||
/** \brief Set DCCIMVAC
|
||||
|
||||
Data cache clean and invalidate
|
||||
*/
|
||||
__STATIC_INLINE void __set_DCCIMVAC(uint32_t value) {
|
||||
__ASM volatile("MCR p15, 0, %0, c7, c14, 1" : : "r"(value) : "memory");
|
||||
}
|
||||
|
||||
/** \brief Clean and Invalidate the entire data or unified cache
|
||||
|
||||
Generic mechanism for cleaning/invalidating the entire data or unified cache to the point of coherency
|
||||
*/
|
||||
__STATIC_INLINE void __L1C_CleanInvalidateCache(uint32_t op) {
|
||||
__STATIC_INLINE void __L1C_CleanInvalidateCache(uint32_t op)
|
||||
{
|
||||
__ASM volatile(
|
||||
" PUSH {R4-R11} \n"
|
||||
|
||||
|
@ -577,26 +491,27 @@ __STATIC_INLINE void __L1C_CleanInvalidateCache(uint32_t op) {
|
|||
|
||||
Critical section, called from undef handler, so systick is disabled
|
||||
*/
|
||||
__STATIC_INLINE void __FPU_Enable(void) {
|
||||
__STATIC_INLINE void __FPU_Enable(void)
|
||||
{
|
||||
__ASM volatile(
|
||||
//Permit access to VFP/NEON, registers by modifying CPACR
|
||||
//Permit access to VFP/NEON, registers by modifying CPACR
|
||||
" MRC p15,0,R1,c1,c0,2 \n"
|
||||
" ORR R1,R1,#0x00F00000 \n"
|
||||
" MCR p15,0,R1,c1,c0,2 \n"
|
||||
|
||||
//Ensure that subsequent instructions occur in the context of VFP/NEON access permitted
|
||||
//Ensure that subsequent instructions occur in the context of VFP/NEON access permitted
|
||||
" ISB \n"
|
||||
|
||||
//Enable VFP/NEON
|
||||
//Enable VFP/NEON
|
||||
" VMRS R1,FPEXC \n"
|
||||
" ORR R1,R1,#0x40000000 \n"
|
||||
" VMSR FPEXC,R1 \n"
|
||||
|
||||
//Initialise VFP/NEON registers to 0
|
||||
//Initialise VFP/NEON registers to 0
|
||||
" MOV R2,#0 \n"
|
||||
#if 0 // TODO: Initialize FPU registers according to available register count
|
||||
".if {TARGET_FEATURE_EXTENSION_REGISTER_COUNT} >= 16 \n"
|
||||
//Initialise D16 registers to 0
|
||||
|
||||
#if TARGET_FEATURE_EXTENSION_REGISTER_COUNT >= 16
|
||||
//Initialise D16 registers to 0
|
||||
" VMOV D0, R2,R2 \n"
|
||||
" VMOV D1, R2,R2 \n"
|
||||
" VMOV D2, R2,R2 \n"
|
||||
|
@ -613,10 +528,10 @@ __STATIC_INLINE void __FPU_Enable(void) {
|
|||
" VMOV D13,R2,R2 \n"
|
||||
" VMOV D14,R2,R2 \n"
|
||||
" VMOV D15,R2,R2 \n"
|
||||
".endif \n"
|
||||
#endif
|
||||
|
||||
".if {TARGET_FEATURE_EXTENSION_REGISTER_COUNT} == 32 \n"
|
||||
//Initialise D32 registers to 0
|
||||
#if TARGET_FEATURE_EXTENSION_REGISTER_COUNT == 32
|
||||
//Initialise D32 registers to 0
|
||||
" VMOV D16,R2,R2 \n"
|
||||
" VMOV D17,R2,R2 \n"
|
||||
" VMOV D18,R2,R2 \n"
|
||||
|
@ -635,7 +550,7 @@ __STATIC_INLINE void __FPU_Enable(void) {
|
|||
" VMOV D31,R2,R2 \n"
|
||||
".endif \n"
|
||||
#endif
|
||||
//Initialise FPSCR to a known state
|
||||
//Initialise FPSCR to a known state
|
||||
" VMRS R2,FPSCR \n"
|
||||
" LDR R3,=0x00086060 \n" //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero.
|
||||
" AND R2,R2,R3 \n"
|
||||
|
@ -643,4 +558,4 @@ __STATIC_INLINE void __FPU_Enable(void) {
|
|||
);
|
||||
}
|
||||
|
||||
#endif /* __CMSIS_ARMCC_H */
|
||||
#endif /* __CMSIS_ARMCLANG_H */
|
|
@ -52,41 +52,9 @@
|
|||
* IAR Compiler
|
||||
*/
|
||||
#elif defined ( __ICCARM__ )
|
||||
#include "cmsis_iccarm.h"
|
||||
|
||||
#ifndef __ASM
|
||||
#define __ASM __asm
|
||||
#endif
|
||||
#ifndef __INLINE
|
||||
#define __INLINE inline
|
||||
#endif
|
||||
#ifndef __STATIC_INLINE
|
||||
#define __STATIC_INLINE static inline
|
||||
#endif
|
||||
|
||||
#include <cmsis_iar.h>
|
||||
|
||||
#ifndef __NO_RETURN
|
||||
#define __NO_RETURN __noreturn
|
||||
#endif
|
||||
#ifndef __USED
|
||||
#define __USED __root
|
||||
#endif
|
||||
#ifndef __WEAK
|
||||
#define __WEAK __weak
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32
|
||||
__packed struct T_UINT32 { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
|
||||
#endif
|
||||
#ifndef __ALIGNED
|
||||
#warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored.
|
||||
#define __ALIGNED(x)
|
||||
#endif
|
||||
#ifndef __PACKED
|
||||
#define __PACKED __packed
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* TI ARM Compiler
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,437 @@
|
|||
/**************************************************************************//**
|
||||
* @file cmsis_cp15.h
|
||||
* @brief CMSIS compiler specific macros, functions, instructions
|
||||
* @version V1.0.1
|
||||
* @date 07. Sep 2017
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2017 ARM Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __CMSIS_CP15_H
|
||||
#define __CMSIS_CP15_H
|
||||
|
||||
/** \brief Get ACTLR
|
||||
\return Auxiliary Control register value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_ACTLR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
// __ASM volatile("MRC p15, 0, %0, c1, c0, 1" : "=r" (result) : : "memory" );
|
||||
__get_CP(15, 0, result, 1, 0, 1);
|
||||
return(result);
|
||||
}
|
||||
|
||||
/** \brief Set ACTLR
|
||||
\param [in] actlr Auxiliary Control value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_ACTLR(uint32_t actlr)
|
||||
{
|
||||
// __ASM volatile ("MCR p15, 0, %0, c1, c0, 1" : : "r" (actlr) : "memory");
|
||||
__set_CP(15, 0, actlr, 1, 0, 1);
|
||||
}
|
||||
|
||||
/** \brief Get CPACR
|
||||
\return Coprocessor Access Control register value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_CPACR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
// __ASM volatile("MRC p15, 0, %0, c1, c0, 2" : "=r"(result) : : "memory");
|
||||
__get_CP(15, 0, result, 1, 0, 2);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Set CPACR
|
||||
\param [in] cpacr Coprocessor Access Control value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_CPACR(uint32_t cpacr)
|
||||
{
|
||||
// __ASM volatile("MCR p15, 0, %0, c1, c0, 2" : : "r"(cpacr) : "memory");
|
||||
__set_CP(15, 0, cpacr, 1, 0, 2);
|
||||
}
|
||||
|
||||
/** \brief Get DFSR
|
||||
\return Data Fault Status Register value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_DFSR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
// __ASM volatile("MRC p15, 0, %0, c5, c0, 0" : "=r"(result) : : "memory");
|
||||
__get_CP(15, 0, result, 5, 0, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Set DFSR
|
||||
\param [in] dfsr Data Fault Status value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_DFSR(uint32_t dfsr)
|
||||
{
|
||||
// __ASM volatile("MCR p15, 0, %0, c5, c0, 0" : : "r"(dfsr) : "memory");
|
||||
__set_CP(15, 0, dfsr, 5, 0, 0);
|
||||
}
|
||||
|
||||
/** \brief Get IFSR
|
||||
\return Instruction Fault Status Register value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_IFSR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
// __ASM volatile("MRC p15, 0, %0, c5, c0, 1" : "=r"(result) : : "memory");
|
||||
__get_CP(15, 0, result, 5, 0, 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Set IFSR
|
||||
\param [in] ifsr Instruction Fault Status value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_IFSR(uint32_t ifsr)
|
||||
{
|
||||
// __ASM volatile("MCR p15, 0, %0, c5, c0, 1" : : "r"(ifsr) : "memory");
|
||||
__set_CP(15, 0, ifsr, 5, 0, 1);
|
||||
}
|
||||
|
||||
/** \brief Get ISR
|
||||
\return Interrupt Status Register value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_ISR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
// __ASM volatile("MRC p15, 0, %0, c12, c1, 0" : "=r"(result) : : "memory");
|
||||
__get_CP(15, 0, result, 12, 1, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Get CBAR
|
||||
\return Configuration Base Address register value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_CBAR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
// __ASM volatile("MRC p15, 4, %0, c15, c0, 0" : "=r"(result) : : "memory");
|
||||
__get_CP(15, 4, result, 15, 0, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Get TTBR0
|
||||
|
||||
This function returns the value of the Translation Table Base Register 0.
|
||||
|
||||
\return Translation Table Base Register 0 value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_TTBR0(void)
|
||||
{
|
||||
uint32_t result;
|
||||
// __ASM volatile("MRC p15, 0, %0, c2, c0, 0" : "=r"(result) : : "memory");
|
||||
__get_CP(15, 0, result, 2, 0, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Set TTBR0
|
||||
|
||||
This function assigns the given value to the Translation Table Base Register 0.
|
||||
|
||||
\param [in] ttbr0 Translation Table Base Register 0 value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_TTBR0(uint32_t ttbr0)
|
||||
{
|
||||
// __ASM volatile("MCR p15, 0, %0, c2, c0, 0" : : "r"(ttbr0) : "memory");
|
||||
__set_CP(15, 0, ttbr0, 2, 0, 0);
|
||||
}
|
||||
|
||||
/** \brief Get DACR
|
||||
|
||||
This function returns the value of the Domain Access Control Register.
|
||||
|
||||
\return Domain Access Control Register value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_DACR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
// __ASM volatile("MRC p15, 0, %0, c3, c0, 0" : "=r"(result) : : "memory");
|
||||
__get_CP(15, 0, result, 3, 0, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Set DACR
|
||||
|
||||
This function assigns the given value to the Domain Access Control Register.
|
||||
|
||||
\param [in] dacr Domain Access Control Register value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_DACR(uint32_t dacr)
|
||||
{
|
||||
// __ASM volatile("MCR p15, 0, %0, c3, c0, 0" : : "r"(dacr) : "memory");
|
||||
__set_CP(15, 0, dacr, 3, 0, 0);
|
||||
}
|
||||
|
||||
/** \brief Set SCTLR
|
||||
|
||||
This function assigns the given value to the System Control Register.
|
||||
|
||||
\param [in] sctlr System Control Register value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_SCTLR(uint32_t sctlr)
|
||||
{
|
||||
// __ASM volatile("MCR p15, 0, %0, c1, c0, 0" : : "r"(sctlr) : "memory");
|
||||
__set_CP(15, 0, sctlr, 1, 0, 0);
|
||||
}
|
||||
|
||||
/** \brief Get SCTLR
|
||||
\return System Control Register value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_SCTLR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
// __ASM volatile("MRC p15, 0, %0, c1, c0, 0" : "=r"(result) : : "memory");
|
||||
__get_CP(15, 0, result, 1, 0, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Set ACTRL
|
||||
\param [in] actrl Auxiliary Control Register value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_ACTRL(uint32_t actrl)
|
||||
{
|
||||
// __ASM volatile("MCR p15, 0, %0, c1, c0, 1" : : "r"(actrl) : "memory");
|
||||
__set_CP(15, 0, actrl, 1, 0, 1);
|
||||
}
|
||||
|
||||
/** \brief Get ACTRL
|
||||
\return Auxiliary Control Register value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_ACTRL(void)
|
||||
{
|
||||
uint32_t result;
|
||||
// __ASM volatile("MRC p15, 0, %0, c1, c0, 1" : "=r"(result) : : "memory");
|
||||
__get_CP(15, 0, result, 1, 0, 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Get MPIDR
|
||||
|
||||
This function returns the value of the Multiprocessor Affinity Register.
|
||||
|
||||
\return Multiprocessor Affinity Register value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_MPIDR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
// __ASM volatile("MRC p15, 0, %0, c0, c0, 5" : "=r"(result) : : "memory");
|
||||
__get_CP(15, 0, result, 0, 0, 5);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Get VBAR
|
||||
|
||||
This function returns the value of the Vector Base Address Register.
|
||||
|
||||
\return Vector Base Address Register
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_VBAR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
// __ASM volatile("MRC p15, 0, %0, c12, c0, 0" : "=r"(result) : : "memory");
|
||||
__get_CP(15, 0, result, 12, 0, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Set VBAR
|
||||
|
||||
This function assigns the given value to the Vector Base Address Register.
|
||||
|
||||
\param [in] vbar Vector Base Address Register value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_VBAR(uint32_t vbar)
|
||||
{
|
||||
// __ASM volatile("MCR p15, 0, %0, c12, c0, 1" : : "r"(vbar) : "memory");
|
||||
__set_CP(15, 0, vbar, 12, 0, 1);
|
||||
}
|
||||
|
||||
#if (defined(__CORTEX_A) && (__CORTEX_A == 7U) && \
|
||||
defined(__TIM_PRESENT) && (__TIM_PRESENT == 1U)) || \
|
||||
defined(DOXYGEN)
|
||||
|
||||
/** \brief Set CNTFRQ
|
||||
|
||||
This function assigns the given value to PL1 Physical Timer Counter Frequency Register (CNTFRQ).
|
||||
|
||||
\param [in] value CNTFRQ Register value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_CNTFRQ(uint32_t value)
|
||||
{
|
||||
// __ASM volatile("MCR p15, 0, %0, c14, c0, 0" : : "r"(value) : "memory");
|
||||
__set_CP(15, 0, value, 14, 0, 0);
|
||||
}
|
||||
|
||||
/** \brief Get CNTFRQ
|
||||
|
||||
This function returns the value of the PL1 Physical Timer Counter Frequency Register (CNTFRQ).
|
||||
|
||||
\return CNTFRQ Register value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_CNTFRQ(void)
|
||||
{
|
||||
uint32_t result;
|
||||
// __ASM volatile("MRC p15, 0, %0, c14, c0, 0" : "=r"(result) : : "memory");
|
||||
__get_CP(15, 0, result, 14, 0 , 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Set CNTP_TVAL
|
||||
|
||||
This function assigns the given value to PL1 Physical Timer Value Register (CNTP_TVAL).
|
||||
|
||||
\param [in] value CNTP_TVAL Register value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_CNTP_TVAL(uint32_t value)
|
||||
{
|
||||
// __ASM volatile("MCR p15, 0, %0, c14, c2, 0" : : "r"(value) : "memory");
|
||||
__set_CP(15, 0, value, 14, 2, 0);
|
||||
}
|
||||
|
||||
/** \brief Get CNTP_TVAL
|
||||
|
||||
This function returns the value of the PL1 Physical Timer Value Register (CNTP_TVAL).
|
||||
|
||||
\return CNTP_TVAL Register value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_CNTP_TVAL(void)
|
||||
{
|
||||
uint32_t result;
|
||||
// __ASM volatile("MRC p15, 0, %0, c14, c2, 0" : "=r"(result) : : "memory");
|
||||
__get_CP(15, 0, result, 14, 2, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Set CNTP_CTL
|
||||
|
||||
This function assigns the given value to PL1 Physical Timer Control Register (CNTP_CTL).
|
||||
|
||||
\param [in] value CNTP_CTL Register value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_CNTP_CTL(uint32_t value)
|
||||
{
|
||||
// __ASM volatile("MCR p15, 0, %0, c14, c2, 1" : : "r"(value) : "memory");
|
||||
__set_CP(15, 0, value, 14, 2, 1);
|
||||
}
|
||||
|
||||
/** \brief Get CNTP_CTL register
|
||||
\return CNTP_CTL Register value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_CNTP_CTL(void)
|
||||
{
|
||||
uint32_t result;
|
||||
// __ASM volatile("MRC p15, 0, %0, c14, c2, 1" : "=r"(result) : : "memory");
|
||||
__get_CP(15, 0, result, 14, 2, 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/** \brief Set TLBIALL
|
||||
|
||||
TLB Invalidate All
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_TLBIALL(uint32_t value)
|
||||
{
|
||||
// __ASM volatile("MCR p15, 0, %0, c8, c7, 0" : : "r"(value) : "memory");
|
||||
__set_CP(15, 0, value, 8, 7, 0);
|
||||
}
|
||||
|
||||
/** \brief Set BPIALL.
|
||||
|
||||
Branch Predictor Invalidate All
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_BPIALL(uint32_t value)
|
||||
{
|
||||
// __ASM volatile("MCR p15, 0, %0, c7, c5, 6" : : "r"(value) : "memory");
|
||||
__set_CP(15, 0, value, 7, 5, 6);
|
||||
}
|
||||
|
||||
/** \brief Set ICIALLU
|
||||
|
||||
Instruction Cache Invalidate All
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_ICIALLU(uint32_t value)
|
||||
{
|
||||
// __ASM volatile("MCR p15, 0, %0, c7, c5, 0" : : "r"(value) : "memory");
|
||||
__set_CP(15, 0, value, 7, 5, 0);
|
||||
}
|
||||
|
||||
/** \brief Set DCCMVAC
|
||||
|
||||
Data cache clean
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_DCCMVAC(uint32_t value)
|
||||
{
|
||||
// __ASM volatile("MCR p15, 0, %0, c7, c10, 1" : : "r"(value) : "memory");
|
||||
__set_CP(15, 0, value, 7, 10, 1);
|
||||
}
|
||||
|
||||
/** \brief Set DCIMVAC
|
||||
|
||||
Data cache invalidate
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_DCIMVAC(uint32_t value)
|
||||
{
|
||||
// __ASM volatile("MCR p15, 0, %0, c7, c6, 1" : : "r"(value) : "memory");
|
||||
__set_CP(15, 0, value, 7, 6, 1);
|
||||
}
|
||||
|
||||
/** \brief Set DCCIMVAC
|
||||
|
||||
Data cache clean and invalidate
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_DCCIMVAC(uint32_t value)
|
||||
{
|
||||
// __ASM volatile("MCR p15, 0, %0, c7, c14, 1" : : "r"(value) : "memory");
|
||||
__set_CP(15, 0, value, 7, 14, 1);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set CCSIDR
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_CCSIDR(uint32_t value)
|
||||
{
|
||||
// __ASM volatile("MCR p15, 2, %0, c0, c0, 0" : : "r"(value) : "memory");
|
||||
__set_CP(15, 2, value, 0, 0, 0);
|
||||
}
|
||||
|
||||
/** \brief Get CCSIDR
|
||||
\return CCSIDR Register value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_CCSIDR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
// __ASM volatile("MRC p15, 1, %0, c0, c0, 0" : "=r"(result) : : "memory");
|
||||
__get_CP(15, 1, result, 0, 0, 0);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Get CLIDR
|
||||
\return CLIDR Register value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_CLIDR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
// __ASM volatile("MRC p15, 1, %0, c0, c0, 1" : "=r"(result) : : "memory");
|
||||
__get_CP(15, 1, result, 0, 0, 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,737 @@
|
|||
/**************************************************************************//**
|
||||
* @file cmsis_gcc.h
|
||||
* @brief CMSIS compiler specific macros, functions, instructions
|
||||
* @version V1.0.1
|
||||
* @date 07. Sep 2017
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2017 ARM Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef __CMSIS_GCC_H
|
||||
#define __CMSIS_GCC_H
|
||||
|
||||
/* ignore some GCC warnings */
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wsign-conversion"
|
||||
#pragma GCC diagnostic ignored "-Wconversion"
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
|
||||
/* Fallback for __has_builtin */
|
||||
#ifndef __has_builtin
|
||||
#define __has_builtin(x) (0)
|
||||
#endif
|
||||
|
||||
/* CMSIS compiler specific defines */
|
||||
#ifndef __ASM
|
||||
#define __ASM asm
|
||||
#endif
|
||||
#ifndef __INLINE
|
||||
#define __INLINE inline
|
||||
#endif
|
||||
#ifndef __FORCEINLINE
|
||||
#define __FORCEINLINE __attribute__((always_inline))
|
||||
#endif
|
||||
#ifndef __STATIC_INLINE
|
||||
#define __STATIC_INLINE static inline
|
||||
#endif
|
||||
#ifndef __STATIC_FORCEINLINE
|
||||
#define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline
|
||||
#endif
|
||||
#ifndef __NO_RETURN
|
||||
#define __NO_RETURN __attribute__((noreturn))
|
||||
#endif
|
||||
#ifndef __USED
|
||||
#define __USED __attribute__((used))
|
||||
#endif
|
||||
#ifndef __WEAK
|
||||
#define __WEAK __attribute__((weak))
|
||||
#endif
|
||||
#ifndef __PACKED
|
||||
#define __PACKED __attribute__((packed, aligned(1)))
|
||||
#endif
|
||||
#ifndef __PACKED_STRUCT
|
||||
#define __PACKED_STRUCT struct __attribute__((packed, aligned(1)))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT16_WRITE
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wpacked"
|
||||
/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */
|
||||
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
|
||||
#pragma GCC diagnostic pop
|
||||
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT16_READ
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wpacked"
|
||||
/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */
|
||||
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
|
||||
#pragma GCC diagnostic pop
|
||||
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_WRITE
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wpacked"
|
||||
/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */
|
||||
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
|
||||
#pragma GCC diagnostic pop
|
||||
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_READ
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wpacked"
|
||||
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
|
||||
#pragma GCC diagnostic pop
|
||||
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
|
||||
#endif
|
||||
#ifndef __ALIGNED
|
||||
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||
#endif
|
||||
|
||||
/* ########################## Core Instruction Access ######################### */
|
||||
/**
|
||||
\brief No Operation
|
||||
*/
|
||||
#define __NOP() __ASM volatile ("nop")
|
||||
|
||||
/**
|
||||
\brief Wait For Interrupt
|
||||
*/
|
||||
#define __WFI() __ASM volatile ("wfi")
|
||||
|
||||
/**
|
||||
\brief Wait For Event
|
||||
*/
|
||||
#define __WFE() __ASM volatile ("wfe")
|
||||
|
||||
/**
|
||||
\brief Send Event
|
||||
*/
|
||||
#define __SEV() __ASM volatile ("sev")
|
||||
|
||||
/**
|
||||
\brief Instruction Synchronization Barrier
|
||||
\details Instruction Synchronization Barrier flushes the pipeline in the processor,
|
||||
so that all instructions following the ISB are fetched from cache or memory,
|
||||
after the instruction has been completed.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __ISB(void)
|
||||
{
|
||||
__ASM volatile ("isb 0xF":::"memory");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Data Synchronization Barrier
|
||||
\details Acts as a special kind of Data Memory Barrier.
|
||||
It completes when all explicit memory accesses before this instruction complete.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __DSB(void)
|
||||
{
|
||||
__ASM volatile ("dsb 0xF":::"memory");
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Data Memory Barrier
|
||||
\details Ensures the apparent order of the explicit memory operations before
|
||||
and after the instruction, without ensuring their completion.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __DMB(void)
|
||||
{
|
||||
__ASM volatile ("dmb 0xF":::"memory");
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Reverse byte order (32 bit)
|
||||
\details Reverses the byte order in integer value.
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __REV(uint32_t value)
|
||||
{
|
||||
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
|
||||
return __builtin_bswap32(value);
|
||||
#else
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
|
||||
return(result);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Reverse byte order (16 bit)
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#ifndef __NO_EMBEDDED_ASM
|
||||
__attribute__((section(".rev16_text"))) __STATIC_INLINE uint32_t __REV16(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
__ASM volatile("rev16 %0, %1" : "=r" (result) : "r" (value));
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
\brief Reverse byte order in signed short value
|
||||
\details Reverses the byte order in a signed short value with sign extension to integer.
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__STATIC_FORCEINLINE int32_t __REVSH(int32_t value)
|
||||
{
|
||||
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||
return (short)__builtin_bswap16(value);
|
||||
#else
|
||||
int32_t result;
|
||||
|
||||
__ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
|
||||
return(result);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Rotate Right in unsigned value (32 bit)
|
||||
\details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
|
||||
\param [in] op1 Value to rotate
|
||||
\param [in] op2 Number of Bits to rotate
|
||||
\return Rotated value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
return (op1 >> op2) | (op1 << (32U - op2));
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Breakpoint
|
||||
\param [in] value is ignored by the processor.
|
||||
If required, a debugger can use it to store additional information about the breakpoint.
|
||||
*/
|
||||
#define __BKPT(value) __ASM volatile ("bkpt "#value)
|
||||
|
||||
/**
|
||||
\brief Reverse bit order of value
|
||||
\details Reverses the bit order of the given value.
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __RBIT(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||
(defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
|
||||
(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) )
|
||||
__ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
|
||||
#else
|
||||
int32_t s = (4 /*sizeof(v)*/ * 8) - 1; /* extra shift needed at end */
|
||||
|
||||
result = value; /* r will be reversed bits of v; first get LSB of v */
|
||||
for (value >>= 1U; value; value >>= 1U)
|
||||
{
|
||||
result <<= 1U;
|
||||
result |= value & 1U;
|
||||
s--;
|
||||
}
|
||||
result <<= s; /* shift when v's highest bits are zero */
|
||||
#endif
|
||||
return(result);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Count leading zeros
|
||||
\param [in] value Value to count the leading zeros
|
||||
\return number of leading zeros in value
|
||||
*/
|
||||
#define __CLZ __builtin_clz
|
||||
|
||||
/**
|
||||
\brief LDR Exclusive (8 bit)
|
||||
\details Executes a exclusive LDR instruction for 8 bit value.
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint8_t at (*ptr)
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint8_t __LDREXB(volatile uint8_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||
__ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) );
|
||||
#else
|
||||
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
|
||||
accepted by assembler. So has to use following less efficient pattern.
|
||||
*/
|
||||
__ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
|
||||
#endif
|
||||
return ((uint8_t) result); /* Add explicit type cast here */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief LDR Exclusive (16 bit)
|
||||
\details Executes a exclusive LDR instruction for 16 bit values.
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint16_t at (*ptr)
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint16_t __LDREXH(volatile uint16_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||
__ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) );
|
||||
#else
|
||||
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
|
||||
accepted by assembler. So has to use following less efficient pattern.
|
||||
*/
|
||||
__ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
|
||||
#endif
|
||||
return ((uint16_t) result); /* Add explicit type cast here */
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief LDR Exclusive (32 bit)
|
||||
\details Executes a exclusive LDR instruction for 32 bit values.
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint32_t at (*ptr)
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __LDREXW(volatile uint32_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief STR Exclusive (8 bit)
|
||||
\details Executes a exclusive STR instruction for 8 bit values.
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief STR Exclusive (16 bit)
|
||||
\details Executes a exclusive STR instruction for 16 bit values.
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief STR Exclusive (32 bit)
|
||||
\details Executes a exclusive STR instruction for 32 bit values.
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Remove the exclusive lock
|
||||
\details Removes the exclusive lock which is created by LDREX.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __CLREX(void)
|
||||
{
|
||||
__ASM volatile ("clrex" ::: "memory");
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Signed Saturate
|
||||
\details Saturates a signed value.
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (1..32)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __SSAT(ARG1,ARG2) \
|
||||
__extension__ \
|
||||
({ \
|
||||
int32_t __RES, __ARG1 = (ARG1); \
|
||||
__ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||
__RES; \
|
||||
})
|
||||
|
||||
|
||||
/**
|
||||
\brief Unsigned Saturate
|
||||
\details Saturates an unsigned value.
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (0..31)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __USAT(ARG1,ARG2) \
|
||||
__extension__ \
|
||||
({ \
|
||||
uint32_t __RES, __ARG1 = (ARG1); \
|
||||
__ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||
__RES; \
|
||||
})
|
||||
|
||||
/* ########################### Core Function Access ########################### */
|
||||
|
||||
/**
|
||||
\brief Enable IRQ Interrupts
|
||||
\details Enables IRQ interrupts by clearing the I-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __enable_irq(void)
|
||||
{
|
||||
__ASM volatile ("cpsie i" : : : "memory");
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Disable IRQ Interrupts
|
||||
\details Disables IRQ interrupts by setting the I-bit in the CPSR.
|
||||
Can only be executed in Privileged modes.
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __disable_irq(void)
|
||||
{
|
||||
__ASM volatile ("cpsid i" : : : "memory");
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Get FPSCR
|
||||
\details Returns the current value of the Floating Point Status/Control register.
|
||||
\return Floating Point Status/Control register value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_FPSCR(void)
|
||||
{
|
||||
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
|
||||
#if __has_builtin(__builtin_arm_get_fpscr) || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2)
|
||||
/* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */
|
||||
return __builtin_arm_get_fpscr();
|
||||
#else
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
|
||||
return(result);
|
||||
#endif
|
||||
#else
|
||||
return(0U);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Set FPSCR
|
||||
\details Assigns the given value to the Floating Point Status/Control register.
|
||||
\param [in] fpscr Floating Point Status/Control value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_FPSCR(uint32_t fpscr)
|
||||
{
|
||||
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
|
||||
#if __has_builtin(__builtin_arm_set_fpscr) || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2)
|
||||
/* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */
|
||||
__builtin_arm_set_fpscr(fpscr);
|
||||
#else
|
||||
__ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc", "memory");
|
||||
#endif
|
||||
#else
|
||||
(void)fpscr;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** \brief Get CPSR Register
|
||||
\return CPSR Register value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_CPSR(void)
|
||||
{
|
||||
uint32_t result;
|
||||
__ASM volatile("MRS %0, cpsr" : "=r" (result) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
/** \brief Set CPSR Register
|
||||
\param [in] cpsr CPSR value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_CPSR(uint32_t cpsr)
|
||||
{
|
||||
__ASM volatile ("MSR cpsr, %0" : : "r" (cpsr) : "memory");
|
||||
}
|
||||
|
||||
/** \brief Get Mode
|
||||
\return Processor Mode
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_mode(void) {
|
||||
return (__get_CPSR() & 0x1FU);
|
||||
}
|
||||
|
||||
/** \brief Set Mode
|
||||
\param [in] mode Mode value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_mode(uint32_t mode) {
|
||||
__ASM volatile("MSR cpsr_c, %0" : : "r" (mode) : "memory");
|
||||
}
|
||||
|
||||
/** \brief Get Stack Pointer
|
||||
\return Stack Pointer value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_SP(void)
|
||||
{
|
||||
uint32_t result;
|
||||
__ASM volatile("MOV %0, sp" : "=r" (result) : : "memory");
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Set Stack Pointer
|
||||
\param [in] stack Stack Pointer value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_SP(uint32_t stack)
|
||||
{
|
||||
__ASM volatile("MOV sp, %0" : : "r" (stack) : "memory");
|
||||
}
|
||||
|
||||
/** \brief Get USR/SYS Stack Pointer
|
||||
\return USR/SYS Stack Pointer value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_SP_usr(void)
|
||||
{
|
||||
uint32_t cpsr = __get_CPSR();
|
||||
uint32_t result;
|
||||
__ASM volatile(
|
||||
"CPS #0x1F \n"
|
||||
"MOV %0, sp " : "=r"(result) : : "memory"
|
||||
);
|
||||
__set_CPSR(cpsr);
|
||||
__ISB();
|
||||
return result;
|
||||
}
|
||||
|
||||
/** \brief Set USR/SYS Stack Pointer
|
||||
\param [in] topOfProcStack USR/SYS Stack Pointer value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_SP_usr(uint32_t topOfProcStack)
|
||||
{
|
||||
uint32_t cpsr = __get_CPSR();
|
||||
__ASM volatile(
|
||||
"CPS #0x1F \n"
|
||||
"MOV sp, %0 " : : "r" (topOfProcStack) : "memory"
|
||||
);
|
||||
__set_CPSR(cpsr);
|
||||
__ISB();
|
||||
}
|
||||
|
||||
/** \brief Get FPEXC
|
||||
\return Floating Point Exception Control register value
|
||||
*/
|
||||
__STATIC_FORCEINLINE uint32_t __get_FPEXC(void)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1)
|
||||
uint32_t result;
|
||||
__ASM volatile("VMRS %0, fpexc" : "=r" (result) );
|
||||
return(result);
|
||||
#else
|
||||
return(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** \brief Set FPEXC
|
||||
\param [in] fpexc Floating Point Exception Control value to set
|
||||
*/
|
||||
__STATIC_FORCEINLINE void __set_FPEXC(uint32_t fpexc)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1)
|
||||
__ASM volatile ("VMSR fpexc, %0" : : "r" (fpexc) : "memory");
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Include common core functions to access Coprocessor 15 registers
|
||||
*/
|
||||
|
||||
#define __get_CP(cp, op1, Rt, CRn, CRm, op2) __ASM volatile("MRC p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : "=r" (Rt) : : "memory" )
|
||||
#define __set_CP(cp, op1, Rt, CRn, CRm, op2) __ASM volatile("MCR p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : : "r" (Rt) : "memory" )
|
||||
|
||||
#include "cmsis_cp15.h"
|
||||
|
||||
__STATIC_FORCEINLINE int32_t log2_up(uint32_t n)
|
||||
{
|
||||
int32_t log = -1;
|
||||
uint32_t t = n;
|
||||
while(t)
|
||||
{
|
||||
log++; t >>=1;
|
||||
}
|
||||
/* if n not power of 2 -> round up*/
|
||||
if ( n & (n - 1) ) log++;
|
||||
return log;
|
||||
}
|
||||
|
||||
__STATIC_INLINE void __L1C_MaintainDCacheSetWay(uint32_t level, uint32_t maint)
|
||||
{
|
||||
register volatile uint32_t Dummy;
|
||||
register volatile uint32_t ccsidr;
|
||||
uint32_t num_sets;
|
||||
uint32_t num_ways;
|
||||
uint32_t shift_way;
|
||||
uint32_t log2_linesize;
|
||||
uint32_t log2_num_ways;
|
||||
|
||||
Dummy = level << 1;
|
||||
/* set csselr, select ccsidr register */
|
||||
__set_CCSIDR(Dummy);
|
||||
/* get current ccsidr register */
|
||||
ccsidr = __get_CCSIDR();
|
||||
num_sets = ((ccsidr & 0x0FFFE000) >> 13) + 1;
|
||||
num_ways = ((ccsidr & 0x00001FF8) >> 3) + 1;
|
||||
log2_linesize = (ccsidr & 0x00000007) + 2 + 2;
|
||||
log2_num_ways = log2_up(num_ways);
|
||||
shift_way = 32 - log2_num_ways;
|
||||
for(int way = num_ways-1; way >= 0; way--) {
|
||||
for(int set = num_sets-1; set >= 0; set--) {
|
||||
Dummy = (level << 1) | (set << log2_linesize) | (way << shift_way);
|
||||
switch (maint)
|
||||
{
|
||||
case 0:
|
||||
__ASM volatile("MCR p15, 0, %0, c7, c6, 2" : : "r"(Dummy) : "memory"); // DCISW. Invalidate by Set/Way
|
||||
break;
|
||||
|
||||
case 1:
|
||||
__ASM volatile("MCR p15, 0, %0, c7, c10, 2" : : "r"(Dummy) : "memory"); // DCCSW. Clean by Set/Way
|
||||
break;
|
||||
|
||||
default:
|
||||
__ASM volatile("MCR p15, 0, %0, c7, c14, 2" : : "r"(Dummy) : "memory"); // DCCISW. Clean and Invalidate by Set/Way
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
__DMB();
|
||||
}
|
||||
|
||||
/** \brief Clean and Invalidate the entire data or unified cache
|
||||
|
||||
Generic mechanism for cleaning/invalidating the entire data or unified cache to the point of coherency
|
||||
*/
|
||||
__STATIC_INLINE void __L1C_CleanInvalidateCache(uint32_t op) {
|
||||
register volatile uint32_t clidr;
|
||||
uint32_t cache_type;
|
||||
clidr = __get_CLIDR();
|
||||
for(uint32_t i = 0; i<7; i++)
|
||||
{
|
||||
cache_type = (clidr >> i*3) & 0x7UL;
|
||||
if ((cache_type >= 2) && (cache_type <= 4))
|
||||
{
|
||||
__L1C_MaintainDCacheSetWay(i, op);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** \brief Enable Floating Point Unit
|
||||
|
||||
Critical section, called from undef handler, so systick is disabled
|
||||
*/
|
||||
__STATIC_INLINE void __FPU_Enable(void) {
|
||||
__ASM volatile(
|
||||
//Permit access to VFP/NEON, registers by modifying CPACR
|
||||
" MRC p15,0,R1,c1,c0,2 \n"
|
||||
" ORR R1,R1,#0x00F00000 \n"
|
||||
" MCR p15,0,R1,c1,c0,2 \n"
|
||||
|
||||
//Ensure that subsequent instructions occur in the context of VFP/NEON access permitted
|
||||
" ISB \n"
|
||||
|
||||
//Enable VFP/NEON
|
||||
" VMRS R1,FPEXC \n"
|
||||
" ORR R1,R1,#0x40000000 \n"
|
||||
" VMSR FPEXC,R1 \n"
|
||||
|
||||
//Initialise VFP/NEON registers to 0
|
||||
" MOV R2,#0 \n"
|
||||
|
||||
#if TARGET_FEATURE_EXTENSION_REGISTER_COUNT >= 16
|
||||
//Initialise D16 registers to 0
|
||||
" VMOV D0, R2,R2 \n"
|
||||
" VMOV D1, R2,R2 \n"
|
||||
" VMOV D2, R2,R2 \n"
|
||||
" VMOV D3, R2,R2 \n"
|
||||
" VMOV D4, R2,R2 \n"
|
||||
" VMOV D5, R2,R2 \n"
|
||||
" VMOV D6, R2,R2 \n"
|
||||
" VMOV D7, R2,R2 \n"
|
||||
" VMOV D8, R2,R2 \n"
|
||||
" VMOV D9, R2,R2 \n"
|
||||
" VMOV D10,R2,R2 \n"
|
||||
" VMOV D11,R2,R2 \n"
|
||||
" VMOV D12,R2,R2 \n"
|
||||
" VMOV D13,R2,R2 \n"
|
||||
" VMOV D14,R2,R2 \n"
|
||||
" VMOV D15,R2,R2 \n"
|
||||
#endif
|
||||
|
||||
#if TARGET_FEATURE_EXTENSION_REGISTER_COUNT == 32
|
||||
//Initialise D32 registers to 0
|
||||
" VMOV D16,R2,R2 \n"
|
||||
" VMOV D17,R2,R2 \n"
|
||||
" VMOV D18,R2,R2 \n"
|
||||
" VMOV D19,R2,R2 \n"
|
||||
" VMOV D20,R2,R2 \n"
|
||||
" VMOV D21,R2,R2 \n"
|
||||
" VMOV D22,R2,R2 \n"
|
||||
" VMOV D23,R2,R2 \n"
|
||||
" VMOV D24,R2,R2 \n"
|
||||
" VMOV D25,R2,R2 \n"
|
||||
" VMOV D26,R2,R2 \n"
|
||||
" VMOV D27,R2,R2 \n"
|
||||
" VMOV D28,R2,R2 \n"
|
||||
" VMOV D29,R2,R2 \n"
|
||||
" VMOV D30,R2,R2 \n"
|
||||
" VMOV D31,R2,R2 \n"
|
||||
#endif
|
||||
//Initialise FPSCR to a known state
|
||||
" VMRS R2,FPSCR \n"
|
||||
" LDR R3,=0x00086060 \n" //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero.
|
||||
" AND R2,R2,R3 \n"
|
||||
" VMSR FPSCR,R2 "
|
||||
);
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
#endif /* __CMSIS_GCC_H */
|
|
@ -0,0 +1,591 @@
|
|||
/**************************************************************************//**
|
||||
* @file cmsis_iccarm.h
|
||||
* @brief CMSIS compiler ICCARM (IAR compiler) header file
|
||||
* @version V5.0.3
|
||||
* @date 29. August 2017
|
||||
******************************************************************************/
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2017 IAR Systems
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License")
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef __CMSIS_ICCARM_H__
|
||||
#define __CMSIS_ICCARM_H__
|
||||
|
||||
#ifndef __ICCARM__
|
||||
#error This file should only be compiled by ICCARM
|
||||
#endif
|
||||
|
||||
#pragma system_include
|
||||
|
||||
#define __IAR_FT _Pragma("inline=forced") __intrinsic
|
||||
|
||||
#if (__VER__ >= 8000000)
|
||||
#define __ICCARM_V8 1
|
||||
#else
|
||||
#define __ICCARM_V8 0
|
||||
#endif
|
||||
|
||||
#pragma language=extended
|
||||
|
||||
#ifndef __ALIGNED
|
||||
#if __ICCARM_V8
|
||||
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||
#elif (__VER__ >= 7080000)
|
||||
/* Needs IAR language extensions */
|
||||
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||
#else
|
||||
#warning No compiler specific solution for __ALIGNED.__ALIGNED is ignored.
|
||||
#define __ALIGNED(x)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Define compiler macros for CPU architecture, used in CMSIS 5.
|
||||
*/
|
||||
#if __ARM_ARCH_7A__
|
||||
/* Macro already defined */
|
||||
#else
|
||||
#if defined(__ARM7A__)
|
||||
#define __ARM_ARCH_7A__ 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef __ASM
|
||||
#define __ASM __asm
|
||||
#endif
|
||||
|
||||
#ifndef __INLINE
|
||||
#define __INLINE inline
|
||||
#endif
|
||||
|
||||
#ifndef __NO_RETURN
|
||||
#define __NO_RETURN _Pragma("object_attribute=__noreturn")
|
||||
#endif
|
||||
|
||||
#ifndef __PACKED
|
||||
/* Needs IAR language extensions */
|
||||
#if __ICCARM_V8
|
||||
#define __PACKED __attribute__((packed, aligned(1)))
|
||||
#else
|
||||
#define __PACKED __packed
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef __PACKED_STRUCT
|
||||
/* Needs IAR language extensions */
|
||||
#if __ICCARM_V8
|
||||
#define __PACKED_STRUCT struct __attribute__((packed, aligned(1)))
|
||||
#else
|
||||
#define __PACKED_STRUCT __packed struct
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef __PACKED_UNION
|
||||
/* Needs IAR language extensions */
|
||||
#if __ICCARM_V8
|
||||
#define __PACKED_UNION union __attribute__((packed, aligned(1)))
|
||||
#else
|
||||
#define __PACKED_UNION __packed union
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef __RESTRICT
|
||||
#define __RESTRICT restrict
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef __STATIC_INLINE
|
||||
#define __STATIC_INLINE static inline
|
||||
#endif
|
||||
|
||||
#ifndef __STATIC_FORCEINLINE
|
||||
#define __STATIC_FORCEINLINE _Pragma("inline=forced") static inline
|
||||
#endif
|
||||
#ifndef __FORCEINLINE
|
||||
#define __FORCEINLINE _Pragma("inline=forced")
|
||||
#endif
|
||||
|
||||
#ifndef __UNALIGNED_UINT16_READ
|
||||
#pragma language=save
|
||||
#pragma language=extended
|
||||
__IAR_FT uint16_t __iar_uint16_read(void const *ptr) {
|
||||
return *(__packed uint16_t*)(ptr);
|
||||
}
|
||||
#pragma language=restore
|
||||
#define __UNALIGNED_UINT16_READ(PTR) __iar_uint16_read(PTR)
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef __UNALIGNED_UINT16_WRITE
|
||||
#pragma language=save
|
||||
#pragma language=extended
|
||||
__IAR_FT void __iar_uint16_write(void const *ptr, uint16_t val) {
|
||||
*(__packed uint16_t*)(ptr) = val;;
|
||||
}
|
||||
#pragma language=restore
|
||||
#define __UNALIGNED_UINT16_WRITE(PTR,VAL) __iar_uint16_write(PTR,VAL)
|
||||
#endif
|
||||
|
||||
#ifndef __UNALIGNED_UINT32_READ
|
||||
#pragma language=save
|
||||
#pragma language=extended
|
||||
__IAR_FT uint32_t __iar_uint32_read(void const *ptr) {
|
||||
return *(__packed uint32_t*)(ptr);
|
||||
}
|
||||
#pragma language=restore
|
||||
#define __UNALIGNED_UINT32_READ(PTR) __iar_uint32_read(PTR)
|
||||
#endif
|
||||
|
||||
#ifndef __UNALIGNED_UINT32_WRITE
|
||||
#pragma language=save
|
||||
#pragma language=extended
|
||||
__IAR_FT void __iar_uint32_write(void const *ptr, uint32_t val) {
|
||||
*(__packed uint32_t*)(ptr) = val;;
|
||||
}
|
||||
#pragma language=restore
|
||||
#define __UNALIGNED_UINT32_WRITE(PTR,VAL) __iar_uint32_write(PTR,VAL)
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#ifndef __UNALIGNED_UINT32 /* deprecated */
|
||||
#pragma language=save
|
||||
#pragma language=extended
|
||||
__packed struct __iar_u32 { uint32_t v; };
|
||||
#pragma language=restore
|
||||
#define __UNALIGNED_UINT32(PTR) (((struct __iar_u32 *)(PTR))->v)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef __USED
|
||||
#if __ICCARM_V8
|
||||
#define __USED __attribute__((used))
|
||||
#else
|
||||
#define __USED _Pragma("__root")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef __WEAK
|
||||
#if __ICCARM_V8
|
||||
#define __WEAK __attribute__((weak))
|
||||
#else
|
||||
#define __WEAK _Pragma("__weak")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef __ICCARM_INTRINSICS_VERSION__
|
||||
#define __ICCARM_INTRINSICS_VERSION__ 0
|
||||
#endif
|
||||
|
||||
#if __ICCARM_INTRINSICS_VERSION__ == 2
|
||||
|
||||
#if defined(__CLZ)
|
||||
#undef __CLZ
|
||||
#endif
|
||||
#if defined(__REVSH)
|
||||
#undef __REVSH
|
||||
#endif
|
||||
#if defined(__RBIT)
|
||||
#undef __RBIT
|
||||
#endif
|
||||
#if defined(__SSAT)
|
||||
#undef __SSAT
|
||||
#endif
|
||||
#if defined(__USAT)
|
||||
#undef __USAT
|
||||
#endif
|
||||
|
||||
#include "iccarm_builtin.h"
|
||||
|
||||
#define __enable_irq __iar_builtin_enable_interrupt
|
||||
#define __disable_irq __iar_builtin_disable_interrupt
|
||||
#define __enable_fault_irq __iar_builtin_enable_fiq
|
||||
#define __disable_fault_irq __iar_builtin_disable_fiq
|
||||
#define __arm_rsr __iar_builtin_rsr
|
||||
#define __arm_wsr __iar_builtin_wsr
|
||||
|
||||
#if __FPU_PRESENT
|
||||
#define __get_FPSCR() (__arm_rsr("FPSCR"))
|
||||
#else
|
||||
#define __get_FPSCR() ( 0 )
|
||||
#endif
|
||||
|
||||
#define __set_FPSCR(VALUE) (__arm_wsr("FPSCR", VALUE))
|
||||
|
||||
#define __get_CPSR() (__arm_rsr("CPSR"))
|
||||
#define __get_mode() (__get_CPSR() & 0x1FU)
|
||||
|
||||
#define __set_CPSR(VALUE) (__arm_wsr("CPSR", (VALUE)))
|
||||
#define __set_mode(VALUE) (__arm_wsr("CPSR_c", (VALUE)))
|
||||
|
||||
|
||||
#define __get_FPEXC() (__arm_rsr("FPEXC"))
|
||||
#define __set_FPEXC(VALUE) (__arm_wsr("FPEXC", VALUE))
|
||||
|
||||
#define __get_CP(cp, op1, RT, CRn, CRm, op2) \
|
||||
(RT = __arm_rsr("p" # cp ":" # op1 ":c" # CRn ":c" # CRm ":" # op2))
|
||||
|
||||
#define __set_CP(cp, op1, RT, CRn, CRm, op2) \
|
||||
(__arm_wsr("p" # cp ":" # op1 ":c" # CRn ":c" # CRm ":" # op2, RT))
|
||||
|
||||
#include "cmsis_cp15.h"
|
||||
|
||||
#define __NOP __iar_builtin_no_operation
|
||||
|
||||
__IAR_FT uint8_t __CLZ(uint32_t val) {
|
||||
return __iar_builtin_CLZ(val);
|
||||
}
|
||||
|
||||
#define __CLREX __iar_builtin_CLREX
|
||||
|
||||
#define __DMB __iar_builtin_DMB
|
||||
#define __DSB __iar_builtin_DSB
|
||||
#define __ISB __iar_builtin_ISB
|
||||
|
||||
#define __LDREXB __iar_builtin_LDREXB
|
||||
#define __LDREXH __iar_builtin_LDREXH
|
||||
#define __LDREXW __iar_builtin_LDREX
|
||||
|
||||
#define __RBIT __iar_builtin_RBIT
|
||||
#define __REV __iar_builtin_REV
|
||||
#define __REV16 __iar_builtin_REV16
|
||||
|
||||
__IAR_FT int32_t __REVSH(int32_t val) {
|
||||
return __iar_builtin_REVSH((int16_t)val);
|
||||
}
|
||||
|
||||
#define __ROR __iar_builtin_ROR
|
||||
#define __RRX __iar_builtin_RRX
|
||||
|
||||
#define __SEV __iar_builtin_SEV
|
||||
|
||||
#define __SSAT __iar_builtin_SSAT
|
||||
|
||||
#define __STREXB __iar_builtin_STREXB
|
||||
#define __STREXH __iar_builtin_STREXH
|
||||
#define __STREXW __iar_builtin_STREX
|
||||
|
||||
#define __USAT __iar_builtin_USAT
|
||||
|
||||
#define __WFE __iar_builtin_WFE
|
||||
#define __WFI __iar_builtin_WFI
|
||||
|
||||
#define __SADD8 __iar_builtin_SADD8
|
||||
#define __QADD8 __iar_builtin_QADD8
|
||||
#define __SHADD8 __iar_builtin_SHADD8
|
||||
#define __UADD8 __iar_builtin_UADD8
|
||||
#define __UQADD8 __iar_builtin_UQADD8
|
||||
#define __UHADD8 __iar_builtin_UHADD8
|
||||
#define __SSUB8 __iar_builtin_SSUB8
|
||||
#define __QSUB8 __iar_builtin_QSUB8
|
||||
#define __SHSUB8 __iar_builtin_SHSUB8
|
||||
#define __USUB8 __iar_builtin_USUB8
|
||||
#define __UQSUB8 __iar_builtin_UQSUB8
|
||||
#define __UHSUB8 __iar_builtin_UHSUB8
|
||||
#define __SADD16 __iar_builtin_SADD16
|
||||
#define __QADD16 __iar_builtin_QADD16
|
||||
#define __SHADD16 __iar_builtin_SHADD16
|
||||
#define __UADD16 __iar_builtin_UADD16
|
||||
#define __UQADD16 __iar_builtin_UQADD16
|
||||
#define __UHADD16 __iar_builtin_UHADD16
|
||||
#define __SSUB16 __iar_builtin_SSUB16
|
||||
#define __QSUB16 __iar_builtin_QSUB16
|
||||
#define __SHSUB16 __iar_builtin_SHSUB16
|
||||
#define __USUB16 __iar_builtin_USUB16
|
||||
#define __UQSUB16 __iar_builtin_UQSUB16
|
||||
#define __UHSUB16 __iar_builtin_UHSUB16
|
||||
#define __SASX __iar_builtin_SASX
|
||||
#define __QASX __iar_builtin_QASX
|
||||
#define __SHASX __iar_builtin_SHASX
|
||||
#define __UASX __iar_builtin_UASX
|
||||
#define __UQASX __iar_builtin_UQASX
|
||||
#define __UHASX __iar_builtin_UHASX
|
||||
#define __SSAX __iar_builtin_SSAX
|
||||
#define __QSAX __iar_builtin_QSAX
|
||||
#define __SHSAX __iar_builtin_SHSAX
|
||||
#define __USAX __iar_builtin_USAX
|
||||
#define __UQSAX __iar_builtin_UQSAX
|
||||
#define __UHSAX __iar_builtin_UHSAX
|
||||
#define __USAD8 __iar_builtin_USAD8
|
||||
#define __USADA8 __iar_builtin_USADA8
|
||||
#define __SSAT16 __iar_builtin_SSAT16
|
||||
#define __USAT16 __iar_builtin_USAT16
|
||||
#define __UXTB16 __iar_builtin_UXTB16
|
||||
#define __UXTAB16 __iar_builtin_UXTAB16
|
||||
#define __SXTB16 __iar_builtin_SXTB16
|
||||
#define __SXTAB16 __iar_builtin_SXTAB16
|
||||
#define __SMUAD __iar_builtin_SMUAD
|
||||
#define __SMUADX __iar_builtin_SMUADX
|
||||
#define __SMMLA __iar_builtin_SMMLA
|
||||
#define __SMLAD __iar_builtin_SMLAD
|
||||
#define __SMLADX __iar_builtin_SMLADX
|
||||
#define __SMLALD __iar_builtin_SMLALD
|
||||
#define __SMLALDX __iar_builtin_SMLALDX
|
||||
#define __SMUSD __iar_builtin_SMUSD
|
||||
#define __SMUSDX __iar_builtin_SMUSDX
|
||||
#define __SMLSD __iar_builtin_SMLSD
|
||||
#define __SMLSDX __iar_builtin_SMLSDX
|
||||
#define __SMLSLD __iar_builtin_SMLSLD
|
||||
#define __SMLSLDX __iar_builtin_SMLSLDX
|
||||
#define __SEL __iar_builtin_SEL
|
||||
#define __QADD __iar_builtin_QADD
|
||||
#define __QSUB __iar_builtin_QSUB
|
||||
#define __PKHBT __iar_builtin_PKHBT
|
||||
#define __PKHTB __iar_builtin_PKHTB
|
||||
|
||||
#else /* __ICCARM_INTRINSICS_VERSION__ == 2 */
|
||||
|
||||
#if !__FPU_PRESENT
|
||||
#define __get_FPSCR __cmsis_iar_get_FPSR_not_active
|
||||
#endif
|
||||
|
||||
#include <intrinsics.h>
|
||||
|
||||
#if !__FPU_PRESENT
|
||||
#define __get_FPSCR() (0)
|
||||
#endif
|
||||
|
||||
#pragma diag_suppress=Pe940
|
||||
#pragma diag_suppress=Pe177
|
||||
|
||||
#define __enable_irq __enable_interrupt
|
||||
#define __disable_irq __disable_interrupt
|
||||
#define __enable_fault_irq __enable_fiq
|
||||
#define __disable_fault_irq __disable_fiq
|
||||
#define __NOP __no_operation
|
||||
|
||||
#define __get_xPSR __get_PSR
|
||||
|
||||
__IAR_FT void __set_mode(uint32_t mode)
|
||||
{
|
||||
__ASM volatile("MSR cpsr_c, %0" : : "r" (mode) : "memory");
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __LDREXW(uint32_t volatile *ptr) {
|
||||
return __LDREX((unsigned long *)ptr);
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __STREXW(uint32_t value, uint32_t volatile *ptr) {
|
||||
return __STREX(value, (unsigned long *)ptr);
|
||||
}
|
||||
|
||||
|
||||
__IAR_FT uint32_t __RRX(uint32_t value) {
|
||||
uint32_t result;
|
||||
__ASM("RRX %0, %1" : "=r"(result) : "r" (value) : "cc");
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
__IAR_FT uint32_t __ROR(uint32_t op1, uint32_t op2) {
|
||||
return (op1 >> op2) | (op1 << ((sizeof(op1)*8)-op2));
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __get_FPEXC(void)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1)
|
||||
uint32_t result;
|
||||
__ASM volatile("VMRS %0, fpexc" : "=r" (result) : : "memory");
|
||||
return(result);
|
||||
#else
|
||||
return(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
__IAR_FT void __set_FPEXC(uint32_t fpexc)
|
||||
{
|
||||
#if (__FPU_PRESENT == 1)
|
||||
__ASM volatile ("VMSR fpexc, %0" : : "r" (fpexc) : "memory");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#define __get_CP(cp, op1, Rt, CRn, CRm, op2) \
|
||||
__ASM volatile("MRC p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : "=r" (Rt) : : "memory" )
|
||||
#define __set_CP(cp, op1, Rt, CRn, CRm, op2) \
|
||||
__ASM volatile("MCR p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : : "r" (Rt) : "memory" )
|
||||
|
||||
#include "cmsis_cp15.h"
|
||||
|
||||
#endif /* __ICCARM_INTRINSICS_VERSION__ == 2 */
|
||||
|
||||
#define __BKPT(value) __asm volatile ("BKPT %0" : : "i"(value))
|
||||
|
||||
|
||||
__IAR_FT uint32_t __get_SP_usr(void)
|
||||
{
|
||||
uint32_t cpsr;
|
||||
uint32_t result;
|
||||
__ASM volatile(
|
||||
"MRS %0, cpsr \n"
|
||||
"CPS #0x1F \n" // no effect in USR mode
|
||||
"MOV %1, sp \n"
|
||||
"MSR cpsr_c, %2 \n" // no effect in USR mode
|
||||
"ISB" : "=r"(cpsr), "=r"(result) : "r"(cpsr) : "memory"
|
||||
);
|
||||
return result;
|
||||
}
|
||||
|
||||
__IAR_FT void __set_SP_usr(uint32_t topOfProcStack)
|
||||
{
|
||||
uint32_t cpsr;
|
||||
__ASM volatile(
|
||||
"MRS %0, cpsr \n"
|
||||
"CPS #0x1F \n" // no effect in USR mode
|
||||
"MOV sp, %1 \n"
|
||||
"MSR cpsr_c, %2 \n" // no effect in USR mode
|
||||
"ISB" : "=r"(cpsr) : "r" (topOfProcStack), "r"(cpsr) : "memory"
|
||||
);
|
||||
}
|
||||
|
||||
#define __get_mode() (__get_CPSR() & 0x1FU)
|
||||
|
||||
|
||||
__STATIC_INLINE
|
||||
void __L1C_CleanInvalidateCache(uint32_t op)
|
||||
{
|
||||
__ASM volatile(
|
||||
" PUSH {R4-R11} \n"
|
||||
|
||||
" MRC p15, 1, R6, c0, c0, 1 \n" // Read CLIDR
|
||||
" ANDS R3, R6, #0x07000000 \n" // Extract coherency level
|
||||
" MOV R3, R3, LSR #23 \n" // Total cache levels << 1
|
||||
" BEQ Finished \n" // If 0, no need to clean
|
||||
|
||||
" MOV R10, #0 \n" // R10 holds current cache level << 1
|
||||
"Loop1: ADD R2, R10, R10, LSR #1 \n" // R2 holds cache "Set" position
|
||||
" MOV R1, R6, LSR R2 \n" // Bottom 3 bits are the Cache-type for this level
|
||||
" AND R1, R1, #7 \n" // Isolate those lower 3 bits
|
||||
" CMP R1, #2 \n"
|
||||
" BLT Skip \n" // No cache or only instruction cache at this level
|
||||
|
||||
" MCR p15, 2, R10, c0, c0, 0 \n" // Write the Cache Size selection register
|
||||
" ISB \n" // ISB to sync the change to the CacheSizeID reg
|
||||
" MRC p15, 1, R1, c0, c0, 0 \n" // Reads current Cache Size ID register
|
||||
" AND R2, R1, #7 \n" // Extract the line length field
|
||||
" ADD R2, R2, #4 \n" // Add 4 for the line length offset (log2 16 bytes)
|
||||
" MOVW R4, #0x3FF \n"
|
||||
" ANDS R4, R4, R1, LSR #3 \n" // R4 is the max number on the way size (right aligned)
|
||||
" CLZ R5, R4 \n" // R5 is the bit position of the way size increment
|
||||
" MOVW R7, #0x7FFF \n"
|
||||
" ANDS R7, R7, R1, LSR #13 \n" // R7 is the max number of the index size (right aligned)
|
||||
|
||||
"Loop2: MOV R9, R4 \n" // R9 working copy of the max way size (right aligned)
|
||||
|
||||
"Loop3: ORR R11, R10, R9, LSL R5 \n" // Factor in the Way number and cache number into R11
|
||||
" ORR R11, R11, R7, LSL R2 \n" // Factor in the Set number
|
||||
" CMP R0, #0 \n"
|
||||
" BNE Dccsw \n"
|
||||
" MCR p15, 0, R11, c7, c6, 2 \n" // DCISW. Invalidate by Set/Way
|
||||
" B cont \n"
|
||||
"Dccsw: CMP R0, #1 \n"
|
||||
" BNE Dccisw \n"
|
||||
" MCR p15, 0, R11, c7, c10, 2 \n" // DCCSW. Clean by Set/Way
|
||||
" B cont \n"
|
||||
"Dccisw: MCR p15, 0, R11, c7, c14, 2 \n" // DCCISW. Clean and Invalidate by Set/Way
|
||||
"cont: SUBS R9, R9, #1 \n" // Decrement the Way number
|
||||
" BGE Loop3 \n"
|
||||
" SUBS R7, R7, #1 \n" // Decrement the Set number
|
||||
" BGE Loop2 \n"
|
||||
"Skip: ADD R10, R10, #2 \n" // Increment the cache number
|
||||
" CMP R3, R10 \n"
|
||||
" BGT Loop1 \n"
|
||||
|
||||
"Finished: \n"
|
||||
" DSB \n"
|
||||
" POP {R4-R11} "
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
__STATIC_INLINE
|
||||
void __FPU_Enable(void)
|
||||
{
|
||||
__ASM volatile(
|
||||
//Permit access to VFP/NEON, registers by modifying CPACR
|
||||
" MRC p15,0,R1,c1,c0,2 \n"
|
||||
" ORR R1,R1,#0x00F00000 \n"
|
||||
" MCR p15,0,R1,c1,c0,2 \n"
|
||||
|
||||
//Ensure that subsequent instructions occur in the context of VFP/NEON access permitted
|
||||
" ISB \n"
|
||||
|
||||
//Enable VFP/NEON
|
||||
" VMRS R1,FPEXC \n"
|
||||
" ORR R1,R1,#0x40000000 \n"
|
||||
" VMSR FPEXC,R1 \n"
|
||||
|
||||
//Initialise VFP/NEON registers to 0
|
||||
" MOV R2,#0 \n"
|
||||
|
||||
#if TARGET_FEATURE_EXTENSION_REGISTER_COUNT >= 16
|
||||
//Initialise D16 registers to 0
|
||||
" VMOV D0, R2,R2 \n"
|
||||
" VMOV D1, R2,R2 \n"
|
||||
" VMOV D2, R2,R2 \n"
|
||||
" VMOV D3, R2,R2 \n"
|
||||
" VMOV D4, R2,R2 \n"
|
||||
" VMOV D5, R2,R2 \n"
|
||||
" VMOV D6, R2,R2 \n"
|
||||
" VMOV D7, R2,R2 \n"
|
||||
" VMOV D8, R2,R2 \n"
|
||||
" VMOV D9, R2,R2 \n"
|
||||
" VMOV D10,R2,R2 \n"
|
||||
" VMOV D11,R2,R2 \n"
|
||||
" VMOV D12,R2,R2 \n"
|
||||
" VMOV D13,R2,R2 \n"
|
||||
" VMOV D14,R2,R2 \n"
|
||||
" VMOV D15,R2,R2 \n"
|
||||
#endif
|
||||
|
||||
#if TARGET_FEATURE_EXTENSION_REGISTER_COUNT == 32
|
||||
//Initialise D32 registers to 0
|
||||
" VMOV D16,R2,R2 \n"
|
||||
" VMOV D17,R2,R2 \n"
|
||||
" VMOV D18,R2,R2 \n"
|
||||
" VMOV D19,R2,R2 \n"
|
||||
" VMOV D20,R2,R2 \n"
|
||||
" VMOV D21,R2,R2 \n"
|
||||
" VMOV D22,R2,R2 \n"
|
||||
" VMOV D23,R2,R2 \n"
|
||||
" VMOV D24,R2,R2 \n"
|
||||
" VMOV D25,R2,R2 \n"
|
||||
" VMOV D26,R2,R2 \n"
|
||||
" VMOV D27,R2,R2 \n"
|
||||
" VMOV D28,R2,R2 \n"
|
||||
" VMOV D29,R2,R2 \n"
|
||||
" VMOV D30,R2,R2 \n"
|
||||
" VMOV D31,R2,R2 \n"
|
||||
".endif \n"
|
||||
#endif
|
||||
//Initialise FPSCR to a known state
|
||||
" VMRS R2,FPSCR \n"
|
||||
" MOV32 R3,#0x00086060 \n" //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero.
|
||||
" AND R2,R2,R3 \n"
|
||||
" VMSR FPSCR,R2 \n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
#undef __IAR_FT
|
||||
#undef __ICCARM_V8
|
||||
|
||||
#pragma diag_default=Pe940
|
||||
#pragma diag_default=Pe177
|
||||
|
||||
#endif /* __CMSIS_ICCARM_H__ */
|
File diff suppressed because it is too large
Load Diff
|
@ -1,276 +0,0 @@
|
|||
/**************************************************************************//**
|
||||
* @file core_ca9.h
|
||||
* @brief CMSIS Cortex-A9 Core Peripheral Access Layer Header File
|
||||
* @version
|
||||
* @date 25 March 2013
|
||||
*
|
||||
* @note
|
||||
*
|
||||
******************************************************************************/
|
||||
/* Copyright (c) 2009 - 2012 ARM LIMITED
|
||||
|
||||
All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
- Neither the name of ARM nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
*
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#if defined ( __ICCARM__ )
|
||||
#pragma system_include /* treat file as system include file for MISRA check */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef __CORE_CA9_H_GENERIC
|
||||
#define __CORE_CA9_H_GENERIC
|
||||
|
||||
|
||||
/** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions
|
||||
CMSIS violates the following MISRA-C:2004 rules:
|
||||
|
||||
\li Required Rule 8.5, object/function definition in header file.<br>
|
||||
Function definitions in header files are used to allow 'inlining'.
|
||||
|
||||
\li Required Rule 18.4, declaration of union type or object of union type: '{...}'.<br>
|
||||
Unions are used for effective representation of core registers.
|
||||
|
||||
\li Advisory Rule 19.7, Function-like macro defined.<br>
|
||||
Function-like macros are used to allow more efficient code.
|
||||
*/
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* CMSIS definitions
|
||||
******************************************************************************/
|
||||
/** \ingroup Cortex_A9
|
||||
@{
|
||||
*/
|
||||
|
||||
/* CMSIS CA9 definitions */
|
||||
#define __CA9_CMSIS_VERSION_MAIN (0x03) /*!< [31:16] CMSIS HAL main version */
|
||||
#define __CA9_CMSIS_VERSION_SUB (0x10) /*!< [15:0] CMSIS HAL sub version */
|
||||
#define __CA9_CMSIS_VERSION ((__CA9_CMSIS_VERSION_MAIN << 16) | \
|
||||
__CA9_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
|
||||
|
||||
#define __CORTEX_A (0x09) /*!< Cortex-A Core */
|
||||
|
||||
|
||||
#if defined ( __CC_ARM )
|
||||
#define __ASM __asm /*!< asm keyword for ARM Compiler */
|
||||
#define __INLINE __inline /*!< inline keyword for ARM Compiler */
|
||||
#define __STATIC_INLINE static __inline
|
||||
#define __STATIC_ASM static __asm
|
||||
|
||||
#elif defined ( __ICCARM__ )
|
||||
#define __ASM __asm /*!< asm keyword for IAR Compiler */
|
||||
#define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */
|
||||
#define __STATIC_INLINE static inline
|
||||
#define __STATIC_ASM static __asm
|
||||
|
||||
#include <stdint.h>
|
||||
inline uint32_t __get_PSR(void) {
|
||||
__ASM("mrs r0, cpsr");
|
||||
}
|
||||
|
||||
#elif defined ( __TMS470__ )
|
||||
#define __ASM __asm /*!< asm keyword for TI CCS Compiler */
|
||||
#define __STATIC_INLINE static inline
|
||||
#define __STATIC_ASM static __asm
|
||||
|
||||
#elif defined ( __GNUC__ )
|
||||
#define __ASM __asm /*!< asm keyword for GNU Compiler */
|
||||
#define __INLINE inline /*!< inline keyword for GNU Compiler */
|
||||
#define __STATIC_INLINE static inline
|
||||
#define __STATIC_ASM static __asm
|
||||
|
||||
#elif defined ( __TASKING__ )
|
||||
#define __ASM __asm /*!< asm keyword for TASKING Compiler */
|
||||
#define __INLINE inline /*!< inline keyword for TASKING Compiler */
|
||||
#define __STATIC_INLINE static inline
|
||||
#define __STATIC_ASM static __asm
|
||||
|
||||
#endif
|
||||
|
||||
/** __FPU_USED indicates whether an FPU is used or not. For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions.
|
||||
*/
|
||||
#if defined ( __CC_ARM )
|
||||
#if defined __TARGET_FPU_VFP
|
||||
#if (__FPU_PRESENT == 1)
|
||||
#define __FPU_USED 1
|
||||
#else
|
||||
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#define __FPU_USED 0
|
||||
#endif
|
||||
#else
|
||||
#define __FPU_USED 0
|
||||
#endif
|
||||
|
||||
#elif defined ( __ICCARM__ )
|
||||
#if defined __ARMVFP__
|
||||
#if (__FPU_PRESENT == 1)
|
||||
#define __FPU_USED 1
|
||||
#else
|
||||
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#define __FPU_USED 0
|
||||
#endif
|
||||
#else
|
||||
#define __FPU_USED 0
|
||||
#endif
|
||||
|
||||
#elif defined ( __TMS470__ )
|
||||
#if defined __TI_VFP_SUPPORT__
|
||||
#if (__FPU_PRESENT == 1)
|
||||
#define __FPU_USED 1
|
||||
#else
|
||||
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#define __FPU_USED 0
|
||||
#endif
|
||||
#else
|
||||
#define __FPU_USED 0
|
||||
#endif
|
||||
|
||||
#elif defined ( __GNUC__ )
|
||||
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
|
||||
#if (__FPU_PRESENT == 1)
|
||||
#define __FPU_USED 1
|
||||
#else
|
||||
#warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#define __FPU_USED 0
|
||||
#endif
|
||||
#else
|
||||
#define __FPU_USED 0
|
||||
#endif
|
||||
|
||||
#elif defined ( __TASKING__ )
|
||||
#if defined __FPU_VFP__
|
||||
#if (__FPU_PRESENT == 1)
|
||||
#define __FPU_USED 1
|
||||
#else
|
||||
#error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)"
|
||||
#define __FPU_USED 0
|
||||
#endif
|
||||
#else
|
||||
#define __FPU_USED 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stdint.h> /*!< standard types definitions */
|
||||
#include "core_caInstr.h" /*!< Core Instruction Access */
|
||||
#include "core_caFunc.h" /*!< Core Function Access */
|
||||
#include "core_cm4_simd.h" /*!< Compiler specific SIMD Intrinsics */
|
||||
|
||||
#endif /* __CORE_CA9_H_GENERIC */
|
||||
|
||||
#ifndef __CMSIS_GENERIC
|
||||
|
||||
#ifndef __CORE_CA9_H_DEPENDANT
|
||||
#define __CORE_CA9_H_DEPENDANT
|
||||
|
||||
/* check device defines and use defaults */
|
||||
#if defined __CHECK_DEVICE_DEFINES
|
||||
#ifndef __CA9_REV
|
||||
#define __CA9_REV 0x0000
|
||||
#warning "__CA9_REV not defined in device header file; using default!"
|
||||
#endif
|
||||
|
||||
#ifndef __FPU_PRESENT
|
||||
#define __FPU_PRESENT 1
|
||||
#warning "__FPU_PRESENT not defined in device header file; using default!"
|
||||
#endif
|
||||
|
||||
#ifndef __Vendor_SysTickConfig
|
||||
#define __Vendor_SysTickConfig 1
|
||||
#endif
|
||||
|
||||
#if __Vendor_SysTickConfig == 0
|
||||
#error "__Vendor_SysTickConfig set to 0, but vendor systick timer must be supplied for Cortex-A9"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* IO definitions (access restrictions to peripheral registers) */
|
||||
/**
|
||||
\defgroup CMSIS_glob_defs CMSIS Global Defines
|
||||
|
||||
<strong>IO Type Qualifiers</strong> are used
|
||||
\li to specify the access to peripheral variables.
|
||||
\li for automatic generation of peripheral register debug information.
|
||||
*/
|
||||
#ifdef __cplusplus
|
||||
#define __I volatile /*!< Defines 'read only' permissions */
|
||||
#else
|
||||
#define __I volatile const /*!< Defines 'read only' permissions */
|
||||
#endif
|
||||
#define __O volatile /*!< Defines 'write only' permissions */
|
||||
#define __IO volatile /*!< Defines 'read / write' permissions */
|
||||
|
||||
/*@} end of group Cortex_A9 */
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Register Abstraction
|
||||
******************************************************************************/
|
||||
/** \defgroup CMSIS_core_register Defines and Type Definitions
|
||||
\brief Type definitions and defines for Cortex-A processor based devices.
|
||||
*/
|
||||
|
||||
/** \ingroup CMSIS_core_register
|
||||
\defgroup CMSIS_CORE Status and Control Registers
|
||||
\brief Core Register type definitions.
|
||||
@{
|
||||
*/
|
||||
|
||||
/** \brief Union type to access the Application Program Status Register (APSR).
|
||||
*/
|
||||
typedef union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */
|
||||
uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */
|
||||
uint32_t reserved1:7; /*!< bit: 20..23 Reserved */
|
||||
uint32_t Q:1; /*!< bit: 27 Saturation condition flag */
|
||||
uint32_t V:1; /*!< bit: 28 Overflow condition code flag */
|
||||
uint32_t C:1; /*!< bit: 29 Carry condition code flag */
|
||||
uint32_t Z:1; /*!< bit: 30 Zero condition code flag */
|
||||
uint32_t N:1; /*!< bit: 31 Negative condition code flag */
|
||||
} b; /*!< Structure used for bit access */
|
||||
uint32_t w; /*!< Type used for word access */
|
||||
} APSR_Type;
|
||||
|
||||
|
||||
/*@} end of group CMSIS_CORE */
|
||||
|
||||
/*@} end of CMSIS_Core_FPUFunctions */
|
||||
|
||||
|
||||
#endif /* __CORE_CA9_H_GENERIC */
|
||||
|
||||
#endif /* __CMSIS_GENERIC */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -1,45 +0,0 @@
|
|||
/**************************************************************************//**
|
||||
* @file core_caInstr.h
|
||||
* @brief CMSIS Cortex-A9 Core Peripheral Access Layer Header File
|
||||
* @version
|
||||
* @date 04. December 2012
|
||||
*
|
||||
* @note
|
||||
*
|
||||
******************************************************************************/
|
||||
/* Copyright (c) 2009 - 2012 ARM LIMITED
|
||||
|
||||
All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
- Neither the name of ARM nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
*
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef __CORE_CAINSTR_H__
|
||||
#define __CORE_CAINSTR_H__
|
||||
|
||||
#define __CORTEX_M 0x3
|
||||
#include "core_cmInstr.h"
|
||||
#undef __CORTEX_M
|
||||
|
||||
#endif
|
||||
|
|
@ -1,847 +0,0 @@
|
|||
;/**************************************************************************//**
|
||||
; * @file core_ca_mmu.h
|
||||
; * @brief MMU Startup File for A9_MP Device Series
|
||||
; * @version V1.01
|
||||
; * @date 10 Sept 2014
|
||||
; *
|
||||
; * @note
|
||||
; *
|
||||
; ******************************************************************************/
|
||||
;/* Copyright (c) 2012-2014 ARM LIMITED
|
||||
;
|
||||
; All rights reserved.
|
||||
; Redistribution and use in source and binary forms, with or without
|
||||
; modification, are permitted provided that the following conditions are met:
|
||||
; - Redistributions of source code must retain the above copyright
|
||||
; notice, this list of conditions and the following disclaimer.
|
||||
; - Redistributions in binary form must reproduce the above copyright
|
||||
; notice, this list of conditions and the following disclaimer in the
|
||||
; documentation and/or other materials provided with the distribution.
|
||||
; - Neither the name of ARM nor the names of its contributors may be used
|
||||
; to endorse or promote products derived from this software without
|
||||
; specific prior written permission.
|
||||
; *
|
||||
; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
; AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
; ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
; LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
; INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
; ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
; POSSIBILITY OF SUCH DAMAGE.
|
||||
; ---------------------------------------------------------------------------*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef _MMU_FUNC_H
|
||||
#define _MMU_FUNC_H
|
||||
|
||||
#define SECTION_DESCRIPTOR (0x2)
|
||||
#define SECTION_MASK (0xFFFFFFFC)
|
||||
|
||||
#define SECTION_TEXCB_MASK (0xFFFF8FF3)
|
||||
#define SECTION_B_SHIFT (2)
|
||||
#define SECTION_C_SHIFT (3)
|
||||
#define SECTION_TEX0_SHIFT (12)
|
||||
#define SECTION_TEX1_SHIFT (13)
|
||||
#define SECTION_TEX2_SHIFT (14)
|
||||
|
||||
#define SECTION_XN_MASK (0xFFFFFFEF)
|
||||
#define SECTION_XN_SHIFT (4)
|
||||
|
||||
#define SECTION_DOMAIN_MASK (0xFFFFFE1F)
|
||||
#define SECTION_DOMAIN_SHIFT (5)
|
||||
|
||||
#define SECTION_P_MASK (0xFFFFFDFF)
|
||||
#define SECTION_P_SHIFT (9)
|
||||
|
||||
#define SECTION_AP_MASK (0xFFFF73FF)
|
||||
#define SECTION_AP_SHIFT (10)
|
||||
#define SECTION_AP2_SHIFT (15)
|
||||
|
||||
#define SECTION_S_MASK (0xFFFEFFFF)
|
||||
#define SECTION_S_SHIFT (16)
|
||||
|
||||
#define SECTION_NG_MASK (0xFFFDFFFF)
|
||||
#define SECTION_NG_SHIFT (17)
|
||||
|
||||
#define SECTION_NS_MASK (0xFFF7FFFF)
|
||||
#define SECTION_NS_SHIFT (19)
|
||||
|
||||
|
||||
#define PAGE_L1_DESCRIPTOR (0x1)
|
||||
#define PAGE_L1_MASK (0xFFFFFFFC)
|
||||
|
||||
#define PAGE_L2_4K_DESC (0x2)
|
||||
#define PAGE_L2_4K_MASK (0xFFFFFFFD)
|
||||
|
||||
#define PAGE_L2_64K_DESC (0x1)
|
||||
#define PAGE_L2_64K_MASK (0xFFFFFFFC)
|
||||
|
||||
#define PAGE_4K_TEXCB_MASK (0xFFFFFE33)
|
||||
#define PAGE_4K_B_SHIFT (2)
|
||||
#define PAGE_4K_C_SHIFT (3)
|
||||
#define PAGE_4K_TEX0_SHIFT (6)
|
||||
#define PAGE_4K_TEX1_SHIFT (7)
|
||||
#define PAGE_4K_TEX2_SHIFT (8)
|
||||
|
||||
#define PAGE_64K_TEXCB_MASK (0xFFFF8FF3)
|
||||
#define PAGE_64K_B_SHIFT (2)
|
||||
#define PAGE_64K_C_SHIFT (3)
|
||||
#define PAGE_64K_TEX0_SHIFT (12)
|
||||
#define PAGE_64K_TEX1_SHIFT (13)
|
||||
#define PAGE_64K_TEX2_SHIFT (14)
|
||||
|
||||
#define PAGE_TEXCB_MASK (0xFFFF8FF3)
|
||||
#define PAGE_B_SHIFT (2)
|
||||
#define PAGE_C_SHIFT (3)
|
||||
#define PAGE_TEX_SHIFT (12)
|
||||
|
||||
#define PAGE_XN_4K_MASK (0xFFFFFFFE)
|
||||
#define PAGE_XN_4K_SHIFT (0)
|
||||
#define PAGE_XN_64K_MASK (0xFFFF7FFF)
|
||||
#define PAGE_XN_64K_SHIFT (15)
|
||||
|
||||
|
||||
#define PAGE_DOMAIN_MASK (0xFFFFFE1F)
|
||||
#define PAGE_DOMAIN_SHIFT (5)
|
||||
|
||||
#define PAGE_P_MASK (0xFFFFFDFF)
|
||||
#define PAGE_P_SHIFT (9)
|
||||
|
||||
#define PAGE_AP_MASK (0xFFFFFDCF)
|
||||
#define PAGE_AP_SHIFT (4)
|
||||
#define PAGE_AP2_SHIFT (9)
|
||||
|
||||
#define PAGE_S_MASK (0xFFFFFBFF)
|
||||
#define PAGE_S_SHIFT (10)
|
||||
|
||||
#define PAGE_NG_MASK (0xFFFFF7FF)
|
||||
#define PAGE_NG_SHIFT (11)
|
||||
|
||||
#define PAGE_NS_MASK (0xFFFFFFF7)
|
||||
#define PAGE_NS_SHIFT (3)
|
||||
|
||||
#define OFFSET_1M (0x00100000)
|
||||
#define OFFSET_64K (0x00010000)
|
||||
#define OFFSET_4K (0x00001000)
|
||||
|
||||
#define DESCRIPTOR_FAULT (0x00000000)
|
||||
|
||||
/* ########################### MMU Function Access ########################### */
|
||||
/** \ingroup MMU_FunctionInterface
|
||||
\defgroup MMU_Functions MMU Functions Interface
|
||||
@{
|
||||
*/
|
||||
|
||||
/* Attributes enumerations */
|
||||
|
||||
/* Region size attributes */
|
||||
typedef enum
|
||||
{
|
||||
SECTION,
|
||||
PAGE_4k,
|
||||
PAGE_64k,
|
||||
} mmu_region_size_Type;
|
||||
|
||||
/* Region type attributes */
|
||||
typedef enum
|
||||
{
|
||||
NORMAL,
|
||||
DEVICE,
|
||||
SHARED_DEVICE,
|
||||
NON_SHARED_DEVICE,
|
||||
STRONGLY_ORDERED
|
||||
} mmu_memory_Type;
|
||||
|
||||
/* Region cacheability attributes */
|
||||
typedef enum
|
||||
{
|
||||
NON_CACHEABLE,
|
||||
WB_WA,
|
||||
WT,
|
||||
WB_NO_WA,
|
||||
} mmu_cacheability_Type;
|
||||
|
||||
/* Region parity check attributes */
|
||||
typedef enum
|
||||
{
|
||||
ECC_DISABLED,
|
||||
ECC_ENABLED,
|
||||
} mmu_ecc_check_Type;
|
||||
|
||||
/* Region execution attributes */
|
||||
typedef enum
|
||||
{
|
||||
EXECUTE,
|
||||
NON_EXECUTE,
|
||||
} mmu_execute_Type;
|
||||
|
||||
/* Region global attributes */
|
||||
typedef enum
|
||||
{
|
||||
GLOBAL,
|
||||
NON_GLOBAL,
|
||||
} mmu_global_Type;
|
||||
|
||||
/* Region shareability attributes */
|
||||
typedef enum
|
||||
{
|
||||
NON_SHARED,
|
||||
SHARED,
|
||||
} mmu_shared_Type;
|
||||
|
||||
/* Region security attributes */
|
||||
typedef enum
|
||||
{
|
||||
SECURE,
|
||||
NON_SECURE,
|
||||
} mmu_secure_Type;
|
||||
|
||||
/* Region access attributes */
|
||||
typedef enum
|
||||
{
|
||||
NO_ACCESS,
|
||||
RW,
|
||||
READ,
|
||||
} mmu_access_Type;
|
||||
|
||||
/* Memory Region definition */
|
||||
typedef struct RegionStruct {
|
||||
mmu_region_size_Type rg_t;
|
||||
mmu_memory_Type mem_t;
|
||||
uint8_t domain;
|
||||
mmu_cacheability_Type inner_norm_t;
|
||||
mmu_cacheability_Type outer_norm_t;
|
||||
mmu_ecc_check_Type e_t;
|
||||
mmu_execute_Type xn_t;
|
||||
mmu_global_Type g_t;
|
||||
mmu_secure_Type sec_t;
|
||||
mmu_access_Type priv_t;
|
||||
mmu_access_Type user_t;
|
||||
mmu_shared_Type sh_t;
|
||||
|
||||
} mmu_region_attributes_Type;
|
||||
|
||||
/** \brief Set section execution-never attribute
|
||||
|
||||
The function sets section execution-never attribute
|
||||
|
||||
\param [out] descriptor_l1 L1 descriptor.
|
||||
\param [in] xn Section execution-never attribute : EXECUTE , NON_EXECUTE.
|
||||
|
||||
\return 0
|
||||
*/
|
||||
__STATIC_INLINE int __xn_section(uint32_t *descriptor_l1, mmu_execute_Type xn)
|
||||
{
|
||||
*descriptor_l1 &= SECTION_XN_MASK;
|
||||
*descriptor_l1 |= ((xn & 0x1) << SECTION_XN_SHIFT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Set section domain
|
||||
|
||||
The function sets section domain
|
||||
|
||||
\param [out] descriptor_l1 L1 descriptor.
|
||||
\param [in] domain Section domain
|
||||
|
||||
\return 0
|
||||
*/
|
||||
__STATIC_INLINE int __domain_section(uint32_t *descriptor_l1, uint8_t domain)
|
||||
{
|
||||
*descriptor_l1 &= SECTION_DOMAIN_MASK;
|
||||
*descriptor_l1 |= ((domain & 0xF) << SECTION_DOMAIN_SHIFT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Set section parity check
|
||||
|
||||
The function sets section parity check
|
||||
|
||||
\param [out] descriptor_l1 L1 descriptor.
|
||||
\param [in] p_bit Parity check: ECC_DISABLED, ECC_ENABLED
|
||||
|
||||
\return 0
|
||||
*/
|
||||
__STATIC_INLINE int __p_section(uint32_t *descriptor_l1, mmu_ecc_check_Type p_bit)
|
||||
{
|
||||
*descriptor_l1 &= SECTION_P_MASK;
|
||||
*descriptor_l1 |= ((p_bit & 0x1) << SECTION_P_SHIFT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Set section access privileges
|
||||
|
||||
The function sets section access privileges
|
||||
|
||||
\param [out] descriptor_l1 L1 descriptor.
|
||||
\param [in] user User Level Access: NO_ACCESS, RW, READ
|
||||
\param [in] priv Privilege Level Access: NO_ACCESS, RW, READ
|
||||
\param [in] afe Access flag enable
|
||||
|
||||
\return 0
|
||||
*/
|
||||
__STATIC_INLINE int __ap_section(uint32_t *descriptor_l1, mmu_access_Type user, mmu_access_Type priv, uint32_t afe)
|
||||
{
|
||||
uint32_t ap = 0;
|
||||
|
||||
if (afe == 0) { //full access
|
||||
if ((priv == NO_ACCESS) && (user == NO_ACCESS)) { ap = 0x0; }
|
||||
else if ((priv == RW) && (user == NO_ACCESS)) { ap = 0x1; }
|
||||
else if ((priv == RW) && (user == READ)) { ap = 0x2; }
|
||||
else if ((priv == RW) && (user == RW)) { ap = 0x3; }
|
||||
else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; }
|
||||
else if ((priv == READ) && (user == READ)) { ap = 0x7; }
|
||||
}
|
||||
|
||||
else { //Simplified access
|
||||
if ((priv == RW) && (user == NO_ACCESS)) { ap = 0x1; }
|
||||
else if ((priv == RW) && (user == RW)) { ap = 0x3; }
|
||||
else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; }
|
||||
else if ((priv == READ) && (user == READ)) { ap = 0x7; }
|
||||
}
|
||||
|
||||
*descriptor_l1 &= SECTION_AP_MASK;
|
||||
*descriptor_l1 |= (ap & 0x3) << SECTION_AP_SHIFT;
|
||||
*descriptor_l1 |= ((ap & 0x4)>>2) << SECTION_AP2_SHIFT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Set section shareability
|
||||
|
||||
The function sets section shareability
|
||||
|
||||
\param [out] descriptor_l1 L1 descriptor.
|
||||
\param [in] s_bit Section shareability: NON_SHARED, SHARED
|
||||
|
||||
\return 0
|
||||
*/
|
||||
__STATIC_INLINE int __shared_section(uint32_t *descriptor_l1, mmu_shared_Type s_bit)
|
||||
{
|
||||
*descriptor_l1 &= SECTION_S_MASK;
|
||||
*descriptor_l1 |= ((s_bit & 0x1) << SECTION_S_SHIFT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Set section Global attribute
|
||||
|
||||
The function sets section Global attribute
|
||||
|
||||
\param [out] descriptor_l1 L1 descriptor.
|
||||
\param [in] g_bit Section attribute: GLOBAL, NON_GLOBAL
|
||||
|
||||
\return 0
|
||||
*/
|
||||
__STATIC_INLINE int __global_section(uint32_t *descriptor_l1, mmu_global_Type g_bit)
|
||||
{
|
||||
*descriptor_l1 &= SECTION_NG_MASK;
|
||||
*descriptor_l1 |= ((g_bit & 0x1) << SECTION_NG_SHIFT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Set section Security attribute
|
||||
|
||||
The function sets section Global attribute
|
||||
|
||||
\param [out] descriptor_l1 L1 descriptor.
|
||||
\param [in] s_bit Section Security attribute: SECURE, NON_SECURE
|
||||
|
||||
\return 0
|
||||
*/
|
||||
__STATIC_INLINE int __secure_section(uint32_t *descriptor_l1, mmu_secure_Type s_bit)
|
||||
{
|
||||
*descriptor_l1 &= SECTION_NS_MASK;
|
||||
*descriptor_l1 |= ((s_bit & 0x1) << SECTION_NS_SHIFT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Page 4k or 64k */
|
||||
/** \brief Set 4k/64k page execution-never attribute
|
||||
|
||||
The function sets 4k/64k page execution-never attribute
|
||||
|
||||
\param [out] descriptor_l2 L2 descriptor.
|
||||
\param [in] xn Page execution-never attribute : EXECUTE , NON_EXECUTE.
|
||||
\param [in] page Page size: PAGE_4k, PAGE_64k,
|
||||
|
||||
\return 0
|
||||
*/
|
||||
__STATIC_INLINE int __xn_page(uint32_t *descriptor_l2, mmu_execute_Type xn, mmu_region_size_Type page)
|
||||
{
|
||||
if (page == PAGE_4k)
|
||||
{
|
||||
*descriptor_l2 &= PAGE_XN_4K_MASK;
|
||||
*descriptor_l2 |= ((xn & 0x1) << PAGE_XN_4K_SHIFT);
|
||||
}
|
||||
else
|
||||
{
|
||||
*descriptor_l2 &= PAGE_XN_64K_MASK;
|
||||
*descriptor_l2 |= ((xn & 0x1) << PAGE_XN_64K_SHIFT);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Set 4k/64k page domain
|
||||
|
||||
The function sets 4k/64k page domain
|
||||
|
||||
\param [out] descriptor_l1 L1 descriptor.
|
||||
\param [in] domain Page domain
|
||||
|
||||
\return 0
|
||||
*/
|
||||
__STATIC_INLINE int __domain_page(uint32_t *descriptor_l1, uint8_t domain)
|
||||
{
|
||||
*descriptor_l1 &= PAGE_DOMAIN_MASK;
|
||||
*descriptor_l1 |= ((domain & 0xf) << PAGE_DOMAIN_SHIFT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Set 4k/64k page parity check
|
||||
|
||||
The function sets 4k/64k page parity check
|
||||
|
||||
\param [out] descriptor_l1 L1 descriptor.
|
||||
\param [in] p_bit Parity check: ECC_DISABLED, ECC_ENABLED
|
||||
|
||||
\return 0
|
||||
*/
|
||||
__STATIC_INLINE int __p_page(uint32_t *descriptor_l1, mmu_ecc_check_Type p_bit)
|
||||
{
|
||||
*descriptor_l1 &= SECTION_P_MASK;
|
||||
*descriptor_l1 |= ((p_bit & 0x1) << SECTION_P_SHIFT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Set 4k/64k page access privileges
|
||||
|
||||
The function sets 4k/64k page access privileges
|
||||
|
||||
\param [out] descriptor_l2 L2 descriptor.
|
||||
\param [in] user User Level Access: NO_ACCESS, RW, READ
|
||||
\param [in] priv Privilege Level Access: NO_ACCESS, RW, READ
|
||||
\param [in] afe Access flag enable
|
||||
|
||||
\return 0
|
||||
*/
|
||||
__STATIC_INLINE int __ap_page(uint32_t *descriptor_l2, mmu_access_Type user, mmu_access_Type priv, uint32_t afe)
|
||||
{
|
||||
uint32_t ap = 0;
|
||||
|
||||
if (afe == 0) { //full access
|
||||
if ((priv == NO_ACCESS) && (user == NO_ACCESS)) { ap = 0x0; }
|
||||
else if ((priv == RW) && (user == NO_ACCESS)) { ap = 0x1; }
|
||||
else if ((priv == RW) && (user == READ)) { ap = 0x2; }
|
||||
else if ((priv == RW) && (user == RW)) { ap = 0x3; }
|
||||
else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; }
|
||||
else if ((priv == READ) && (user == READ)) { ap = 0x6; }
|
||||
}
|
||||
|
||||
else { //Simplified access
|
||||
if ((priv == RW) && (user == NO_ACCESS)) { ap = 0x1; }
|
||||
else if ((priv == RW) && (user == RW)) { ap = 0x3; }
|
||||
else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; }
|
||||
else if ((priv == READ) && (user == READ)) { ap = 0x7; }
|
||||
}
|
||||
|
||||
*descriptor_l2 &= PAGE_AP_MASK;
|
||||
*descriptor_l2 |= (ap & 0x3) << PAGE_AP_SHIFT;
|
||||
*descriptor_l2 |= ((ap & 0x4)>>2) << PAGE_AP2_SHIFT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Set 4k/64k page shareability
|
||||
|
||||
The function sets 4k/64k page shareability
|
||||
|
||||
\param [out] descriptor_l2 L2 descriptor.
|
||||
\param [in] s_bit 4k/64k page shareability: NON_SHARED, SHARED
|
||||
|
||||
\return 0
|
||||
*/
|
||||
__STATIC_INLINE int __shared_page(uint32_t *descriptor_l2, mmu_shared_Type s_bit)
|
||||
{
|
||||
*descriptor_l2 &= PAGE_S_MASK;
|
||||
*descriptor_l2 |= ((s_bit & 0x1) << PAGE_S_SHIFT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Set 4k/64k page Global attribute
|
||||
|
||||
The function sets 4k/64k page Global attribute
|
||||
|
||||
\param [out] descriptor_l2 L2 descriptor.
|
||||
\param [in] g_bit 4k/64k page attribute: GLOBAL, NON_GLOBAL
|
||||
|
||||
\return 0
|
||||
*/
|
||||
__STATIC_INLINE int __global_page(uint32_t *descriptor_l2, mmu_global_Type g_bit)
|
||||
{
|
||||
*descriptor_l2 &= PAGE_NG_MASK;
|
||||
*descriptor_l2 |= ((g_bit & 0x1) << PAGE_NG_SHIFT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Set 4k/64k page Security attribute
|
||||
|
||||
The function sets 4k/64k page Global attribute
|
||||
|
||||
\param [out] descriptor_l1 L1 descriptor.
|
||||
\param [in] s_bit 4k/64k page Security attribute: SECURE, NON_SECURE
|
||||
|
||||
\return 0
|
||||
*/
|
||||
__STATIC_INLINE int __secure_page(uint32_t *descriptor_l1, mmu_secure_Type s_bit)
|
||||
{
|
||||
*descriptor_l1 &= PAGE_NS_MASK;
|
||||
*descriptor_l1 |= ((s_bit & 0x1) << PAGE_NS_SHIFT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/** \brief Set Section memory attributes
|
||||
|
||||
The function sets section memory attributes
|
||||
|
||||
\param [out] descriptor_l1 L1 descriptor.
|
||||
\param [in] mem Section memory type: NORMAL, DEVICE, SHARED_DEVICE, NON_SHARED_DEVICE, STRONGLY_ORDERED
|
||||
\param [in] outer Outer cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA,
|
||||
\param [in] inner Inner cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA,
|
||||
|
||||
\return 0
|
||||
*/
|
||||
__STATIC_INLINE int __memory_section(uint32_t *descriptor_l1, mmu_memory_Type mem, mmu_cacheability_Type outer, mmu_cacheability_Type inner)
|
||||
{
|
||||
*descriptor_l1 &= SECTION_TEXCB_MASK;
|
||||
|
||||
if (STRONGLY_ORDERED == mem)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (SHARED_DEVICE == mem)
|
||||
{
|
||||
*descriptor_l1 |= (1 << SECTION_B_SHIFT);
|
||||
}
|
||||
else if (NON_SHARED_DEVICE == mem)
|
||||
{
|
||||
*descriptor_l1 |= (1 << SECTION_TEX1_SHIFT);
|
||||
}
|
||||
else if (NORMAL == mem)
|
||||
{
|
||||
*descriptor_l1 |= 1 << SECTION_TEX2_SHIFT;
|
||||
switch(inner)
|
||||
{
|
||||
case NON_CACHEABLE:
|
||||
break;
|
||||
case WB_WA:
|
||||
*descriptor_l1 |= (1 << SECTION_B_SHIFT);
|
||||
break;
|
||||
case WT:
|
||||
*descriptor_l1 |= 1 << SECTION_C_SHIFT;
|
||||
break;
|
||||
case WB_NO_WA:
|
||||
*descriptor_l1 |= (1 << SECTION_B_SHIFT) | (1 << SECTION_C_SHIFT);
|
||||
break;
|
||||
}
|
||||
switch(outer)
|
||||
{
|
||||
case NON_CACHEABLE:
|
||||
break;
|
||||
case WB_WA:
|
||||
*descriptor_l1 |= (1 << SECTION_TEX0_SHIFT);
|
||||
break;
|
||||
case WT:
|
||||
*descriptor_l1 |= 1 << SECTION_TEX1_SHIFT;
|
||||
break;
|
||||
case WB_NO_WA:
|
||||
*descriptor_l1 |= (1 << SECTION_TEX0_SHIFT) | (1 << SECTION_TEX0_SHIFT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Set 4k/64k page memory attributes
|
||||
|
||||
The function sets 4k/64k page memory attributes
|
||||
|
||||
\param [out] descriptor_l2 L2 descriptor.
|
||||
\param [in] mem 4k/64k page memory type: NORMAL, DEVICE, SHARED_DEVICE, NON_SHARED_DEVICE, STRONGLY_ORDERED
|
||||
\param [in] outer Outer cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA,
|
||||
\param [in] inner Inner cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA,
|
||||
|
||||
\return 0
|
||||
*/
|
||||
__STATIC_INLINE int __memory_page(uint32_t *descriptor_l2, mmu_memory_Type mem, mmu_cacheability_Type outer, mmu_cacheability_Type inner, mmu_region_size_Type page)
|
||||
{
|
||||
*descriptor_l2 &= PAGE_4K_TEXCB_MASK;
|
||||
|
||||
if (page == PAGE_64k)
|
||||
{
|
||||
//same as section
|
||||
__memory_section(descriptor_l2, mem, outer, inner);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (STRONGLY_ORDERED == mem)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else if (SHARED_DEVICE == mem)
|
||||
{
|
||||
*descriptor_l2 |= (1 << PAGE_4K_B_SHIFT);
|
||||
}
|
||||
else if (NON_SHARED_DEVICE == mem)
|
||||
{
|
||||
*descriptor_l2 |= (1 << PAGE_4K_TEX1_SHIFT);
|
||||
}
|
||||
else if (NORMAL == mem)
|
||||
{
|
||||
*descriptor_l2 |= 1 << PAGE_4K_TEX2_SHIFT;
|
||||
switch(inner)
|
||||
{
|
||||
case NON_CACHEABLE:
|
||||
break;
|
||||
case WB_WA:
|
||||
*descriptor_l2 |= (1 << PAGE_4K_B_SHIFT);
|
||||
break;
|
||||
case WT:
|
||||
*descriptor_l2 |= 1 << PAGE_4K_C_SHIFT;
|
||||
break;
|
||||
case WB_NO_WA:
|
||||
*descriptor_l2 |= (1 << PAGE_4K_B_SHIFT) | (1 << PAGE_4K_C_SHIFT);
|
||||
break;
|
||||
}
|
||||
switch(outer)
|
||||
{
|
||||
case NON_CACHEABLE:
|
||||
break;
|
||||
case WB_WA:
|
||||
*descriptor_l2 |= (1 << PAGE_4K_TEX0_SHIFT);
|
||||
break;
|
||||
case WT:
|
||||
*descriptor_l2 |= 1 << PAGE_4K_TEX1_SHIFT;
|
||||
break;
|
||||
case WB_NO_WA:
|
||||
*descriptor_l2 |= (1 << PAGE_4K_TEX0_SHIFT) | (1 << PAGE_4K_TEX0_SHIFT);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** \brief Create a L1 section descriptor
|
||||
|
||||
The function creates a section descriptor.
|
||||
|
||||
Assumptions:
|
||||
- 16MB super sections not supported
|
||||
- TEX remap disabled, so memory type and attributes are described directly by bits in the descriptor
|
||||
- Functions always return 0
|
||||
|
||||
\param [out] descriptor L1 descriptor
|
||||
\param [out] descriptor2 L2 descriptor
|
||||
\param [in] reg Section attributes
|
||||
|
||||
\return 0
|
||||
*/
|
||||
__STATIC_INLINE int __get_section_descriptor(uint32_t *descriptor, mmu_region_attributes_Type reg)
|
||||
{
|
||||
*descriptor = 0;
|
||||
|
||||
__memory_section(descriptor, reg.mem_t, reg.outer_norm_t, reg.inner_norm_t);
|
||||
__xn_section(descriptor,reg.xn_t);
|
||||
__domain_section(descriptor, reg.domain);
|
||||
__p_section(descriptor, reg.e_t);
|
||||
__ap_section(descriptor, reg.priv_t, reg.user_t, 1);
|
||||
__shared_section(descriptor,reg.sh_t);
|
||||
__global_section(descriptor,reg.g_t);
|
||||
__secure_section(descriptor,reg.sec_t);
|
||||
*descriptor &= SECTION_MASK;
|
||||
*descriptor |= SECTION_DESCRIPTOR;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/** \brief Create a L1 and L2 4k/64k page descriptor
|
||||
|
||||
The function creates a 4k/64k page descriptor.
|
||||
Assumptions:
|
||||
- TEX remap disabled, so memory type and attributes are described directly by bits in the descriptor
|
||||
- Functions always return 0
|
||||
|
||||
\param [out] descriptor L1 descriptor
|
||||
\param [out] descriptor2 L2 descriptor
|
||||
\param [in] reg 4k/64k page attributes
|
||||
|
||||
\return 0
|
||||
*/
|
||||
__STATIC_INLINE int __get_page_descriptor(uint32_t *descriptor, uint32_t *descriptor2, mmu_region_attributes_Type reg)
|
||||
{
|
||||
*descriptor = 0;
|
||||
*descriptor2 = 0;
|
||||
|
||||
switch (reg.rg_t)
|
||||
{
|
||||
case PAGE_4k:
|
||||
__memory_page(descriptor2, reg.mem_t, reg.outer_norm_t, reg.inner_norm_t, PAGE_4k);
|
||||
__xn_page(descriptor2, reg.xn_t, PAGE_4k);
|
||||
__domain_page(descriptor, reg.domain);
|
||||
__p_page(descriptor, reg.e_t);
|
||||
__ap_page(descriptor2, reg.priv_t, reg.user_t, 1);
|
||||
__shared_page(descriptor2,reg.sh_t);
|
||||
__global_page(descriptor2,reg.g_t);
|
||||
__secure_page(descriptor,reg.sec_t);
|
||||
*descriptor &= PAGE_L1_MASK;
|
||||
*descriptor |= PAGE_L1_DESCRIPTOR;
|
||||
*descriptor2 &= PAGE_L2_4K_MASK;
|
||||
*descriptor2 |= PAGE_L2_4K_DESC;
|
||||
break;
|
||||
|
||||
case PAGE_64k:
|
||||
__memory_page(descriptor2, reg.mem_t, reg.outer_norm_t, reg.inner_norm_t, PAGE_64k);
|
||||
__xn_page(descriptor2, reg.xn_t, PAGE_64k);
|
||||
__domain_page(descriptor, reg.domain);
|
||||
__p_page(descriptor, reg.e_t);
|
||||
__ap_page(descriptor2, reg.priv_t, reg.user_t, 1);
|
||||
__shared_page(descriptor2,reg.sh_t);
|
||||
__global_page(descriptor2,reg.g_t);
|
||||
__secure_page(descriptor,reg.sec_t);
|
||||
*descriptor &= PAGE_L1_MASK;
|
||||
*descriptor |= PAGE_L1_DESCRIPTOR;
|
||||
*descriptor2 &= PAGE_L2_64K_MASK;
|
||||
*descriptor2 |= PAGE_L2_64K_DESC;
|
||||
break;
|
||||
|
||||
case SECTION:
|
||||
//error
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/** \brief Create a 1MB Section
|
||||
|
||||
\param [in] ttb Translation table base address
|
||||
\param [in] base_address Section base address
|
||||
\param [in] count Number of sections to create
|
||||
\param [in] descriptor_l1 L1 descriptor (region attributes)
|
||||
|
||||
*/
|
||||
__STATIC_INLINE void __TTSection(uint32_t *ttb, uint32_t base_address, uint32_t count, uint32_t descriptor_l1)
|
||||
{
|
||||
uint32_t offset;
|
||||
uint32_t entry;
|
||||
uint32_t i;
|
||||
|
||||
offset = base_address >> 20;
|
||||
entry = (base_address & 0xFFF00000) | descriptor_l1;
|
||||
|
||||
//4 bytes aligned
|
||||
ttb = ttb + offset;
|
||||
|
||||
for (i = 0; i < count; i++ )
|
||||
{
|
||||
//4 bytes aligned
|
||||
*ttb++ = entry;
|
||||
entry += OFFSET_1M;
|
||||
}
|
||||
}
|
||||
|
||||
/** \brief Create a 4k page entry
|
||||
|
||||
\param [in] ttb L1 table base address
|
||||
\param [in] base_address 4k base address
|
||||
\param [in] count Number of 4k pages to create
|
||||
\param [in] descriptor_l1 L1 descriptor (region attributes)
|
||||
\param [in] ttb_l2 L2 table base address
|
||||
\param [in] descriptor_l2 L2 descriptor (region attributes)
|
||||
|
||||
*/
|
||||
__STATIC_INLINE void __TTPage_4k(uint32_t *ttb, uint32_t base_address, uint32_t count, uint32_t descriptor_l1, uint32_t *ttb_l2, uint32_t descriptor_l2 )
|
||||
{
|
||||
|
||||
uint32_t offset, offset2;
|
||||
uint32_t entry, entry2;
|
||||
uint32_t i;
|
||||
|
||||
|
||||
offset = base_address >> 20;
|
||||
entry = ((int)ttb_l2 & 0xFFFFFC00) | descriptor_l1;
|
||||
|
||||
//4 bytes aligned
|
||||
ttb += offset;
|
||||
//create l1_entry
|
||||
*ttb = entry;
|
||||
|
||||
offset2 = (base_address & 0xff000) >> 12;
|
||||
ttb_l2 += offset2;
|
||||
entry2 = (base_address & 0xFFFFF000) | descriptor_l2;
|
||||
for (i = 0; i < count; i++ )
|
||||
{
|
||||
//4 bytes aligned
|
||||
*ttb_l2++ = entry2;
|
||||
entry2 += OFFSET_4K;
|
||||
}
|
||||
}
|
||||
|
||||
/** \brief Create a 64k page entry
|
||||
|
||||
\param [in] ttb L1 table base address
|
||||
\param [in] base_address 64k base address
|
||||
\param [in] count Number of 64k pages to create
|
||||
\param [in] descriptor_l1 L1 descriptor (region attributes)
|
||||
\param [in] ttb_l2 L2 table base address
|
||||
\param [in] descriptor_l2 L2 descriptor (region attributes)
|
||||
|
||||
*/
|
||||
__STATIC_INLINE void __TTPage_64k(uint32_t *ttb, uint32_t base_address, uint32_t count, uint32_t descriptor_l1, uint32_t *ttb_l2, uint32_t descriptor_l2 )
|
||||
{
|
||||
uint32_t offset, offset2;
|
||||
uint32_t entry, entry2;
|
||||
uint32_t i,j;
|
||||
|
||||
|
||||
offset = base_address >> 20;
|
||||
entry = ((int)ttb_l2 & 0xFFFFFC00) | descriptor_l1;
|
||||
|
||||
//4 bytes aligned
|
||||
ttb += offset;
|
||||
//create l1_entry
|
||||
*ttb = entry;
|
||||
|
||||
offset2 = (base_address & 0xff000) >> 12;
|
||||
ttb_l2 += offset2;
|
||||
entry2 = (base_address & 0xFFFF0000) | descriptor_l2;
|
||||
for (i = 0; i < count; i++ )
|
||||
{
|
||||
//create 16 entries
|
||||
for (j = 0; j < 16; j++)
|
||||
//4 bytes aligned
|
||||
*ttb_l2++ = entry2;
|
||||
entry2 += OFFSET_64K;
|
||||
}
|
||||
}
|
||||
|
||||
/*@} end of MMU_Functions */
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -1,673 +0,0 @@
|
|||
/**************************************************************************//**
|
||||
* @file core_cm4_simd.h
|
||||
* @brief CMSIS Cortex-M4 SIMD Header File
|
||||
* @version V3.20
|
||||
* @date 25. February 2013
|
||||
*
|
||||
* @note
|
||||
*
|
||||
******************************************************************************/
|
||||
/* Copyright (c) 2009 - 2013 ARM LIMITED
|
||||
|
||||
All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
- Neither the name of ARM nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
*
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef __CORE_CM4_SIMD_H
|
||||
#define __CORE_CM4_SIMD_H
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* Hardware Abstraction Layer
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
/* ################### Compiler specific Intrinsics ########################### */
|
||||
/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics
|
||||
Access to dedicated SIMD instructions
|
||||
@{
|
||||
*/
|
||||
|
||||
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
|
||||
/* ARM armcc specific functions */
|
||||
|
||||
/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/
|
||||
#define __SADD8 __sadd8
|
||||
#define __QADD8 __qadd8
|
||||
#define __SHADD8 __shadd8
|
||||
#define __UADD8 __uadd8
|
||||
#define __UQADD8 __uqadd8
|
||||
#define __UHADD8 __uhadd8
|
||||
#define __SSUB8 __ssub8
|
||||
#define __QSUB8 __qsub8
|
||||
#define __SHSUB8 __shsub8
|
||||
#define __USUB8 __usub8
|
||||
#define __UQSUB8 __uqsub8
|
||||
#define __UHSUB8 __uhsub8
|
||||
#define __SADD16 __sadd16
|
||||
#define __QADD16 __qadd16
|
||||
#define __SHADD16 __shadd16
|
||||
#define __UADD16 __uadd16
|
||||
#define __UQADD16 __uqadd16
|
||||
#define __UHADD16 __uhadd16
|
||||
#define __SSUB16 __ssub16
|
||||
#define __QSUB16 __qsub16
|
||||
#define __SHSUB16 __shsub16
|
||||
#define __USUB16 __usub16
|
||||
#define __UQSUB16 __uqsub16
|
||||
#define __UHSUB16 __uhsub16
|
||||
#define __SASX __sasx
|
||||
#define __QASX __qasx
|
||||
#define __SHASX __shasx
|
||||
#define __UASX __uasx
|
||||
#define __UQASX __uqasx
|
||||
#define __UHASX __uhasx
|
||||
#define __SSAX __ssax
|
||||
#define __QSAX __qsax
|
||||
#define __SHSAX __shsax
|
||||
#define __USAX __usax
|
||||
#define __UQSAX __uqsax
|
||||
#define __UHSAX __uhsax
|
||||
#define __USAD8 __usad8
|
||||
#define __USADA8 __usada8
|
||||
#define __SSAT16 __ssat16
|
||||
#define __USAT16 __usat16
|
||||
#define __UXTB16 __uxtb16
|
||||
#define __UXTAB16 __uxtab16
|
||||
#define __SXTB16 __sxtb16
|
||||
#define __SXTAB16 __sxtab16
|
||||
#define __SMUAD __smuad
|
||||
#define __SMUADX __smuadx
|
||||
#define __SMLAD __smlad
|
||||
#define __SMLADX __smladx
|
||||
#define __SMLALD __smlald
|
||||
#define __SMLALDX __smlaldx
|
||||
#define __SMUSD __smusd
|
||||
#define __SMUSDX __smusdx
|
||||
#define __SMLSD __smlsd
|
||||
#define __SMLSDX __smlsdx
|
||||
#define __SMLSLD __smlsld
|
||||
#define __SMLSLDX __smlsldx
|
||||
#define __SEL __sel
|
||||
#define __QADD __qadd
|
||||
#define __QSUB __qsub
|
||||
|
||||
#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \
|
||||
((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) )
|
||||
|
||||
#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \
|
||||
((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) )
|
||||
|
||||
#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \
|
||||
((int64_t)(ARG3) << 32) ) >> 32))
|
||||
|
||||
/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
|
||||
/* IAR iccarm specific functions */
|
||||
|
||||
/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/
|
||||
#include <cmsis_iar.h>
|
||||
|
||||
/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
|
||||
/* TI CCS specific functions */
|
||||
|
||||
/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/
|
||||
#include <cmsis_ccs.h>
|
||||
|
||||
/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
|
||||
/* GNU gcc specific functions */
|
||||
|
||||
/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
#define __SSAT16(ARG1,ARG2) \
|
||||
({ \
|
||||
uint32_t __RES, __ARG1 = (ARG1); \
|
||||
__ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||
__RES; \
|
||||
})
|
||||
|
||||
#define __USAT16(ARG1,ARG2) \
|
||||
({ \
|
||||
uint32_t __RES, __ARG1 = (ARG1); \
|
||||
__ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||
__RES; \
|
||||
})
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1));
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1));
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
#define __SMLALD(ARG1,ARG2,ARG3) \
|
||||
({ \
|
||||
uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((uint64_t)(ARG3) >> 32), __ARG3_L = (uint32_t)((uint64_t)(ARG3) & 0xFFFFFFFFUL); \
|
||||
__ASM volatile ("smlald %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \
|
||||
(uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \
|
||||
})
|
||||
|
||||
#define __SMLALDX(ARG1,ARG2,ARG3) \
|
||||
({ \
|
||||
uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((uint64_t)(ARG3) >> 32), __ARG3_L = (uint32_t)((uint64_t)(ARG3) & 0xFFFFFFFFUL); \
|
||||
__ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \
|
||||
(uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \
|
||||
})
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
#define __SMLSLD(ARG1,ARG2,ARG3) \
|
||||
({ \
|
||||
uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((ARG3) >> 32), __ARG3_L = (uint32_t)((ARG3) & 0xFFFFFFFFUL); \
|
||||
__ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \
|
||||
(uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \
|
||||
})
|
||||
|
||||
#define __SMLSLDX(ARG1,ARG2,ARG3) \
|
||||
({ \
|
||||
uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((ARG3) >> 32), __ARG3_L = (uint32_t)((ARG3) & 0xFFFFFFFFUL); \
|
||||
__ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \
|
||||
(uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \
|
||||
})
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SEL (uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
#define __PKHBT(ARG1,ARG2,ARG3) \
|
||||
({ \
|
||||
uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
|
||||
__ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
|
||||
__RES; \
|
||||
})
|
||||
|
||||
#define __PKHTB(ARG1,ARG2,ARG3) \
|
||||
({ \
|
||||
uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \
|
||||
if (ARG3 == 0) \
|
||||
__ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \
|
||||
else \
|
||||
__ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \
|
||||
__RES; \
|
||||
})
|
||||
|
||||
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3)
|
||||
{
|
||||
int32_t result;
|
||||
|
||||
__ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
|
||||
/* TASKING carm specific functions */
|
||||
|
||||
|
||||
/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/
|
||||
/* not yet supported */
|
||||
/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/*@} end of group CMSIS_SIMD_intrinsics */
|
||||
|
||||
|
||||
#endif /* __CORE_CM4_SIMD_H */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -1,916 +0,0 @@
|
|||
/**************************************************************************//**
|
||||
* @file core_cmInstr.h
|
||||
* @brief CMSIS Cortex-M Core Instruction Access Header File
|
||||
* @version V4.10
|
||||
* @date 18. March 2015
|
||||
*
|
||||
* @note
|
||||
*
|
||||
******************************************************************************/
|
||||
/* Copyright (c) 2009 - 2014 ARM LIMITED
|
||||
|
||||
All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
- Neither the name of ARM nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
*
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifndef __CORE_CMINSTR_H
|
||||
#define __CORE_CMINSTR_H
|
||||
|
||||
|
||||
/* ########################## Core Instruction Access ######################### */
|
||||
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
|
||||
Access to dedicated instructions
|
||||
@{
|
||||
*/
|
||||
|
||||
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
|
||||
/* ARM armcc specific functions */
|
||||
|
||||
#if (__ARMCC_VERSION < 400677)
|
||||
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
|
||||
#endif
|
||||
|
||||
|
||||
/** \brief No Operation
|
||||
|
||||
No Operation does nothing. This instruction can be used for code alignment purposes.
|
||||
*/
|
||||
#define __NOP __nop
|
||||
|
||||
|
||||
/** \brief Wait For Interrupt
|
||||
|
||||
Wait For Interrupt is a hint instruction that suspends execution
|
||||
until one of a number of events occurs.
|
||||
*/
|
||||
#define __WFI __wfi
|
||||
|
||||
|
||||
/** \brief Wait For Event
|
||||
|
||||
Wait For Event is a hint instruction that permits the processor to enter
|
||||
a low-power state until one of a number of events occurs.
|
||||
*/
|
||||
#define __WFE __wfe
|
||||
|
||||
|
||||
/** \brief Send Event
|
||||
|
||||
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
|
||||
*/
|
||||
#define __SEV __sev
|
||||
|
||||
|
||||
/** \brief Instruction Synchronization Barrier
|
||||
|
||||
Instruction Synchronization Barrier flushes the pipeline in the processor,
|
||||
so that all instructions following the ISB are fetched from cache or
|
||||
memory, after the instruction has been completed.
|
||||
*/
|
||||
#define __ISB() do {\
|
||||
__schedule_barrier();\
|
||||
__isb(0xF);\
|
||||
__schedule_barrier();\
|
||||
} while (0)
|
||||
|
||||
/** \brief Data Synchronization Barrier
|
||||
|
||||
This function acts as a special kind of Data Memory Barrier.
|
||||
It completes when all explicit memory accesses before this instruction complete.
|
||||
*/
|
||||
#define __DSB() do {\
|
||||
__schedule_barrier();\
|
||||
__dsb(0xF);\
|
||||
__schedule_barrier();\
|
||||
} while (0)
|
||||
|
||||
/** \brief Data Memory Barrier
|
||||
|
||||
This function ensures the apparent order of the explicit memory operations before
|
||||
and after the instruction, without ensuring their completion.
|
||||
*/
|
||||
#define __DMB() do {\
|
||||
__schedule_barrier();\
|
||||
__dmb(0xF);\
|
||||
__schedule_barrier();\
|
||||
} while (0)
|
||||
|
||||
/** \brief Reverse byte order (32 bit)
|
||||
|
||||
This function reverses the byte order in integer value.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#define __REV __rev
|
||||
|
||||
|
||||
/** \brief Reverse byte order (16 bit)
|
||||
|
||||
This function reverses the byte order in two unsigned short values.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#ifndef __NO_EMBEDDED_ASM
|
||||
__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
|
||||
{
|
||||
rev16 r0, r0
|
||||
bx lr
|
||||
}
|
||||
#endif
|
||||
|
||||
/** \brief Reverse byte order in signed short value
|
||||
|
||||
This function reverses the byte order in a signed short value with sign extension to integer.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#ifndef __NO_EMBEDDED_ASM
|
||||
__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value)
|
||||
{
|
||||
revsh r0, r0
|
||||
bx lr
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/** \brief Rotate Right in unsigned value (32 bit)
|
||||
|
||||
This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
|
||||
|
||||
\param [in] value Value to rotate
|
||||
\param [in] value Number of Bits to rotate
|
||||
\return Rotated value
|
||||
*/
|
||||
#define __ROR __ror
|
||||
|
||||
|
||||
/** \brief Breakpoint
|
||||
|
||||
This function causes the processor to enter Debug state.
|
||||
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
|
||||
|
||||
\param [in] value is ignored by the processor.
|
||||
If required, a debugger can use it to store additional information about the breakpoint.
|
||||
*/
|
||||
#define __BKPT(value) __breakpoint(value)
|
||||
|
||||
|
||||
/** \brief Reverse bit order of value
|
||||
|
||||
This function reverses the bit order of the given value.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300)
|
||||
#define __RBIT __rbit
|
||||
#else
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
int32_t s = 4 /*sizeof(v)*/ * 8 - 1; // extra shift needed at end
|
||||
|
||||
result = value; // r will be reversed bits of v; first get LSB of v
|
||||
for (value >>= 1; value; value >>= 1)
|
||||
{
|
||||
result <<= 1;
|
||||
result |= value & 1;
|
||||
s--;
|
||||
}
|
||||
result <<= s; // shift when v's highest bits are zero
|
||||
return(result);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/** \brief Count leading zeros
|
||||
|
||||
This function counts the number of leading zeros of a data value.
|
||||
|
||||
\param [in] value Value to count the leading zeros
|
||||
\return number of leading zeros in value
|
||||
*/
|
||||
#define __CLZ __clz
|
||||
|
||||
|
||||
#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300)
|
||||
|
||||
/** \brief LDR Exclusive (8 bit)
|
||||
|
||||
This function executes a exclusive LDR instruction for 8 bit value.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint8_t at (*ptr)
|
||||
*/
|
||||
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
|
||||
|
||||
|
||||
/** \brief LDR Exclusive (16 bit)
|
||||
|
||||
This function executes a exclusive LDR instruction for 16 bit values.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint16_t at (*ptr)
|
||||
*/
|
||||
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
|
||||
|
||||
|
||||
/** \brief LDR Exclusive (32 bit)
|
||||
|
||||
This function executes a exclusive LDR instruction for 32 bit values.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint32_t at (*ptr)
|
||||
*/
|
||||
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
|
||||
|
||||
|
||||
/** \brief STR Exclusive (8 bit)
|
||||
|
||||
This function executes a exclusive STR instruction for 8 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
#define __STREXB(value, ptr) __strex(value, ptr)
|
||||
|
||||
|
||||
/** \brief STR Exclusive (16 bit)
|
||||
|
||||
This function executes a exclusive STR instruction for 16 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
#define __STREXH(value, ptr) __strex(value, ptr)
|
||||
|
||||
|
||||
/** \brief STR Exclusive (32 bit)
|
||||
|
||||
This function executes a exclusive STR instruction for 32 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
#define __STREXW(value, ptr) __strex(value, ptr)
|
||||
|
||||
|
||||
/** \brief Remove the exclusive lock
|
||||
|
||||
This function removes the exclusive lock which is created by LDREX.
|
||||
|
||||
*/
|
||||
#define __CLREX __clrex
|
||||
|
||||
|
||||
/** \brief Signed Saturate
|
||||
|
||||
This function saturates a signed value.
|
||||
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (1..32)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __SSAT __ssat
|
||||
|
||||
|
||||
/** \brief Unsigned Saturate
|
||||
|
||||
This function saturates an unsigned value.
|
||||
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (0..31)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __USAT __usat
|
||||
|
||||
|
||||
/** \brief Rotate Right with Extend (32 bit)
|
||||
|
||||
This function moves each bit of a bitstring right by one bit.
|
||||
The carry input is shifted in at the left end of the bitstring.
|
||||
|
||||
\param [in] value Value to rotate
|
||||
\return Rotated value
|
||||
*/
|
||||
#ifndef __NO_EMBEDDED_ASM
|
||||
__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value)
|
||||
{
|
||||
rrx r0, r0
|
||||
bx lr
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/** \brief LDRT Unprivileged (8 bit)
|
||||
|
||||
This function executes a Unprivileged LDRT instruction for 8 bit value.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint8_t at (*ptr)
|
||||
*/
|
||||
#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr))
|
||||
|
||||
|
||||
/** \brief LDRT Unprivileged (16 bit)
|
||||
|
||||
This function executes a Unprivileged LDRT instruction for 16 bit values.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint16_t at (*ptr)
|
||||
*/
|
||||
#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr))
|
||||
|
||||
|
||||
/** \brief LDRT Unprivileged (32 bit)
|
||||
|
||||
This function executes a Unprivileged LDRT instruction for 32 bit values.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint32_t at (*ptr)
|
||||
*/
|
||||
#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr))
|
||||
|
||||
|
||||
/** \brief STRT Unprivileged (8 bit)
|
||||
|
||||
This function executes a Unprivileged STRT instruction for 8 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
*/
|
||||
#define __STRBT(value, ptr) __strt(value, ptr)
|
||||
|
||||
|
||||
/** \brief STRT Unprivileged (16 bit)
|
||||
|
||||
This function executes a Unprivileged STRT instruction for 16 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
*/
|
||||
#define __STRHT(value, ptr) __strt(value, ptr)
|
||||
|
||||
|
||||
/** \brief STRT Unprivileged (32 bit)
|
||||
|
||||
This function executes a Unprivileged STRT instruction for 32 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
*/
|
||||
#define __STRT(value, ptr) __strt(value, ptr)
|
||||
|
||||
#endif /* (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) */
|
||||
|
||||
|
||||
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
|
||||
/* GNU gcc specific functions */
|
||||
|
||||
/* Define macros for porting to both thumb1 and thumb2.
|
||||
* For thumb1, use low register (r0-r7), specified by constrant "l"
|
||||
* Otherwise, use general registers, specified by constrant "r" */
|
||||
#if defined (__thumb__) && !defined (__thumb2__)
|
||||
#define __CMSIS_GCC_OUT_REG(r) "=l" (r)
|
||||
#define __CMSIS_GCC_USE_REG(r) "l" (r)
|
||||
#else
|
||||
#define __CMSIS_GCC_OUT_REG(r) "=r" (r)
|
||||
#define __CMSIS_GCC_USE_REG(r) "r" (r)
|
||||
#endif
|
||||
|
||||
/** \brief No Operation
|
||||
|
||||
No Operation does nothing. This instruction can be used for code alignment purposes.
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE void __NOP(void)
|
||||
{
|
||||
__ASM volatile ("nop");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Wait For Interrupt
|
||||
|
||||
Wait For Interrupt is a hint instruction that suspends execution
|
||||
until one of a number of events occurs.
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE void __WFI(void)
|
||||
{
|
||||
__ASM volatile ("wfi");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Wait For Event
|
||||
|
||||
Wait For Event is a hint instruction that permits the processor to enter
|
||||
a low-power state until one of a number of events occurs.
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE void __WFE(void)
|
||||
{
|
||||
__ASM volatile ("wfe");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Send Event
|
||||
|
||||
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE void __SEV(void)
|
||||
{
|
||||
__ASM volatile ("sev");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Instruction Synchronization Barrier
|
||||
|
||||
Instruction Synchronization Barrier flushes the pipeline in the processor,
|
||||
so that all instructions following the ISB are fetched from cache or
|
||||
memory, after the instruction has been completed.
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE void __ISB(void)
|
||||
{
|
||||
__ASM volatile ("isb 0xF":::"memory");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Data Synchronization Barrier
|
||||
|
||||
This function acts as a special kind of Data Memory Barrier.
|
||||
It completes when all explicit memory accesses before this instruction complete.
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE void __DSB(void)
|
||||
{
|
||||
__ASM volatile ("dsb 0xF":::"memory");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Data Memory Barrier
|
||||
|
||||
This function ensures the apparent order of the explicit memory operations before
|
||||
and after the instruction, without ensuring their completion.
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE void __DMB(void)
|
||||
{
|
||||
__ASM volatile ("dmb 0xF":::"memory");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Reverse byte order (32 bit)
|
||||
|
||||
This function reverses the byte order in integer value.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV(uint32_t value)
|
||||
{
|
||||
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
|
||||
return __builtin_bswap32(value);
|
||||
#else
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
|
||||
return(result);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/** \brief Reverse byte order (16 bit)
|
||||
|
||||
This function reverses the byte order in two unsigned short values.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV16(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Reverse byte order in signed short value
|
||||
|
||||
This function reverses the byte order in a signed short value with sign extension to integer.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE int32_t __REVSH(int32_t value)
|
||||
{
|
||||
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||
return (short)__builtin_bswap16(value);
|
||||
#else
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
|
||||
return(result);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/** \brief Rotate Right in unsigned value (32 bit)
|
||||
|
||||
This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
|
||||
|
||||
\param [in] value Value to rotate
|
||||
\param [in] value Number of Bits to rotate
|
||||
\return Rotated value
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
|
||||
{
|
||||
return (op1 >> op2) | (op1 << (32 - op2));
|
||||
}
|
||||
|
||||
|
||||
/** \brief Breakpoint
|
||||
|
||||
This function causes the processor to enter Debug state.
|
||||
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
|
||||
|
||||
\param [in] value is ignored by the processor.
|
||||
If required, a debugger can use it to store additional information about the breakpoint.
|
||||
*/
|
||||
#define __BKPT(value) __ASM volatile ("bkpt "#value)
|
||||
|
||||
|
||||
/** \brief Reverse bit order of value
|
||||
|
||||
This function reverses the bit order of the given value.
|
||||
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300)
|
||||
__ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
|
||||
#else
|
||||
int32_t s = 4 /*sizeof(v)*/ * 8 - 1; // extra shift needed at end
|
||||
|
||||
result = value; // r will be reversed bits of v; first get LSB of v
|
||||
for (value >>= 1; value; value >>= 1)
|
||||
{
|
||||
result <<= 1;
|
||||
result |= value & 1;
|
||||
s--;
|
||||
}
|
||||
result <<= s; // shift when v's highest bits are zero
|
||||
#endif
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Count leading zeros
|
||||
|
||||
This function counts the number of leading zeros of a data value.
|
||||
|
||||
\param [in] value Value to count the leading zeros
|
||||
\return number of leading zeros in value
|
||||
*/
|
||||
#define __CLZ __builtin_clz
|
||||
|
||||
|
||||
#if (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300)
|
||||
|
||||
/** \brief LDR Exclusive (8 bit)
|
||||
|
||||
This function executes a exclusive LDR instruction for 8 bit value.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint8_t at (*ptr)
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||
__ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) );
|
||||
#else
|
||||
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
|
||||
accepted by assembler. So has to use following less efficient pattern.
|
||||
*/
|
||||
__ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
|
||||
#endif
|
||||
return ((uint8_t) result); /* Add explicit type cast here */
|
||||
}
|
||||
|
||||
|
||||
/** \brief LDR Exclusive (16 bit)
|
||||
|
||||
This function executes a exclusive LDR instruction for 16 bit values.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint16_t at (*ptr)
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||
__ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) );
|
||||
#else
|
||||
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
|
||||
accepted by assembler. So has to use following less efficient pattern.
|
||||
*/
|
||||
__ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
|
||||
#endif
|
||||
return ((uint16_t) result); /* Add explicit type cast here */
|
||||
}
|
||||
|
||||
|
||||
/** \brief LDR Exclusive (32 bit)
|
||||
|
||||
This function executes a exclusive LDR instruction for 32 bit values.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint32_t at (*ptr)
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief STR Exclusive (8 bit)
|
||||
|
||||
This function executes a exclusive STR instruction for 8 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief STR Exclusive (16 bit)
|
||||
|
||||
This function executes a exclusive STR instruction for 16 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief STR Exclusive (32 bit)
|
||||
|
||||
This function executes a exclusive STR instruction for 32 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
\return 0 Function succeeded
|
||||
\return 1 Function failed
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief Remove the exclusive lock
|
||||
|
||||
This function removes the exclusive lock which is created by LDREX.
|
||||
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE void __CLREX(void)
|
||||
{
|
||||
__ASM volatile ("clrex" ::: "memory");
|
||||
}
|
||||
|
||||
|
||||
/** \brief Signed Saturate
|
||||
|
||||
This function saturates a signed value.
|
||||
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (1..32)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __SSAT(ARG1,ARG2) \
|
||||
({ \
|
||||
uint32_t __RES, __ARG1 = (ARG1); \
|
||||
__ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||
__RES; \
|
||||
})
|
||||
|
||||
|
||||
/** \brief Unsigned Saturate
|
||||
|
||||
This function saturates an unsigned value.
|
||||
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (0..31)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __USAT(ARG1,ARG2) \
|
||||
({ \
|
||||
uint32_t __RES, __ARG1 = (ARG1); \
|
||||
__ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||
__RES; \
|
||||
})
|
||||
|
||||
|
||||
/** \brief Rotate Right with Extend (32 bit)
|
||||
|
||||
This function moves each bit of a bitstring right by one bit.
|
||||
The carry input is shifted in at the left end of the bitstring.
|
||||
|
||||
\param [in] value Value to rotate
|
||||
\return Rotated value
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __RRX(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief LDRT Unprivileged (8 bit)
|
||||
|
||||
This function executes a Unprivileged LDRT instruction for 8 bit value.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint8_t at (*ptr)
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint8_t __LDRBT(volatile uint8_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||
__ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*addr) );
|
||||
#else
|
||||
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
|
||||
accepted by assembler. So has to use following less efficient pattern.
|
||||
*/
|
||||
__ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
|
||||
#endif
|
||||
return ((uint8_t) result); /* Add explicit type cast here */
|
||||
}
|
||||
|
||||
|
||||
/** \brief LDRT Unprivileged (16 bit)
|
||||
|
||||
This function executes a Unprivileged LDRT instruction for 16 bit values.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint16_t at (*ptr)
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint16_t __LDRHT(volatile uint16_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||
__ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*addr) );
|
||||
#else
|
||||
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
|
||||
accepted by assembler. So has to use following less efficient pattern.
|
||||
*/
|
||||
__ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
|
||||
#endif
|
||||
return ((uint16_t) result); /* Add explicit type cast here */
|
||||
}
|
||||
|
||||
|
||||
/** \brief LDRT Unprivileged (32 bit)
|
||||
|
||||
This function executes a Unprivileged LDRT instruction for 32 bit values.
|
||||
|
||||
\param [in] ptr Pointer to data
|
||||
\return value of type uint32_t at (*ptr)
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __LDRT(volatile uint32_t *addr)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*addr) );
|
||||
return(result);
|
||||
}
|
||||
|
||||
|
||||
/** \brief STRT Unprivileged (8 bit)
|
||||
|
||||
This function executes a Unprivileged STRT instruction for 8 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE void __STRBT(uint8_t value, volatile uint8_t *addr)
|
||||
{
|
||||
__ASM volatile ("strbt %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) );
|
||||
}
|
||||
|
||||
|
||||
/** \brief STRT Unprivileged (16 bit)
|
||||
|
||||
This function executes a Unprivileged STRT instruction for 16 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE void __STRHT(uint16_t value, volatile uint16_t *addr)
|
||||
{
|
||||
__ASM volatile ("strht %1, %0" : "=Q" (*addr) : "r" ((uint32_t)value) );
|
||||
}
|
||||
|
||||
|
||||
/** \brief STRT Unprivileged (32 bit)
|
||||
|
||||
This function executes a Unprivileged STRT instruction for 32 bit values.
|
||||
|
||||
\param [in] value Value to store
|
||||
\param [in] ptr Pointer to location
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE void __STRT(uint32_t value, volatile uint32_t *addr)
|
||||
{
|
||||
__ASM volatile ("strt %1, %0" : "=Q" (*addr) : "r" (value) );
|
||||
}
|
||||
|
||||
#endif /* (__CORTEX_M >= 0x03) || (__CORTEX_SC >= 300) */
|
||||
|
||||
|
||||
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
|
||||
/* IAR iccarm specific functions */
|
||||
#include <cmsis_iar.h>
|
||||
|
||||
|
||||
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
|
||||
/* TI CCS specific functions */
|
||||
#include <cmsis_ccs.h>
|
||||
|
||||
|
||||
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
|
||||
/* TASKING carm specific functions */
|
||||
/*
|
||||
* The CMSIS functions have been implemented as intrinsics in the compiler.
|
||||
* Please use "carm -?i" to get an up to date list of all intrinsics,
|
||||
* Including the CMSIS ones.
|
||||
*/
|
||||
|
||||
|
||||
#elif defined ( __CSMC__ ) /*------------------ COSMIC Compiler -------------------*/
|
||||
/* Cosmic specific functions */
|
||||
#include <cmsis_csm.h>
|
||||
|
||||
#endif
|
||||
|
||||
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
|
||||
|
||||
#endif /* __CORE_CMINSTR_H */
|
|
@ -0,0 +1,180 @@
|
|||
/**************************************************************************//**
|
||||
* @file irq_ctrl.h
|
||||
* @brief Interrupt Controller API header file
|
||||
* @version V1.0.0
|
||||
* @date 23. June 2017
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2017 ARM Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef IRQ_CTRL_H_
|
||||
#define IRQ_CTRL_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifndef IRQHANDLER_T
|
||||
#define IRQHANDLER_T
|
||||
/// Interrupt handler data type
|
||||
typedef void (*IRQHandler_t) (void);
|
||||
#endif
|
||||
|
||||
#ifndef IRQN_ID_T
|
||||
#define IRQN_ID_T
|
||||
/// Interrupt ID number data type
|
||||
typedef int32_t IRQn_ID_t;
|
||||
#endif
|
||||
|
||||
/* Interrupt mode bit-masks */
|
||||
#define IRQ_MODE_TRIG_Pos (0U)
|
||||
#define IRQ_MODE_TRIG_Msk (0x07UL /*<< IRQ_MODE_TRIG_Pos*/)
|
||||
#define IRQ_MODE_TRIG_LEVEL (0x00UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: level triggered interrupt
|
||||
#define IRQ_MODE_TRIG_LEVEL_LOW (0x01UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: low level triggered interrupt
|
||||
#define IRQ_MODE_TRIG_LEVEL_HIGH (0x02UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: high level triggered interrupt
|
||||
#define IRQ_MODE_TRIG_EDGE (0x04UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: edge triggered interrupt
|
||||
#define IRQ_MODE_TRIG_EDGE_RISING (0x05UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: rising edge triggered interrupt
|
||||
#define IRQ_MODE_TRIG_EDGE_FALLING (0x06UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: falling edge triggered interrupt
|
||||
#define IRQ_MODE_TRIG_EDGE_BOTH (0x07UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: rising and falling edge triggered interrupt
|
||||
|
||||
#define IRQ_MODE_TYPE_Pos (3U)
|
||||
#define IRQ_MODE_TYPE_Msk (0x01UL << IRQ_MODE_TYPE_Pos)
|
||||
#define IRQ_MODE_TYPE_IRQ (0x00UL << IRQ_MODE_TYPE_Pos) ///< Type: interrupt source triggers CPU IRQ line
|
||||
#define IRQ_MODE_TYPE_FIQ (0x01UL << IRQ_MODE_TYPE_Pos) ///< Type: interrupt source triggers CPU FIQ line
|
||||
|
||||
#define IRQ_MODE_DOMAIN_Pos (4U)
|
||||
#define IRQ_MODE_DOMAIN_Msk (0x01UL << IRQ_MODE_DOMAIN_Pos)
|
||||
#define IRQ_MODE_DOMAIN_NONSECURE (0x00UL << IRQ_MODE_DOMAIN_Pos) ///< Domain: interrupt is targeting non-secure domain
|
||||
#define IRQ_MODE_DOMAIN_SECURE (0x01UL << IRQ_MODE_DOMAIN_Pos) ///< Domain: interrupt is targeting secure domain
|
||||
|
||||
#define IRQ_MODE_CPU_Pos (5U)
|
||||
#define IRQ_MODE_CPU_Msk (0xFFUL << IRQ_MODE_CPU_Pos)
|
||||
#define IRQ_MODE_CPU_ALL (0x00UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets all CPUs
|
||||
#define IRQ_MODE_CPU_0 (0x01UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 0
|
||||
#define IRQ_MODE_CPU_1 (0x02UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 1
|
||||
#define IRQ_MODE_CPU_2 (0x04UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 2
|
||||
#define IRQ_MODE_CPU_3 (0x08UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 3
|
||||
#define IRQ_MODE_CPU_4 (0x10UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 4
|
||||
#define IRQ_MODE_CPU_5 (0x20UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 5
|
||||
#define IRQ_MODE_CPU_6 (0x40UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 6
|
||||
#define IRQ_MODE_CPU_7 (0x80UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 7
|
||||
|
||||
#define IRQ_MODE_ERROR (0x80000000UL) ///< Bit indicating mode value error
|
||||
|
||||
/* Interrupt priority bit-masks */
|
||||
#define IRQ_PRIORITY_Msk (0x0000FFFFUL) ///< Interrupt priority value bit-mask
|
||||
#define IRQ_PRIORITY_ERROR (0x80000000UL) ///< Bit indicating priority value error
|
||||
|
||||
/// Initialize interrupt controller.
|
||||
/// \return 0 on success, -1 on error.
|
||||
int32_t IRQ_Initialize (void);
|
||||
|
||||
/// Register interrupt handler.
|
||||
/// \param[in] irqn interrupt ID number
|
||||
/// \param[in] handler interrupt handler function address
|
||||
/// \return 0 on success, -1 on error.
|
||||
int32_t IRQ_SetHandler (IRQn_ID_t irqn, IRQHandler_t handler);
|
||||
|
||||
/// Get the registered interrupt handler.
|
||||
/// \param[in] irqn interrupt ID number
|
||||
/// \return registered interrupt handler function address.
|
||||
IRQHandler_t IRQ_GetHandler (IRQn_ID_t irqn);
|
||||
|
||||
/// Enable interrupt.
|
||||
/// \param[in] irqn interrupt ID number
|
||||
/// \return 0 on success, -1 on error.
|
||||
int32_t IRQ_Enable (IRQn_ID_t irqn);
|
||||
|
||||
/// Disable interrupt.
|
||||
/// \param[in] irqn interrupt ID number
|
||||
/// \return 0 on success, -1 on error.
|
||||
int32_t IRQ_Disable (IRQn_ID_t irqn);
|
||||
|
||||
/// Get interrupt enable state.
|
||||
/// \param[in] irqn interrupt ID number
|
||||
/// \return 0 - interrupt is disabled, 1 - interrupt is enabled.
|
||||
uint32_t IRQ_GetEnableState (IRQn_ID_t irqn);
|
||||
|
||||
/// Configure interrupt request mode.
|
||||
/// \param[in] irqn interrupt ID number
|
||||
/// \param[in] mode mode configuration
|
||||
/// \return 0 on success, -1 on error.
|
||||
int32_t IRQ_SetMode (IRQn_ID_t irqn, uint32_t mode);
|
||||
|
||||
/// Get interrupt mode configuration.
|
||||
/// \param[in] irqn interrupt ID number
|
||||
/// \return current interrupt mode configuration with optional IRQ_MODE_ERROR bit set.
|
||||
uint32_t IRQ_GetMode (IRQn_ID_t irqn);
|
||||
|
||||
/// Get ID number of current interrupt request (IRQ).
|
||||
/// \return interrupt ID number.
|
||||
IRQn_ID_t IRQ_GetActiveIRQ (void);
|
||||
|
||||
/// Get ID number of current fast interrupt request (FIQ).
|
||||
/// \return interrupt ID number.
|
||||
IRQn_ID_t IRQ_GetActiveFIQ (void);
|
||||
|
||||
/// Signal end of interrupt processing.
|
||||
/// \param[in] irqn interrupt ID number
|
||||
/// \return 0 on success, -1 on error.
|
||||
int32_t IRQ_EndOfInterrupt (IRQn_ID_t irqn);
|
||||
|
||||
/// Set interrupt pending flag.
|
||||
/// \param[in] irqn interrupt ID number
|
||||
/// \return 0 on success, -1 on error.
|
||||
int32_t IRQ_SetPending (IRQn_ID_t irqn);
|
||||
|
||||
/// Get interrupt pending flag.
|
||||
/// \param[in] irqn interrupt ID number
|
||||
/// \return 0 - interrupt is not pending, 1 - interrupt is pending.
|
||||
uint32_t IRQ_GetPending (IRQn_ID_t irqn);
|
||||
|
||||
/// Clear interrupt pending flag.
|
||||
/// \param[in] irqn interrupt ID number
|
||||
/// \return 0 on success, -1 on error.
|
||||
int32_t IRQ_ClearPending (IRQn_ID_t irqn);
|
||||
|
||||
/// Set interrupt priority value.
|
||||
/// \param[in] irqn interrupt ID number
|
||||
/// \param[in] priority interrupt priority value
|
||||
/// \return 0 on success, -1 on error.
|
||||
int32_t IRQ_SetPriority (IRQn_ID_t irqn, uint32_t priority);
|
||||
|
||||
/// Get interrupt priority.
|
||||
/// \param[in] irqn interrupt ID number
|
||||
/// \return current interrupt priority value with optional IRQ_PRIORITY_ERROR bit set.
|
||||
uint32_t IRQ_GetPriority (IRQn_ID_t irqn);
|
||||
|
||||
/// Set priority masking threshold.
|
||||
/// \param[in] priority priority masking threshold value
|
||||
/// \return 0 on success, -1 on error.
|
||||
int32_t IRQ_SetPriorityMask (uint32_t priority);
|
||||
|
||||
/// Get priority masking threshold
|
||||
/// \return current priority masking threshold value with optional IRQ_PRIORITY_ERROR bit set.
|
||||
uint32_t IRQ_GetPriorityMask (void);
|
||||
|
||||
/// Set priority grouping field split point
|
||||
/// \param[in] bits number of MSB bits included in the group priority field comparison
|
||||
/// \return 0 on success, -1 on error.
|
||||
int32_t IRQ_SetPriorityGroupBits (uint32_t bits);
|
||||
|
||||
/// Get priority grouping field split point
|
||||
/// \return current number of MSB bits included in the group priority field comparison with
|
||||
/// optional IRQ_PRIORITY_ERROR bit set.
|
||||
uint32_t IRQ_GetPriorityGroupBits (void);
|
||||
|
||||
#endif // IRQ_CTRL_H_
|
|
@ -0,0 +1,403 @@
|
|||
/**************************************************************************//**
|
||||
* @file irq_ctrl_gic.c
|
||||
* @brief Interrupt controller handling implementation for GIC
|
||||
* @version V1.0.0
|
||||
* @date 30. June 2017
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2017 ARM Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <cmsis.h>
|
||||
|
||||
#include "irq_ctrl.h"
|
||||
|
||||
#if defined(__GIC_PRESENT) && (__GIC_PRESENT == 1U)
|
||||
|
||||
/// Number of implemented interrupt lines
|
||||
#ifndef IRQ_GIC_LINE_COUNT
|
||||
#define IRQ_GIC_LINE_COUNT (1020U)
|
||||
#endif
|
||||
|
||||
static IRQHandler_t IRQTable[IRQ_GIC_LINE_COUNT] = { 0U };
|
||||
static uint32_t IRQ_ID0;
|
||||
|
||||
/// Initialize interrupt controller.
|
||||
__WEAK int32_t IRQ_Initialize (void) {
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0U; i < IRQ_GIC_LINE_COUNT; i++) {
|
||||
IRQTable[i] = (IRQHandler_t)NULL;
|
||||
}
|
||||
GIC_Enable();
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/// Register interrupt handler.
|
||||
__WEAK int32_t IRQ_SetHandler (IRQn_ID_t irqn, IRQHandler_t handler) {
|
||||
int32_t status;
|
||||
|
||||
if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) {
|
||||
IRQTable[irqn] = handler;
|
||||
status = 0;
|
||||
} else {
|
||||
status = -1;
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
|
||||
/// Get the registered interrupt handler.
|
||||
__WEAK IRQHandler_t IRQ_GetHandler (IRQn_ID_t irqn) {
|
||||
IRQHandler_t h;
|
||||
|
||||
if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) {
|
||||
h = IRQTable[irqn];
|
||||
} else {
|
||||
h = (IRQHandler_t)0;
|
||||
}
|
||||
|
||||
return (h);
|
||||
}
|
||||
|
||||
|
||||
/// Enable interrupt.
|
||||
__WEAK int32_t IRQ_Enable (IRQn_ID_t irqn) {
|
||||
int32_t status;
|
||||
|
||||
if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) {
|
||||
GIC_EnableIRQ ((IRQn_Type)irqn);
|
||||
status = 0;
|
||||
} else {
|
||||
status = -1;
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
|
||||
/// Disable interrupt.
|
||||
__WEAK int32_t IRQ_Disable (IRQn_ID_t irqn) {
|
||||
int32_t status;
|
||||
|
||||
if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) {
|
||||
GIC_DisableIRQ ((IRQn_Type)irqn);
|
||||
status = 0;
|
||||
} else {
|
||||
status = -1;
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
|
||||
/// Get interrupt enable state.
|
||||
__WEAK uint32_t IRQ_GetEnableState (IRQn_ID_t irqn) {
|
||||
uint32_t enable;
|
||||
|
||||
if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) {
|
||||
enable = GIC_GetEnableIRQ((IRQn_Type)irqn);
|
||||
} else {
|
||||
enable = 0U;
|
||||
}
|
||||
|
||||
return (enable);
|
||||
}
|
||||
|
||||
|
||||
/// Configure interrupt request mode.
|
||||
__WEAK int32_t IRQ_SetMode (IRQn_ID_t irqn, uint32_t mode) {
|
||||
int32_t status;
|
||||
uint32_t val;
|
||||
uint8_t cfg;
|
||||
uint8_t secure;
|
||||
uint8_t cpu;
|
||||
|
||||
status = 0;
|
||||
|
||||
if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) {
|
||||
// Check triggering mode
|
||||
val = (mode & IRQ_MODE_TRIG_Msk);
|
||||
|
||||
if (val == IRQ_MODE_TRIG_LEVEL) {
|
||||
cfg = 0x00U;
|
||||
} else if (val == IRQ_MODE_TRIG_EDGE) {
|
||||
cfg = 0x02U;
|
||||
} else {
|
||||
status = -1;
|
||||
}
|
||||
|
||||
// Check interrupt type
|
||||
val = mode & IRQ_MODE_TYPE_Msk;
|
||||
|
||||
if (val != IRQ_MODE_TYPE_IRQ) {
|
||||
status = -1;
|
||||
}
|
||||
|
||||
// Check interrupt domain
|
||||
val = mode & IRQ_MODE_DOMAIN_Msk;
|
||||
|
||||
if (val == IRQ_MODE_DOMAIN_NONSECURE) {
|
||||
secure = 0;
|
||||
} else {
|
||||
// Check security extensions support
|
||||
val = GIC_DistributorInfo() & (1UL << 10U);
|
||||
|
||||
if (val != 0U) {
|
||||
// Security extensions are supported
|
||||
secure = 1;
|
||||
} else {
|
||||
status = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Check interrupt CPU targets
|
||||
val = mode & IRQ_MODE_CPU_Msk;
|
||||
|
||||
if (val == IRQ_MODE_CPU_ALL) {
|
||||
cpu = 0xFF;
|
||||
} else {
|
||||
cpu = val >> IRQ_MODE_CPU_Pos;
|
||||
}
|
||||
|
||||
// Apply configuration if no mode error
|
||||
if (status == 0) {
|
||||
GIC_SetConfiguration((IRQn_Type)irqn, cfg);
|
||||
GIC_SetTarget ((IRQn_Type)irqn, cpu);
|
||||
|
||||
if (secure != 0U) {
|
||||
GIC_SetGroup ((IRQn_Type)irqn, secure);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
|
||||
/// Get interrupt mode configuration.
|
||||
__WEAK uint32_t IRQ_GetMode (IRQn_ID_t irqn) {
|
||||
uint32_t mode;
|
||||
uint32_t val;
|
||||
|
||||
if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) {
|
||||
mode = IRQ_MODE_TYPE_IRQ;
|
||||
|
||||
// Get trigger mode
|
||||
val = GIC_GetConfiguration((IRQn_Type)irqn);
|
||||
|
||||
if ((val & 2U) != 0U) {
|
||||
// Corresponding interrupt is edge triggered
|
||||
mode |= IRQ_MODE_TRIG_EDGE;
|
||||
} else {
|
||||
// Corresponding interrupt is level triggered
|
||||
mode |= IRQ_MODE_TRIG_LEVEL;
|
||||
}
|
||||
|
||||
// Get interrupt CPU targets
|
||||
mode |= GIC_GetTarget ((IRQn_Type)irqn) << IRQ_MODE_CPU_Pos;
|
||||
|
||||
} else {
|
||||
mode = IRQ_MODE_ERROR;
|
||||
}
|
||||
|
||||
return (mode);
|
||||
}
|
||||
|
||||
|
||||
/// Get ID number of current interrupt request (IRQ).
|
||||
__WEAK IRQn_ID_t IRQ_GetActiveIRQ (void) {
|
||||
IRQn_ID_t irqn;
|
||||
uint32_t prio;
|
||||
|
||||
/* Dummy read to avoid GIC 390 errata 801120 */
|
||||
GIC_GetHighPendingIRQ();
|
||||
|
||||
irqn = GIC_AcknowledgePending();
|
||||
|
||||
__DSB();
|
||||
|
||||
/* Workaround GIC 390 errata 733075 (GIC-390_Errata_Notice_v6.pdf, 09-Jul-2014) */
|
||||
/* The following workaround code is for a single-core system. It would be */
|
||||
/* different in a multi-core system. */
|
||||
/* If the ID is 0 or 0x3FE or 0x3FF, then the GIC CPU interface may be locked-up */
|
||||
/* so unlock it, otherwise service the interrupt as normal. */
|
||||
/* Special IDs 1020=0x3FC and 1021=0x3FD are reserved values in GICv1 and GICv2 */
|
||||
/* so will not occur here. */
|
||||
|
||||
if ((irqn == 0) || (irqn >= 0x3FE)) {
|
||||
/* Unlock the CPU interface with a dummy write to Interrupt Priority Register */
|
||||
prio = GIC_GetPriority((IRQn_Type)0);
|
||||
GIC_SetPriority ((IRQn_Type)0, prio);
|
||||
|
||||
__DSB();
|
||||
|
||||
if ((irqn == 0U) && ((GIC_GetIRQStatus ((IRQn_Type)irqn) & 1U) != 0U) && (IRQ_ID0 == 0U)) {
|
||||
/* If the ID is 0, is active and has not been seen before */
|
||||
IRQ_ID0 = 1U;
|
||||
}
|
||||
/* End of Workaround GIC 390 errata 733075 */
|
||||
}
|
||||
|
||||
return (irqn);
|
||||
}
|
||||
|
||||
|
||||
/// Get ID number of current fast interrupt request (FIQ).
|
||||
__WEAK IRQn_ID_t IRQ_GetActiveFIQ (void) {
|
||||
return ((IRQn_ID_t)-1);
|
||||
}
|
||||
|
||||
|
||||
/// Signal end of interrupt processing.
|
||||
__WEAK int32_t IRQ_EndOfInterrupt (IRQn_ID_t irqn) {
|
||||
int32_t status;
|
||||
|
||||
if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) {
|
||||
GIC_EndInterrupt ((IRQn_Type)irqn);
|
||||
|
||||
if (irqn == 0) {
|
||||
IRQ_ID0 = 0U;
|
||||
}
|
||||
|
||||
status = 0;
|
||||
} else {
|
||||
status = -1;
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
|
||||
/// Set interrupt pending flag.
|
||||
__WEAK int32_t IRQ_SetPending (IRQn_ID_t irqn) {
|
||||
int32_t status;
|
||||
|
||||
if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) {
|
||||
GIC_SetPendingIRQ ((IRQn_Type)irqn);
|
||||
status = 0;
|
||||
} else {
|
||||
status = -1;
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
/// Get interrupt pending flag.
|
||||
__WEAK uint32_t IRQ_GetPending (IRQn_ID_t irqn) {
|
||||
uint32_t pending;
|
||||
|
||||
if ((irqn >= 16) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) {
|
||||
pending = GIC_GetPendingIRQ ((IRQn_Type)irqn);
|
||||
} else {
|
||||
pending = 0U;
|
||||
}
|
||||
|
||||
return (pending & 1U);
|
||||
}
|
||||
|
||||
|
||||
/// Clear interrupt pending flag.
|
||||
__WEAK int32_t IRQ_ClearPending (IRQn_ID_t irqn) {
|
||||
int32_t status;
|
||||
|
||||
if ((irqn >= 16) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) {
|
||||
GIC_ClearPendingIRQ ((IRQn_Type)irqn);
|
||||
status = 0;
|
||||
} else {
|
||||
status = -1;
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
|
||||
/// Set interrupt priority value.
|
||||
__WEAK int32_t IRQ_SetPriority (IRQn_ID_t irqn, uint32_t priority) {
|
||||
int32_t status;
|
||||
|
||||
if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) {
|
||||
GIC_SetPriority ((IRQn_Type)irqn, priority);
|
||||
status = 0;
|
||||
} else {
|
||||
status = -1;
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
|
||||
/// Get interrupt priority.
|
||||
__WEAK uint32_t IRQ_GetPriority (IRQn_ID_t irqn) {
|
||||
uint32_t priority;
|
||||
|
||||
if ((irqn >= 0) && (irqn < (IRQn_ID_t)IRQ_GIC_LINE_COUNT)) {
|
||||
priority = GIC_GetPriority ((IRQn_Type)irqn);
|
||||
} else {
|
||||
priority = IRQ_PRIORITY_ERROR;
|
||||
}
|
||||
|
||||
return (priority);
|
||||
}
|
||||
|
||||
|
||||
/// Set priority masking threshold.
|
||||
__WEAK int32_t IRQ_SetPriorityMask (uint32_t priority) {
|
||||
GIC_SetInterfacePriorityMask (priority);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/// Get priority masking threshold
|
||||
__WEAK uint32_t IRQ_GetPriorityMask (void) {
|
||||
return GIC_GetInterfacePriorityMask();
|
||||
}
|
||||
|
||||
|
||||
/// Set priority grouping field split point
|
||||
__WEAK int32_t IRQ_SetPriorityGroupBits (uint32_t bits) {
|
||||
int32_t status;
|
||||
|
||||
if (bits == IRQ_PRIORITY_Msk) {
|
||||
bits = 7U;
|
||||
}
|
||||
|
||||
if (bits < 8U) {
|
||||
GIC_SetBinaryPoint (7U - bits);
|
||||
status = 0;
|
||||
} else {
|
||||
status = -1;
|
||||
}
|
||||
|
||||
return (status);
|
||||
}
|
||||
|
||||
|
||||
/// Get priority grouping field split point
|
||||
__WEAK uint32_t IRQ_GetPriorityGroupBits (void) {
|
||||
uint32_t bp;
|
||||
|
||||
bp = GIC_GetBinaryPoint() & 0x07U;
|
||||
|
||||
return (7U - bp);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -572,32 +572,6 @@ extern "C"
|
|||
(((q63_t) (x >> 32) * y)));
|
||||
}
|
||||
|
||||
/*
|
||||
#if defined (ARM_MATH_CM0_FAMILY) && defined ( __CC_ARM )
|
||||
#define __CLZ __clz
|
||||
#endif
|
||||
*/
|
||||
/* note: function can be removed when all toolchain support __CLZ for Cortex-M0 */
|
||||
#if defined (ARM_MATH_CM0_FAMILY) && ((defined (__ICCARM__)) )
|
||||
CMSIS_INLINE __STATIC_INLINE uint32_t __CLZ(
|
||||
q31_t data);
|
||||
|
||||
CMSIS_INLINE __STATIC_INLINE uint32_t __CLZ(
|
||||
q31_t data)
|
||||
{
|
||||
uint32_t count = 0;
|
||||
uint32_t mask = 0x80000000;
|
||||
|
||||
while ((data & mask) == 0)
|
||||
{
|
||||
count += 1u;
|
||||
mask = mask >> 1u;
|
||||
}
|
||||
|
||||
return (count);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Function to Calculates 1/in (reciprocal) value of Q31 Data type.
|
||||
*/
|
||||
|
@ -700,47 +674,6 @@ extern "C"
|
|||
return (signBits + 1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @brief C custom defined intrinisic function for only M0 processors
|
||||
*/
|
||||
#if defined(ARM_MATH_CM0_FAMILY)
|
||||
CMSIS_INLINE __STATIC_INLINE q31_t __SSAT(
|
||||
q31_t x,
|
||||
uint32_t y)
|
||||
{
|
||||
int32_t posMax, negMin;
|
||||
uint32_t i;
|
||||
|
||||
posMax = 1;
|
||||
for (i = 0; i < (y - 1); i++)
|
||||
{
|
||||
posMax = posMax * 2;
|
||||
}
|
||||
|
||||
if (x > 0)
|
||||
{
|
||||
posMax = (posMax - 1);
|
||||
|
||||
if (x > posMax)
|
||||
{
|
||||
x = posMax;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
negMin = -posMax;
|
||||
|
||||
if (x < negMin)
|
||||
{
|
||||
x = negMin;
|
||||
}
|
||||
}
|
||||
return (x);
|
||||
}
|
||||
#endif /* end of ARM_MATH_CM0_FAMILY */
|
||||
|
||||
|
||||
/*
|
||||
* @brief C custom defined intrinsic function for M3 and M0 processors
|
||||
*/
|
|
@ -73,6 +73,9 @@
|
|||
#ifndef __PACKED_STRUCT
|
||||
#define __PACKED_STRUCT __packed struct
|
||||
#endif
|
||||
#ifndef __PACKED_UNION
|
||||
#define __PACKED_UNION __packed union
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32 /* deprecated */
|
||||
#define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x)))
|
||||
#endif
|
||||
|
@ -91,7 +94,9 @@
|
|||
#ifndef __ALIGNED
|
||||
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||
#endif
|
||||
|
||||
#ifndef __RESTRICT
|
||||
#define __RESTRICT __restrict
|
||||
#endif
|
||||
|
||||
/* ########################### Core Function Access ########################### */
|
||||
/** \ingroup CMSIS_Core_FunctionInterface
|
||||
|
@ -456,7 +461,7 @@ __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
|
|||
\return Reversed value
|
||||
*/
|
||||
#ifndef __NO_EMBEDDED_ASM
|
||||
__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
|
||||
__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint16_t __REV16(uint16_t value)
|
||||
{
|
||||
rev16 r0, r0
|
||||
bx lr
|
||||
|
@ -471,7 +476,7 @@ __attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(u
|
|||
\return Reversed value
|
||||
*/
|
||||
#ifndef __NO_EMBEDDED_ASM
|
||||
__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value)
|
||||
__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int16_t __REVSH(int16_t value)
|
||||
{
|
||||
revsh r0, r0
|
||||
bx lr
|
||||
|
@ -512,17 +517,17 @@ __attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(in
|
|||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
int32_t s = (4 /*sizeof(v)*/ * 8) - 1; /* extra shift needed at end */
|
||||
uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */
|
||||
|
||||
result = value; /* r will be reversed bits of v; first get LSB of v */
|
||||
for (value >>= 1U; value; value >>= 1U)
|
||||
for (value >>= 1U; value != 0U; value >>= 1U)
|
||||
{
|
||||
result <<= 1U;
|
||||
result |= value & 1U;
|
||||
s--;
|
||||
}
|
||||
result <<= s; /* shift when v's highest bits are zero */
|
||||
return(result);
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -719,6 +724,50 @@ __attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint3
|
|||
*/
|
||||
#define __STRT(value, ptr) __strt(value, ptr)
|
||||
|
||||
#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
|
||||
|
||||
/**
|
||||
\brief Signed Saturate
|
||||
\details Saturates a signed value.
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (1..32)
|
||||
\return Saturated value
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat)
|
||||
{
|
||||
if ((sat >= 1U) && (sat <= 32U)) {
|
||||
const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U);
|
||||
const int32_t min = -1 - max ;
|
||||
if (val > max) {
|
||||
return max;
|
||||
} else if (val < min) {
|
||||
return min;
|
||||
}
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Unsigned Saturate
|
||||
\details Saturates an unsigned value.
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (0..31)
|
||||
\return Saturated value
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat)
|
||||
{
|
||||
if (sat <= 31U) {
|
||||
const uint32_t max = ((1U << sat) - 1U);
|
||||
if (val > (int32_t)max) {
|
||||
return max;
|
||||
} else if (val < 0) {
|
||||
return 0U;
|
||||
}
|
||||
}
|
||||
return (uint32_t)val;
|
||||
}
|
||||
|
||||
#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||
(defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
//lint -esym(9058, IRQn) disable MISRA 2012 Rule 2.4 for IRQn
|
||||
/*lint -esym(9058, IRQn)*/ /* disable MISRA 2012 Rule 2.4 for IRQn */
|
||||
|
||||
#ifndef __CMSIS_ARMCLANG_H
|
||||
#define __CMSIS_ARMCLANG_H
|
||||
|
@ -56,10 +56,13 @@
|
|||
#ifndef __PACKED_STRUCT
|
||||
#define __PACKED_STRUCT struct __attribute__((packed, aligned(1)))
|
||||
#endif
|
||||
#ifndef __PACKED_UNION
|
||||
#define __PACKED_UNION union __attribute__((packed, aligned(1)))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32 /* deprecated */
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wpacked"
|
||||
//lint -esym(9058, T_UINT32) disable MISRA 2012 Rule 2.4 for T_UINT32
|
||||
/*lint -esym(9058, T_UINT32)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32 */
|
||||
struct __attribute__((packed)) T_UINT32 { uint32_t v; };
|
||||
#pragma clang diagnostic pop
|
||||
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
|
||||
|
@ -67,7 +70,7 @@
|
|||
#ifndef __UNALIGNED_UINT16_WRITE
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wpacked"
|
||||
//lint -esym(9058, T_UINT16_WRITE) disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE
|
||||
/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */
|
||||
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
|
||||
#pragma clang diagnostic pop
|
||||
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
|
||||
|
@ -75,7 +78,7 @@
|
|||
#ifndef __UNALIGNED_UINT16_READ
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wpacked"
|
||||
//lint -esym(9058, T_UINT16_READ) disable MISRA 2012 Rule 2.4 for T_UINT16_READ
|
||||
/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */
|
||||
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
|
||||
#pragma clang diagnostic pop
|
||||
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
|
||||
|
@ -83,7 +86,7 @@
|
|||
#ifndef __UNALIGNED_UINT32_WRITE
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wpacked"
|
||||
//lint -esym(9058, T_UINT32_WRITE) disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE
|
||||
/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */
|
||||
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
|
||||
#pragma clang diagnostic pop
|
||||
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
|
||||
|
@ -91,6 +94,7 @@
|
|||
#ifndef __UNALIGNED_UINT32_READ
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wpacked"
|
||||
/*lint -esym(9058, T_UINT32_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_READ */
|
||||
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
|
||||
#pragma clang diagnostic pop
|
||||
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
|
||||
|
@ -98,6 +102,9 @@
|
|||
#ifndef __ALIGNED
|
||||
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||
#endif
|
||||
#ifndef __RESTRICT
|
||||
#define __RESTRICT __restrict
|
||||
#endif
|
||||
|
||||
|
||||
/* ########################### Core Function Access ########################### */
|
||||
|
@ -677,36 +684,24 @@ __attribute__((always_inline)) __STATIC_INLINE void __TZ_set_MSPLIM_NS(uint32_t
|
|||
\details Returns the current value of the Floating Point Status/Control register.
|
||||
\return Floating Point Status/Control register value
|
||||
*/
|
||||
/* #define __get_FPSCR __builtin_arm_get_fpscr */
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __get_FPSCR(void)
|
||||
{
|
||||
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
|
||||
return(result);
|
||||
#define __get_FPSCR (uint32_t)__builtin_arm_get_fpscr
|
||||
#else
|
||||
return(0U);
|
||||
#define __get_FPSCR() ((uint32_t)0U)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
\brief Set FPSCR
|
||||
\details Assigns the given value to the Floating Point Status/Control register.
|
||||
\param [in] fpscr Floating Point Status/Control value to set
|
||||
*/
|
||||
/* #define __set_FPSCR __builtin_arm_set_fpscr */
|
||||
__attribute__((always_inline)) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
|
||||
{
|
||||
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
|
||||
__ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "memory");
|
||||
#define __set_FPSCR __builtin_arm_set_fpscr
|
||||
#else
|
||||
(void)fpscr;
|
||||
#define __set_FPSCR(x) ((void)(x))
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* ((defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
|
||||
(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */
|
||||
|
@ -791,7 +786,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
|
|||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#define __REV __builtin_bswap32
|
||||
#define __REV (uint32_t)__builtin_bswap32
|
||||
|
||||
|
||||
/**
|
||||
|
@ -800,16 +795,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
|
|||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
#define __REV16 __builtin_bswap16 /* ToDo ARMCLANG: check if __builtin_bswap16 could be used */
|
||||
#if 0
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV16(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
|
||||
return(result);
|
||||
}
|
||||
#endif
|
||||
#define __REV16 (uint16_t)__builtin_bswap16
|
||||
|
||||
|
||||
/**
|
||||
|
@ -818,13 +804,13 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __REV16(uint32_t value)
|
|||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
/* ToDo ARMCLANG: check if __builtin_bswap16 could be used */
|
||||
__attribute__((always_inline)) __STATIC_INLINE int32_t __REVSH(int32_t value)
|
||||
__attribute__((always_inline)) __STATIC_INLINE int16_t __REVSH(int16_t value)
|
||||
{
|
||||
int32_t result;
|
||||
int16_t result;
|
||||
|
||||
__ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
|
||||
return(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
@ -848,7 +834,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint
|
|||
\param [in] value is ignored by the processor.
|
||||
If required, a debugger can use it to store additional information about the breakpoint.
|
||||
*/
|
||||
#define __BKPT(value) __ASM volatile ("bkpt "#value)
|
||||
#define __BKPT(value) __ASM volatile ("bkpt "#value)
|
||||
|
||||
|
||||
/**
|
||||
|
@ -857,30 +843,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint
|
|||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
/* ToDo ARMCLANG: check if __builtin_arm_rbit is supported */
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
|
||||
#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||
(defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
|
||||
(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) )
|
||||
__ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
|
||||
#else
|
||||
int32_t s = (4 /*sizeof(v)*/ * 8) - 1; /* extra shift needed at end */
|
||||
|
||||
result = value; /* r will be reversed bits of v; first get LSB of v */
|
||||
for (value >>= 1U; value; value >>= 1U)
|
||||
{
|
||||
result <<= 1U;
|
||||
result |= value & 1U;
|
||||
s--;
|
||||
}
|
||||
result <<= s; /* shift when v's highest bits are zero */
|
||||
#endif
|
||||
return(result);
|
||||
}
|
||||
|
||||
#define __RBIT (uint32_t)__builtin_arm_rbit
|
||||
|
||||
/**
|
||||
\brief Count leading zeros
|
||||
|
@ -970,6 +933,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
|
|||
#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||
(defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
|
||||
(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) )
|
||||
|
||||
/**
|
||||
\brief Signed Saturate
|
||||
\details Saturates a signed value.
|
||||
|
@ -1086,6 +1050,51 @@ __attribute__((always_inline)) __STATIC_INLINE void __STRT(uint32_t value, volat
|
|||
__ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) );
|
||||
}
|
||||
|
||||
#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||
(defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
|
||||
(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */
|
||||
|
||||
/**
|
||||
\brief Signed Saturate
|
||||
\details Saturates a signed value.
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (1..32)
|
||||
\return Saturated value
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat)
|
||||
{
|
||||
if ((sat >= 1U) && (sat <= 32U)) {
|
||||
const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U);
|
||||
const int32_t min = -1 - max ;
|
||||
if (val > max) {
|
||||
return max;
|
||||
} else if (val < min) {
|
||||
return min;
|
||||
}
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Unsigned Saturate
|
||||
\details Saturates an unsigned value.
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (0..31)
|
||||
\return Saturated value
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat)
|
||||
{
|
||||
if (sat <= 31U) {
|
||||
const uint32_t max = ((1U << sat) - 1U);
|
||||
if (val > (int32_t)max) {
|
||||
return max;
|
||||
} else if (val < 0) {
|
||||
return 0U;
|
||||
}
|
||||
}
|
||||
return (uint32_t)val;
|
||||
}
|
||||
|
||||
#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||
(defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
|
||||
(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */
|
|
@ -52,88 +52,9 @@
|
|||
* IAR Compiler
|
||||
*/
|
||||
#elif defined ( __ICCARM__ )
|
||||
#include <cmsis_iccarm.h>
|
||||
|
||||
#ifndef __ASM
|
||||
#define __ASM __asm
|
||||
#endif
|
||||
#ifndef __INLINE
|
||||
#define __INLINE inline
|
||||
#endif
|
||||
#ifndef __STATIC_INLINE
|
||||
#define __STATIC_INLINE static inline
|
||||
#endif
|
||||
|
||||
#include <cmsis_iar.h>
|
||||
|
||||
/* CMSIS compiler control architecture macros */
|
||||
#if (__CORE__ == __ARM6M__) || (__CORE__ == __ARM6SM__)
|
||||
#ifndef __ARM_ARCH_6M__
|
||||
#define __ARM_ARCH_6M__ 1
|
||||
#endif
|
||||
#elif (__CORE__ == __ARM7M__)
|
||||
#ifndef __ARM_ARCH_7M__
|
||||
#define __ARM_ARCH_7M__ 1
|
||||
#endif
|
||||
#elif (__CORE__ == __ARM7EM__)
|
||||
#ifndef __ARM_ARCH_7EM__
|
||||
#define __ARM_ARCH_7EM__ 1
|
||||
#endif
|
||||
#elif (__CORE__ == __ARM8M_BASELINE__)
|
||||
#ifndef __ARM_ARCH_8M_BASE__
|
||||
#define __ARM_ARCH_8M_BASE__ 1
|
||||
#endif
|
||||
#elif (__CORE__ == __ARM8M_MAINLINE__)
|
||||
#ifndef __ARM_ARCH_8M_MAIN__
|
||||
#define __ARM_ARCH_8M_MAIN__ 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// IAR version 7.8.1 and earlier do not include __ALIGNED
|
||||
#ifndef __ALIGNED
|
||||
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||
#endif
|
||||
|
||||
#ifndef __NO_RETURN
|
||||
#define __NO_RETURN __noreturn
|
||||
#endif
|
||||
#ifndef __USED
|
||||
#define __USED __root
|
||||
#endif
|
||||
#ifndef __WEAK
|
||||
#define __WEAK __weak
|
||||
#endif
|
||||
#ifndef __PACKED
|
||||
#define __PACKED __packed
|
||||
#endif
|
||||
#ifndef __PACKED_STRUCT
|
||||
#define __PACKED_STRUCT __packed struct
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32 /* deprecated */
|
||||
__packed struct T_UINT32 { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT16_WRITE
|
||||
__PACKED_STRUCT T_UINT16_WRITE { uint16_t v; };
|
||||
#define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT16_READ
|
||||
__PACKED_STRUCT T_UINT16_READ { uint16_t v; };
|
||||
#define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v)
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_WRITE
|
||||
__PACKED_STRUCT T_UINT32_WRITE { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32_READ
|
||||
__PACKED_STRUCT T_UINT32_READ { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v)
|
||||
#endif
|
||||
#ifndef __ALIGNED
|
||||
#warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored.
|
||||
#define __ALIGNED(x)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* TI ARM Compiler
|
||||
*/
|
||||
|
@ -164,6 +85,9 @@
|
|||
#ifndef __PACKED_STRUCT
|
||||
#define __PACKED_STRUCT struct __attribute__((packed))
|
||||
#endif
|
||||
#ifndef __PACKED_UNION
|
||||
#define __PACKED_UNION union __attribute__((packed))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32 /* deprecated */
|
||||
struct __attribute__((packed)) T_UINT32 { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
|
||||
|
@ -187,6 +111,10 @@
|
|||
#ifndef __ALIGNED
|
||||
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||
#endif
|
||||
#ifndef __RESTRICT
|
||||
#warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
|
||||
#define __RESTRICT
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
|
@ -223,6 +151,9 @@
|
|||
#ifndef __PACKED_STRUCT
|
||||
#define __PACKED_STRUCT struct __packed__
|
||||
#endif
|
||||
#ifndef __PACKED_UNION
|
||||
#define __PACKED_UNION union __packed__
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32 /* deprecated */
|
||||
struct __packed__ T_UINT32 { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
|
||||
|
@ -246,6 +177,10 @@
|
|||
#ifndef __ALIGNED
|
||||
#define __ALIGNED(x) __align(x)
|
||||
#endif
|
||||
#ifndef __RESTRICT
|
||||
#warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
|
||||
#define __RESTRICT
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
|
@ -280,6 +215,9 @@
|
|||
#ifndef __PACKED_STRUCT
|
||||
#define __PACKED_STRUCT @packed struct
|
||||
#endif
|
||||
#ifndef __PACKED_UNION
|
||||
#define __PACKED_UNION @packed union
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32 /* deprecated */
|
||||
@packed struct T_UINT32 { uint32_t v; };
|
||||
#define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v)
|
||||
|
@ -304,6 +242,10 @@
|
|||
#warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored.
|
||||
#define __ALIGNED(x)
|
||||
#endif
|
||||
#ifndef __RESTRICT
|
||||
#warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored.
|
||||
#define __RESTRICT
|
||||
#endif
|
||||
|
||||
|
||||
#else
|
||||
|
|
|
@ -31,6 +31,11 @@
|
|||
#pragma GCC diagnostic ignored "-Wconversion"
|
||||
#pragma GCC diagnostic ignored "-Wunused-parameter"
|
||||
|
||||
/* Fallback for __has_builtin */
|
||||
#ifndef __has_builtin
|
||||
#define __has_builtin(x) (0)
|
||||
#endif
|
||||
|
||||
/* CMSIS compiler specific defines */
|
||||
#ifndef __ASM
|
||||
#define __ASM __asm
|
||||
|
@ -56,6 +61,9 @@
|
|||
#ifndef __PACKED_STRUCT
|
||||
#define __PACKED_STRUCT struct __attribute__((packed, aligned(1)))
|
||||
#endif
|
||||
#ifndef __PACKED_UNION
|
||||
#define __PACKED_UNION union __attribute__((packed, aligned(1)))
|
||||
#endif
|
||||
#ifndef __UNALIGNED_UINT32 /* deprecated */
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wpacked"
|
||||
|
@ -99,6 +107,9 @@
|
|||
#ifndef __ALIGNED
|
||||
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||
#endif
|
||||
#ifndef __RESTRICT
|
||||
#define __RESTRICT __restrict
|
||||
#endif
|
||||
|
||||
|
||||
/* ########################### Core Function Access ########################### */
|
||||
|
@ -694,12 +705,17 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __get_FPSCR(void)
|
|||
{
|
||||
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
|
||||
#if __has_builtin(__builtin_arm_get_fpscr) || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2)
|
||||
/* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */
|
||||
return __builtin_arm_get_fpscr();
|
||||
#else
|
||||
uint32_t result;
|
||||
|
||||
__ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
|
||||
return(result);
|
||||
#endif
|
||||
#else
|
||||
return(0U);
|
||||
return(0U);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -713,7 +729,12 @@ __attribute__((always_inline)) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
|
|||
{
|
||||
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
|
||||
#if __has_builtin(__builtin_arm_set_fpscr) || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2)
|
||||
/* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */
|
||||
__builtin_arm_set_fpscr(fpscr);
|
||||
#else
|
||||
__ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc", "memory");
|
||||
#endif
|
||||
#else
|
||||
(void)fpscr;
|
||||
#endif
|
||||
|
@ -826,7 +847,7 @@ __attribute__((always_inline)) __STATIC_INLINE void __DMB(void)
|
|||
|
||||
/**
|
||||
\brief Reverse byte order (32 bit)
|
||||
\details Reverses the byte order in integer value.
|
||||
\details Reverses the byte order in unsigned integer value.
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
|
@ -845,13 +866,13 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __REV(uint32_t value)
|
|||
|
||||
/**
|
||||
\brief Reverse byte order (16 bit)
|
||||
\details Reverses the byte order in two unsigned short values.
|
||||
\details Reverses the byte order in unsigned short value.
|
||||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __REV16(uint32_t value)
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint16_t __REV16(uint16_t value)
|
||||
{
|
||||
uint32_t result;
|
||||
uint16_t result;
|
||||
|
||||
__ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
|
||||
return(result);
|
||||
|
@ -864,15 +885,15 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __REV16(uint32_t value)
|
|||
\param [in] value Value to reverse
|
||||
\return Reversed value
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE int32_t __REVSH(int32_t value)
|
||||
__attribute__((always_inline)) __STATIC_INLINE int16_t __REVSH(int16_t value)
|
||||
{
|
||||
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
|
||||
return (short)__builtin_bswap16(value);
|
||||
return (int16_t)__builtin_bswap16(value);
|
||||
#else
|
||||
int32_t result;
|
||||
int16_t result;
|
||||
|
||||
__ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
|
||||
return(result);
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -915,10 +936,10 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
|
|||
(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) )
|
||||
__ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
|
||||
#else
|
||||
int32_t s = (4 /*sizeof(v)*/ * 8) - 1; /* extra shift needed at end */
|
||||
uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */
|
||||
|
||||
result = value; /* r will be reversed bits of v; first get LSB of v */
|
||||
for (value >>= 1U; value; value >>= 1U)
|
||||
for (value >>= 1U; value != 0U; value >>= 1U)
|
||||
{
|
||||
result <<= 1U;
|
||||
result |= value & 1U;
|
||||
|
@ -926,7 +947,7 @@ __attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
|
|||
}
|
||||
result <<= s; /* shift when v's highest bits are zero */
|
||||
#endif
|
||||
return(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1074,11 +1095,12 @@ __attribute__((always_inline)) __STATIC_INLINE void __CLREX(void)
|
|||
/**
|
||||
\brief Signed Saturate
|
||||
\details Saturates a signed value.
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (1..32)
|
||||
\param [in] ARG1 Value to be saturated
|
||||
\param [in] ARG2 Bit position to saturate to (1..32)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __SSAT(ARG1,ARG2) \
|
||||
__extension__ \
|
||||
({ \
|
||||
int32_t __RES, __ARG1 = (ARG1); \
|
||||
__ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||
|
@ -1089,11 +1111,12 @@ __attribute__((always_inline)) __STATIC_INLINE void __CLREX(void)
|
|||
/**
|
||||
\brief Unsigned Saturate
|
||||
\details Saturates an unsigned value.
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (0..31)
|
||||
\param [in] ARG1 Value to be saturated
|
||||
\param [in] ARG2 Bit position to saturate to (0..31)
|
||||
\return Saturated value
|
||||
*/
|
||||
#define __USAT(ARG1,ARG2) \
|
||||
__extension__ \
|
||||
({ \
|
||||
uint32_t __RES, __ARG1 = (ARG1); \
|
||||
__ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
|
||||
|
@ -1211,6 +1234,51 @@ __attribute__((always_inline)) __STATIC_INLINE void __STRT(uint32_t value, volat
|
|||
__ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) );
|
||||
}
|
||||
|
||||
#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||
(defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
|
||||
(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */
|
||||
|
||||
/**
|
||||
\brief Signed Saturate
|
||||
\details Saturates a signed value.
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (1..32)
|
||||
\return Saturated value
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat)
|
||||
{
|
||||
if ((sat >= 1U) && (sat <= 32U)) {
|
||||
const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U);
|
||||
const int32_t min = -1 - max ;
|
||||
if (val > max) {
|
||||
return max;
|
||||
} else if (val < min) {
|
||||
return min;
|
||||
}
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Unsigned Saturate
|
||||
\details Saturates an unsigned value.
|
||||
\param [in] value Value to be saturated
|
||||
\param [in] sat Bit position to saturate to (0..31)
|
||||
\return Saturated value
|
||||
*/
|
||||
__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat)
|
||||
{
|
||||
if (sat <= 31U) {
|
||||
const uint32_t max = ((1U << sat) - 1U);
|
||||
if (val > (int32_t)max) {
|
||||
return max;
|
||||
} else if (val < 0) {
|
||||
return 0U;
|
||||
}
|
||||
}
|
||||
return (uint32_t)val;
|
||||
}
|
||||
|
||||
#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \
|
||||
(defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \
|
||||
(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */
|
|
@ -0,0 +1,771 @@
|
|||
/**************************************************************************//**
|
||||
* @file cmsis_iccarm.h
|
||||
* @brief CMSIS compiler ICCARM (IAR compiler) header file
|
||||
* @version V5.0.3
|
||||
* @date 29. August 2017
|
||||
******************************************************************************/
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2017 IAR Systems
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License")
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#ifndef __CMSIS_ICCARM_H__
|
||||
#define __CMSIS_ICCARM_H__
|
||||
|
||||
#ifndef __ICCARM__
|
||||
#error This file should only be compiled by ICCARM
|
||||
#endif
|
||||
|
||||
#pragma system_include
|
||||
|
||||
#define __IAR_FT _Pragma("inline=forced") __intrinsic
|
||||
|
||||
#if (__VER__ >= 8000000)
|
||||
#define __ICCARM_V8 1
|
||||
#else
|
||||
#define __ICCARM_V8 0
|
||||
#endif
|
||||
|
||||
#ifndef __ALIGNED
|
||||
#if __ICCARM_V8
|
||||
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||
#elif (__VER__ >= 7080000)
|
||||
/* Needs IAR language extensions */
|
||||
#define __ALIGNED(x) __attribute__((aligned(x)))
|
||||
#else
|
||||
#warning No compiler specific solution for __ALIGNED.__ALIGNED is ignored.
|
||||
#define __ALIGNED(x)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/* Define compiler macros for CPU architecture, used in CMSIS 5.
|
||||
*/
|
||||
#if __ARM_ARCH_6M__ || __ARM_ARCH_7M__ || __ARM_ARCH_7EM__ || __ARM_ARCH_8M_BASE__ || __ARM_ARCH_8M_MAIN__
|
||||
/* Macros already defined */
|
||||
#else
|
||||
#if defined(__ARM8M_MAINLINE__) || defined(__ARM8EM_MAINLINE__)
|
||||
#define __ARM_ARCH_8M_MAIN__ 1
|
||||
#elif defined(__ARM8M_BASELINE__)
|
||||
#define __ARM_ARCH_8M_BASE__ 1
|
||||
#elif defined(__ARM_ARCH_PROFILE) && __ARM_ARCH_PROFILE == 'M'
|
||||
#if __ARM_ARCH == 6
|
||||
#define __ARM_ARCH_6M__ 1
|
||||
#elif __ARM_ARCH == 7
|
||||
#if __ARM_FEATURE_DSP
|
||||
#define __ARM_ARCH_7EM__ 1
|
||||
#else
|
||||
#define __ARM_ARCH_7M__ 1
|
||||
#endif
|
||||
#endif /* __ARM_ARCH */
|
||||
#endif /* __ARM_ARCH_PROFILE == 'M' */
|
||||
#endif
|
||||
|
||||
/* Alternativ core deduction for older ICCARM's */
|
||||
#if !defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_7M__) && !defined(__ARM_ARCH_7EM__) && \
|
||||
!defined(__ARM_ARCH_8M_BASE__) && !defined(__ARM_ARCH_8M_MAIN__)
|
||||
#if defined(__ARM6M__) && (__CORE__ == __ARM6M__)
|
||||
#define __ARM_ARCH_6M__ 1
|
||||
#elif defined(__ARM7M__) && (__CORE__ == __ARM7M__)
|
||||
#define __ARM_ARCH_7M__ 1
|
||||
#elif defined(__ARM7EM__) && (__CORE__ == __ARM7EM__)
|
||||
#define __ARM_ARCH_7EM__ 1
|
||||
#elif defined(__ARM8M_BASELINE__) && (__CORE == __ARM8M_BASELINE__)
|
||||
#define __ARM_ARCH_8M_BASE__ 1
|
||||
#elif defined(__ARM8M_MAINLINE__) && (__CORE == __ARM8M_MAINLINE__)
|
||||
#define __ARM_ARCH_8M_MAIN__ 1
|
||||
#elif defined(__ARM8EM_MAINLINE__) && (__CORE == __ARM8EM_MAINLINE__)
|
||||
#define __ARM_ARCH_8M_MAIN__ 1
|
||||
#else
|
||||
#error "Unknown target."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#if defined(__ARM_ARCH_6M__) && __ARM_ARCH_6M__==1
|
||||
#define __IAR_M0_FAMILY 1
|
||||
#elif defined(__ARM_ARCH_8M_BASE__) && __ARM_ARCH_8M_BASE__==1
|
||||
#define __IAR_M0_FAMILY 1
|
||||
#else
|
||||
#define __IAR_M0_FAMILY 0
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef __ASM
|
||||
#define __ASM __asm
|
||||
#endif
|
||||
|
||||
#ifndef __INLINE
|
||||
#define __INLINE inline
|
||||
#endif
|
||||
|
||||
#ifndef __NO_RETURN
|
||||
#if __ICCARM_V8
|
||||
#define __NO_RETURN __attribute__((noreturn))
|
||||
#else
|
||||
#define __NO_RETURN _Pragma("object_attribute=__noreturn")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef __PACKED
|
||||
#if __ICCARM_V8
|
||||
#define __PACKED __attribute__((packed, aligned(1)))
|
||||
#else
|
||||
/* Needs IAR language extensions */
|
||||
#define __PACKED __packed
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef __PACKED_STRUCT
|
||||
#if __ICCARM_V8
|
||||
#define __PACKED_STRUCT struct __attribute__((packed, aligned(1)))
|
||||
#else
|
||||
/* Needs IAR language extensions */
|
||||
#define __PACKED_STRUCT __packed struct
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef __PACKED_UNION
|
||||
#if __ICCARM_V8
|
||||
#define __PACKED_UNION union __attribute__((packed, aligned(1)))
|
||||
#else
|
||||
/* Needs IAR language extensions */
|
||||
#define __PACKED_UNION __packed union
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef __RESTRICT
|
||||
#define __RESTRICT restrict
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef __STATIC_INLINE
|
||||
#define __STATIC_INLINE static inline
|
||||
#endif
|
||||
|
||||
#ifndef __UNALIGNED_UINT16_READ
|
||||
#pragma language=save
|
||||
#pragma language=extended
|
||||
__IAR_FT uint16_t __iar_uint16_read(void const *ptr) {
|
||||
return *(__packed uint16_t*)(ptr);
|
||||
}
|
||||
#pragma language=restore
|
||||
#define __UNALIGNED_UINT16_READ(PTR) __iar_uint16_read(PTR)
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef __UNALIGNED_UINT16_WRITE
|
||||
#pragma language=save
|
||||
#pragma language=extended
|
||||
__IAR_FT void __iar_uint16_write(void const *ptr, uint16_t val) {
|
||||
*(__packed uint16_t*)(ptr) = val;;
|
||||
}
|
||||
#pragma language=restore
|
||||
#define __UNALIGNED_UINT16_WRITE(PTR,VAL) __iar_uint16_write(PTR,VAL)
|
||||
#endif
|
||||
|
||||
#ifndef __UNALIGNED_UINT32_READ
|
||||
#pragma language=save
|
||||
#pragma language=extended
|
||||
__IAR_FT uint32_t __iar_uint32_read(void const *ptr) {
|
||||
return *(__packed uint32_t*)(ptr);
|
||||
}
|
||||
#pragma language=restore
|
||||
#define __UNALIGNED_UINT32_READ(PTR) __iar_uint32_read(PTR)
|
||||
#endif
|
||||
|
||||
#ifndef __UNALIGNED_UINT32_WRITE
|
||||
#pragma language=save
|
||||
#pragma language=extended
|
||||
__IAR_FT void __iar_uint32_write(void const *ptr, uint32_t val) {
|
||||
*(__packed uint32_t*)(ptr) = val;;
|
||||
}
|
||||
#pragma language=restore
|
||||
#define __UNALIGNED_UINT32_WRITE(PTR,VAL) __iar_uint32_write(PTR,VAL)
|
||||
#endif
|
||||
|
||||
#ifndef __UNALIGNED_UINT32 /* deprecated */
|
||||
#pragma language=save
|
||||
#pragma language=extended
|
||||
__packed struct __iar_u32 { uint32_t v; };
|
||||
#pragma language=restore
|
||||
#define __UNALIGNED_UINT32(PTR) (((struct __iar_u32 *)(PTR))->v)
|
||||
#endif
|
||||
|
||||
#ifndef __USED
|
||||
#if __ICCARM_V8
|
||||
#define __USED __attribute__((used))
|
||||
#else
|
||||
#define __USED _Pragma("__root")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef __WEAK
|
||||
#if __ICCARM_V8
|
||||
#define __WEAK __attribute__((weak))
|
||||
#else
|
||||
#define __WEAK _Pragma("__weak")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef __ICCARM_INTRINSICS_VERSION__
|
||||
#define __ICCARM_INTRINSICS_VERSION__ 0
|
||||
#endif
|
||||
|
||||
#if __ICCARM_INTRINSICS_VERSION__ == 2
|
||||
|
||||
#if defined(__CLZ)
|
||||
#undef __CLZ
|
||||
#endif
|
||||
#if defined(__REVSH)
|
||||
#undef __REVSH
|
||||
#endif
|
||||
#if defined(__RBIT)
|
||||
#undef __RBIT
|
||||
#endif
|
||||
#if defined(__SSAT)
|
||||
#undef __SSAT
|
||||
#endif
|
||||
#if defined(__USAT)
|
||||
#undef __USAT
|
||||
#endif
|
||||
|
||||
#include "iccarm_builtin.h"
|
||||
|
||||
#define __disable_fault_irq __iar_builtin_disable_fiq
|
||||
#define __disable_irq __iar_builtin_disable_interrupt
|
||||
#define __enable_fault_irq __iar_builtin_enable_fiq
|
||||
#define __enable_irq __iar_builtin_enable_interrupt
|
||||
#define __arm_rsr __iar_builtin_rsr
|
||||
#define __arm_wsr __iar_builtin_wsr
|
||||
|
||||
|
||||
#define __get_APSR() (__arm_rsr("APSR"))
|
||||
#define __get_BASEPRI() (__arm_rsr("BASEPRI"))
|
||||
#define __get_CONTROL() (__arm_rsr("CONTROL"))
|
||||
#define __get_FAULTMASK() (__arm_rsr("FAULTMASK"))
|
||||
|
||||
#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||
(defined (__FPU_USED ) && (__FPU_USED == 1U)) )
|
||||
#define __get_FPSCR() (__arm_rsr("FPSCR"))
|
||||
#define __set_FPSCR(VALUE) (__arm_wsr("FPSCR", (VALUE)))
|
||||
#else
|
||||
#define __get_FPSCR() ( 0 )
|
||||
#define __set_FPSCR(VALUE) ((void)VALUE)
|
||||
#endif
|
||||
|
||||
#define __get_IPSR() (__arm_rsr("IPSR"))
|
||||
#define __get_MSP() (__arm_rsr("MSP"))
|
||||
#define __get_MSPLIM() (__arm_rsr("MSPLIM"))
|
||||
#define __get_PRIMASK() (__arm_rsr("PRIMASK"))
|
||||
#define __get_PSP() (__arm_rsr("PSP"))
|
||||
#define __get_PSPLIM() (__arm_rsr("PSPLIM"))
|
||||
#define __get_xPSR() (__arm_rsr("xPSR"))
|
||||
|
||||
#define __set_BASEPRI(VALUE) (__arm_wsr("BASEPRI", (VALUE)))
|
||||
#define __set_BASEPRI_MAX(VALUE) (__arm_wsr("BASEPRI_MAX", (VALUE)))
|
||||
#define __set_CONTROL(VALUE) (__arm_wsr("CONTROL", (VALUE)))
|
||||
#define __set_FAULTMASK(VALUE) (__arm_wsr("FAULTMASK", (VALUE)))
|
||||
#define __set_MSP(VALUE) (__arm_wsr("MSP", (VALUE)))
|
||||
#define __set_MSPLIM(VALUE) (__arm_wsr("MSPLIM", (VALUE)))
|
||||
#define __set_PRIMASK(VALUE) (__arm_wsr("PRIMASK", (VALUE)))
|
||||
#define __set_PSP(VALUE) (__arm_wsr("PSP", (VALUE)))
|
||||
#define __set_PSPLIM(VALUE) (__arm_wsr("PSPLIM", (VALUE)))
|
||||
|
||||
#define __TZ_get_CONTROL_NS() (__arm_rsr("CONTROL_NS"))
|
||||
#define __TZ_set_CONTROL_NS(VALUE) (__arm_wsr("CONTROL_NS", (VALUE)))
|
||||
#define __TZ_get_PSP_NS() (__arm_rsr("PSP_NS"))
|
||||
#define __TZ_set_PSP_NS(VALUE) (__arm_wsr("PSP_NS", (VALUE)))
|
||||
#define __TZ_get_MSP_NS() (__arm_rsr("MSP_NS"))
|
||||
#define __TZ_set_MSP_NS(VALUE) (__arm_wsr("MSP_NS", (VALUE)))
|
||||
#define __TZ_get_SP_NS() (__arm_rsr("SP_NS"))
|
||||
#define __TZ_set_SP_NS(VALUE) (__arm_wsr("SP_NS", (VALUE)))
|
||||
#define __TZ_get_PRIMASK_NS() (__arm_rsr("PRIMASK_NS"))
|
||||
#define __TZ_set_PRIMASK_NS(VALUE) (__arm_wsr("PRIMASK_NS", (VALUE)))
|
||||
#define __TZ_get_BASEPRI_NS() (__arm_rsr("BASEPRI_NS"))
|
||||
#define __TZ_set_BASEPRI_NS(VALUE) (__arm_wsr("BASEPRI_NS", (VALUE)))
|
||||
#define __TZ_get_FAULTMASK_NS() (__arm_rsr("FAULTMASK_NS"))
|
||||
#define __TZ_set_FAULTMASK_NS(VALUE)(__arm_wsr("FAULTMASK_NS", (VALUE)))
|
||||
#define __TZ_get_PSPLIM_NS() (__arm_rsr("PSPLIM_NS"))
|
||||
#define __TZ_set_PSPLIM_NS(VALUE) (__arm_wsr("PSPLIM_NS", (VALUE)))
|
||||
#define __TZ_get_MSPLIM_NS() (__arm_rsr("MSPLIM_NS"))
|
||||
#define __TZ_set_MSPLIM_NS(VALUE) (__arm_wsr("MSPLIM_NS", (VALUE)))
|
||||
|
||||
#define __NOP __iar_builtin_no_operation
|
||||
|
||||
__IAR_FT uint8_t __CLZ(uint32_t val) {
|
||||
return __iar_builtin_CLZ(val);
|
||||
}
|
||||
|
||||
#define __CLREX __iar_builtin_CLREX
|
||||
|
||||
#define __DMB __iar_builtin_DMB
|
||||
#define __DSB __iar_builtin_DSB
|
||||
#define __ISB __iar_builtin_ISB
|
||||
|
||||
#define __LDREXB __iar_builtin_LDREXB
|
||||
#define __LDREXH __iar_builtin_LDREXH
|
||||
#define __LDREXW __iar_builtin_LDREX
|
||||
|
||||
#define __RBIT __iar_builtin_RBIT
|
||||
#define __REV __iar_builtin_REV
|
||||
#define __REV16 __iar_builtin_REV16
|
||||
|
||||
__IAR_FT int32_t __REVSH(int32_t val) {
|
||||
return __iar_builtin_REVSH((int16_t)val);
|
||||
}
|
||||
|
||||
#define __ROR __iar_builtin_ROR
|
||||
#define __RRX __iar_builtin_RRX
|
||||
|
||||
#define __SEV __iar_builtin_SEV
|
||||
|
||||
#if !__IAR_M0_FAMILY
|
||||
#define __SSAT __iar_builtin_SSAT
|
||||
#endif
|
||||
|
||||
#define __STREXB __iar_builtin_STREXB
|
||||
#define __STREXH __iar_builtin_STREXH
|
||||
#define __STREXW __iar_builtin_STREX
|
||||
|
||||
#if !__IAR_M0_FAMILY
|
||||
#define __USAT __iar_builtin_USAT
|
||||
#endif
|
||||
|
||||
#define __WFE __iar_builtin_WFE
|
||||
#define __WFI __iar_builtin_WFI
|
||||
|
||||
#if __ARM_MEDIA__
|
||||
#define __SADD8 __iar_builtin_SADD8
|
||||
#define __QADD8 __iar_builtin_QADD8
|
||||
#define __SHADD8 __iar_builtin_SHADD8
|
||||
#define __UADD8 __iar_builtin_UADD8
|
||||
#define __UQADD8 __iar_builtin_UQADD8
|
||||
#define __UHADD8 __iar_builtin_UHADD8
|
||||
#define __SSUB8 __iar_builtin_SSUB8
|
||||
#define __QSUB8 __iar_builtin_QSUB8
|
||||
#define __SHSUB8 __iar_builtin_SHSUB8
|
||||
#define __USUB8 __iar_builtin_USUB8
|
||||
#define __UQSUB8 __iar_builtin_UQSUB8
|
||||
#define __UHSUB8 __iar_builtin_UHSUB8
|
||||
#define __SADD16 __iar_builtin_SADD16
|
||||
#define __QADD16 __iar_builtin_QADD16
|
||||
#define __SHADD16 __iar_builtin_SHADD16
|
||||
#define __UADD16 __iar_builtin_UADD16
|
||||
#define __UQADD16 __iar_builtin_UQADD16
|
||||
#define __UHADD16 __iar_builtin_UHADD16
|
||||
#define __SSUB16 __iar_builtin_SSUB16
|
||||
#define __QSUB16 __iar_builtin_QSUB16
|
||||
#define __SHSUB16 __iar_builtin_SHSUB16
|
||||
#define __USUB16 __iar_builtin_USUB16
|
||||
#define __UQSUB16 __iar_builtin_UQSUB16
|
||||
#define __UHSUB16 __iar_builtin_UHSUB16
|
||||
#define __SASX __iar_builtin_SASX
|
||||
#define __QASX __iar_builtin_QASX
|
||||
#define __SHASX __iar_builtin_SHASX
|
||||
#define __UASX __iar_builtin_UASX
|
||||
#define __UQASX __iar_builtin_UQASX
|
||||
#define __UHASX __iar_builtin_UHASX
|
||||
#define __SSAX __iar_builtin_SSAX
|
||||
#define __QSAX __iar_builtin_QSAX
|
||||
#define __SHSAX __iar_builtin_SHSAX
|
||||
#define __USAX __iar_builtin_USAX
|
||||
#define __UQSAX __iar_builtin_UQSAX
|
||||
#define __UHSAX __iar_builtin_UHSAX
|
||||
#define __USAD8 __iar_builtin_USAD8
|
||||
#define __USADA8 __iar_builtin_USADA8
|
||||
#define __SSAT16 __iar_builtin_SSAT16
|
||||
#define __USAT16 __iar_builtin_USAT16
|
||||
#define __UXTB16 __iar_builtin_UXTB16
|
||||
#define __UXTAB16 __iar_builtin_UXTAB16
|
||||
#define __SXTB16 __iar_builtin_SXTB16
|
||||
#define __SXTAB16 __iar_builtin_SXTAB16
|
||||
#define __SMUAD __iar_builtin_SMUAD
|
||||
#define __SMUADX __iar_builtin_SMUADX
|
||||
#define __SMMLA __iar_builtin_SMMLA
|
||||
#define __SMLAD __iar_builtin_SMLAD
|
||||
#define __SMLADX __iar_builtin_SMLADX
|
||||
#define __SMLALD __iar_builtin_SMLALD
|
||||
#define __SMLALDX __iar_builtin_SMLALDX
|
||||
#define __SMUSD __iar_builtin_SMUSD
|
||||
#define __SMUSDX __iar_builtin_SMUSDX
|
||||
#define __SMLSD __iar_builtin_SMLSD
|
||||
#define __SMLSDX __iar_builtin_SMLSDX
|
||||
#define __SMLSLD __iar_builtin_SMLSLD
|
||||
#define __SMLSLDX __iar_builtin_SMLSLDX
|
||||
#define __SEL __iar_builtin_SEL
|
||||
#define __QADD __iar_builtin_QADD
|
||||
#define __QSUB __iar_builtin_QSUB
|
||||
#define __PKHBT __iar_builtin_PKHBT
|
||||
#define __PKHTB __iar_builtin_PKHTB
|
||||
#endif
|
||||
|
||||
#else /* __ICCARM_INTRINSICS_VERSION__ == 2 */
|
||||
|
||||
#if __IAR_M0_FAMILY
|
||||
/* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */
|
||||
#define __CLZ __cmsis_iar_clz_not_active
|
||||
#define __SSAT __cmsis_iar_ssat_not_active
|
||||
#define __USAT __cmsis_iar_usat_not_active
|
||||
#define __RBIT __cmsis_iar_rbit_not_active
|
||||
#define __get_APSR __cmsis_iar_get_APSR_not_active
|
||||
#endif
|
||||
|
||||
|
||||
#if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||
(defined (__FPU_USED ) && (__FPU_USED == 1U)) ))
|
||||
#define __get_FPSCR __cmsis_iar_get_FPSR_not_active
|
||||
#define __set_FPSCR __cmsis_iar_set_FPSR_not_active
|
||||
#endif
|
||||
|
||||
#include <intrinsics.h>
|
||||
|
||||
#if __IAR_M0_FAMILY
|
||||
/* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */
|
||||
#undef __CLZ
|
||||
#undef __SSAT
|
||||
#undef __USAT
|
||||
#undef __RBIT
|
||||
#undef __get_APSR
|
||||
|
||||
__STATIC_INLINE uint8_t __CLZ(uint32_t data) {
|
||||
if (data == 0u) { return 32u; }
|
||||
|
||||
uint32_t count = 0;
|
||||
uint32_t mask = 0x80000000;
|
||||
|
||||
while ((data & mask) == 0)
|
||||
{
|
||||
count += 1u;
|
||||
mask = mask >> 1u;
|
||||
}
|
||||
return (count);
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t __RBIT(uint32_t v) {
|
||||
uint8_t sc = 31;
|
||||
uint32_t r = v;
|
||||
for (v >>= 1U; v; v >>= 1U)
|
||||
{
|
||||
r <<= 1U;
|
||||
r |= v & 1U;
|
||||
sc--;
|
||||
}
|
||||
return (r << sc);
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t __get_APSR(void) {
|
||||
uint32_t res;
|
||||
__asm("MRS %0,APSR" : "=r" (res));
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \
|
||||
(defined (__FPU_USED ) && (__FPU_USED == 1U)) ))
|
||||
#undef __get_FPSCR
|
||||
#undef __set_FPSCR
|
||||
#define __get_FPSCR() (0)
|
||||
#define __set_FPSCR(VALUE) ((void)VALUE)
|
||||
#endif
|
||||
|
||||
#pragma diag_suppress=Pe940
|
||||
#pragma diag_suppress=Pe177
|
||||
|
||||
#define __enable_irq __enable_interrupt
|
||||
#define __disable_irq __disable_interrupt
|
||||
#define __NOP __no_operation
|
||||
|
||||
#define __get_xPSR __get_PSR
|
||||
|
||||
#if (!defined(__ARM_ARCH_6M__) || __ARM_ARCH_6M__==0)
|
||||
|
||||
__IAR_FT uint32_t __LDREXW(uint32_t volatile *ptr) {
|
||||
return __LDREX((unsigned long *)ptr);
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __STREXW(uint32_t value, uint32_t volatile *ptr) {
|
||||
return __STREX(value, (unsigned long *)ptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */
|
||||
#if (__CORTEX_M >= 0x03)
|
||||
|
||||
__IAR_FT uint32_t __RRX(uint32_t value) {
|
||||
uint32_t result;
|
||||
__ASM("RRX %0, %1" : "=r"(result) : "r" (value) : "cc");
|
||||
return(result);
|
||||
}
|
||||
|
||||
__IAR_FT void __set_BASEPRI_MAX(uint32_t value) {
|
||||
__asm volatile("MSR BASEPRI_MAX,%0"::"r" (value));
|
||||
}
|
||||
|
||||
|
||||
#define __enable_fault_irq __enable_fiq
|
||||
#define __disable_fault_irq __disable_fiq
|
||||
|
||||
|
||||
#endif /* (__CORTEX_M >= 0x03) */
|
||||
|
||||
__IAR_FT uint32_t __ROR(uint32_t op1, uint32_t op2) {
|
||||
return (op1 >> op2) | (op1 << ((sizeof(op1)*8)-op2));
|
||||
}
|
||||
|
||||
#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
|
||||
(defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
|
||||
|
||||
__IAR_FT uint32_t __TZ_get_CONTROL_NS(void) {
|
||||
uint32_t res;
|
||||
__asm volatile("MRS %0,CONTROL_NS" : "=r" (res));
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT void __TZ_set_CONTROL_NS(uint32_t value) {
|
||||
__asm volatile("MSR CONTROL_NS,%0" :: "r" (value));
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __TZ_get_PSP_NS(void) {
|
||||
uint32_t res;
|
||||
__asm volatile("MRS %0,PSP_NS" : "=r" (res));
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT void __TZ_set_PSP_NS(uint32_t value) {
|
||||
__asm volatile("MSR PSP_NS,%0" :: "r" (value));
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __TZ_get_MSP_NS(void) {
|
||||
uint32_t res;
|
||||
__asm volatile("MRS %0,MSP_NS" : "=r" (res));
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT void __TZ_set_MSP_NS(uint32_t value) {
|
||||
__asm volatile("MSR MSP_NS,%0" :: "r" (value));
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __TZ_get_SP_NS(void) {
|
||||
uint32_t res;
|
||||
__asm volatile("MRS %0,SP_NS" : "=r" (res));
|
||||
return res;
|
||||
}
|
||||
__IAR_FT void __TZ_set_SP_NS(uint32_t value) {
|
||||
__asm volatile("MSR SP_NS,%0" :: "r" (value));
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __TZ_get_PRIMASK_NS(void) {
|
||||
uint32_t res;
|
||||
__asm volatile("MRS %0,PRIMASK_NS" : "=r" (res));
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT void __TZ_set_PRIMASK_NS(uint32_t value) {
|
||||
__asm volatile("MSR PRIMASK_NS,%0" :: "r" (value));
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __TZ_get_BASEPRI_NS(void) {
|
||||
uint32_t res;
|
||||
__asm volatile("MRS %0,BASEPRI_NS" : "=r" (res));
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT void __TZ_set_BASEPRI_NS(uint32_t value) {
|
||||
__asm volatile("MSR BASEPRI_NS,%0" :: "r" (value));
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __TZ_get_FAULTMASK_NS(void) {
|
||||
uint32_t res;
|
||||
__asm volatile("MRS %0,FAULTMASK_NS" : "=r" (res));
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT void __TZ_set_FAULTMASK_NS(uint32_t value) {
|
||||
__asm volatile("MSR FAULTMASK_NS,%0" :: "r" (value));
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __TZ_get_PSPLIM_NS(void) {
|
||||
uint32_t res;
|
||||
__asm volatile("MRS %0,PSPLIM_NS" : "=r" (res));
|
||||
return res;
|
||||
}
|
||||
__IAR_FT void __TZ_set_PSPLIM_NS(uint32_t value) {
|
||||
__asm volatile("MSR PSPLIM_NS,%0" :: "r" (value));
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __TZ_get_MSPLIM_NS(void) {
|
||||
uint32_t res;
|
||||
__asm volatile("MRS %0,MSPLIM_NS" : "=r" (res));
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT void __TZ_set_MSPLIM_NS(uint32_t value) {
|
||||
__asm volatile("MSR MSPLIM_NS,%0" :: "r" (value));
|
||||
}
|
||||
|
||||
#endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */
|
||||
|
||||
#endif /* __ICCARM_INTRINSICS_VERSION__ == 2 */
|
||||
|
||||
#define __BKPT(value) __asm volatile ("BKPT %0" : : "i"(value))
|
||||
|
||||
#if __IAR_M0_FAMILY
|
||||
__STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat) {
|
||||
if ((sat >= 1U) && (sat <= 32U)) {
|
||||
const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U);
|
||||
const int32_t min = -1 - max ;
|
||||
if (val > max) {
|
||||
return max;
|
||||
} else if (val < min) {
|
||||
return min;
|
||||
}
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
__STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat) {
|
||||
if (sat <= 31U) {
|
||||
const uint32_t max = ((1U << sat) - 1U);
|
||||
if (val > (int32_t)max) {
|
||||
return max;
|
||||
} else if (val < 0) {
|
||||
return 0U;
|
||||
}
|
||||
}
|
||||
return (uint32_t)val;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (__CORTEX_M >= 0x03) /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */
|
||||
|
||||
__IAR_FT uint8_t __LDRBT(volatile uint8_t *addr) {
|
||||
uint32_t res;
|
||||
__ASM("LDRBT %0, [%1]" : "=r" (res) : "r" (addr) : "memory");
|
||||
return ((uint8_t)res);
|
||||
}
|
||||
|
||||
__IAR_FT uint16_t __LDRHT(volatile uint16_t *addr) {
|
||||
uint32_t res;
|
||||
__ASM("LDRHT %0, [%1]" : "=r" (res) : "r" (addr) : "memory");
|
||||
return ((uint16_t)res);
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __LDRT(volatile uint32_t *addr) {
|
||||
uint32_t res;
|
||||
__ASM("LDRT %0, [%1]" : "=r" (res) : "r" (addr) : "memory");
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT void __STRBT(uint8_t value, volatile uint8_t *addr) {
|
||||
__ASM("STRBT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory");
|
||||
}
|
||||
|
||||
__IAR_FT void __STRHT(uint16_t value, volatile uint16_t *addr) {
|
||||
__ASM("STRHT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory");
|
||||
}
|
||||
|
||||
__IAR_FT void __STRT(uint32_t value, volatile uint32_t *addr) {
|
||||
__ASM("STRT %1, [%0]" : : "r" (addr), "r" (value) : "memory");
|
||||
}
|
||||
|
||||
#endif /* (__CORTEX_M >= 0x03) */
|
||||
|
||||
#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \
|
||||
(defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) )
|
||||
|
||||
|
||||
__IAR_FT uint8_t __LDAB(volatile uint8_t *ptr) {
|
||||
uint32_t res;
|
||||
__ASM volatile ("LDAB %0, [%1]" : "=r" (res) : "r" (*ptr) : "memory");
|
||||
return ((uint8_t)res);
|
||||
}
|
||||
|
||||
__IAR_FT uint16_t __LDAH(volatile uint16_t *ptr) {
|
||||
uint32_t res;
|
||||
__ASM volatile ("LDAH %0, [%1]" : "=r" (res) : "r" (*ptr) : "memory");
|
||||
return ((uint16_t)res);
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __LDA(volatile uint32_t *ptr) {
|
||||
uint32_t res;
|
||||
__ASM volatile ("LDA %0, [%1]" : "=r" (res) : "r" (*ptr) : "memory");
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT void __STLB(uint8_t value, volatile uint8_t *ptr) {
|
||||
__ASM volatile ("STLB %1, [%0]" :: "r" (*ptr), "r" (value) : "memory");
|
||||
}
|
||||
|
||||
__IAR_FT void __STLH(uint16_t value, volatile uint16_t *ptr) {
|
||||
__ASM volatile ("STLH %1, [%0]" :: "r" (*ptr), "r" (value) : "memory");
|
||||
}
|
||||
|
||||
__IAR_FT void __STL(uint32_t value, volatile uint32_t *ptr) {
|
||||
__ASM volatile ("STL %1, [%0]" :: "r" (*ptr), "r" (value) : "memory");
|
||||
}
|
||||
|
||||
__IAR_FT uint8_t __LDAEXB(volatile uint8_t *ptr) {
|
||||
uint32_t res;
|
||||
__ASM volatile ("LDAEXB %0, [%1]" : "=r" (res) : "r" (*ptr) : "memory");
|
||||
return ((uint8_t)res);
|
||||
}
|
||||
|
||||
__IAR_FT uint16_t __LDAEXH(volatile uint16_t *ptr) {
|
||||
uint32_t res;
|
||||
__ASM volatile ("LDAEXH %0, [%1]" : "=r" (res) : "r" (*ptr) : "memory");
|
||||
return ((uint16_t)res);
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __LDAEX(volatile uint32_t *ptr) {
|
||||
uint32_t res;
|
||||
__ASM volatile ("LDAEX %0, [%1]" : "=r" (res) : "r" (*ptr) : "memory");
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) {
|
||||
uint32_t res;
|
||||
__ASM volatile ("STLEXB %0, %2, [%1]" : "=r" (res) : "r" (*ptr), "r" (value) : "memory");
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) {
|
||||
uint32_t res;
|
||||
__ASM volatile ("STLEXH %0, %2, [%1]" : "=r" (res) : "r" (*ptr), "r" (value) : "memory");
|
||||
return res;
|
||||
}
|
||||
|
||||
__IAR_FT uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) {
|
||||
uint32_t res;
|
||||
__ASM volatile ("STLEX %0, %2, [%1]" : "=r" (res) : "r" (*ptr), "r" (value) : "memory");
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */
|
||||
|
||||
#undef __IAR_FT
|
||||
#undef __IAR_M0_FAMILY
|
||||
#undef __ICCARM_V8
|
||||
|
||||
#pragma diag_default=Pe940
|
||||
#pragma diag_default=Pe177
|
||||
|
||||
#endif /* __CMSIS_ICCARM_H__ */
|
|
@ -0,0 +1,39 @@
|
|||
/**************************************************************************//**
|
||||
* @file cmsis_version.h
|
||||
* @brief CMSIS Core(M) Version definitions
|
||||
* @version V5.0.2
|
||||
* @date 19. April 2017
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2017 ARM Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#if defined ( __ICCARM__ )
|
||||
#pragma system_include /* treat file as system include file for MISRA check */
|
||||
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||
#pragma clang system_header /* treat file as system include file */
|
||||
#endif
|
||||
|
||||
#ifndef __CMSIS_VERSION_H
|
||||
#define __CMSIS_VERSION_H
|
||||
|
||||
/* CMSIS Version definitions */
|
||||
#define __CM_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS Core(M) main version */
|
||||
#define __CM_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS Core(M) sub version */
|
||||
#define __CM_CMSIS_VERSION ((__CM_CMSIS_VERSION_MAIN << 16U) | \
|
||||
__CM_CMSIS_VERSION_SUB ) /*!< CMSIS Core(M) version number */
|
||||
#endif
|
|
@ -1,8 +1,8 @@
|
|||
/**************************************************************************//**
|
||||
* @file core_armv8mbl.h
|
||||
* @brief CMSIS ARMv8MBL Core Peripheral Access Layer Header File
|
||||
* @version V5.0.2
|
||||
* @date 13. February 2017
|
||||
* @version V5.0.3
|
||||
* @date 09. August 2017
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2017 ARM Limited. All rights reserved.
|
||||
|
@ -59,12 +59,14 @@
|
|||
\ingroup Cortex_ARMv8MBL
|
||||
@{
|
||||
*/
|
||||
|
||||
#include "cmsis_version.h"
|
||||
|
||||
/* CMSIS cmGrebe definitions */
|
||||
#define __ARMv8MBL_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */
|
||||
#define __ARMv8MBL_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */
|
||||
/* CMSIS definitions */
|
||||
#define __ARMv8MBL_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */
|
||||
#define __ARMv8MBL_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */
|
||||
#define __ARMv8MBL_CMSIS_VERSION ((__ARMv8MBL_CMSIS_VERSION_MAIN << 16U) | \
|
||||
__ARMv8MBL_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
|
||||
__ARMv8MBL_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */
|
||||
|
||||
#define __CORTEX_M ( 2U) /*!< Cortex-M Core */
|
||||
|
||||
|
@ -881,10 +883,17 @@ typedef struct
|
|||
__IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */
|
||||
__IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */
|
||||
uint32_t RESERVED0[7U];
|
||||
union {
|
||||
__IOM uint32_t MAIR[2];
|
||||
struct {
|
||||
__IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */
|
||||
__IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */
|
||||
};
|
||||
};
|
||||
} MPU_Type;
|
||||
|
||||
#define MPU_TYPE_RALIASES 1U
|
||||
|
||||
/* MPU Type Register Definitions */
|
||||
#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */
|
||||
#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */
|
||||
|
@ -1627,6 +1636,10 @@ __STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn)
|
|||
{
|
||||
return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
|
||||
}
|
||||
else
|
||||
{
|
||||
return(0U);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1729,6 +1742,13 @@ __STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn)
|
|||
|
||||
/*@} end of CMSIS_Core_NVICFunctions */
|
||||
|
||||
/* ########################## MPU functions #################################### */
|
||||
|
||||
#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U)
|
||||
|
||||
#include "mpu_armv8.h"
|
||||
|
||||
#endif
|
||||
|
||||
/* ########################## FPU functions #################################### */
|
||||
/**
|
|
@ -1,8 +1,8 @@
|
|||
/**************************************************************************//**
|
||||
* @file core_armv8mml.h
|
||||
* @brief CMSIS ARMv8MML Core Peripheral Access Layer Header File
|
||||
* @version V5.0.2
|
||||
* @date 13. February 2017
|
||||
* @version V5.0.3
|
||||
* @date 09. August 2017
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2017 ARM Limited. All rights reserved.
|
||||
|
@ -60,11 +60,13 @@
|
|||
@{
|
||||
*/
|
||||
|
||||
#include "cmsis_version.h"
|
||||
|
||||
/* CMSIS ARMv8MML definitions */
|
||||
#define __ARMv8MML_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */
|
||||
#define __ARMv8MML_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */
|
||||
#define __ARMv8MML_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */
|
||||
#define __ARMv8MML_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */
|
||||
#define __ARMv8MML_CMSIS_VERSION ((__ARMv8MML_CMSIS_VERSION_MAIN << 16U) | \
|
||||
__ARMv8MML_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
|
||||
__ARMv8MML_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */
|
||||
|
||||
#define __CORTEX_M (81U) /*!< Cortex-M Core */
|
||||
|
||||
|
@ -83,6 +85,17 @@
|
|||
#define __FPU_USED 0U
|
||||
#endif
|
||||
|
||||
#if defined(__ARM_FEATURE_DSP)
|
||||
#if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U)
|
||||
#define __DSP_USED 1U
|
||||
#else
|
||||
#error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)"
|
||||
#define __DSP_USED 0U
|
||||
#endif
|
||||
#else
|
||||
#define __DSP_USED 0U
|
||||
#endif
|
||||
|
||||
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||
#if defined __ARM_PCS_VFP
|
||||
#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)
|
||||
|
@ -95,6 +108,17 @@
|
|||
#define __FPU_USED 0U
|
||||
#endif
|
||||
|
||||
#if defined(__ARM_FEATURE_DSP)
|
||||
#if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U)
|
||||
#define __DSP_USED 1U
|
||||
#else
|
||||
#error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)"
|
||||
#define __DSP_USED 0U
|
||||
#endif
|
||||
#else
|
||||
#define __DSP_USED 0U
|
||||
#endif
|
||||
|
||||
#elif defined ( __GNUC__ )
|
||||
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
|
||||
#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)
|
||||
|
@ -106,7 +130,18 @@
|
|||
#else
|
||||
#define __FPU_USED 0U
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(__ARM_FEATURE_DSP)
|
||||
#if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U)
|
||||
#define __DSP_USED 1U
|
||||
#else
|
||||
#error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)"
|
||||
#define __DSP_USED 0U
|
||||
#endif
|
||||
#else
|
||||
#define __DSP_USED 0U
|
||||
#endif
|
||||
|
||||
#elif defined ( __ICCARM__ )
|
||||
#if defined __ARMVFP__
|
||||
#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)
|
||||
|
@ -119,6 +154,17 @@
|
|||
#define __FPU_USED 0U
|
||||
#endif
|
||||
|
||||
#if defined(__ARM_FEATURE_DSP)
|
||||
#if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U)
|
||||
#define __DSP_USED 1U
|
||||
#else
|
||||
#error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)"
|
||||
#define __DSP_USED 0U
|
||||
#endif
|
||||
#else
|
||||
#define __DSP_USED 0U
|
||||
#endif
|
||||
|
||||
#elif defined ( __TI_ARM__ )
|
||||
#if defined __TI_VFP_SUPPORT__
|
||||
#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)
|
||||
|
@ -480,7 +526,7 @@ typedef struct
|
|||
uint32_t RESERVED4[15U];
|
||||
__IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */
|
||||
__IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */
|
||||
__IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 1 */
|
||||
__IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */
|
||||
uint32_t RESERVED5[1U];
|
||||
__OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */
|
||||
uint32_t RESERVED6[1U];
|
||||
|
@ -1505,10 +1551,17 @@ typedef struct
|
|||
__IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Region Base Address Register Alias 3 */
|
||||
__IOM uint32_t RLAR_A3; /*!< Offset: 0x028 (R/W) MPU Region Limit Address Register Alias 3 */
|
||||
uint32_t RESERVED0[1];
|
||||
union {
|
||||
__IOM uint32_t MAIR[2];
|
||||
struct {
|
||||
__IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */
|
||||
__IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */
|
||||
};
|
||||
};
|
||||
} MPU_Type;
|
||||
|
||||
#define MPU_TYPE_RALIASES 4U
|
||||
|
||||
/* MPU Type Register Definitions */
|
||||
#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */
|
||||
#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */
|
||||
|
@ -2661,6 +2714,13 @@ __STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn)
|
|||
|
||||
/*@} end of CMSIS_Core_NVICFunctions */
|
||||
|
||||
/* ########################## MPU functions #################################### */
|
||||
|
||||
#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U)
|
||||
|
||||
#include "mpu_armv8.h"
|
||||
|
||||
#endif
|
||||
|
||||
/* ########################## FPU functions #################################### */
|
||||
/**
|
|
@ -2,7 +2,7 @@
|
|||
* @file core_cm0.h
|
||||
* @brief CMSIS Cortex-M0 Core Peripheral Access Layer Header File
|
||||
* @version V5.0.2
|
||||
* @date 13. February 2017
|
||||
* @date 19. April 2017
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2017 ARM Limited. All rights reserved.
|
||||
|
@ -60,11 +60,13 @@
|
|||
@{
|
||||
*/
|
||||
|
||||
#include "cmsis_version.h"
|
||||
|
||||
/* CMSIS CM0 definitions */
|
||||
#define __CM0_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */
|
||||
#define __CM0_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */
|
||||
#define __CM0_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */
|
||||
#define __CM0_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */
|
||||
#define __CM0_CMSIS_VERSION ((__CM0_CMSIS_VERSION_MAIN << 16U) | \
|
||||
__CM0_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
|
||||
__CM0_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */
|
||||
|
||||
#define __CORTEX_M (0U) /*!< Cortex-M Core */
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
/**************************************************************************//**
|
||||
* @file core_cm0plus.h
|
||||
* @brief CMSIS Cortex-M0+ Core Peripheral Access Layer Header File
|
||||
* @version V5.0.2
|
||||
* @date 13. February 2017
|
||||
* @version V5.0.3
|
||||
* @date 09. August 2017
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2017 ARM Limited. All rights reserved.
|
||||
|
@ -60,11 +60,13 @@
|
|||
@{
|
||||
*/
|
||||
|
||||
#include "cmsis_version.h"
|
||||
|
||||
/* CMSIS CM0+ definitions */
|
||||
#define __CM0PLUS_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */
|
||||
#define __CM0PLUS_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */
|
||||
#define __CM0PLUS_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */
|
||||
#define __CM0PLUS_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */
|
||||
#define __CM0PLUS_CMSIS_VERSION ((__CM0PLUS_CMSIS_VERSION_MAIN << 16U) | \
|
||||
__CM0PLUS_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
|
||||
__CM0PLUS_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */
|
||||
|
||||
#define __CORTEX_M (0U) /*!< Cortex-M Core */
|
||||
|
||||
|
@ -528,6 +530,8 @@ typedef struct
|
|||
__IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */
|
||||
} MPU_Type;
|
||||
|
||||
#define MPU_TYPE_RALIASES 1U
|
||||
|
||||
/* MPU Type Register Definitions */
|
||||
#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */
|
||||
#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */
|
||||
|
@ -932,6 +936,13 @@ __STATIC_INLINE void __NVIC_SystemReset(void)
|
|||
|
||||
/*@} end of CMSIS_Core_NVICFunctions */
|
||||
|
||||
/* ########################## MPU functions #################################### */
|
||||
|
||||
#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U)
|
||||
|
||||
#include "mpu_armv7.h"
|
||||
|
||||
#endif
|
||||
|
||||
/* ########################## FPU functions #################################### */
|
||||
/**
|
|
@ -1,8 +1,8 @@
|
|||
/**************************************************************************//**
|
||||
* @file core_cm23.h
|
||||
* @brief CMSIS Cortex-M23 Core Peripheral Access Layer Header File
|
||||
* @version V5.0.2
|
||||
* @date 13. February 2017
|
||||
* @version V5.0.3
|
||||
* @date 09. August 2017
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2017 ARM Limited. All rights reserved.
|
||||
|
@ -60,11 +60,13 @@
|
|||
@{
|
||||
*/
|
||||
|
||||
/* CMSIS cmGrebe definitions */
|
||||
#define __CM23_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */
|
||||
#define __CM23_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */
|
||||
#include "cmsis_version.h"
|
||||
|
||||
/* CMSIS definitions */
|
||||
#define __CM23_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */
|
||||
#define __CM23_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */
|
||||
#define __CM23_CMSIS_VERSION ((__CM23_CMSIS_VERSION_MAIN << 16U) | \
|
||||
__CM23_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
|
||||
__CM23_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */
|
||||
|
||||
#define __CORTEX_M (23U) /*!< Cortex-M Core */
|
||||
|
||||
|
@ -881,10 +883,17 @@ typedef struct
|
|||
__IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */
|
||||
__IOM uint32_t RLAR; /*!< Offset: 0x010 (R/W) MPU Region Limit Address Register */
|
||||
uint32_t RESERVED0[7U];
|
||||
union {
|
||||
__IOM uint32_t MAIR[2];
|
||||
struct {
|
||||
__IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */
|
||||
__IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */
|
||||
};
|
||||
};
|
||||
} MPU_Type;
|
||||
|
||||
#define MPU_TYPE_RALIASES 1U
|
||||
|
||||
/* MPU Type Register Definitions */
|
||||
#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */
|
||||
#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */
|
||||
|
@ -1627,6 +1636,10 @@ __STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn)
|
|||
{
|
||||
return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
|
||||
}
|
||||
else
|
||||
{
|
||||
return(0U);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1729,6 +1742,13 @@ __STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn)
|
|||
|
||||
/*@} end of CMSIS_Core_NVICFunctions */
|
||||
|
||||
/* ########################## MPU functions #################################### */
|
||||
|
||||
#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U)
|
||||
|
||||
#include "mpu_armv8.h"
|
||||
|
||||
#endif
|
||||
|
||||
/* ########################## FPU functions #################################### */
|
||||
/**
|
|
@ -1,8 +1,8 @@
|
|||
/**************************************************************************//**
|
||||
* @file core_cm3.h
|
||||
* @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File
|
||||
* @version V5.0.2
|
||||
* @date 13. February 2017
|
||||
* @version V5.0.3
|
||||
* @date 09. August 2017
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2017 ARM Limited. All rights reserved.
|
||||
|
@ -60,11 +60,13 @@
|
|||
@{
|
||||
*/
|
||||
|
||||
#include "cmsis_version.h"
|
||||
|
||||
/* CMSIS CM3 definitions */
|
||||
#define __CM3_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */
|
||||
#define __CM3_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */
|
||||
#define __CM3_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */
|
||||
#define __CM3_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */
|
||||
#define __CM3_CMSIS_VERSION ((__CM3_CMSIS_VERSION_MAIN << 16U) | \
|
||||
__CM3_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
|
||||
__CM3_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */
|
||||
|
||||
#define __CORTEX_M (3U) /*!< Cortex-M Core */
|
||||
|
||||
|
@ -1162,6 +1164,8 @@ typedef struct
|
|||
__IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */
|
||||
} MPU_Type;
|
||||
|
||||
#define MPU_TYPE_RALIASES 4U
|
||||
|
||||
/* MPU Type Register Definitions */
|
||||
#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */
|
||||
#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */
|
||||
|
@ -1761,6 +1765,13 @@ __STATIC_INLINE void __NVIC_SystemReset(void)
|
|||
|
||||
/*@} end of CMSIS_Core_NVICFunctions */
|
||||
|
||||
/* ########################## MPU functions #################################### */
|
||||
|
||||
#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U)
|
||||
|
||||
#include "mpu_armv7.h"
|
||||
|
||||
#endif
|
||||
|
||||
/* ########################## FPU functions #################################### */
|
||||
/**
|
|
@ -1,8 +1,8 @@
|
|||
/**************************************************************************//**
|
||||
* @file core_cm33.h
|
||||
* @brief CMSIS Cortex-M33 Core Peripheral Access Layer Header File
|
||||
* @version V5.0.2
|
||||
* @date 13. February 2017
|
||||
* @version V5.0.3
|
||||
* @date 09. August 2017
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2017 ARM Limited. All rights reserved.
|
||||
|
@ -60,11 +60,13 @@
|
|||
@{
|
||||
*/
|
||||
|
||||
#include "cmsis_version.h"
|
||||
|
||||
/* CMSIS CM33 definitions */
|
||||
#define __CM33_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */
|
||||
#define __CM33_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */
|
||||
#define __CM33_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */
|
||||
#define __CM33_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */
|
||||
#define __CM33_CMSIS_VERSION ((__CM33_CMSIS_VERSION_MAIN << 16U) | \
|
||||
__CM33_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
|
||||
__CM33_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */
|
||||
|
||||
#define __CORTEX_M (33U) /*!< Cortex-M Core */
|
||||
|
||||
|
@ -83,6 +85,17 @@
|
|||
#define __FPU_USED 0U
|
||||
#endif
|
||||
|
||||
#if defined(__ARM_FEATURE_DSP)
|
||||
#if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U)
|
||||
#define __DSP_USED 1U
|
||||
#else
|
||||
#error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)"
|
||||
#define __DSP_USED 0U
|
||||
#endif
|
||||
#else
|
||||
#define __DSP_USED 0U
|
||||
#endif
|
||||
|
||||
#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||
#if defined __ARM_PCS_VFP
|
||||
#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)
|
||||
|
@ -95,6 +108,17 @@
|
|||
#define __FPU_USED 0U
|
||||
#endif
|
||||
|
||||
#if defined(__ARM_FEATURE_DSP)
|
||||
#if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U)
|
||||
#define __DSP_USED 1U
|
||||
#else
|
||||
#error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)"
|
||||
#define __DSP_USED 0U
|
||||
#endif
|
||||
#else
|
||||
#define __DSP_USED 0U
|
||||
#endif
|
||||
|
||||
#elif defined ( __GNUC__ )
|
||||
#if defined (__VFP_FP__) && !defined(__SOFTFP__)
|
||||
#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)
|
||||
|
@ -107,6 +131,17 @@
|
|||
#define __FPU_USED 0U
|
||||
#endif
|
||||
|
||||
#if defined(__ARM_FEATURE_DSP)
|
||||
#if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U)
|
||||
#define __DSP_USED 1U
|
||||
#else
|
||||
#error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)"
|
||||
#define __DSP_USED 0U
|
||||
#endif
|
||||
#else
|
||||
#define __DSP_USED 0U
|
||||
#endif
|
||||
|
||||
#elif defined ( __ICCARM__ )
|
||||
#if defined __ARMVFP__
|
||||
#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)
|
||||
|
@ -119,6 +154,17 @@
|
|||
#define __FPU_USED 0U
|
||||
#endif
|
||||
|
||||
#if defined(__ARM_FEATURE_DSP)
|
||||
#if defined(__DSP_PRESENT) && (__DSP_PRESENT == 1U)
|
||||
#define __DSP_USED 1U
|
||||
#else
|
||||
#error "Compiler generates DSP (SIMD) instructions for a devices without DSP extensions (check __DSP_PRESENT)"
|
||||
#define __DSP_USED 0U
|
||||
#endif
|
||||
#else
|
||||
#define __DSP_USED 0U
|
||||
#endif
|
||||
|
||||
#elif defined ( __TI_ARM__ )
|
||||
#if defined __TI_VFP_SUPPORT__
|
||||
#if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)
|
||||
|
@ -480,7 +526,7 @@ typedef struct
|
|||
uint32_t RESERVED4[15U];
|
||||
__IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */
|
||||
__IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */
|
||||
__IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 1 */
|
||||
__IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */
|
||||
uint32_t RESERVED5[1U];
|
||||
__OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */
|
||||
uint32_t RESERVED6[1U];
|
||||
|
@ -1505,10 +1551,17 @@ typedef struct
|
|||
__IOM uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Region Base Address Register Alias 3 */
|
||||
__IOM uint32_t RLAR_A3; /*!< Offset: 0x028 (R/W) MPU Region Limit Address Register Alias 3 */
|
||||
uint32_t RESERVED0[1];
|
||||
union {
|
||||
__IOM uint32_t MAIR[2];
|
||||
struct {
|
||||
__IOM uint32_t MAIR0; /*!< Offset: 0x030 (R/W) MPU Memory Attribute Indirection Register 0 */
|
||||
__IOM uint32_t MAIR1; /*!< Offset: 0x034 (R/W) MPU Memory Attribute Indirection Register 1 */
|
||||
};
|
||||
};
|
||||
} MPU_Type;
|
||||
|
||||
#define MPU_TYPE_RALIASES 4U
|
||||
|
||||
/* MPU Type Register Definitions */
|
||||
#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */
|
||||
#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */
|
||||
|
@ -1534,8 +1587,8 @@ typedef struct
|
|||
#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */
|
||||
|
||||
/* MPU Region Base Address Register Definitions */
|
||||
#define MPU_RBAR_ADDR_Pos 5U /*!< MPU RBAR: ADDR Position */
|
||||
#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */
|
||||
#define MPU_RBAR_BASE_Pos 5U /*!< MPU RBAR: ADDR Position */
|
||||
#define MPU_RBAR_BASE_Msk (0x7FFFFFFUL << MPU_RBAR_BASE_Pos) /*!< MPU RBAR: ADDR Mask */
|
||||
|
||||
#define MPU_RBAR_SH_Pos 3U /*!< MPU RBAR: SH Position */
|
||||
#define MPU_RBAR_SH_Msk (0x3UL << MPU_RBAR_SH_Pos) /*!< MPU RBAR: SH Mask */
|
||||
|
@ -2557,6 +2610,10 @@ __STATIC_INLINE uint32_t TZ_NVIC_GetPendingIRQ_NS(IRQn_Type IRQn)
|
|||
{
|
||||
return((uint32_t)(((NVIC_NS->ISPR[(((uint32_t)(int32_t)IRQn) >> 5UL)] & (1UL << (((uint32_t)(int32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL));
|
||||
}
|
||||
else
|
||||
{
|
||||
return(0U);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -2657,6 +2714,13 @@ __STATIC_INLINE uint32_t TZ_NVIC_GetPriority_NS(IRQn_Type IRQn)
|
|||
|
||||
/*@} end of CMSIS_Core_NVICFunctions */
|
||||
|
||||
/* ########################## MPU functions #################################### */
|
||||
|
||||
#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U)
|
||||
|
||||
#include "mpu_armv8.h"
|
||||
|
||||
#endif
|
||||
|
||||
/* ########################## FPU functions #################################### */
|
||||
/**
|
|
@ -1,8 +1,8 @@
|
|||
/**************************************************************************//**
|
||||
* @file core_cm4.h
|
||||
* @brief CMSIS Cortex-M4 Core Peripheral Access Layer Header File
|
||||
* @version V5.0.2
|
||||
* @date 13. February 2017
|
||||
* @version V5.0.3
|
||||
* @date 09. August 2017
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2017 ARM Limited. All rights reserved.
|
||||
|
@ -60,11 +60,13 @@
|
|||
@{
|
||||
*/
|
||||
|
||||
/* CMSIS CM4 definitions */
|
||||
#define __CM4_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */
|
||||
#define __CM4_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */
|
||||
#include "cmsis_version.h"
|
||||
|
||||
/* CMSIS CM4 definitions */
|
||||
#define __CM4_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */
|
||||
#define __CM4_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */
|
||||
#define __CM4_CMSIS_VERSION ((__CM4_CMSIS_VERSION_MAIN << 16U) | \
|
||||
__CM4_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
|
||||
__CM4_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */
|
||||
|
||||
#define __CORTEX_M (4U) /*!< Cortex-M Core */
|
||||
|
||||
|
@ -1227,6 +1229,8 @@ typedef struct
|
|||
__IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */
|
||||
} MPU_Type;
|
||||
|
||||
#define MPU_TYPE_RALIASES 4U
|
||||
|
||||
/* MPU Type Register Definitions */
|
||||
#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */
|
||||
#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */
|
||||
|
@ -1935,6 +1939,14 @@ __STATIC_INLINE void __NVIC_SystemReset(void)
|
|||
|
||||
/*@} end of CMSIS_Core_NVICFunctions */
|
||||
|
||||
/* ########################## MPU functions #################################### */
|
||||
|
||||
#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U)
|
||||
|
||||
#include "mpu_armv7.h"
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/* ########################## FPU functions #################################### */
|
||||
/**
|
|
@ -1,8 +1,8 @@
|
|||
/**************************************************************************//**
|
||||
* @file core_cm7.h
|
||||
* @brief CMSIS Cortex-M7 Core Peripheral Access Layer Header File
|
||||
* @version V5.0.2
|
||||
* @date 13. February 2017
|
||||
* @version V5.0.3
|
||||
* @date 09. August 2017
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2017 ARM Limited. All rights reserved.
|
||||
|
@ -60,11 +60,13 @@
|
|||
@{
|
||||
*/
|
||||
|
||||
#include "cmsis_version.h"
|
||||
|
||||
/* CMSIS CM7 definitions */
|
||||
#define __CM7_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */
|
||||
#define __CM7_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */
|
||||
#define __CM7_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */
|
||||
#define __CM7_CMSIS_VERSION_SUB ( __CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */
|
||||
#define __CM7_CMSIS_VERSION ((__CM7_CMSIS_VERSION_MAIN << 16U) | \
|
||||
__CM7_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
|
||||
__CM7_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */
|
||||
|
||||
#define __CORTEX_M (7U) /*!< Cortex-M Core */
|
||||
|
||||
|
@ -482,7 +484,7 @@ typedef struct
|
|||
uint32_t RESERVED4[15U];
|
||||
__IM uint32_t MVFR0; /*!< Offset: 0x240 (R/ ) Media and VFP Feature Register 0 */
|
||||
__IM uint32_t MVFR1; /*!< Offset: 0x244 (R/ ) Media and VFP Feature Register 1 */
|
||||
__IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 1 */
|
||||
__IM uint32_t MVFR2; /*!< Offset: 0x248 (R/ ) Media and VFP Feature Register 2 */
|
||||
uint32_t RESERVED5[1U];
|
||||
__OM uint32_t ICIALLU; /*!< Offset: 0x250 ( /W) I-Cache Invalidate All to PoU */
|
||||
uint32_t RESERVED6[1U];
|
||||
|
@ -1432,6 +1434,8 @@ typedef struct
|
|||
__IOM uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 Region Attribute and Size Register */
|
||||
} MPU_Type;
|
||||
|
||||
#define MPU_TYPE_RALIASES 4U
|
||||
|
||||
/* MPU Type Register Definitions */
|
||||
#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */
|
||||
#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */
|
||||
|
@ -2143,6 +2147,13 @@ __STATIC_INLINE void __NVIC_SystemReset(void)
|
|||
|
||||
/*@} end of CMSIS_Core_NVICFunctions */
|
||||
|
||||
/* ########################## MPU functions #################################### */
|
||||
|
||||
#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U)
|
||||
|
||||
#include "mpu_armv7.h"
|
||||
|
||||
#endif
|
||||
|
||||
/* ########################## FPU functions #################################### */
|
||||
/**
|
|
@ -2,7 +2,7 @@
|
|||
* @file core_sc000.h
|
||||
* @brief CMSIS SC000 Core Peripheral Access Layer Header File
|
||||
* @version V5.0.2
|
||||
* @date 13. February 2017
|
||||
* @date 19. April 2017
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2017 ARM Limited. All rights reserved.
|
||||
|
@ -60,11 +60,13 @@
|
|||
@{
|
||||
*/
|
||||
|
||||
#include "cmsis_version.h"
|
||||
|
||||
/* CMSIS SC000 definitions */
|
||||
#define __SC000_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */
|
||||
#define __SC000_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */
|
||||
#define __SC000_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */
|
||||
#define __SC000_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */
|
||||
#define __SC000_CMSIS_VERSION ((__SC000_CMSIS_VERSION_MAIN << 16U) | \
|
||||
__SC000_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
|
||||
__SC000_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */
|
||||
|
||||
#define __CORTEX_SC (000U) /*!< Cortex secure core */
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
* @file core_sc300.h
|
||||
* @brief CMSIS SC300 Core Peripheral Access Layer Header File
|
||||
* @version V5.0.2
|
||||
* @date 13. February 2017
|
||||
* @date 19. April 2017
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2009-2017 ARM Limited. All rights reserved.
|
||||
|
@ -60,11 +60,13 @@
|
|||
@{
|
||||
*/
|
||||
|
||||
#include "cmsis_version.h"
|
||||
|
||||
/* CMSIS SC300 definitions */
|
||||
#define __SC300_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS HAL main version */
|
||||
#define __SC300_CMSIS_VERSION_SUB ( 0U) /*!< [15:0] CMSIS HAL sub version */
|
||||
#define __SC300_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */
|
||||
#define __SC300_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */
|
||||
#define __SC300_CMSIS_VERSION ((__SC300_CMSIS_VERSION_MAIN << 16U) | \
|
||||
__SC300_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */
|
||||
__SC300_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */
|
||||
|
||||
#define __CORTEX_SC (300U) /*!< Cortex secure core */
|
||||
|
|
@ -0,0 +1,191 @@
|
|||
/******************************************************************************
|
||||
* @file mpu_armv7.h
|
||||
* @brief CMSIS MPU API for ARMv7 MPU
|
||||
* @version V5.0.3
|
||||
* @date 09. August 2017
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2017 ARM Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ARM_MPU_ARMV7_H
|
||||
#define ARM_MPU_ARMV7_H
|
||||
|
||||
#define ARM_MPU_REGION_SIZE_32B ((uint8_t)0x04U)
|
||||
#define ARM_MPU_REGION_SIZE_64B ((uint8_t)0x05U)
|
||||
#define ARM_MPU_REGION_SIZE_128B ((uint8_t)0x06U)
|
||||
#define ARM_MPU_REGION_SIZE_256B ((uint8_t)0x07U)
|
||||
#define ARM_MPU_REGION_SIZE_512B ((uint8_t)0x08U)
|
||||
#define ARM_MPU_REGION_SIZE_1KB ((uint8_t)0x09U)
|
||||
#define ARM_MPU_REGION_SIZE_2KB ((uint8_t)0x0AU)
|
||||
#define ARM_MPU_REGION_SIZE_4KB ((uint8_t)0x0BU)
|
||||
#define ARM_MPU_REGION_SIZE_8KB ((uint8_t)0x0CU)
|
||||
#define ARM_MPU_REGION_SIZE_16KB ((uint8_t)0x0DU)
|
||||
#define ARM_MPU_REGION_SIZE_32KB ((uint8_t)0x0EU)
|
||||
#define ARM_MPU_REGION_SIZE_64KB ((uint8_t)0x0FU)
|
||||
#define ARM_MPU_REGION_SIZE_128KB ((uint8_t)0x10U)
|
||||
#define ARM_MPU_REGION_SIZE_256KB ((uint8_t)0x11U)
|
||||
#define ARM_MPU_REGION_SIZE_512KB ((uint8_t)0x12U)
|
||||
#define ARM_MPU_REGION_SIZE_1MB ((uint8_t)0x13U)
|
||||
#define ARM_MPU_REGION_SIZE_2MB ((uint8_t)0x14U)
|
||||
#define ARM_MPU_REGION_SIZE_4MB ((uint8_t)0x15U)
|
||||
#define ARM_MPU_REGION_SIZE_8MB ((uint8_t)0x16U)
|
||||
#define ARM_MPU_REGION_SIZE_16MB ((uint8_t)0x17U)
|
||||
#define ARM_MPU_REGION_SIZE_32MB ((uint8_t)0x18U)
|
||||
#define ARM_MPU_REGION_SIZE_64MB ((uint8_t)0x19U)
|
||||
#define ARM_MPU_REGION_SIZE_128MB ((uint8_t)0x1AU)
|
||||
#define ARM_MPU_REGION_SIZE_256MB ((uint8_t)0x1BU)
|
||||
#define ARM_MPU_REGION_SIZE_512MB ((uint8_t)0x1CU)
|
||||
#define ARM_MPU_REGION_SIZE_1GB ((uint8_t)0x1DU)
|
||||
#define ARM_MPU_REGION_SIZE_2GB ((uint8_t)0x1EU)
|
||||
#define ARM_MPU_REGION_SIZE_4GB ((uint8_t)0x1FU)
|
||||
|
||||
#define ARM_MPU_AP_NONE 0U
|
||||
#define ARM_MPU_AP_PRIV 1U
|
||||
#define ARM_MPU_AP_URO 2U
|
||||
#define ARM_MPU_AP_FULL 3U
|
||||
#define ARM_MPU_AP_PRO 5U
|
||||
#define ARM_MPU_AP_RO 6U
|
||||
|
||||
/** MPU Region Base Address Register Value
|
||||
*
|
||||
* \param Region The region to be configured, number 0 to 15.
|
||||
* \param BaseAddress The base address for the region.
|
||||
*/
|
||||
#define ARM_MPU_RBAR(Region, BaseAddress) \
|
||||
(((BaseAddress) & MPU_RBAR_ADDR_Msk) | \
|
||||
((Region) & MPU_RBAR_REGION_Msk) | \
|
||||
(MPU_RBAR_VALID_Msk))
|
||||
|
||||
/**
|
||||
* MPU Region Attribut and Size Register Value
|
||||
*
|
||||
* \param DisableExec Instruction access disable bit, 1= disable instruction fetches.
|
||||
* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode.
|
||||
* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral.
|
||||
* \param IsShareable Region is shareable between multiple bus masters.
|
||||
* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache.
|
||||
* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy.
|
||||
* \param SubRegionDisable Sub-region disable field.
|
||||
* \param Size Region size of the region to be configured, for example 4K, 8K.
|
||||
*/
|
||||
#define ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size) \
|
||||
((((DisableExec ) << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk) | \
|
||||
(((AccessPermission) << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) | \
|
||||
(((TypeExtField ) << MPU_RASR_TEX_Pos) & MPU_RASR_TEX_Msk) | \
|
||||
(((IsShareable ) << MPU_RASR_S_Pos) & MPU_RASR_S_Msk) | \
|
||||
(((IsCacheable ) << MPU_RASR_C_Pos) & MPU_RASR_C_Msk) | \
|
||||
(((IsBufferable ) << MPU_RASR_B_Pos) & MPU_RASR_B_Msk) | \
|
||||
(((SubRegionDisable) << MPU_RASR_SRD_Pos) & MPU_RASR_SRD_Msk) | \
|
||||
(((Size ) << MPU_RASR_SIZE_Pos) & MPU_RASR_SIZE_Msk) | \
|
||||
(MPU_RASR_ENABLE_Msk))
|
||||
|
||||
|
||||
/**
|
||||
* Struct for a single MPU Region
|
||||
*/
|
||||
typedef struct _ARM_MPU_Region_t {
|
||||
uint32_t RBAR; //!< The region base address register value (RBAR)
|
||||
uint32_t RASR; //!< The region attribute and size register value (RASR) \ref MPU_RASR
|
||||
} ARM_MPU_Region_t;
|
||||
|
||||
/** Enable the MPU.
|
||||
* \param MPU_Control Default access permissions for unconfigured regions.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control)
|
||||
{
|
||||
__DSB();
|
||||
__ISB();
|
||||
MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
|
||||
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
|
||||
SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Disable the MPU.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_Disable(void)
|
||||
{
|
||||
__DSB();
|
||||
__ISB();
|
||||
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
|
||||
SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
|
||||
#endif
|
||||
MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk;
|
||||
}
|
||||
|
||||
/** Clear and disable the given MPU region.
|
||||
* \param rnr Region number to be cleared.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr)
|
||||
{
|
||||
MPU->RNR = rnr;
|
||||
MPU->RASR = 0U;
|
||||
}
|
||||
|
||||
/** Configure an MPU region.
|
||||
* \param rbar Value for RBAR register.
|
||||
* \param rsar Value for RSAR register.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rbar, uint32_t rasr)
|
||||
{
|
||||
MPU->RBAR = rbar;
|
||||
MPU->RASR = rasr;
|
||||
}
|
||||
|
||||
/** Configure the given MPU region.
|
||||
* \param rnr Region number to be configured.
|
||||
* \param rbar Value for RBAR register.
|
||||
* \param rsar Value for RSAR register.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_SetRegionEx(uint32_t rnr, uint32_t rbar, uint32_t rasr)
|
||||
{
|
||||
MPU->RNR = rnr;
|
||||
MPU->RBAR = rbar;
|
||||
MPU->RASR = rasr;
|
||||
}
|
||||
|
||||
/** Memcopy with strictly ordered memory access, e.g. for register targets.
|
||||
* \param dst Destination data is copied to.
|
||||
* \param src Source data is copied from.
|
||||
* \param len Amount of data words to be copied.
|
||||
*/
|
||||
__STATIC_INLINE void orderedCpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len)
|
||||
{
|
||||
uint32_t i;
|
||||
for (i = 0U; i < len; ++i)
|
||||
{
|
||||
dst[i] = src[i];
|
||||
}
|
||||
}
|
||||
|
||||
/** Load the given number of MPU regions from a table.
|
||||
* \param table Pointer to the MPU configuration table.
|
||||
* \param cnt Amount of regions to be configured.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_Load(ARM_MPU_Region_t const* table, uint32_t cnt)
|
||||
{
|
||||
static const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U;
|
||||
if (cnt > MPU_TYPE_RALIASES) {
|
||||
orderedCpy(&(MPU->RBAR), &(table->RBAR), MPU_TYPE_RALIASES*rowWordSize);
|
||||
ARM_MPU_Load(table+MPU_TYPE_RALIASES, cnt-MPU_TYPE_RALIASES);
|
||||
} else {
|
||||
orderedCpy(&(MPU->RBAR), &(table->RBAR), cnt*rowWordSize);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,323 @@
|
|||
/******************************************************************************
|
||||
* @file mpu_armv8.h
|
||||
* @brief CMSIS MPU API for ARMv8 MPU
|
||||
* @version V5.0.3
|
||||
* @date 09. August 2017
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2017 ARM Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef ARM_MPU_ARMV8_H
|
||||
#define ARM_MPU_ARMV8_H
|
||||
|
||||
/** \brief Attribute for device memory (outer only) */
|
||||
#define ARM_MPU_ATTR_DEVICE ( 0U )
|
||||
|
||||
/** \brief Attribute for non-cacheable, normal memory */
|
||||
#define ARM_MPU_ATTR_NON_CACHEABLE ( 4U )
|
||||
|
||||
/** \brief Attribute for normal memory (outer and inner)
|
||||
* \param NT Non-Transient: Set to 1 for non-transient data.
|
||||
* \param WB Write-Back: Set to 1 to use write-back update policy.
|
||||
* \param RA Read Allocation: Set to 1 to use cache allocation on read miss.
|
||||
* \param WA Write Allocation: Set to 1 to use cache allocation on write miss.
|
||||
*/
|
||||
#define ARM_MPU_ATTR_MEMORY_(NT, WB, RA, WA) \
|
||||
(((NT & 1U) << 3U) | ((WB & 1U) << 2U) | ((RA & 1U) << 1U) | (WA & 1U))
|
||||
|
||||
/** \brief Device memory type non Gathering, non Re-ordering, non Early Write Acknowledgement */
|
||||
#define ARM_MPU_ATTR_DEVICE_nGnRnE (0U)
|
||||
|
||||
/** \brief Device memory type non Gathering, non Re-ordering, Early Write Acknowledgement */
|
||||
#define ARM_MPU_ATTR_DEVICE_nGnRE (1U)
|
||||
|
||||
/** \brief Device memory type non Gathering, Re-ordering, Early Write Acknowledgement */
|
||||
#define ARM_MPU_ATTR_DEVICE_nGRE (2U)
|
||||
|
||||
/** \brief Device memory type Gathering, Re-ordering, Early Write Acknowledgement */
|
||||
#define ARM_MPU_ATTR_DEVICE_GRE (3U)
|
||||
|
||||
/** \brief Memory Attribute
|
||||
* \param O Outer memory attributes
|
||||
* \param I O == ARM_MPU_ATTR_DEVICE: Device memory attributes, else: Inner memory attributes
|
||||
*/
|
||||
#define ARM_MPU_ATTR(O, I) (((O & 0xFU) << 4U) | (((O & 0xFU) != 0U) ? (I & 0xFU) : ((I & 0x3U) << 2U)))
|
||||
|
||||
/** \brief Normal memory non-shareable */
|
||||
#define ARM_MPU_SH_NON (0U)
|
||||
|
||||
/** \brief Normal memory outer shareable */
|
||||
#define ARM_MPU_SH_OUTER (2U)
|
||||
|
||||
/** \brief Normal memory inner shareable */
|
||||
#define ARM_MPU_SH_INNER (3U)
|
||||
|
||||
/** \brief Memory access permissions
|
||||
* \param RO Read-Only: Set to 1 for read-only memory.
|
||||
* \param NP Non-Privileged: Set to 1 for non-privileged memory.
|
||||
*/
|
||||
#define ARM_MPU_AP_(RO, NP) (((RO & 1U) << 1U) | (NP & 1U))
|
||||
|
||||
/** \brief Region Base Address Register value
|
||||
* \param BASE The base address bits [31:5] of a memory region. The value is zero extended. Effective address gets 32 byte aligned.
|
||||
* \param SH Defines the Shareability domain for this memory region.
|
||||
* \param RO Read-Only: Set to 1 for a read-only memory region.
|
||||
* \param NP Non-Privileged: Set to 1 for a non-privileged memory region.
|
||||
* \oaram XN eXecute Never: Set to 1 for a non-executable memory region.
|
||||
*/
|
||||
#define ARM_MPU_RBAR(BASE, SH, RO, NP, XN) \
|
||||
((BASE & MPU_RBAR_BASE_Pos) | \
|
||||
((SH << MPU_RBAR_SH_Pos) & MPU_RBAR_SH_Msk) | \
|
||||
((ARM_MPU_AP_(RO, NP) << MPU_RBAR_AP_Pos) & MPU_RBAR_AP_Msk) | \
|
||||
((XN << MPU_RBAR_XN_Pos) & MPU_RBAR_XN_Msk))
|
||||
|
||||
/** \brief Region Limit Address Register value
|
||||
* \param LIMIT The limit address bits [31:5] for this memory region. The value is one extended.
|
||||
* \param IDX The attribute index to be associated with this memory region.
|
||||
*/
|
||||
#define ARM_MPU_RLAR(LIMIT, IDX) \
|
||||
((LIMIT & MPU_RLAR_LIMIT_Msk) | \
|
||||
((IDX << MPU_RLAR_AttrIndx_Pos) & MPU_RLAR_AttrIndx_Msk) | \
|
||||
(MPU_RLAR_EN_Msk))
|
||||
|
||||
/**
|
||||
* Struct for a single MPU Region
|
||||
*/
|
||||
typedef struct _ARM_MPU_Region_t {
|
||||
uint32_t RBAR; /*!< Region Base Address Register value */
|
||||
uint32_t RLAR; /*!< Region Limit Address Register value */
|
||||
} ARM_MPU_Region_t;
|
||||
|
||||
/** Enable the MPU.
|
||||
* \param MPU_Control Default access permissions for unconfigured regions.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control)
|
||||
{
|
||||
__DSB();
|
||||
__ISB();
|
||||
MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
|
||||
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
|
||||
SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Disable the MPU.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_Disable(void)
|
||||
{
|
||||
__DSB();
|
||||
__ISB();
|
||||
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
|
||||
SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
|
||||
#endif
|
||||
MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk;
|
||||
}
|
||||
|
||||
#ifdef MPU_NS
|
||||
/** Enable the Non-secure MPU.
|
||||
* \param MPU_Control Default access permissions for unconfigured regions.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_Enable_NS(uint32_t MPU_Control)
|
||||
{
|
||||
__DSB();
|
||||
__ISB();
|
||||
MPU_NS->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk;
|
||||
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
|
||||
SCB_NS->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Disable the Non-secure MPU.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_Disable_NS(void)
|
||||
{
|
||||
__DSB();
|
||||
__ISB();
|
||||
#ifdef SCB_SHCSR_MEMFAULTENA_Msk
|
||||
SCB_NS->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk;
|
||||
#endif
|
||||
MPU_NS->CTRL &= ~MPU_CTRL_ENABLE_Msk;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Set the memory attribute encoding to the given MPU.
|
||||
* \param mpu Pointer to the MPU to be configured.
|
||||
* \param idx The attribute index to be set [0-7]
|
||||
* \param attr The attribute value to be set.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_SetMemAttrEx(MPU_Type* mpu, uint8_t idx, uint8_t attr)
|
||||
{
|
||||
const uint8_t reg = idx / 4U;
|
||||
const uint32_t pos = ((idx % 4U) * 8U);
|
||||
const uint32_t mask = 0xFFU << pos;
|
||||
|
||||
if (reg >= (sizeof(MPU->MAIR) / sizeof(MPU->MAIR[0]))) {
|
||||
return; // invalid index
|
||||
}
|
||||
|
||||
MPU->MAIR[reg] = ((MPU->MAIR[reg] & ~mask) | ((attr << pos) & mask));
|
||||
}
|
||||
|
||||
/** Set the memory attribute encoding.
|
||||
* \param idx The attribute index to be set [0-7]
|
||||
* \param attr The attribute value to be set.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_SetMemAttr(uint8_t idx, uint8_t attr)
|
||||
{
|
||||
ARM_MPU_SetMemAttrEx(MPU, idx, attr);
|
||||
}
|
||||
|
||||
#ifdef MPU_NS
|
||||
/** Set the memory attribute encoding to the Non-secure MPU.
|
||||
* \param idx The attribute index to be set [0-7]
|
||||
* \param attr The attribute value to be set.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_SetMemAttr_NS(uint8_t idx, uint8_t attr)
|
||||
{
|
||||
ARM_MPU_SetMemAttrEx(MPU_NS, idx, attr);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Clear and disable the given MPU region of the given MPU.
|
||||
* \param mpu Pointer to MPU to be used.
|
||||
* \param rnr Region number to be cleared.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_ClrRegionEx(MPU_Type* mpu, uint32_t rnr)
|
||||
{
|
||||
MPU->RNR = rnr;
|
||||
MPU->RLAR = 0U;
|
||||
}
|
||||
|
||||
/** Clear and disable the given MPU region.
|
||||
* \param rnr Region number to be cleared.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr)
|
||||
{
|
||||
ARM_MPU_ClrRegionEx(MPU, rnr);
|
||||
}
|
||||
|
||||
#ifdef MPU_NS
|
||||
/** Clear and disable the given Non-secure MPU region.
|
||||
* \param rnr Region number to be cleared.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_ClrRegion_NS(uint32_t rnr)
|
||||
{
|
||||
ARM_MPU_ClrRegionEx(MPU_NS, rnr);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Configure the given MPU region of the given MPU.
|
||||
* \param mpu Pointer to MPU to be used.
|
||||
* \param rnr Region number to be configured.
|
||||
* \param rbar Value for RBAR register.
|
||||
* \param rlar Value for RLAR register.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_SetRegionEx(MPU_Type* mpu, uint32_t rnr, uint32_t rbar, uint32_t rlar)
|
||||
{
|
||||
MPU->RNR = rnr;
|
||||
MPU->RBAR = rbar;
|
||||
MPU->RLAR = rlar;
|
||||
}
|
||||
|
||||
/** Configure the given MPU region.
|
||||
* \param rnr Region number to be configured.
|
||||
* \param rbar Value for RBAR register.
|
||||
* \param rlar Value for RLAR register.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rnr, uint32_t rbar, uint32_t rlar)
|
||||
{
|
||||
ARM_MPU_SetRegionEx(MPU, rnr, rbar, rlar);
|
||||
}
|
||||
|
||||
#ifdef MPU_NS
|
||||
/** Configure the given Non-secure MPU region.
|
||||
* \param rnr Region number to be configured.
|
||||
* \param rbar Value for RBAR register.
|
||||
* \param rlar Value for RLAR register.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_SetRegion_NS(uint32_t rnr, uint32_t rbar, uint32_t rlar)
|
||||
{
|
||||
ARM_MPU_SetRegionEx(MPU_NS, rnr, rbar, rlar);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Memcopy with strictly ordered memory access, e.g. for register targets.
|
||||
* \param dst Destination data is copied to.
|
||||
* \param src Source data is copied from.
|
||||
* \param len Amount of data words to be copied.
|
||||
*/
|
||||
__STATIC_INLINE void orderedCpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len)
|
||||
{
|
||||
uint32_t i;
|
||||
for (i = 0U; i < len; ++i)
|
||||
{
|
||||
dst[i] = src[i];
|
||||
}
|
||||
}
|
||||
|
||||
/** Load the given number of MPU regions from a table to the given MPU.
|
||||
* \param mpu Pointer to the MPU registers to be used.
|
||||
* \param rnr First region number to be configured.
|
||||
* \param table Pointer to the MPU configuration table.
|
||||
* \param cnt Amount of regions to be configured.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_LoadEx(MPU_Type* mpu, uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt)
|
||||
{
|
||||
static const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U;
|
||||
if (cnt == 1U) {
|
||||
mpu->RNR = rnr;
|
||||
orderedCpy(&(mpu->RBAR), &(table->RBAR), rowWordSize);
|
||||
} else {
|
||||
uint32_t rnrBase = rnr & ~(MPU_TYPE_RALIASES-1U);
|
||||
uint32_t rnrOffset = rnr % MPU_TYPE_RALIASES;
|
||||
|
||||
mpu->RNR = rnrBase;
|
||||
if ((rnrOffset + cnt) > MPU_TYPE_RALIASES) {
|
||||
uint32_t c = MPU_TYPE_RALIASES - rnrOffset;
|
||||
orderedCpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), c*rowWordSize);
|
||||
ARM_MPU_LoadEx(mpu, rnr + c, table + c, cnt - c);
|
||||
} else {
|
||||
orderedCpy(&(mpu->RBAR)+(rnrOffset*2U), &(table->RBAR), cnt*rowWordSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Load the given number of MPU regions from a table.
|
||||
* \param rnr First region number to be configured.
|
||||
* \param table Pointer to the MPU configuration table.
|
||||
* \param cnt Amount of regions to be configured.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_Load(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt)
|
||||
{
|
||||
ARM_MPU_LoadEx(MPU, rnr, table, cnt);
|
||||
}
|
||||
|
||||
#ifdef MPU_NS
|
||||
/** Load the given number of MPU regions from a table to the Non-secure MPU.
|
||||
* \param rnr First region number to be configured.
|
||||
* \param table Pointer to the MPU configuration table.
|
||||
* \param cnt Amount of regions to be configured.
|
||||
*/
|
||||
__STATIC_INLINE void ARM_MPU_Load_NS(uint32_t rnr, ARM_MPU_Region_t const* table, uint32_t cnt)
|
||||
{
|
||||
ARM_MPU_LoadEx(MPU_NS, rnr, table, cnt);
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -1,94 +0,0 @@
|
|||
/* Copyright (c) 2009 - 2012 ARM LIMITED
|
||||
|
||||
All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
- Neither the name of ARM nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
*
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Functions
|
||||
*---------------------------------------------------------------------------*/
|
||||
.text
|
||||
.global __v7_all_cache
|
||||
/*
|
||||
* __STATIC_ASM void __v7_all_cache(uint32_t op) {
|
||||
*/
|
||||
__v7_all_cache:
|
||||
.arm
|
||||
|
||||
PUSH {R4-R11}
|
||||
|
||||
MRC p15, 1, R6, c0, c0, 1 /* Read CLIDR */
|
||||
ANDS R3, R6, #0x07000000 /* Extract coherency level */
|
||||
MOV R3, R3, LSR #23 /* Total cache levels << 1 */
|
||||
BEQ Finished /* If 0, no need to clean */
|
||||
|
||||
MOV R10, #0 /* R10 holds current cache level << 1 */
|
||||
Loop1: ADD R2, R10, R10, LSR #1 /* R2 holds cache "Set" position */
|
||||
MOV R1, R6, LSR R2 /* Bottom 3 bits are the Cache-type for this level */
|
||||
AND R1, R1, #7 /* Isolate those lower 3 bits */
|
||||
CMP R1, #2
|
||||
BLT Skip /* No cache or only instruction cache at this level */
|
||||
|
||||
MCR p15, 2, R10, c0, c0, 0 /* Write the Cache Size selection register */
|
||||
ISB /* ISB to sync the change to the CacheSizeID reg */
|
||||
MRC p15, 1, R1, c0, c0, 0 /* Reads current Cache Size ID register */
|
||||
AND R2, R1, #7 /* Extract the line length field */
|
||||
ADD R2, R2, #4 /* Add 4 for the line length offset (log2 16 bytes) */
|
||||
LDR R4, =0x3FF
|
||||
ANDS R4, R4, R1, LSR #3 /* R4 is the max number on the way size (right aligned) */
|
||||
CLZ R5, R4 /* R5 is the bit position of the way size increment */
|
||||
LDR R7, =0x7FFF
|
||||
ANDS R7, R7, R1, LSR #13 /* R7 is the max number of the index size (right aligned) */
|
||||
|
||||
Loop2: MOV R9, R4 /* R9 working copy of the max way size (right aligned) */
|
||||
|
||||
Loop3: ORR R11, R10, R9, LSL R5 /* Factor in the Way number and cache number into R11 */
|
||||
ORR R11, R11, R7, LSL R2 /* Factor in the Set number */
|
||||
CMP R0, #0
|
||||
BNE Dccsw
|
||||
MCR p15, 0, R11, c7, c6, 2 /* DCISW. Invalidate by Set/Way */
|
||||
B cont
|
||||
Dccsw: CMP R0, #1
|
||||
BNE Dccisw
|
||||
MCR p15, 0, R11, c7, c10, 2 /* DCCSW. Clean by Set/Way */
|
||||
B cont
|
||||
Dccisw: MCR p15, 0, R11, c7, c14, 2 /* DCCISW, Clean and Invalidate by Set/Way */
|
||||
cont: SUBS R9, R9, #1 /* Decrement the Way number */
|
||||
BGE Loop3
|
||||
SUBS R7, R7, #1 /* Decrement the Set number */
|
||||
BGE Loop2
|
||||
Skip: ADD R10, R10, #2 /* increment the cache number */
|
||||
CMP R3, R10
|
||||
BGT Loop1
|
||||
|
||||
Finished:
|
||||
DSB
|
||||
POP {R4-R11}
|
||||
BX lr
|
||||
|
||||
|
||||
.END
|
||||
/*----------------------------------------------------------------------------
|
||||
* end of file
|
||||
*---------------------------------------------------------------------------*/
|
|
@ -1,97 +0,0 @@
|
|||
/* Copyright (c) 2009 - 2012 ARM LIMITED
|
||||
|
||||
All rights reserved.
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
- Neither the name of ARM nor the names of its contributors may be used
|
||||
to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
*
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/*----------------------------------------------------------------------------
|
||||
* Functions
|
||||
*---------------------------------------------------------------------------*/
|
||||
SECTION `.text`:CODE:NOROOT(2)
|
||||
arm
|
||||
PUBLIC __v7_all_cache
|
||||
/*
|
||||
* __STATIC_ASM void __v7_all_cache(uint32_t op) {
|
||||
*/
|
||||
|
||||
__v7_all_cache:
|
||||
|
||||
|
||||
PUSH {R4-R11}
|
||||
|
||||
MRC p15, 1, R6, c0, c0, 1 /* Read CLIDR */
|
||||
ANDS R3, R6, #0x07000000 /* Extract coherency level */
|
||||
MOV R3, R3, LSR #23 /* Total cache levels << 1 */
|
||||
BEQ Finished /* If 0, no need to clean */
|
||||
|
||||
MOV R10, #0 /* R10 holds current cache level << 1 */
|
||||
Loop1: ADD R2, R10, R10, LSR #1 /* R2 holds cache "Set" position */
|
||||
MOV R1, R6, LSR R2 /* Bottom 3 bits are the Cache-type for this level */
|
||||
AND R1, R1, #7 /* Isolate those lower 3 bits */
|
||||
CMP R1, #2
|
||||
BLT Skip /* No cache or only instruction cache at this level */
|
||||
|
||||
MCR p15, 2, R10, c0, c0, 0 /* Write the Cache Size selection register */
|
||||
ISB /* ISB to sync the change to the CacheSizeID reg */
|
||||
MRC p15, 1, R1, c0, c0, 0 /* Reads current Cache Size ID register */
|
||||
AND R2, R1, #7 /* Extract the line length field */
|
||||
ADD R2, R2, #4 /* Add 4 for the line length offset (log2 16 bytes) */
|
||||
LDR R4, =0x3FF
|
||||
ANDS R4, R4, R1, LSR #3 /* R4 is the max number on the way size (right aligned) */
|
||||
CLZ R5, R4 /* R5 is the bit position of the way size increment */
|
||||
LDR R7, =0x7FFF
|
||||
ANDS R7, R7, R1, LSR #13 /* R7 is the max number of the index size (right aligned) */
|
||||
|
||||
Loop2: MOV R9, R4 /* R9 working copy of the max way size (right aligned) */
|
||||
|
||||
Loop3: ORR R11, R10, R9, LSL R5 /* Factor in the Way number and cache number into R11 */
|
||||
ORR R11, R11, R7, LSL R2 /* Factor in the Set number */
|
||||
CMP R0, #0
|
||||
BNE Dccsw
|
||||
MCR p15, 0, R11, c7, c6, 2 /* DCISW. Invalidate by Set/Way */
|
||||
B cont
|
||||
Dccsw: CMP R0, #1
|
||||
BNE Dccisw
|
||||
MCR p15, 0, R11, c7, c10, 2 /* DCCSW. Clean by Set/Way */
|
||||
B cont
|
||||
Dccisw: MCR p15, 0, R11, c7, c14, 2 /* DCCISW, Clean and Invalidate by Set/Way */
|
||||
cont: SUBS R9, R9, #1 /* Decrement the Way number */
|
||||
BGE Loop3
|
||||
SUBS R7, R7, #1 /* Decrement the Set number */
|
||||
BGE Loop2
|
||||
Skip: ADD R10, R10, #2 /* increment the cache number */
|
||||
CMP R3, R10
|
||||
BGT Loop1
|
||||
|
||||
Finished:
|
||||
DSB
|
||||
POP {R4-R11}
|
||||
BX lr
|
||||
|
||||
|
||||
END
|
||||
/*----------------------------------------------------------------------------
|
||||
* end of file
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
|
@ -659,47 +659,6 @@ extern "C"
|
|||
return (signBits + 1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* @brief C custom defined intrinisic function for only M0 processors
|
||||
*/
|
||||
#if defined(ARM_MATH_CM0_FAMILY)
|
||||
static __INLINE q31_t __SSAT(
|
||||
q31_t x,
|
||||
uint32_t y)
|
||||
{
|
||||
int32_t posMax, negMin;
|
||||
uint32_t i;
|
||||
|
||||
posMax = 1;
|
||||
for (i = 0; i < (y - 1); i++)
|
||||
{
|
||||
posMax = posMax * 2;
|
||||
}
|
||||
|
||||
if(x > 0)
|
||||
{
|
||||
posMax = (posMax - 1);
|
||||
|
||||
if(x > posMax)
|
||||
{
|
||||
x = posMax;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
negMin = -posMax;
|
||||
|
||||
if(x < negMin)
|
||||
{
|
||||
x = negMin;
|
||||
}
|
||||
}
|
||||
return (x);
|
||||
}
|
||||
#endif /* end of ARM_MATH_CM0_FAMILY */
|
||||
|
||||
|
||||
/*
|
||||
* @brief C custom defined intrinsic function for M3 and M0 processors
|
||||
*/
|
||||
|
|
|
@ -222,15 +222,15 @@ class CThunk
|
|||
uint32_t start_addr = (uint32_t)&m_thunk & 0xFFFFFFE0;
|
||||
uint32_t end_addr = (uint32_t)&m_thunk + sizeof(m_thunk);
|
||||
uint32_t addr;
|
||||
|
||||
|
||||
/* Data cache clean and invalid */
|
||||
for (addr = start_addr; addr < end_addr; addr += 0x20) {
|
||||
__v7_clean_inv_dcache_mva((void *)addr);
|
||||
L1C_CleanInvalidateDCacheMVA((void *)addr);
|
||||
}
|
||||
/* Instruction cache invalid */
|
||||
__v7_inv_icache_all();
|
||||
__ca9u_inv_tlb_all();
|
||||
__v7_inv_btac();
|
||||
L1C_InvalidateICacheAll();
|
||||
MMU_InvalidateTLB();
|
||||
L1C_InvalidateBTAC();
|
||||
}
|
||||
#endif
|
||||
#if defined(__CORTEX_M7)
|
||||
|
|
|
@ -39,10 +39,10 @@ bool core_util_is_isr_active(void)
|
|||
{
|
||||
#if defined(__CORTEX_A9)
|
||||
switch(__get_CPSR() & 0x1FU) {
|
||||
case MODE_USR:
|
||||
case MODE_SYS:
|
||||
case CPSR_M_USR:
|
||||
case CPSR_M_SYS:
|
||||
return false;
|
||||
case MODE_SVC:
|
||||
case CPSR_M_SVC:
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include "platform/mbed_sleep.h"
|
||||
#include "TimerEvent.h"
|
||||
#include "lp_ticker_api.h"
|
||||
#include "core_cm.h"
|
||||
#include "rtx_core_cm.h"
|
||||
#include "mbed_critical.h"
|
||||
#include "mbed_assert.h"
|
||||
#include <new>
|
||||
|
@ -58,7 +58,7 @@ public:
|
|||
// Ensure SysTick has the correct priority as it is still used
|
||||
// to trigger software interrupts on each tick. The period does
|
||||
// not matter since it will never start counting.
|
||||
SysTick_Setup(16);
|
||||
OS_Tick_Setup(osRtxConfig.tick_freq, OS_TICK_HANDLER);
|
||||
#endif
|
||||
};
|
||||
|
||||
|
@ -138,41 +138,57 @@ protected:
|
|||
static RtosTimer *os_timer;
|
||||
static uint64_t os_timer_data[sizeof(RtosTimer) / 8];
|
||||
|
||||
/// Setup System Timer.
|
||||
int32_t osRtxSysTimerSetup (void)
|
||||
/// Enable System Timer.
|
||||
int32_t OS_Tick_Enable (void)
|
||||
{
|
||||
// Do not use SingletonPtr since this relies on the RTOS
|
||||
if (NULL == os_timer) {
|
||||
os_timer = new (os_timer_data) RtosTimer();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// Enable System Timer.
|
||||
void osRtxSysTimerEnable (void)
|
||||
{
|
||||
// set to fire interrupt on next tick
|
||||
os_timer->schedule_tick();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Disable System Timer.
|
||||
void osRtxSysTimerDisable (void)
|
||||
int32_t OS_Tick_Disable (void)
|
||||
{
|
||||
os_timer->cancel_tick();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Acknowledge System Timer IRQ.
|
||||
void osRtxSysTimerAckIRQ (void)
|
||||
int32_t OS_Tick_AcknowledgeIRQ (void)
|
||||
{
|
||||
os_timer->schedule_tick();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// Get System Timer count.
|
||||
uint32_t osRtxSysTimerGetCount (void)
|
||||
uint32_t OS_Tick_GetCount (void)
|
||||
{
|
||||
return os_timer->get_time() & 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
// Get OS Tick IRQ number.
|
||||
int32_t OS_Tick_GetIRQn (void) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Get OS Tick overflow status.
|
||||
uint32_t OS_Tick_GetOverflow (void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get OS Tick interval.
|
||||
uint32_t OS_Tick_GetInterval (void) {
|
||||
return 1000;
|
||||
}
|
||||
|
||||
static void default_idle_hook(void)
|
||||
{
|
||||
uint32_t elapsed_ticks = 0;
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
*
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* $Date: 10. January 2017
|
||||
* $Revision: V2.1.0
|
||||
* $Date: 9. June 2017
|
||||
* $Revision: V2.1.1
|
||||
*
|
||||
* Project: CMSIS-RTOS API
|
||||
* Title: cmsis_os.h RTX header file
|
||||
|
@ -118,6 +118,11 @@
|
|||
* - added: osKernelRestoreLock
|
||||
* Updated Thread and Event Flags:
|
||||
* - changed flags parameter and return type from int32_t to uint32_t
|
||||
* Version 2.1.1
|
||||
* Additional functions allowed to be called from Interrupt Service Routines:
|
||||
* - osKernelGetTickCount, osKernelGetTickFreq
|
||||
* Changed Kernel Tick type to uint32_t:
|
||||
* - updated: osKernelGetTickCount, osDelayUntil
|
||||
*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef CMSIS_OS_H_
|
||||
|
@ -430,7 +435,6 @@ uint32_t osKernelSysTick (void);
|
|||
/// Create a Thread Definition with function, priority, and stack requirements.
|
||||
/// \param name name of the thread function.
|
||||
/// \param priority initial priority of the thread function.
|
||||
/// \param instances number of possible thread instances.
|
||||
/// \param stacksz stack size (in bytes) requirements for the thread function.
|
||||
#if defined (osObjectsExternal) // object is external
|
||||
#define osThreadDef(name, priority, stacksz) \
|
||||
|
@ -439,7 +443,7 @@ extern const osThreadDef_t os_thread_def_##name
|
|||
#if (osCMSIS < 0x20000U)
|
||||
#define osThreadDef(name, priority, stacksz) \
|
||||
const osThreadDef_t os_thread_def_##name = \
|
||||
{ (name), (priority), (1), (stacksz) }
|
||||
{ (name), (priority), 1, (stacksz) }
|
||||
#else
|
||||
#define osThreadDef(name, priority, stacksz) \
|
||||
uint64_t os_thread_stack##name[(stacksz)?(((stacksz+7)/8)):1] __attribute__((section(".bss.os.thread.stack"))); \
|
||||
|
@ -447,7 +451,7 @@ static osRtxThread_t os_thread_cb_##name __attribute__((section(".bss.os.thread.
|
|||
const osThreadDef_t os_thread_def_##name = \
|
||||
{ (name), \
|
||||
{ NULL, osThreadDetached, \
|
||||
(&os_thread_cb_##name),\
|
||||
&os_thread_cb_##name,\
|
||||
osRtxThreadCbSize, \
|
||||
(stacksz) ? (&os_thread_stack##name) : NULL, \
|
||||
8*((stacksz+7)/8), \
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
/** \addtogroup rtos */
|
||||
/** @{*/
|
||||
/*
|
||||
* Copyright (c) 2013-2017 ARM Limited. All rights reserved.
|
||||
*
|
||||
|
@ -19,12 +17,17 @@
|
|||
*
|
||||
* ----------------------------------------------------------------------
|
||||
*
|
||||
* $Date: 10. January 2017
|
||||
* $Revision: V2.1.0
|
||||
* $Date: 9. June 2017
|
||||
* $Revision: V2.1.1
|
||||
*
|
||||
* Project: CMSIS-RTOS2 API
|
||||
* Title: cmsis_os2.h header file
|
||||
*
|
||||
* Version 2.1.1
|
||||
* Additional functions allowed to be called from Interrupt Service Routines:
|
||||
* - osKernelGetTickCount, osKernelGetTickFreq
|
||||
* Changed Kernel Tick type to uint32_t:
|
||||
* - updated: osKernelGetTickCount, osDelayUntil
|
||||
* Version 2.1.0
|
||||
* Support for critical and uncritical sections (nesting safe):
|
||||
* - updated: osKernelLock, osKernelUnlock
|
||||
|
@ -151,7 +154,7 @@ typedef enum {
|
|||
/// Entry point of a thread.
|
||||
typedef void (*osThreadFunc_t) (void *argument);
|
||||
|
||||
/// Entry point of a timer call back function.
|
||||
/// Timer callback function.
|
||||
typedef void (*osTimerFunc_t) (void *argument);
|
||||
|
||||
/// Timer type.
|
||||
|
@ -160,15 +163,15 @@ typedef enum {
|
|||
osTimerPeriodic = 1 ///< Repeating timer.
|
||||
} osTimerType_t;
|
||||
|
||||
/// Timeout value.
|
||||
// Timeout value.
|
||||
#define osWaitForever 0xFFFFFFFFU ///< Wait forever timeout value.
|
||||
|
||||
/// Flags options (\ref osThreadFlagsWait and \ref osEventFlagsWait).
|
||||
// Flags options (\ref osThreadFlagsWait and \ref osEventFlagsWait).
|
||||
#define osFlagsWaitAny 0x00000000U ///< Wait for any flag (default).
|
||||
#define osFlagsWaitAll 0x00000001U ///< Wait for all flags.
|
||||
#define osFlagsNoClear 0x00000002U ///< Do not clear flags which have been specified to wait for.
|
||||
|
||||
/// Flags errors (returned by osThreadFlagsXxxx and osEventFlagsXxxx).
|
||||
// Flags errors (returned by osThreadFlagsXxxx and osEventFlagsXxxx).
|
||||
#define osFlagsError 0x80000000U ///< Error indicator.
|
||||
#define osFlagsErrorUnknown 0xFFFFFFFFU ///< osError (-1).
|
||||
#define osFlagsErrorTimeout 0xFFFFFFFEU ///< osErrorTimeout (-2).
|
||||
|
@ -176,11 +179,11 @@ typedef enum {
|
|||
#define osFlagsErrorParameter 0xFFFFFFFCU ///< osErrorParameter (-4).
|
||||
#define osFlagsErrorISR 0xFFFFFFFAU ///< osErrorISR (-6).
|
||||
|
||||
/// Thread attributes (attr_bits in \ref osThreadAttr_t).
|
||||
#define osThreadDetached 0x00000000U ///< Thread created in detached state (default)
|
||||
#define osThreadJoinable 0x00000001U ///< Thread created in joinable state
|
||||
// Thread attributes (attr_bits in \ref osThreadAttr_t).
|
||||
#define osThreadDetached 0x00000000U ///< Thread created in detached mode (default)
|
||||
#define osThreadJoinable 0x00000001U ///< Thread created in joinable mode
|
||||
|
||||
/// Mutex attributes (attr_bits in \ref osMutexAttr_t).
|
||||
// Mutex attributes (attr_bits in \ref osMutexAttr_t).
|
||||
#define osMutexRecursive 0x00000001U ///< Recursive mutex.
|
||||
#define osMutexPrioInherit 0x00000002U ///< Priority inherit protocol.
|
||||
#define osMutexRobust 0x00000008U ///< Robust mutex.
|
||||
|
@ -337,10 +340,10 @@ void osKernelResume (uint32_t sleep_ticks);
|
|||
|
||||
/// Get the RTOS kernel tick count.
|
||||
/// \return RTOS kernel current tick count.
|
||||
uint64_t osKernelGetTickCount (void);
|
||||
uint32_t osKernelGetTickCount (void);
|
||||
|
||||
/// Get the RTOS kernel tick frequency.
|
||||
/// \return frequency of the kernel tick.
|
||||
/// \return frequency of the kernel tick in hertz, i.e. kernel ticks per second.
|
||||
uint32_t osKernelGetTickFreq (void);
|
||||
|
||||
/// Get the RTOS kernel system timer count.
|
||||
|
@ -348,7 +351,7 @@ uint32_t osKernelGetTickFreq (void);
|
|||
uint32_t osKernelGetSysTimerCount (void);
|
||||
|
||||
/// Get the RTOS kernel system timer frequency.
|
||||
/// \return frequency of the system timer.
|
||||
/// \return frequency of the system timer in hertz, i.e. timer ticks per second.
|
||||
uint32_t osKernelGetSysTimerFreq (void);
|
||||
|
||||
|
||||
|
@ -475,15 +478,15 @@ osStatus_t osDelay (uint32_t ticks);
|
|||
/// Wait until specified time.
|
||||
/// \param[in] ticks absolute time in ticks
|
||||
/// \return status code that indicates the execution status of the function.
|
||||
osStatus_t osDelayUntil (uint64_t ticks);
|
||||
osStatus_t osDelayUntil (uint32_t ticks);
|
||||
|
||||
|
||||
// ==== Timer Management Functions ====
|
||||
|
||||
/// Create and Initialize a timer.
|
||||
/// \param[in] func start address of a timer call back function.
|
||||
/// \param[in] type osTimerOnce for one-shot or osTimerPeriodic for periodic behavior.
|
||||
/// \param[in] argument argument to the timer call back function.
|
||||
/// \param[in] func function pointer to callback function.
|
||||
/// \param[in] type \ref osTimerOnce for one-shot or \ref osTimerPeriodic for periodic behavior.
|
||||
/// \param[in] argument argument to the timer callback function.
|
||||
/// \param[in] attr timer attributes; NULL: default values.
|
||||
/// \return timer ID for reference by other functions or NULL in case of error.
|
||||
osTimerId_t osTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr);
|
||||
|
@ -612,7 +615,7 @@ const char *osSemaphoreGetName (osSemaphoreId_t semaphore_id);
|
|||
/// \return status code that indicates the execution status of the function.
|
||||
osStatus_t osSemaphoreAcquire (osSemaphoreId_t semaphore_id, uint32_t timeout);
|
||||
|
||||
/// Release a Semaphore token that was acquired by \ref osSemaphoreAcquire.
|
||||
/// Release a Semaphore token up to the initial maximum count.
|
||||
/// \param[in] semaphore_id semaphore ID obtained by \ref osSemaphoreNew.
|
||||
/// \return status code that indicates the execution status of the function.
|
||||
osStatus_t osSemaphoreRelease (osSemaphoreId_t semaphore_id);
|
||||
|
@ -746,5 +749,3 @@ osStatus_t osMessageQueueDelete (osMessageQueueId_t mq_id);
|
|||
#endif
|
||||
|
||||
#endif // CMSIS_OS2_H_
|
||||
|
||||
/** @}*/
|
|
@ -0,0 +1,74 @@
|
|||
/**************************************************************************//**
|
||||
* @file os_tick.h
|
||||
* @brief CMSIS OS Tick header file
|
||||
* @version V1.0.0
|
||||
* @date 05. June 2017
|
||||
******************************************************************************/
|
||||
/*
|
||||
* Copyright (c) 2017-2017 ARM Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef OS_TICK_H
|
||||
#define OS_TICK_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/// IRQ Handler.
|
||||
#ifndef IRQHANDLER_T
|
||||
#define IRQHANDLER_T
|
||||
typedef void (*IRQHandler_t) (void);
|
||||
#endif
|
||||
|
||||
/// Setup OS Tick.
|
||||
/// \param[in] freq tick frequency in Hz
|
||||
/// \param[in] handler tick IRQ handler
|
||||
/// \return 0 on success, -1 on error.
|
||||
int32_t OS_Tick_Setup (uint32_t freq, IRQHandler_t handler);
|
||||
|
||||
/// Enable OS Tick.
|
||||
/// \return 0 on success, -1 on error.
|
||||
int32_t OS_Tick_Enable (void);
|
||||
|
||||
/// Disable OS Tick.
|
||||
/// \return 0 on success, -1 on error.
|
||||
int32_t OS_Tick_Disable (void);
|
||||
|
||||
/// Acknowledge OS Tick IRQ.
|
||||
/// \return 0 on success, -1 on error.
|
||||
int32_t OS_Tick_AcknowledgeIRQ (void);
|
||||
|
||||
/// Get OS Tick IRQ number.
|
||||
/// \return OS Tick IRQ number.
|
||||
int32_t OS_Tick_GetIRQn (void);
|
||||
|
||||
/// Get OS Tick clock.
|
||||
/// \return OS Tick clock in Hz.
|
||||
uint32_t OS_Tick_GetClock (void);
|
||||
|
||||
/// Get OS Tick interval.
|
||||
/// \return OS Tick interval.
|
||||
uint32_t OS_Tick_GetInterval (void);
|
||||
|
||||
/// Get OS Tick count value.
|
||||
/// \return OS Tick count value.
|
||||
uint32_t OS_Tick_GetCount (void);
|
||||
|
||||
/// Get OS Tick overflow status.
|
||||
/// \return OS Tick overflow status (1 - overflow, 0 - no overflow).
|
||||
uint32_t OS_Tick_GetOverflow (void);
|
||||
|
||||
#endif /* OS_TICK_H */
|
|
@ -24,7 +24,7 @@
|
|||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#include "cmsis_compiler.h"
|
||||
#include "rtx_os.h"
|
||||
|
|
@ -1,5 +1,3 @@
|
|||
/** \addtogroup rtos */
|
||||
/** @{*/
|
||||
/*
|
||||
* Copyright (c) 2013-2017 ARM Limited. All rights reserved.
|
||||
*
|
||||
|
@ -381,4 +379,3 @@
|
|||
//------------- <<< end of configuration section >>> ---------------------------
|
||||
|
||||
#endif // RTX_CONFIG_H_
|
||||
/** @}*/
|
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2017 ARM Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* Project: CMSIS-RTOS RTX
|
||||
* Title: Exception handlers (C functions)
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#include <cmsis.h>
|
||||
|
||||
//Fault Status Register (IFSR/DFSR) definitions
|
||||
#define FSR_ALIGNMENT_FAULT 0x01 //DFSR only. Fault on first lookup
|
||||
#define FSR_INSTRUCTION_CACHE_MAINTENANCE 0x04 //DFSR only - async/external
|
||||
#define FSR_SYNC_EXT_TTB_WALK_FIRST 0x0c //sync/external
|
||||
#define FSR_SYNC_EXT_TTB_WALK_SECOND 0x0e //sync/external
|
||||
#define FSR_SYNC_PARITY_TTB_WALK_FIRST 0x1c //sync/external
|
||||
#define FSR_SYNC_PARITY_TTB_WALK_SECOND 0x1e //sync/external
|
||||
#define FSR_TRANSLATION_FAULT_FIRST 0x05 //MMU Fault - internal
|
||||
#define FSR_TRANSLATION_FAULT_SECOND 0x07 //MMU Fault - internal
|
||||
#define FSR_ACCESS_FLAG_FAULT_FIRST 0x03 //MMU Fault - internal
|
||||
#define FSR_ACCESS_FLAG_FAULT_SECOND 0x06 //MMU Fault - internal
|
||||
#define FSR_DOMAIN_FAULT_FIRST 0x09 //MMU Fault - internal
|
||||
#define FSR_DOMAIN_FAULT_SECOND 0x0b //MMU Fault - internal
|
||||
#define FSR_PERMISSION_FAULT_FIRST 0x0f //MMU Fault - internal
|
||||
#define FSR_PERMISSION_FAULT_SECOND 0x0d //MMU Fault - internal
|
||||
#define FSR_DEBUG_EVENT 0x02 //internal
|
||||
#define FSR_SYNC_EXT_ABORT 0x08 //sync/external
|
||||
#define FSR_TLB_CONFLICT_ABORT 0x10 //sync/external
|
||||
#define FSR_LOCKDOWN 0x14 //internal
|
||||
#define FSR_COPROCESSOR_ABORT 0x1a //internal
|
||||
#define FSR_SYNC_PARITY_ERROR 0x19 //sync/external
|
||||
#define FSR_ASYNC_EXTERNAL_ABORT 0x16 //DFSR only - async/external
|
||||
#define FSR_ASYNC_PARITY_ERROR 0x18 //DFSR only - async/external
|
||||
|
||||
void CDAbtHandler(uint32_t DFSR, uint32_t DFAR, uint32_t LR) {
|
||||
uint32_t FS = (DFSR & (1 << 10)) >> 6 | (DFSR & 0x0f); //Store Fault Status
|
||||
|
||||
switch(FS) {
|
||||
//Synchronous parity errors - retry
|
||||
case FSR_SYNC_PARITY_ERROR:
|
||||
case FSR_SYNC_PARITY_TTB_WALK_FIRST:
|
||||
case FSR_SYNC_PARITY_TTB_WALK_SECOND:
|
||||
return;
|
||||
|
||||
//Your code here. Value in DFAR is invalid for some fault statuses.
|
||||
case FSR_ALIGNMENT_FAULT:
|
||||
case FSR_INSTRUCTION_CACHE_MAINTENANCE:
|
||||
case FSR_SYNC_EXT_TTB_WALK_FIRST:
|
||||
case FSR_SYNC_EXT_TTB_WALK_SECOND:
|
||||
case FSR_TRANSLATION_FAULT_FIRST:
|
||||
case FSR_TRANSLATION_FAULT_SECOND:
|
||||
case FSR_ACCESS_FLAG_FAULT_FIRST:
|
||||
case FSR_ACCESS_FLAG_FAULT_SECOND:
|
||||
case FSR_DOMAIN_FAULT_FIRST:
|
||||
case FSR_DOMAIN_FAULT_SECOND:
|
||||
case FSR_PERMISSION_FAULT_FIRST:
|
||||
case FSR_PERMISSION_FAULT_SECOND:
|
||||
case FSR_DEBUG_EVENT:
|
||||
case FSR_SYNC_EXT_ABORT:
|
||||
case FSR_TLB_CONFLICT_ABORT:
|
||||
case FSR_LOCKDOWN:
|
||||
case FSR_COPROCESSOR_ABORT:
|
||||
case FSR_ASYNC_EXTERNAL_ABORT: //DFAR invalid
|
||||
case FSR_ASYNC_PARITY_ERROR: //DFAR invalid
|
||||
default:
|
||||
while(1);
|
||||
}
|
||||
}
|
||||
|
||||
void CPAbtHandler(uint32_t IFSR, uint32_t IFAR, uint32_t LR) {
|
||||
uint32_t FS = (IFSR & (1 << 10)) >> 6 | (IFSR & 0x0f); //Store Fault Status
|
||||
|
||||
switch(FS) {
|
||||
//Synchronous parity errors - retry
|
||||
case FSR_SYNC_PARITY_ERROR:
|
||||
case FSR_SYNC_PARITY_TTB_WALK_FIRST:
|
||||
case FSR_SYNC_PARITY_TTB_WALK_SECOND:
|
||||
return;
|
||||
|
||||
//Your code here. Value in IFAR is invalid for some fault statuses.
|
||||
case FSR_SYNC_EXT_TTB_WALK_FIRST:
|
||||
case FSR_SYNC_EXT_TTB_WALK_SECOND:
|
||||
case FSR_TRANSLATION_FAULT_FIRST:
|
||||
case FSR_TRANSLATION_FAULT_SECOND:
|
||||
case FSR_ACCESS_FLAG_FAULT_FIRST:
|
||||
case FSR_ACCESS_FLAG_FAULT_SECOND:
|
||||
case FSR_DOMAIN_FAULT_FIRST:
|
||||
case FSR_DOMAIN_FAULT_SECOND:
|
||||
case FSR_PERMISSION_FAULT_FIRST:
|
||||
case FSR_PERMISSION_FAULT_SECOND:
|
||||
case FSR_DEBUG_EVENT: //IFAR invalid
|
||||
case FSR_SYNC_EXT_ABORT:
|
||||
case FSR_TLB_CONFLICT_ABORT:
|
||||
case FSR_LOCKDOWN:
|
||||
case FSR_COPROCESSOR_ABORT:
|
||||
default:
|
||||
while(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//returns amount to decrement lr by
|
||||
//this will be 0 when we have emulated the instruction and want to execute the next instruction
|
||||
//this will be 2 when we have performed some maintenance and want to retry the instruction in Thumb (state == 2)
|
||||
//this will be 4 when we have performed some maintenance and want to retry the instruction in ARM (state == 4)
|
||||
uint32_t CUndefHandler(uint32_t opcode, uint32_t state, uint32_t LR) {
|
||||
const int THUMB = 2;
|
||||
const int ARM = 4;
|
||||
//Lazy VFP/NEON initialisation and switching
|
||||
|
||||
// (ARM ARM section A7.5) VFP data processing instruction?
|
||||
// (ARM ARM section A7.6) VFP/NEON register load/store instruction?
|
||||
// (ARM ARM section A7.8) VFP/NEON register data transfer instruction?
|
||||
// (ARM ARM section A7.9) VFP/NEON 64-bit register data transfer instruction?
|
||||
if ((state == ARM && ((opcode & 0x0C000000) >> 26 == 0x03)) ||
|
||||
(state == THUMB && ((opcode & 0xEC000000) >> 26 == 0x3B))) {
|
||||
if (((opcode & 0x00000E00) >> 9) == 5) {
|
||||
__FPU_Enable();
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
// (ARM ARM section A7.4) NEON data processing instruction?
|
||||
if ((state == ARM && ((opcode & 0xFE000000) >> 24 == 0xF2)) ||
|
||||
(state == THUMB && ((opcode & 0xEF000000) >> 24 == 0xEF)) ||
|
||||
// (ARM ARM section A7.7) NEON load/store instruction?
|
||||
(state == ARM && ((opcode >> 24) == 0xF4)) ||
|
||||
(state == THUMB && ((opcode >> 24) == 0xF9))) {
|
||||
__FPU_Enable();
|
||||
return state;
|
||||
}
|
||||
|
||||
//Add code here for other Undef cases
|
||||
while(1);
|
||||
}
|
|
@ -1,5 +1,3 @@
|
|||
/** \addtogroup rtos */
|
||||
/** @{*/
|
||||
/*
|
||||
* Copyright (c) 2013-2017 ARM Limited. All rights reserved.
|
||||
*
|
||||
|
@ -310,7 +308,7 @@ extern void EvrRtxKernelResumed (void);
|
|||
\param[in] count RTOS kernel current tick count.
|
||||
*/
|
||||
#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_GET_TICK_COUNT_DISABLE))
|
||||
extern void EvrRtxKernelGetTickCount (uint64_t count);
|
||||
extern void EvrRtxKernelGetTickCount (uint32_t count);
|
||||
#else
|
||||
#define EvrRtxKernelGetTickCount(count)
|
||||
#endif
|
||||
|
@ -762,7 +760,7 @@ extern void EvrRtxThreadDelay (uint32_t ticks);
|
|||
\param[in] ticks absolute time in ticks
|
||||
*/
|
||||
#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_DELAY_UNTIL_DISABLE))
|
||||
extern void EvrRtxThreadDelayUntil (uint64_t ticks);
|
||||
extern void EvrRtxThreadDelayUntil (uint32_t ticks);
|
||||
#else
|
||||
#define EvrRtxThreadDelayUntil(ticks)
|
||||
#endif
|
||||
|
@ -1844,4 +1842,3 @@ extern void EvrRtxMessageQueueDestroyed (osMessageQueueId_t mq_id);
|
|||
|
||||
|
||||
#endif // RTX_EVR_H_
|
||||
/** @}*/
|
|
@ -37,9 +37,9 @@ extern "C"
|
|||
|
||||
|
||||
/// Kernel Information
|
||||
#define osRtxVersionAPI 20010000 ///< API version (2.1.0)
|
||||
#define osRtxVersionKernel 50010001 ///< Kernel version (5.1.1)
|
||||
#define osRtxKernelId "RTX V5.1.1" ///< Kernel identification string
|
||||
#define osRtxVersionAPI 20010001 ///< API version (2.1.1)
|
||||
#define osRtxVersionKernel 50020002 ///< Kernel version (5.2.2)
|
||||
#define osRtxKernelId "RTX V5.2.2" ///< Kernel identification string
|
||||
|
||||
|
||||
// ==== Common definitions ====
|
||||
|
@ -283,10 +283,9 @@ typedef struct {
|
|||
struct { ///< Kernel Info
|
||||
uint8_t state; ///< State
|
||||
volatile uint8_t blocked; ///< Blocked
|
||||
uint8_t pendISR; ///< Pending ISR (SV and SysTick)
|
||||
uint8_t pendSV; ///< Pending SV
|
||||
uint32_t sys_freq; ///< System Frequency
|
||||
uint64_t tick; ///< Tick counter
|
||||
uint8_t reserved;
|
||||
uint32_t tick; ///< Tick counter
|
||||
} kernel;
|
||||
int32_t tick_irqn; ///< Tick Timer IRQ Number
|
||||
struct { ///< Thread Info
|
||||
|
@ -341,7 +340,6 @@ typedef struct {
|
|||
osRtxMpInfo_t *memory_pool; ///< Memory Pool Control Blocks
|
||||
osRtxMpInfo_t *message_queue; ///< Message Queue Control Blocks
|
||||
} mpi;
|
||||
uint32_t padding;
|
||||
} osRtxInfo_t;
|
||||
|
||||
extern osRtxInfo_t osRtxInfo; ///< OS Runtime Information
|
||||
|
@ -398,30 +396,6 @@ extern void PendSV_Handler (void);
|
|||
extern void SysTick_Handler (void);
|
||||
|
||||
|
||||
/// OS System Timer functions (default implementation uses SysTick)
|
||||
|
||||
/// Setup System Timer.
|
||||
/// \return system timer IRQ number.
|
||||
extern int32_t osRtxSysTimerSetup (void);
|
||||
|
||||
/// Enable System Timer.
|
||||
extern void osRtxSysTimerEnable (void);
|
||||
|
||||
/// Disable System Timer.
|
||||
extern void osRtxSysTimerDisable (void);
|
||||
|
||||
/// Acknowledge System Timer IRQ.
|
||||
extern void osRtxSysTimerAckIRQ (void);
|
||||
|
||||
/// Get System Timer count.
|
||||
/// \return system timer count.
|
||||
extern uint32_t osRtxSysTimerGetCount (void);
|
||||
|
||||
/// Get System Timer frequency.
|
||||
/// \return system timer frequency.
|
||||
extern uint32_t osRtxSysTimerGetFreq (void);
|
||||
|
||||
|
||||
// ==== OS External Configuration ====
|
||||
|
||||
/// OS Configuration flags
|
|
@ -0,0 +1,447 @@
|
|||
;/*
|
||||
; * Copyright (c) 2013-2017 ARM Limited. All rights reserved.
|
||||
; *
|
||||
; * SPDX-License-Identifier: Apache-2.0
|
||||
; *
|
||||
; * Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
; * not use this file except in compliance with the License.
|
||||
; * You may obtain a copy of the License at
|
||||
; *
|
||||
; * www.apache.org/licenses/LICENSE-2.0
|
||||
; *
|
||||
; * Unless required by applicable law or agreed to in writing, software
|
||||
; * distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
; * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
; * See the License for the specific language governing permissions and
|
||||
; * limitations under the License.
|
||||
; *
|
||||
; * -----------------------------------------------------------------------------
|
||||
; *
|
||||
; * Project: CMSIS-RTOS RTX
|
||||
; * Title: Cortex-A Exception handlers
|
||||
; *
|
||||
; * -----------------------------------------------------------------------------
|
||||
; */
|
||||
|
||||
MODE_FIQ EQU 0x11
|
||||
MODE_IRQ EQU 0x12
|
||||
MODE_SVC EQU 0x13
|
||||
MODE_ABT EQU 0x17
|
||||
MODE_UND EQU 0x1B
|
||||
|
||||
CPSR_BIT_T EQU 0x20
|
||||
|
||||
K_STATE_RUNNING EQU 2 ; osKernelState_t::osKernelRunning
|
||||
I_K_STATE_OFS EQU 8 ; osRtxInfo.kernel.state offset
|
||||
I_TICK_IRQN_OFS EQU 16 ; osRtxInfo.tick_irqn offset
|
||||
I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset
|
||||
TCB_SP_FRAME EQU 34 ; osRtxThread_t.stack_frame offset
|
||||
TCB_SP_OFS EQU 56 ; osRtxThread_t.sp offset
|
||||
|
||||
|
||||
PRESERVE8
|
||||
ARM
|
||||
|
||||
|
||||
AREA |.constdata|, DATA, READONLY
|
||||
EXPORT irqRtxLib
|
||||
irqRtxLib DCB 0 ; Non weak library reference
|
||||
|
||||
|
||||
AREA |.data|, DATA, READWRITE
|
||||
EXPORT IRQ_PendSV
|
||||
IRQ_NestLevel DCD 0 ; IRQ nesting level counter
|
||||
IRQ_PendSV DCB 0 ; Pending SVC flag
|
||||
SVC_Active DCB 0 ; SVC handler execution active flag
|
||||
|
||||
|
||||
AREA |.text|, CODE, READONLY
|
||||
|
||||
|
||||
Undef_Handler\
|
||||
PROC
|
||||
EXPORT Undef_Handler
|
||||
IMPORT CUndefHandler
|
||||
|
||||
SRSFD SP!, #MODE_UND
|
||||
PUSH {R0-R4, R12} ; Save APCS corruptible registers to UND mode stack
|
||||
|
||||
MRS R0, SPSR
|
||||
TST R0, #CPSR_BIT_T ; Check mode
|
||||
MOVEQ R1, #4 ; R1 = 4 ARM mode
|
||||
MOVNE R1, #2 ; R1 = 2 Thumb mode
|
||||
SUB R0, LR, R1
|
||||
LDREQ R0, [R0] ; ARM mode - R0 points to offending instruction
|
||||
BEQ Undef_Cont
|
||||
|
||||
; Thumb instruction
|
||||
; Determine if it is a 32-bit Thumb instruction
|
||||
LDRH R0, [R0]
|
||||
MOV R2, #0x1C
|
||||
CMP R2, R0, LSR #11
|
||||
BHS Undef_Cont ; 16-bit Thumb instruction
|
||||
|
||||
; 32-bit Thumb instruction. Unaligned - reconstruct the offending instruction
|
||||
LDRH R2, [LR]
|
||||
ORR R0, R2, R0, LSL #16
|
||||
Undef_Cont
|
||||
MOV R2, LR ; Set LR to third argument
|
||||
|
||||
AND R12, SP, #4 ; Ensure stack is 8-byte aligned
|
||||
SUB SP, SP, R12 ; Adjust stack
|
||||
PUSH {R12, LR} ; Store stack adjustment and dummy LR
|
||||
|
||||
; R0 =Offending instruction, R1 =2(Thumb) or =4(ARM)
|
||||
BL CUndefHandler
|
||||
|
||||
POP {R12, LR} ; Get stack adjustment & discard dummy LR
|
||||
ADD SP, SP, R12 ; Unadjust stack
|
||||
|
||||
LDR LR, [SP, #24] ; Restore stacked LR and possibly adjust for retry
|
||||
SUB LR, LR, R0
|
||||
LDR R0, [SP, #28] ; Restore stacked SPSR
|
||||
MSR SPSR_CXSF, R0
|
||||
POP {R0-R4, R12} ; Restore stacked APCS registers
|
||||
ADD SP, SP, #8 ; Adjust SP for already-restored banked registers
|
||||
MOVS PC, LR
|
||||
|
||||
ENDP
|
||||
|
||||
|
||||
PAbt_Handler\
|
||||
PROC
|
||||
EXPORT PAbt_Handler
|
||||
IMPORT CPAbtHandler
|
||||
|
||||
SUB LR, LR, #4 ; Pre-adjust LR
|
||||
SRSFD SP!, #MODE_ABT ; Save LR and SPRS to ABT mode stack
|
||||
PUSH {R0-R4, R12} ; Save APCS corruptible registers to ABT mode stack
|
||||
MRC p15, 0, R0, c5, c0, 1 ; IFSR
|
||||
MRC p15, 0, R1, c6, c0, 2 ; IFAR
|
||||
|
||||
MOV R2, LR ; Set LR to third argument
|
||||
|
||||
AND R12, SP, #4 ; Ensure stack is 8-byte aligned
|
||||
SUB SP, SP, R12 ; Adjust stack
|
||||
PUSH {R12, LR} ; Store stack adjustment and dummy LR
|
||||
|
||||
BL CPAbtHandler
|
||||
|
||||
POP {R12, LR} ; Get stack adjustment & discard dummy LR
|
||||
ADD SP, SP, R12 ; Unadjust stack
|
||||
|
||||
POP {R0-R4, R12} ; Restore stack APCS registers
|
||||
RFEFD SP! ; Return from exception
|
||||
|
||||
ENDP
|
||||
|
||||
|
||||
DAbt_Handler\
|
||||
PROC
|
||||
EXPORT DAbt_Handler
|
||||
IMPORT CDAbtHandler
|
||||
|
||||
SUB LR, LR, #8 ; Pre-adjust LR
|
||||
SRSFD SP!, #MODE_ABT ; Save LR and SPRS to ABT mode stack
|
||||
PUSH {R0-R4, R12} ; Save APCS corruptible registers to ABT mode stack
|
||||
CLREX ; State of exclusive monitors unknown after taken data abort
|
||||
MRC p15, 0, R0, c5, c0, 0 ; DFSR
|
||||
MRC p15, 0, R1, c6, c0, 0 ; DFAR
|
||||
|
||||
MOV R2, LR ; Set LR to third argument
|
||||
|
||||
AND R12, SP, #4 ; Ensure stack is 8-byte aligned
|
||||
SUB SP, SP, R12 ; Adjust stack
|
||||
PUSH {R12, LR} ; Store stack adjustment and dummy LR
|
||||
|
||||
BL CDAbtHandler
|
||||
|
||||
POP {R12, LR} ; Get stack adjustment & discard dummy LR
|
||||
ADD SP, SP, R12 ; Unadjust stack
|
||||
|
||||
POP {R0-R4, R12} ; Restore stacked APCS registers
|
||||
RFEFD SP! ; Return from exception
|
||||
|
||||
ENDP
|
||||
|
||||
|
||||
IRQ_Handler\
|
||||
PROC
|
||||
EXPORT IRQ_Handler
|
||||
IMPORT osRtxInfo
|
||||
IMPORT IRQ_GetActiveIRQ
|
||||
IMPORT IRQ_GetHandler
|
||||
IMPORT IRQ_EndOfInterrupt
|
||||
|
||||
SUB LR, LR, #4 ; Pre-adjust LR
|
||||
SRSFD SP!, #MODE_SVC ; Save LR_irq and SPRS_irq on to the SVC stack
|
||||
CPS #MODE_SVC ; Change to SVC mode
|
||||
PUSH {R0-R3, R12, LR} ; Save APCS corruptible registers
|
||||
|
||||
MOV R3, SP ; Move SP into R3
|
||||
AND R3, R3, #4 ; Get stack adjustment to ensure 8-byte alignment
|
||||
SUB SP, SP, R3 ; Adjust stack
|
||||
PUSH {R3, R4} ; Store stack adjustment(R3) and user data(R4)
|
||||
|
||||
BLX IRQ_GetActiveIRQ ; Retrieve interrupt ID into R0
|
||||
MOV R4, R0 ; Move interrupt ID to R4
|
||||
|
||||
LDR R1, =IRQ_NestLevel
|
||||
LDR R3, [R1] ; Load IRQ nest level and increment it
|
||||
ADD R3, R3, #1
|
||||
STR R3, [R1]
|
||||
|
||||
BLX IRQ_GetHandler ; Retrieve interrupt handler address for current ID
|
||||
CMP R0, #0 ; Check if handler address is 0
|
||||
BEQ IRQ_End ; If 0, end interrupt and return
|
||||
|
||||
CPSIE i ; Re-enable interrupts
|
||||
BLX R0 ; Call IRQ handler
|
||||
CPSID i ; Disable interrupts
|
||||
|
||||
IRQ_End
|
||||
MOV R0, R4 ; Move interrupt ID to R0
|
||||
BLX IRQ_EndOfInterrupt ; Signal end of interrupt
|
||||
|
||||
LDR R2, =IRQ_NestLevel
|
||||
LDR R1, [R2] ; Load IRQ nest level and
|
||||
SUBS R1, R1, #1 ; decrement it
|
||||
STR R1, [R2]
|
||||
BNE IRQ_Exit ; Not zero, exit from IRQ handler
|
||||
|
||||
LDR R0, =SVC_Active
|
||||
LDRB R0, [R0] ; Load SVC_Active flag
|
||||
CMP R0, #0
|
||||
BNE IRQ_SwitchCheck ; Skip post processing when SVC active
|
||||
|
||||
; RTX IRQ post processing check
|
||||
PUSH {R5, R6} ; Save user R5 and R6
|
||||
MOV R6, #0
|
||||
LDR R5, =IRQ_PendSV ; Load address of IRQ_PendSV flag
|
||||
B IRQ_PendCheck
|
||||
IRQ_PendExec
|
||||
STRB R6, [R5] ; Clear PendSV flag
|
||||
CPSIE i ; Re-enable interrupts
|
||||
BLX osRtxPendSV_Handler ; Post process pending objects
|
||||
CPSID i ; Disable interrupts
|
||||
IRQ_PendCheck
|
||||
LDRB R0, [R5] ; Load PendSV flag
|
||||
CMP R0, #1 ; Compare PendSV value
|
||||
BEQ IRQ_PendExec ; Branch to IRQ_PendExec if PendSV is set
|
||||
POP {R5, R6} ; Restore user R5 and R6
|
||||
|
||||
IRQ_SwitchCheck
|
||||
; RTX IRQ context switch check
|
||||
LDR R12, =osRtxInfo+I_T_RUN_OFS ; Load address of osRtxInfo.run
|
||||
LDM R12, {R0, R1} ; Load osRtxInfo.thread.run: curr & next
|
||||
CMP R0, R1 ; Check if context switch is required
|
||||
BEQ IRQ_Exit
|
||||
|
||||
POP {R3, R4} ; Restore stack adjustment(R3) and user data(R4)
|
||||
ADD SP, SP, R3 ; Unadjust stack
|
||||
B osRtxContextSwitch
|
||||
|
||||
IRQ_Exit
|
||||
POP {R3, R4} ; Restore stack adjustment(R3) and user data(R4)
|
||||
ADD SP, SP, R3 ; Unadjust stack
|
||||
|
||||
POP {R0-R3, R12, LR} ; Restore stacked APCS registers
|
||||
RFEFD SP! ; Return from IRQ handler
|
||||
|
||||
ENDP
|
||||
|
||||
|
||||
SVC_Handler\
|
||||
PROC
|
||||
EXPORT SVC_Handler
|
||||
IMPORT IRQ_Disable
|
||||
IMPORT IRQ_Enable
|
||||
IMPORT osRtxPendSV_Handler
|
||||
IMPORT osRtxUserSVC
|
||||
IMPORT osRtxInfo
|
||||
|
||||
SRSFD SP!, #MODE_SVC ; Store SPSR_svc and LR_svc onto SVC stack
|
||||
PUSH {R12, LR}
|
||||
|
||||
MRS R12, SPSR ; Load SPSR
|
||||
TST R12, #CPSR_BIT_T ; Thumb bit set?
|
||||
LDRHNE R12, [LR,#-2] ; Thumb: load halfword
|
||||
BICNE R12, R12, #0xFF00 ; extract SVC number
|
||||
LDREQ R12, [LR,#-4] ; ARM: load word
|
||||
BICEQ R12, R12, #0xFF000000 ; extract SVC number
|
||||
CMP R12, #0 ; Compare SVC number
|
||||
BNE SVC_User ; Branch if User SVC
|
||||
|
||||
PUSH {R0-R3}
|
||||
|
||||
LDR R3, =osRtxInfo
|
||||
LDR R1, [R3, #I_K_STATE_OFS] ; Load RTX5 kernel state
|
||||
CMP R1, #K_STATE_RUNNING ; Check osKernelRunning
|
||||
BLT SVC_FuncCall ; Continue if kernel is not running
|
||||
LDR R0, [R3, #I_TICK_IRQN_OFS] ; Load OS Tick irqn
|
||||
BLX IRQ_Disable ; Disable OS Tick interrupt
|
||||
SVC_FuncCall
|
||||
LDR R0, =SVC_Active
|
||||
MOV R1, #1
|
||||
STRB R1, [R0] ; Set SVC_Active flag
|
||||
POP {R0-R3}
|
||||
|
||||
LDR R12, [SP] ; Reload R12 from stack
|
||||
|
||||
CPSIE i ; Re-enable interrupts
|
||||
BLX R12 ; Branch to SVC function
|
||||
CPSID i ; Disable interrupts
|
||||
|
||||
SUB SP, SP, #4 ; Adjust SP
|
||||
STM SP, {SP}^ ; Store SP_usr onto stack
|
||||
POP {R12} ; Pop SP_usr into R12
|
||||
SUB R12, R12, #16 ; Adjust pointer to SP_usr
|
||||
LDMDB R12, {R2,R3} ; Load return values from SVC function
|
||||
PUSH {R0-R3} ; Push return values to stack
|
||||
|
||||
PUSH {R4, R5} ; Save R4 and R5
|
||||
MOV R5, #0
|
||||
LDR R4, =IRQ_PendSV ; Load address of IRQ_PendSV
|
||||
B SVC_PendCheck
|
||||
SVC_PendExec
|
||||
STRB R5, [R4] ; Clear IRQ_PendSV flag
|
||||
CPSIE i ; Re-enable interrupts
|
||||
BLX osRtxPendSV_Handler ; Post process pending objects
|
||||
CPSID i ; Disable interrupts
|
||||
SVC_PendCheck
|
||||
LDRB R0, [R4] ; Load IRQ_PendSV flag
|
||||
CMP R0, #1 ; Compare IRQ_PendSV value
|
||||
BEQ SVC_PendExec ; Branch to SVC_PendExec if IRQ_PendSV is set
|
||||
POP {R4, R5} ; Restore R4 and R5
|
||||
|
||||
LDR R0, =SVC_Active
|
||||
MOV R1, #0
|
||||
STRB R1, [R0] ; Clear SVC_Active flag
|
||||
|
||||
LDR R12, =osRtxInfo
|
||||
LDR R1, [R12, #I_K_STATE_OFS] ; Load RTX5 kernel state
|
||||
CMP R1, #K_STATE_RUNNING ; Check osKernelRunning
|
||||
BLT SVC_ContextCheck ; Continue if kernel is not running
|
||||
LDR R0, [R12, #I_TICK_IRQN_OFS] ; Load OS Tick irqn
|
||||
BLX IRQ_Enable ; Enable OS Tick interrupt
|
||||
SVC_ContextCheck
|
||||
ADD R12, R12, #I_T_RUN_OFS ; Load address of osRtxInfo.thread.run
|
||||
LDM R12, {R0, R1} ; Load osRtxInfo.thread.run: curr & next
|
||||
CMP R0, R1 ; Check if context switch is required
|
||||
BEQ osRtxContextExit ; Exit if curr and next are equal
|
||||
B osRtxContextSwitch ; Continue in context switcher
|
||||
|
||||
SVC_User
|
||||
PUSH {R4, R5}
|
||||
LDR R5,=osRtxUserSVC ; Load address of SVC table
|
||||
LDR R4,[R5] ; Load SVC maximum number
|
||||
CMP R12,R4 ; Check SVC number range
|
||||
BHI SVC_Done ; Branch if out of range
|
||||
|
||||
LDR R12,[R5,R12,LSL #2] ; Load SVC Function Address
|
||||
BLX R12 ; Call SVC Function
|
||||
|
||||
SVC_Done
|
||||
POP {R4, R5, R12, LR}
|
||||
RFEFD SP! ; Return from exception
|
||||
|
||||
ENDP
|
||||
|
||||
|
||||
osRtxContextSwitch\
|
||||
PROC
|
||||
EXPORT osRtxContextSwitch
|
||||
|
||||
; R0 = osRtxInfo.thread.run.curr
|
||||
; R1 = osRtxInfo.thread.run.next
|
||||
; R12 = &osRtxInfo.thread.run
|
||||
|
||||
CMP R0, #0 ; Is osRtxInfo.thread.run.curr == 0
|
||||
ADDEQ SP, SP, #32 ; Equal, curr deleted, adjust current SP
|
||||
BEQ osRtxContextRestore ; Restore context, run.curr = run.next;
|
||||
|
||||
osRtxContextSave
|
||||
SUB SP, SP, #4
|
||||
STM SP, {SP}^ ; Save SP_usr to current stack
|
||||
POP {R3} ; Pop SP_usr into R3
|
||||
|
||||
SUB R3, R3, #64 ; Adjust user sp to end of basic frame (R4)
|
||||
STMIA R3!, {R4-R11} ; Save R4-R11 to user
|
||||
POP {R4-R8} ; Pop current R0-R12 into R4-R8
|
||||
STMIA R3!, {R4-R8} ; Store them to user stack
|
||||
STM R3, {LR}^ ; Store LR_usr directly
|
||||
ADD R3, R3, #4 ; Adjust user sp to PC
|
||||
POP {R4-R6} ; Pop current LR, PC, CPSR
|
||||
STMIA R3!, {R5-R6} ; Restore user PC and CPSR
|
||||
|
||||
SUB R3, R3, #64 ; Adjust user sp to R4
|
||||
|
||||
; Check if VFP state need to be saved
|
||||
MRC p15, 0, R2, c1, c0, 2 ; VFP/NEON access enabled? (CPACR)
|
||||
AND R2, R2, #0x00F00000
|
||||
CMP R2, #0x00F00000
|
||||
BNE osRtxContextSave1 ; Continue, no VFP
|
||||
|
||||
VMRS R2, FPSCR
|
||||
STMDB R3!, {R2,R12} ; Push FPSCR, maintain 8-byte alignment
|
||||
IF {TARGET_FEATURE_EXTENSION_REGISTER_COUNT} == 16
|
||||
VSTMDB R3!, {D0-D15}
|
||||
LDRB R2, [R0, #TCB_SP_FRAME] ; Record in TCB that VFP/D16 state is stacked
|
||||
ORR R2, R2, #2
|
||||
STRB R2, [R0, #TCB_SP_FRAME]
|
||||
ENDIF
|
||||
IF {TARGET_FEATURE_EXTENSION_REGISTER_COUNT} == 32
|
||||
VSTMDB R3!, {D0-D15}
|
||||
VSTMDB R3!, {D16-D31}
|
||||
LDRB R2, [R0, #TCB_SP_FRAME] ; Record in TCB that NEON/D32 state is stacked
|
||||
ORR R2, R2, #4
|
||||
STRB R2, [R0, #TCB_SP_FRAME]
|
||||
ENDIF
|
||||
|
||||
osRtxContextSave1
|
||||
STR R3, [R0, #TCB_SP_OFS] ; Store user sp to osRtxInfo.thread.run.curr
|
||||
|
||||
osRtxContextRestore
|
||||
STR R1, [R12] ; Store run.next to run.curr
|
||||
LDR R3, [R1, #TCB_SP_OFS] ; Load next osRtxThread_t.sp
|
||||
LDRB R2, [R1, #TCB_SP_FRAME] ; Load next osRtxThread_t.stack_frame
|
||||
|
||||
ANDS R2, R2, #0x6 ; Check stack frame for VFP context
|
||||
MRC p15, 0, R2, c1, c0, 2 ; Read CPACR
|
||||
ANDEQ R2, R2, #0xFF0FFFFF ; Disable VFP/NEON access if incoming task does not have stacked VFP/NEON state
|
||||
ORRNE R2, R2, #0x00F00000 ; Enable VFP/NEON access if incoming task does have stacked VFP/NEON state
|
||||
MCR p15, 0, R2, c1, c0, 2 ; Write CPACR
|
||||
BEQ osRtxContextRestore1 ; No VFP
|
||||
ISB ; Only sync if we enabled VFP, otherwise we will context switch before next VFP instruction anyway
|
||||
IF {TARGET_FEATURE_EXTENSION_REGISTER_COUNT} == 32
|
||||
VLDMIA R3!, {D16-D31}
|
||||
ENDIF
|
||||
VLDMIA R3!, {D0-D15}
|
||||
LDR R2, [R3]
|
||||
VMSR FPSCR, R2
|
||||
ADD R3, R3, #8
|
||||
|
||||
osRtxContextRestore1
|
||||
LDMIA R3!, {R4-R11} ; Restore R4-R11
|
||||
MOV R12, R3 ; Move sp pointer to R12
|
||||
ADD R3, R3, #32 ; Adjust sp
|
||||
PUSH {R3} ; Push sp onto stack
|
||||
LDMIA SP, {SP}^ ; Restore SP_usr
|
||||
ADD SP, SP, #4 ; Adjust SP_svc
|
||||
LDMIA R12!, {R0-R3} ; Restore User R0-R3
|
||||
LDR LR, [R12, #12] ; Load SPSR into LR
|
||||
MSR SPSR_CXSF, LR ; Restore SPSR
|
||||
ADD R12, R12, #4 ; Adjust pointer to LR
|
||||
LDM R12, {LR}^ ; Restore LR_usr directly into LR
|
||||
LDR LR, [R12, #4] ; Restore LR
|
||||
LDR R12, [R12, #-4] ; Restore R12
|
||||
|
||||
MOVS PC, LR ; Return from exception
|
||||
|
||||
osRtxContextExit
|
||||
POP {R0-R3, R12, LR} ; Restore stacked APCS registers
|
||||
RFEFD SP! ; Return from exception
|
||||
|
||||
ENDP
|
||||
|
||||
END
|
|
@ -24,7 +24,7 @@
|
|||
; */
|
||||
|
||||
|
||||
I_T_RUN_OFS EQU 28 ; osRtxInfo.thread.run offset
|
||||
I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset
|
||||
TCB_SP_OFS EQU 56 ; TCB.SP offset
|
||||
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
; */
|
||||
|
||||
|
||||
I_T_RUN_OFS EQU 28 ; osRtxInfo.thread.run offset
|
||||
I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset
|
||||
TCB_SP_OFS EQU 56 ; TCB.SP offset
|
||||
|
||||
|
|
@ -23,7 +23,12 @@
|
|||
; * -----------------------------------------------------------------------------
|
||||
; */
|
||||
|
||||
I_T_RUN_OFS EQU 28 ; osInfo.thread.run offset
|
||||
|
||||
IF :LNOT::DEF:__DOMAIN_NS
|
||||
__DOMAIN_NS EQU 0
|
||||
ENDIF
|
||||
|
||||
I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset
|
||||
TCB_SM_OFS EQU 48 ; TCB.stack_mem offset
|
||||
TCB_SP_OFS EQU 56 ; TCB.SP offset
|
||||
TCB_SF_OFS EQU 34 ; TCB.stack_frame offset
|
||||
|
@ -46,10 +51,10 @@ SVC_Handler PROC
|
|||
EXPORT SVC_Handler
|
||||
IMPORT osRtxUserSVC
|
||||
IMPORT osRtxInfo
|
||||
#ifdef __DOMAIN_NS
|
||||
IF __DOMAIN_NS = 1
|
||||
IMPORT TZ_LoadContext_S
|
||||
IMPORT TZ_StoreContext_S
|
||||
#endif
|
||||
ENDIF
|
||||
|
||||
MRS R0,PSP ; Get PSP
|
||||
LDR R1,[R0,#24] ; Load saved PC from stack
|
||||
|
@ -74,7 +79,7 @@ SVC_Context
|
|||
CBZ R1,SVC_ContextSwitch ; Branch if running thread is deleted
|
||||
|
||||
SVC_ContextSave
|
||||
#ifdef __DOMAIN_NS
|
||||
IF __DOMAIN_NS = 1
|
||||
LDR R0,[R1,#TCB_TZM_OFS] ; Load TrustZone memory identifier
|
||||
CBZ R0,SVC_ContextSave1 ; Branch if there is no secure context
|
||||
PUSH {R1,R2,R3,R7} ; Save registers
|
||||
|
@ -82,7 +87,7 @@ SVC_ContextSave
|
|||
BL TZ_StoreContext_S ; Store secure context
|
||||
MOV LR,R7 ; Set EXC_RETURN
|
||||
POP {R1,R2,R3,R7} ; Restore registers
|
||||
#endif
|
||||
ENDIF
|
||||
|
||||
SVC_ContextSave1
|
||||
MRS R0,PSP ; Get PSP
|
||||
|
@ -105,13 +110,13 @@ SVC_ContextSwitch
|
|||
STR R2,[R3] ; osRtxInfo.thread.run: curr = next
|
||||
|
||||
SVC_ContextRestore
|
||||
#ifdef __DOMAIN_NS
|
||||
IF __DOMAIN_NS = 1
|
||||
LDR R0,[R2,#TCB_TZM_OFS] ; Load TrustZone memory identifier
|
||||
CBZ R0,SVC_ContextRestore1 ; Branch if there is no secure context
|
||||
PUSH {R2,R3} ; Save registers
|
||||
BL TZ_LoadContext_S ; Load secure context
|
||||
POP {R2,R3} ; Restore registers
|
||||
#endif
|
||||
ENDIF
|
||||
|
||||
SVC_ContextRestore1
|
||||
MOV R1,R2
|
||||
|
@ -122,16 +127,16 @@ SVC_ContextRestore1
|
|||
ORRS R0,R1
|
||||
MOV LR,R0 ; Set EXC_RETURN
|
||||
|
||||
#ifdef __DOMAIN_NS
|
||||
IF __DOMAIN_NS = 1
|
||||
LSLS R0,R0,#25 ; Check domain of interrupted thread
|
||||
BPL SVC_ContextRestore2 ; Branch if non-secure
|
||||
LDR R0,[R2,#TCB_SP_OFS] ; Load SP
|
||||
MSR PSP,R0 ; Set PSP
|
||||
BX LR ; Exit from handler
|
||||
#else
|
||||
ELSE
|
||||
LDR R0,[R2,#TCB_SM_OFS] ; Load stack memory base
|
||||
MSR PSPLIM,R0 ; Set PSPLIM
|
||||
#endif
|
||||
ENDIF
|
||||
|
||||
SVC_ContextRestore2
|
||||
LDR R0,[R2,#TCB_SP_OFS] ; Load SP
|
||||
|
@ -201,10 +206,10 @@ SysTick_Handler PROC
|
|||
Sys_Context PROC
|
||||
EXPORT Sys_Context
|
||||
IMPORT osRtxInfo
|
||||
#ifdef __DOMAIN_NS
|
||||
IF __DOMAIN_NS = 1
|
||||
IMPORT TZ_LoadContext_S
|
||||
IMPORT TZ_StoreContext_S
|
||||
#endif
|
||||
ENDIF
|
||||
|
||||
LDR R3,=osRtxInfo+I_T_RUN_OFS; Load address of osRtxInfo.run
|
||||
LDM R3!,{R1,R2} ; Load osRtxInfo.thread.run: curr & next
|
||||
|
@ -212,7 +217,7 @@ Sys_Context PROC
|
|||
BEQ Sys_ContextExit ; Branch when threads are the same
|
||||
|
||||
Sys_ContextSave
|
||||
#ifdef __DOMAIN_NS
|
||||
IF __DOMAIN_NS = 1
|
||||
LDR R0,[R1,#TCB_TZM_OFS] ; Load TrustZone memory identifier
|
||||
CBZ R0,Sys_ContextSave1 ; Branch if there is no secure context
|
||||
PUSH {R1,R2,R3,R7} ; Save registers
|
||||
|
@ -225,7 +230,7 @@ Sys_ContextSave
|
|||
MRS R0,PSP ; Get PSP
|
||||
STR R0,[R1,#TCB_SP_OFS] ; Store SP
|
||||
B Sys_ContextSave2
|
||||
#endif
|
||||
ENDIF
|
||||
|
||||
Sys_ContextSave1
|
||||
MRS R0,PSP ; Get PSP
|
||||
|
@ -248,13 +253,13 @@ Sys_ContextSwitch
|
|||
STR R2,[R3] ; osRtxInfo.run: curr = next
|
||||
|
||||
Sys_ContextRestore
|
||||
#ifdef __DOMAIN_NS
|
||||
IF __DOMAIN_NS = 1
|
||||
LDR R0,[R2,#TCB_TZM_OFS] ; Load TrustZone memory identifier
|
||||
CBZ R0,Sys_ContextRestore1 ; Branch if there is no secure context
|
||||
PUSH {R2,R3} ; Save registers
|
||||
BL TZ_LoadContext_S ; Load secure context
|
||||
POP {R2,R3} ; Restore registers
|
||||
#endif
|
||||
ENDIF
|
||||
|
||||
Sys_ContextRestore1
|
||||
MOV R1,R2
|
||||
|
@ -265,16 +270,16 @@ Sys_ContextRestore1
|
|||
ORRS R0,R1
|
||||
MOV LR,R0 ; Set EXC_RETURN
|
||||
|
||||
#ifdef __DOMAIN_NS
|
||||
IF __DOMAIN_NS = 1
|
||||
LSLS R0,R0,#25 ; Check domain of interrupted thread
|
||||
BPL Sys_ContextRestore2 ; Branch if non-secure
|
||||
LDR R0,[R2,#TCB_SP_OFS] ; Load SP
|
||||
MSR PSP,R0 ; Set PSP
|
||||
BX LR ; Exit from handler
|
||||
#else
|
||||
ELSE
|
||||
LDR R0,[R2,#TCB_SM_OFS] ; Load stack memory base
|
||||
MSR PSPLIM,R0 ; Set PSPLIM
|
||||
#endif
|
||||
ENDIF
|
||||
|
||||
Sys_ContextRestore2
|
||||
LDR R0,[R2,#TCB_SP_OFS] ; Load SP
|
||||
|
@ -295,4 +300,4 @@ Sys_ContextExit
|
|||
ENDP
|
||||
|
||||
|
||||
END
|
||||
END
|
|
@ -0,0 +1,3 @@
|
|||
__DOMAIN_NS EQU 1
|
||||
INCLUDE irq_armv8mbl.s
|
||||
END
|
|
@ -24,7 +24,7 @@
|
|||
; */
|
||||
|
||||
|
||||
I_T_RUN_OFS EQU 28 ; osRtxInfo.thread.run offset
|
||||
I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset
|
||||
TCB_SP_OFS EQU 56 ; TCB.SP offset
|
||||
|
||||
|
|
@ -24,7 +24,17 @@
|
|||
; */
|
||||
|
||||
|
||||
I_T_RUN_OFS EQU 28 ; osRtxInfo.thread.run offset
|
||||
IF :LNOT::DEF:__DOMAIN_NS
|
||||
__DOMAIN_NS EQU 0
|
||||
ENDIF
|
||||
|
||||
IF ({FPU}="FPv5-SP") || ({FPU}="FPv5_D16")
|
||||
__FPU_USED EQU 1
|
||||
ELSE
|
||||
__FPU_USED EQU 0
|
||||
ENDIF
|
||||
|
||||
I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset
|
||||
TCB_SM_OFS EQU 48 ; TCB.stack_mem offset
|
||||
TCB_SP_OFS EQU 56 ; TCB.SP offset
|
||||
TCB_SF_OFS EQU 34 ; TCB.stack_frame offset
|
||||
|
@ -47,10 +57,10 @@ SVC_Handler PROC
|
|||
EXPORT SVC_Handler
|
||||
IMPORT osRtxUserSVC
|
||||
IMPORT osRtxInfo
|
||||
#ifdef __DOMAIN_NS
|
||||
IF __DOMAIN_NS = 1
|
||||
IMPORT TZ_LoadContext_S
|
||||
IMPORT TZ_StoreContext_S
|
||||
#endif
|
||||
ENDIF
|
||||
|
||||
MRS R0,PSP ; Get PSP
|
||||
LDR R1,[R0,#24] ; Load saved PC from stack
|
||||
|
@ -70,7 +80,7 @@ SVC_Context
|
|||
CMP R1,R2 ; Check if thread switch is required
|
||||
BXEQ LR ; Exit when threads are the same
|
||||
|
||||
#ifdef __FPU_USED
|
||||
IF __FPU_USED = 1
|
||||
CBNZ R1,SVC_ContextSave ; Branch if running thread is not deleted
|
||||
TST LR,#0x10 ; Check if extended stack frame
|
||||
BNE SVC_ContextSwitch
|
||||
|
@ -79,26 +89,26 @@ SVC_Context
|
|||
BIC R0,#1 ; Clear LSPACT (Lazy state)
|
||||
STR R0,[R1] ; Store FPCCR
|
||||
B SVC_ContextSwitch
|
||||
#else
|
||||
ELSE
|
||||
CBZ R1,SVC_ContextSwitch ; Branch if running thread is deleted
|
||||
#endif
|
||||
ENDIF
|
||||
|
||||
SVC_ContextSave
|
||||
#ifdef __DOMAIN_NS
|
||||
IF __DOMAIN_NS = 1
|
||||
LDR R0,[R1,#TCB_TZM_OFS] ; Load TrustZone memory identifier
|
||||
CBZ R0,SVC_ContextSave1 ; Branch if there is no secure context
|
||||
PUSH {R1,R2,R3,LR} ; Save registers and EXC_RETURN
|
||||
BL TZ_StoreContext_S ; Store secure context
|
||||
POP {R1,R2,R3,LR} ; Restore registers and EXC_RETURN
|
||||
#endif
|
||||
ENDIF
|
||||
|
||||
SVC_ContextSave1
|
||||
MRS R0,PSP ; Get PSP
|
||||
STMDB R0!,{R4-R11} ; Save R4..R11
|
||||
#ifdef __FPU_USED
|
||||
IF __FPU_USED = 1
|
||||
TST LR,#0x10 ; Check if extended stack frame
|
||||
VSTMDBEQ R0!,{S16-S31} ; Save VFP S16.S31
|
||||
#endif
|
||||
ENDIF
|
||||
|
||||
SVC_ContextSave2
|
||||
STR R0,[R1,#TCB_SP_OFS] ; Store SP
|
||||
|
@ -108,13 +118,13 @@ SVC_ContextSwitch
|
|||
STR R2,[R3] ; osRtxInfo.thread.run: curr = next
|
||||
|
||||
SVC_ContextRestore
|
||||
#ifdef __DOMAIN_NS
|
||||
IF __DOMAIN_NS = 1
|
||||
LDR R0,[R2,#TCB_TZM_OFS] ; Load TrustZone memory identifier
|
||||
CBZ R0,SVC_ContextRestore1 ; Branch if there is no secure context
|
||||
PUSH {R2,R3} ; Save registers
|
||||
BL TZ_LoadContext_S ; Load secure context
|
||||
POP {R2,R3} ; Restore registers
|
||||
#endif
|
||||
ENDIF
|
||||
|
||||
SVC_ContextRestore1
|
||||
LDR R0,[R2,#TCB_SM_OFS] ; Load stack memory base
|
||||
|
@ -123,15 +133,15 @@ SVC_ContextRestore1
|
|||
LDR R0,[R2,#TCB_SP_OFS] ; Load SP
|
||||
ORR LR,R1,#0xFFFFFF00 ; Set EXC_RETURN
|
||||
|
||||
#ifdef __DOMAIN_NS
|
||||
IF __DOMAIN_NS = 1
|
||||
TST LR,#0x40 ; Check domain of interrupted thread
|
||||
BNE SVC_ContextRestore2 ; Branch if secure
|
||||
#endif
|
||||
ENDIF
|
||||
|
||||
#ifdef __FPU_USED
|
||||
IF __FPU_USED = 1
|
||||
TST LR,#0x10 ; Check if extended stack frame
|
||||
VLDMIAEQ R0!,{S16-S31} ; Restore VFP S16..S31
|
||||
#endif
|
||||
ENDIF
|
||||
LDMIA R0!,{R4-R11} ; Restore R4..R11
|
||||
|
||||
SVC_ContextRestore2
|
||||
|
@ -190,10 +200,10 @@ SysTick_Handler PROC
|
|||
Sys_Context PROC
|
||||
EXPORT Sys_Context
|
||||
IMPORT osRtxInfo
|
||||
#ifdef __DOMAIN_NS
|
||||
IF __DOMAIN_NS = 1
|
||||
IMPORT TZ_LoadContext_S
|
||||
IMPORT TZ_StoreContext_S
|
||||
#endif
|
||||
ENDIF
|
||||
|
||||
LDR R3,=osRtxInfo+I_T_RUN_OFS; Load address of osRtxInfo.run
|
||||
LDM R3,{R1,R2} ; Load osRtxInfo.thread.run: curr & next
|
||||
|
@ -201,7 +211,7 @@ Sys_Context PROC
|
|||
BXEQ LR ; Exit when threads are the same
|
||||
|
||||
Sys_ContextSave
|
||||
#ifdef __DOMAIN_NS
|
||||
IF __DOMAIN_NS = 1
|
||||
LDR R0,[R1,#TCB_TZM_OFS] ; Load TrustZone memory identifier
|
||||
CBZ R0,Sys_ContextSave1 ; Branch if there is no secure context
|
||||
PUSH {R1,R2,R3,LR} ; Save registers and EXC_RETURN
|
||||
|
@ -210,15 +220,15 @@ Sys_ContextSave
|
|||
TST LR,#0x40 ; Check domain of interrupted thread
|
||||
MRSNE R0,PSP ; Get PSP
|
||||
BNE Sys_ContextSave2 ; Branch if secure
|
||||
#endif
|
||||
ENDIF
|
||||
|
||||
Sys_ContextSave1
|
||||
MRS R0,PSP ; Get PSP
|
||||
STMDB R0!,{R4-R11} ; Save R4..R11
|
||||
#ifdef __FPU_USED
|
||||
IF __FPU_USED = 1
|
||||
TST LR,#0x10 ; Check if extended stack frame
|
||||
VSTMDBEQ R0!,{S16-S31} ; Save VFP S16.S31
|
||||
#endif
|
||||
ENDIF
|
||||
|
||||
Sys_ContextSave2
|
||||
STR R0,[R1,#TCB_SP_OFS] ; Store SP
|
||||
|
@ -228,13 +238,13 @@ Sys_ContextSwitch
|
|||
STR R2,[R3] ; osRtxInfo.run: curr = next
|
||||
|
||||
Sys_ContextRestore
|
||||
#ifdef __DOMAIN_NS
|
||||
IF __DOMAIN_NS = 1
|
||||
LDR R0,[R2,#TCB_TZM_OFS] ; Load TrustZone memory identifier
|
||||
CBZ R0,Sys_ContextRestore1 ; Branch if there is no secure context
|
||||
PUSH {R2,R3} ; Save registers
|
||||
BL TZ_LoadContext_S ; Load secure context
|
||||
POP {R2,R3} ; Restore registers
|
||||
#endif
|
||||
ENDIF
|
||||
|
||||
Sys_ContextRestore1
|
||||
LDR R0,[R2,#TCB_SM_OFS] ; Load stack memory base
|
||||
|
@ -243,15 +253,15 @@ Sys_ContextRestore1
|
|||
LDR R0,[R2,#TCB_SP_OFS] ; Load SP
|
||||
ORR LR,R1,#0xFFFFFF00 ; Set EXC_RETURN
|
||||
|
||||
#ifdef __DOMAIN_NS
|
||||
IF __DOMAIN_NS = 1
|
||||
TST LR,#0x40 ; Check domain of interrupted thread
|
||||
BNE Sys_ContextRestore2 ; Branch if secure
|
||||
#endif
|
||||
ENDIF
|
||||
|
||||
#ifdef __FPU_USED
|
||||
IF __FPU_USED = 1
|
||||
TST LR,#0x10 ; Check if extended stack frame
|
||||
VLDMIAEQ R0!,{S16-S31} ; Restore VFP S16..S31
|
||||
#endif
|
||||
ENDIF
|
||||
LDMIA R0!,{R4-R11} ; Restore R4..R11
|
||||
|
||||
Sys_ContextRestore2
|
||||
|
@ -264,4 +274,4 @@ Sys_ContextExit
|
|||
ENDP
|
||||
|
||||
|
||||
END
|
||||
END
|
|
@ -0,0 +1,3 @@
|
|||
__DOMAIN_NS EQU 1
|
||||
INCLUDE irq_armv8mml.s
|
||||
END
|
|
@ -24,7 +24,7 @@
|
|||
; */
|
||||
|
||||
|
||||
I_T_RUN_OFS EQU 28 ; osRtxInfo.thread.run offset
|
||||
I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset
|
||||
TCB_SP_OFS EQU 56 ; TCB.SP offset
|
||||
TCB_SF_OFS EQU 34 ; TCB.stack_frame offset
|
||||
|
|
@ -0,0 +1,455 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2017 ARM Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* Project: CMSIS-RTOS RTX
|
||||
* Title: Cortex-A Exception handlers
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
.file "irq_ca.S"
|
||||
.syntax unified
|
||||
|
||||
.equ MODE_FIQ, 0x11
|
||||
.equ MODE_IRQ, 0x12
|
||||
.equ MODE_SVC, 0x13
|
||||
.equ MODE_ABT, 0x17
|
||||
.equ MODE_UND, 0x1B
|
||||
|
||||
.equ CPSR_BIT_T, 0x20
|
||||
|
||||
.equ K_STATE_RUNNING, 2 // osKernelState_t::osKernelRunning
|
||||
.equ I_K_STATE_OFS, 8 // osRtxInfo.kernel.state offset
|
||||
.equ I_TICK_IRQN_OFS, 16 // osRtxInfo.tick_irqn offset
|
||||
.equ I_T_RUN_OFS, 20 // osRtxInfo.thread.run offset
|
||||
.equ TCB_SP_FRAME, 34 // osRtxThread_t.stack_frame offset
|
||||
.equ TCB_SP_OFS, 56 // osRtxThread_t.sp offset
|
||||
|
||||
|
||||
.section ".rodata"
|
||||
.global irqRtxLib // Non weak library reference
|
||||
irqRtxLib:
|
||||
.byte 0
|
||||
|
||||
.section ".data"
|
||||
.global IRQ_PendSV
|
||||
IRQ_NestLevel:
|
||||
.word 0 // IRQ nesting level counter
|
||||
IRQ_PendSV:
|
||||
.byte 0 // Pending SVC flag
|
||||
SVC_Active:
|
||||
.byte 0 // SVC handler execution active flag
|
||||
|
||||
.arm
|
||||
.section ".text"
|
||||
.align 4
|
||||
|
||||
|
||||
.type Undef_Handler, %function
|
||||
.global Undef_Handler
|
||||
.fnstart
|
||||
.cantunwind
|
||||
Undef_Handler:
|
||||
|
||||
SRSFD SP!, #MODE_UND
|
||||
PUSH {R0-R4, R12} // Save APCS corruptible registers to UND mode stack
|
||||
|
||||
MRS R0, SPSR
|
||||
TST R0, #CPSR_BIT_T // Check mode
|
||||
MOVEQ R1, #4 // R1 = 4 ARM mode
|
||||
MOVNE R1, #2 // R1 = 2 Thumb mode
|
||||
SUB R0, LR, R1
|
||||
LDREQ R0, [R0] // ARM mode - R0 points to offending instruction
|
||||
BEQ Undef_Cont
|
||||
|
||||
// Thumb instruction
|
||||
// Determine if it is a 32-bit Thumb instruction
|
||||
LDRH R0, [R0]
|
||||
MOV R2, #0x1C
|
||||
CMP R2, R0, LSR #11
|
||||
BHS Undef_Cont // 16-bit Thumb instruction
|
||||
|
||||
// 32-bit Thumb instruction. Unaligned - reconstruct the offending instruction
|
||||
LDRH R2, [LR]
|
||||
ORR R0, R2, R0, LSL #16
|
||||
Undef_Cont:
|
||||
MOV R2, LR // Set LR to third argument
|
||||
|
||||
AND R12, SP, #4 // Ensure stack is 8-byte aligned
|
||||
SUB SP, SP, R12 // Adjust stack
|
||||
PUSH {R12, LR} // Store stack adjustment and dummy LR
|
||||
|
||||
// R0 =Offending instruction, R1 =2(Thumb) or =4(ARM)
|
||||
BL CUndefHandler
|
||||
|
||||
POP {R12, LR} // Get stack adjustment & discard dummy LR
|
||||
ADD SP, SP, R12 // Unadjust stack
|
||||
|
||||
LDR LR, [SP, #24] // Restore stacked LR and possibly adjust for retry
|
||||
SUB LR, LR, R0
|
||||
LDR R0, [SP, #28] // Restore stacked SPSR
|
||||
MSR SPSR_cxsf, R0
|
||||
POP {R0-R4, R12} // Restore stacked APCS registers
|
||||
ADD SP, SP, #8 // Adjust SP for already-restored banked registers
|
||||
MOVS PC, LR
|
||||
|
||||
.fnend
|
||||
.size Undef_Handler, .-Undef_Handler
|
||||
|
||||
|
||||
.type PAbt_Handler, %function
|
||||
.global PAbt_Handler
|
||||
.fnstart
|
||||
.cantunwind
|
||||
PAbt_Handler:
|
||||
|
||||
SUB LR, LR, #4 // Pre-adjust LR
|
||||
SRSFD SP!, #MODE_ABT // Save LR and SPRS to ABT mode stack
|
||||
PUSH {R0-R4, R12} // Save APCS corruptible registers to ABT mode stack
|
||||
MRC p15, 0, R0, c5, c0, 1 // IFSR
|
||||
MRC p15, 0, R1, c6, c0, 2 // IFAR
|
||||
|
||||
MOV R2, LR // Set LR to third argument
|
||||
|
||||
AND R12, SP, #4 // Ensure stack is 8-byte aligned
|
||||
SUB SP, SP, R12 // Adjust stack
|
||||
PUSH {R12, LR} // Store stack adjustment and dummy LR
|
||||
|
||||
BL CPAbtHandler
|
||||
|
||||
POP {R12, LR} // Get stack adjustment & discard dummy LR
|
||||
ADD SP, SP, R12 // Unadjust stack
|
||||
|
||||
POP {R0-R4, R12} // Restore stack APCS registers
|
||||
RFEFD SP! // Return from exception
|
||||
|
||||
.fnend
|
||||
.size PAbt_Handler, .-PAbt_Handler
|
||||
|
||||
|
||||
.type DAbt_Handler, %function
|
||||
.global DAbt_Handler
|
||||
.fnstart
|
||||
.cantunwind
|
||||
DAbt_Handler:
|
||||
SUB LR, LR, #8 // Pre-adjust LR
|
||||
SRSFD SP!, #MODE_ABT // Save LR and SPRS to ABT mode stack
|
||||
PUSH {R0-R4, R12} // Save APCS corruptible registers to ABT mode stack
|
||||
CLREX // State of exclusive monitors unknown after taken data abort
|
||||
MRC p15, 0, R0, c5, c0, 0 // DFSR
|
||||
MRC p15, 0, R1, c6, c0, 0 // DFAR
|
||||
|
||||
MOV R2, LR // Set LR to third argument
|
||||
|
||||
AND R12, SP, #4 // Ensure stack is 8-byte aligned
|
||||
SUB SP, SP, R12 // Adjust stack
|
||||
PUSH {R12, LR} // Store stack adjustment and dummy LR
|
||||
|
||||
BL CDAbtHandler
|
||||
|
||||
POP {R12, LR} // Get stack adjustment & discard dummy LR
|
||||
ADD SP, SP, R12 // Unadjust stack
|
||||
|
||||
POP {R0-R4, R12} // Restore stacked APCS registers
|
||||
RFEFD SP! // Return from exception
|
||||
|
||||
.fnend
|
||||
.size DAbt_Handler, .-DAbt_Handler
|
||||
|
||||
|
||||
.type IRQ_Handler, %function
|
||||
.global IRQ_Handler
|
||||
.fnstart
|
||||
.cantunwind
|
||||
IRQ_Handler:
|
||||
|
||||
SUB LR, LR, #4 // Pre-adjust LR
|
||||
SRSFD SP!, #MODE_SVC // Save LR_irq and SPRS_irq on to the SVC stack
|
||||
CPS #MODE_SVC // Change to SVC mode
|
||||
PUSH {R0-R3, R12, LR} // Save APCS corruptible registers
|
||||
|
||||
MOV R3, SP // Move SP into R3
|
||||
AND R3, R3, #4 // Get stack adjustment to ensure 8-byte alignment
|
||||
SUB SP, SP, R3 // Adjust stack
|
||||
PUSH {R3, R4} // Store stack adjustment(R3) and user data(R4)
|
||||
|
||||
BLX IRQ_GetActiveIRQ // Retrieve interrupt ID into R0
|
||||
MOV R4, R0 // Move interrupt ID to R4
|
||||
|
||||
LDR R1, =IRQ_NestLevel
|
||||
LDR R3, [R1] // Load IRQ nest level and increment it
|
||||
ADD R3, R3, #1
|
||||
STR R3, [R1]
|
||||
|
||||
BLX IRQ_GetHandler // Retrieve interrupt handler address for current ID
|
||||
CMP R0, #0 // Check if handler address is 0
|
||||
BEQ IRQ_End // If 0, end interrupt and return
|
||||
|
||||
CPSIE i // Re-enable interrupts
|
||||
BLX R0 // Call IRQ handler
|
||||
CPSID i // Disable interrupts
|
||||
|
||||
IRQ_End:
|
||||
MOV R0, R4 // Move interrupt ID to R0
|
||||
BLX IRQ_EndOfInterrupt // Signal end of interrupt
|
||||
|
||||
LDR R2, =IRQ_NestLevel
|
||||
LDR R1, [R2] // Load IRQ nest level and
|
||||
SUBS R1, R1, #1 // decrement it
|
||||
STR R1, [R2]
|
||||
BNE IRQ_Exit // Not zero, exit from IRQ handler
|
||||
|
||||
LDR R0, =SVC_Active
|
||||
LDRB R0, [R0] // Load SVC_Active flag
|
||||
CMP R0, #0
|
||||
BNE IRQ_SwitchCheck // Skip post processing when SVC active
|
||||
|
||||
// RTX IRQ post processing check
|
||||
PUSH {R5, R6} // Save user R5 and R6
|
||||
MOV R6, #0
|
||||
LDR R5, =IRQ_PendSV // Load address of IRQ_PendSV flag
|
||||
B IRQ_PendCheck
|
||||
IRQ_PendExec:
|
||||
STRB R6, [R5] // Clear PendSV flag
|
||||
CPSIE i // Re-enable interrupts
|
||||
BLX osRtxPendSV_Handler // Post process pending objects
|
||||
CPSID i // Disable interrupts
|
||||
IRQ_PendCheck:
|
||||
LDRB R0, [R5] // Load PendSV flag
|
||||
CMP R0, #1 // Compare PendSV value
|
||||
BEQ IRQ_PendExec // Branch to IRQ_PendExec if PendSV is set
|
||||
POP {R5, R6} // Restore user R5 and R6
|
||||
|
||||
IRQ_SwitchCheck:
|
||||
// RTX IRQ context switch check
|
||||
LDR R12, =osRtxInfo+I_T_RUN_OFS // Load address of osRtxInfo.run
|
||||
LDM R12, {R0, R1} // Load osRtxInfo.thread.run: curr & next
|
||||
CMP R0, R1 // Check if context switch is required
|
||||
BEQ IRQ_Exit
|
||||
|
||||
POP {R3, R4} // Restore stack adjustment(R3) and user data(R4)
|
||||
ADD SP, SP, R3 // Unadjust stack
|
||||
B osRtxContextSwitch
|
||||
|
||||
IRQ_Exit:
|
||||
POP {R3, R4} // Restore stack adjustment(R3) and user data(R4)
|
||||
ADD SP, SP, R3 // Unadjust stack
|
||||
|
||||
POP {R0-R3, R12, LR} // Restore stacked APCS registers
|
||||
RFEFD SP! // Return from IRQ handler
|
||||
|
||||
.fnend
|
||||
.size IRQ_Handler, .-IRQ_Handler
|
||||
|
||||
|
||||
.type SVC_Handler, %function
|
||||
.global SVC_Handler
|
||||
.fnstart
|
||||
.cantunwind
|
||||
SVC_Handler:
|
||||
|
||||
SRSFD SP!, #MODE_SVC // Store SPSR_svc and LR_svc onto SVC stack
|
||||
PUSH {R12, LR}
|
||||
|
||||
MRS R12, SPSR // Load SPSR
|
||||
TST R12, #CPSR_BIT_T // Thumb bit set?
|
||||
LDRHNE R12, [LR,#-2] // Thumb: load halfword
|
||||
BICNE R12, R12, #0xFF00 // extract SVC number
|
||||
LDREQ R12, [LR,#-4] // ARM: load word
|
||||
BICEQ R12, R12, #0xFF000000 // extract SVC number
|
||||
CMP R12, #0 // Compare SVC number
|
||||
BNE SVC_User // Branch if User SVC
|
||||
|
||||
PUSH {R0-R3}
|
||||
|
||||
LDR R3, =osRtxInfo
|
||||
LDR R1, [R3, #I_K_STATE_OFS] // Load RTX5 kernel state
|
||||
CMP R1, #K_STATE_RUNNING // Check osKernelRunning
|
||||
BLT SVC_FuncCall // Continue if kernel is not running
|
||||
LDR R0, [R3, #I_TICK_IRQN_OFS] // Load OS Tick irqn
|
||||
BLX IRQ_Disable // Disable OS Tick interrupt
|
||||
SVC_FuncCall:
|
||||
LDR R0, =SVC_Active
|
||||
MOV R1, #1
|
||||
STRB R1, [R0] // Set SVC_Active flag
|
||||
POP {R0-R3}
|
||||
|
||||
LDR R12, [SP] // Reload R12 from stack
|
||||
|
||||
CPSIE i // Re-enable interrupts
|
||||
BLX R12 // Branch to SVC function
|
||||
CPSID i // Disable interrupts
|
||||
|
||||
SUB SP, SP, #4 // Adjust SP
|
||||
STM SP, {SP}^ // Store SP_usr onto stack
|
||||
POP {R12} // Pop SP_usr into R12
|
||||
SUB R12, R12, #16 // Adjust pointer to SP_usr
|
||||
LDMDB R12, {R2,R3} // Load return values from SVC function
|
||||
PUSH {R0-R3} // Push return values to stack
|
||||
|
||||
PUSH {R4, R5} // Save R4 and R5
|
||||
MOV R5, #0
|
||||
LDR R4, =IRQ_PendSV // Load address of IRQ_PendSV
|
||||
B SVC_PendCheck
|
||||
SVC_PendExec:
|
||||
STRB R5, [R4] // Clear IRQ_PendSV flag
|
||||
CPSIE i // Re-enable interrupts
|
||||
BLX osRtxPendSV_Handler // Post process pending objects
|
||||
CPSID i // Disable interrupts
|
||||
SVC_PendCheck:
|
||||
LDRB R0, [R4] // Load IRQ_PendSV flag
|
||||
CMP R0, #1 // Compare IRQ_PendSV value
|
||||
BEQ SVC_PendExec // Branch to SVC_PendExec if IRQ_PendSV is set
|
||||
POP {R4, R5} // Restore R4 and R5
|
||||
|
||||
LDR R0, =SVC_Active
|
||||
MOV R1, #0
|
||||
STRB R1, [R0] // Clear SVC_Active flag
|
||||
|
||||
LDR R12, =osRtxInfo
|
||||
LDR R1, [R12, #I_K_STATE_OFS] // Load RTX5 kernel state
|
||||
CMP R1, #K_STATE_RUNNING // Check osKernelRunning
|
||||
BLT SVC_ContextCheck // Continue if kernel is not running
|
||||
LDR R0, [R12, #I_TICK_IRQN_OFS] // Load OS Tick irqn
|
||||
BLX IRQ_Enable // Enable OS Tick interrupt
|
||||
SVC_ContextCheck:
|
||||
ADD R12, R12, #I_T_RUN_OFS // Load address of osRtxInfo.thread.run
|
||||
LDM R12, {R0, R1} // Load osRtxInfo.thread.run: curr & next
|
||||
CMP R0, R1 // Check if context switch is required
|
||||
BEQ osRtxContextExit // Exit if curr and next are equal
|
||||
B osRtxContextSwitch // Continue in context switcher
|
||||
|
||||
SVC_User:
|
||||
PUSH {R4, R5}
|
||||
LDR R5,=osRtxUserSVC // Load address of SVC table
|
||||
LDR R4,[R5] // Load SVC maximum number
|
||||
CMP R12,R4 // Check SVC number range
|
||||
BHI SVC_Done // Branch if out of range
|
||||
|
||||
LDR R12,[R5,R12,LSL #2] // Load SVC Function Address
|
||||
BLX R12 // Call SVC Function
|
||||
|
||||
SVC_Done:
|
||||
POP {R4, R5, R12, LR}
|
||||
RFEFD SP! // Return from exception
|
||||
|
||||
.fnend
|
||||
.size SVC_Handler, .-SVC_Handler
|
||||
|
||||
|
||||
.type osRtxContextSwitch, %function
|
||||
.global osRtxContextSwitch
|
||||
.fnstart
|
||||
.cantunwind
|
||||
osRtxContextSwitch:
|
||||
|
||||
// R0 = osRtxInfo.thread.run.curr
|
||||
// R1 = osRtxInfo.thread.run.next
|
||||
// R12 = &osRtxInfo.thread.run
|
||||
|
||||
CMP R0, #0 // Is osRtxInfo.thread.run.curr == 0
|
||||
ADDEQ SP, SP, #32 // Equal, curr deleted, adjust current SP
|
||||
BEQ osRtxContextRestore // Restore context, run.curr = run.next;
|
||||
|
||||
osRtxContextSave:
|
||||
SUB SP, SP, #4
|
||||
STM SP, {SP}^ // Save SP_usr to current stack
|
||||
POP {R3} // Pop SP_usr into R3
|
||||
|
||||
SUB R3, R3, #64 // Adjust user sp to end of basic frame (R4)
|
||||
STMIA R3!, {R4-R11} // Save R4-R11 to user
|
||||
POP {R4-R8} // Pop current R0-R12 into R4-R8
|
||||
STMIA R3!, {R4-R8} // Store them to user stack
|
||||
STM R3, {LR}^ // Store LR_usr directly
|
||||
ADD R3, R3, #4 // Adjust user sp to PC
|
||||
POP {R4-R6} // Pop current LR, PC, CPSR
|
||||
STMIA R3!, {R5-R6} // Restore user PC and CPSR
|
||||
|
||||
SUB R3, R3, #64 // Adjust user sp to R4
|
||||
|
||||
// Check if VFP state need to be saved
|
||||
MRC p15, 0, R2, c1, c0, 2 // VFP/NEON access enabled? (CPACR)
|
||||
AND R2, R2, #0x00F00000
|
||||
CMP R2, #0x00F00000
|
||||
BNE osRtxContextSave1 // Continue, no VFP
|
||||
|
||||
VMRS R2, FPSCR
|
||||
STMDB R3!, {R2,R12} // Push FPSCR, maintain 8-byte alignment
|
||||
#if TARGET_FEATURE_EXTENSION_REGISTER_COUNT == 16
|
||||
VSTMDB R3!, {D0-D15}
|
||||
LDRB R2, [R0, #TCB_SP_FRAME] // Record in TCB that VFP/D16 state is stacked
|
||||
ORR R2, R2, #2
|
||||
STRB R2, [R0, #TCB_SP_FRAME]
|
||||
#endif
|
||||
#if TARGET_FEATURE_EXTENSION_REGISTER_COUNT == 32
|
||||
VSTMDB R3!, {D0-D15}
|
||||
VSTMDB R3!, {D16-D31}
|
||||
LDRB R2, [R0, #TCB_SP_FRAME] // Record in TCB that NEON/D32 state is stacked
|
||||
ORR R2, R2, #4
|
||||
STRB R2, [R0, #TCB_SP_FRAME]
|
||||
#endif
|
||||
|
||||
osRtxContextSave1:
|
||||
STR R3, [R0, #TCB_SP_OFS] // Store user sp to osRtxInfo.thread.run.curr
|
||||
|
||||
osRtxContextRestore:
|
||||
STR R1, [R12] // Store run.next to run.curr
|
||||
LDR R3, [R1, #TCB_SP_OFS] // Load next osRtxThread_t.sp
|
||||
LDRB R2, [R1, #TCB_SP_FRAME] // Load next osRtxThread_t.stack_frame
|
||||
|
||||
ANDS R2, R2, #0x6 // Check stack frame for VFP context
|
||||
MRC p15, 0, R2, c1, c0, 2 // Read CPACR
|
||||
ANDEQ R2, R2, #0xFF0FFFFF // Disable VFP/NEON access if incoming task does not have stacked VFP/NEON state
|
||||
ORRNE R2, R2, #0x00F00000 // Enable VFP/NEON access if incoming task does have stacked VFP/NEON state
|
||||
MCR p15, 0, R2, c1, c0, 2 // Write CPACR
|
||||
BEQ osRtxContextRestore1 // No VFP
|
||||
ISB // Only sync if we enabled VFP, otherwise we will context switch before next VFP instruction anyway
|
||||
#if TARGET_FEATURE_EXTENSION_REGISTER_COUNT == 32
|
||||
VLDMIA R3!, {D16-D31}
|
||||
#endif
|
||||
VLDMIA R3!, {D0-D15}
|
||||
LDR R2, [R3]
|
||||
VMSR FPSCR, R2
|
||||
ADD R3, R3, #8
|
||||
|
||||
osRtxContextRestore1:
|
||||
LDMIA R3!, {R4-R11} // Restore R4-R11
|
||||
MOV R12, R3 // Move sp pointer to R12
|
||||
ADD R3, R3, #32 // Adjust sp
|
||||
PUSH {R3} // Push sp onto stack
|
||||
LDMIA SP, {SP}^ // Restore SP_usr
|
||||
ADD SP, SP, #4 // Adjust SP_svc
|
||||
LDMIA R12!, {R0-R3} // Restore User R0-R3
|
||||
LDR LR, [R12, #12] // Load SPSR into LR
|
||||
MSR SPSR_cxsf, LR // Restore SPSR
|
||||
ADD R12, R12, #4 // Adjust pointer to LR
|
||||
LDM R12, {LR}^ // Restore LR_usr directly into LR
|
||||
LDR LR, [R12, #4] // Restore LR
|
||||
LDR R12, [R12, #-4] // Restore R12
|
||||
|
||||
MOVS PC, LR // Return from exception
|
||||
|
||||
osRtxContextExit:
|
||||
POP {R0-R3, R12, LR} // Restore stacked APCS registers
|
||||
RFEFD SP! // Return from exception
|
||||
|
||||
.fnend
|
||||
.size osRtxContextSwitch, .-osRtxContextSwitch
|
||||
|
||||
.end
|
|
@ -27,7 +27,7 @@
|
|||
.file "irq_cm0.S"
|
||||
.syntax unified
|
||||
|
||||
.equ I_T_RUN_OFS, 28 // osRtxInfo.thread.run offset
|
||||
.equ I_T_RUN_OFS, 20 // osRtxInfo.thread.run offset
|
||||
.equ TCB_SP_OFS, 56 // TCB.SP offset
|
||||
|
||||
.section ".rodata"
|
|
@ -27,7 +27,7 @@
|
|||
.file "irq_cm0.S"
|
||||
.syntax unified
|
||||
|
||||
.equ I_T_RUN_OFS, 28 // osRtxInfo.thread.run offset
|
||||
.equ I_T_RUN_OFS, 20 // osRtxInfo.thread.run offset
|
||||
.equ TCB_SP_OFS, 56 // TCB.SP offset
|
||||
|
||||
.section ".rodata"
|
|
@ -27,7 +27,11 @@
|
|||
.file "irq_armv8mbl.S"
|
||||
.syntax unified
|
||||
|
||||
.equ I_T_RUN_OFS, 28 // osRtxInfo.thread.run offset
|
||||
.ifndef __DOMAIN_NS
|
||||
.equ __DOMAIN_NS, 0
|
||||
.endif
|
||||
|
||||
.equ I_T_RUN_OFS, 20 // osRtxInfo.thread.run offset
|
||||
.equ TCB_SM_OFS, 48 // TCB.stack_mem offset
|
||||
.equ TCB_SP_OFS, 56 // TCB.SP offset
|
||||
.equ TCB_SF_OFS, 34 // TCB.stack_frame offset
|
||||
|
@ -50,6 +54,7 @@ irqRtxLib:
|
|||
.fnstart
|
||||
.cantunwind
|
||||
SVC_Handler:
|
||||
|
||||
MRS R0,PSP // Get PSP
|
||||
LDR R1,[R0,#24] // Load saved PC from stack
|
||||
SUBS R1,R1,#2 // Point to SVC instruction
|
||||
|
@ -73,7 +78,7 @@ SVC_Context:
|
|||
CBZ R1,SVC_ContextSwitch // Branch if running thread is deleted
|
||||
|
||||
SVC_ContextSave:
|
||||
#ifdef __DOMAIN_NS
|
||||
.if __DOMAIN_NS == 1
|
||||
LDR R0,[R1,#TCB_TZM_OFS] // Load TrustZone memory identifier
|
||||
CBZ R0,SVC_ContextSave1 // Branch if there is no secure context
|
||||
PUSH {R1,R2,R3,R7} // Save registers
|
||||
|
@ -81,7 +86,7 @@ SVC_ContextSave:
|
|||
BL TZ_StoreContext_S // Store secure context
|
||||
MOV LR,R7 // Set EXC_RETURN
|
||||
POP {R1,R2,R3,R7} // Restore registers
|
||||
#endif
|
||||
.endif
|
||||
|
||||
SVC_ContextSave1:
|
||||
MRS R0,PSP // Get PSP
|
||||
|
@ -104,13 +109,13 @@ SVC_ContextSwitch:
|
|||
STR R2,[R3] // osRtxInfo.thread.run: curr = next
|
||||
|
||||
SVC_ContextRestore:
|
||||
#ifdef __DOMAIN_NS
|
||||
.if __DOMAIN_NS == 1
|
||||
LDR R0,[R2,#TCB_TZM_OFS] // Load TrustZone memory identifier
|
||||
CBZ R0,SVC_ContextRestore1 // Branch if there is no secure context
|
||||
PUSH {R2,R3} // Save registers
|
||||
BL TZ_LoadContext_S // Load secure context
|
||||
POP {R2,R3} // Restore registers
|
||||
#endif
|
||||
.endif
|
||||
|
||||
SVC_ContextRestore1:
|
||||
MOV R1,R2
|
||||
|
@ -121,16 +126,16 @@ SVC_ContextRestore1:
|
|||
ORRS R0,R1
|
||||
MOV LR,R0 // Set EXC_RETURN
|
||||
|
||||
#ifdef __DOMAIN_NS
|
||||
.if __DOMAIN_NS == 1
|
||||
LSLS R0,R0,#25 // Check domain of interrupted thread
|
||||
BPL SVC_ContextRestore2 // Branch if non-secure
|
||||
LDR R0,[R2,#TCB_SP_OFS] // Load SP
|
||||
MSR PSP,R0 // Set PSP
|
||||
BX LR // Exit from handler
|
||||
#else
|
||||
.else
|
||||
LDR R0,[R2,#TCB_SM_OFS] // Load stack memory base
|
||||
MSR PSPLIM,R0 // Set PSPLIM
|
||||
#endif
|
||||
.endif
|
||||
|
||||
SVC_ContextRestore2:
|
||||
LDR R0,[R2,#TCB_SP_OFS] // Load SP
|
||||
|
@ -216,7 +221,7 @@ Sys_Context:
|
|||
BEQ Sys_ContextExit // Branch when threads are the same
|
||||
|
||||
Sys_ContextSave:
|
||||
#ifdef __DOMAIN_NS
|
||||
.if __DOMAIN_NS == 1
|
||||
LDR R0,[R1,#TCB_TZM_OFS] // Load TrustZone memory identifier
|
||||
CBZ R0,Sys_ContextSave1 // Branch if there is no secure context
|
||||
PUSH {R1,R2,R3,R7} // Save registers
|
||||
|
@ -229,7 +234,7 @@ Sys_ContextSave:
|
|||
MRS R0,PSP // Get PSP
|
||||
STR R0,[R1,#TCB_SP_OFS] // Store SP
|
||||
B Sys_ContextSave2
|
||||
#endif
|
||||
.endif
|
||||
|
||||
Sys_ContextSave1:
|
||||
MRS R0,PSP // Get PSP
|
||||
|
@ -252,13 +257,13 @@ Sys_ContextSwitch:
|
|||
STR R2,[R3] // osRtxInfo.run: curr = next
|
||||
|
||||
Sys_ContextRestore:
|
||||
#ifdef __DOMAIN_NS
|
||||
.if __DOMAIN_NS == 1
|
||||
LDR R0,[R2,#TCB_TZM_OFS] // Load TrustZone memory identifier
|
||||
CBZ R0,Sys_ContextRestore1 // Branch if there is no secure context
|
||||
PUSH {R2,R3} // Save registers
|
||||
BL TZ_LoadContext_S // Load secure context
|
||||
POP {R2,R3} // Restore registers
|
||||
#endif
|
||||
.endif
|
||||
|
||||
Sys_ContextRestore1:
|
||||
MOV R1,R2
|
||||
|
@ -269,16 +274,16 @@ Sys_ContextRestore1:
|
|||
ORRS R0,R1
|
||||
MOV LR,R0 // Set EXC_RETURN
|
||||
|
||||
#ifdef __DOMAIN_NS
|
||||
.if __DOMAIN_NS == 1
|
||||
LSLS R0,R0,#25 // Check domain of interrupted thread
|
||||
BPL Sys_ContextRestore2 // Branch if non-secure
|
||||
LDR R0,[R2,#TCB_SP_OFS] // Load SP
|
||||
MSR PSP,R0 // Set PSP
|
||||
BX LR // Exit from handler
|
||||
#else
|
||||
.else
|
||||
LDR R0,[R2,#TCB_SM_OFS] // Load stack memory base
|
||||
MSR PSPLIM,R0 // Set PSPLIM
|
||||
#endif
|
||||
.endif
|
||||
|
||||
Sys_ContextRestore2:
|
||||
LDR R0,[R2,#TCB_SP_OFS] // Load SP
|
|
@ -0,0 +1,3 @@
|
|||
.equ __DOMAIN_NS, 1
|
||||
.include "../Source/GCC/irq_armv8mbl.S"
|
||||
.end
|
|
@ -27,7 +27,7 @@
|
|||
.file "irq_cm3.S"
|
||||
.syntax unified
|
||||
|
||||
.equ I_T_RUN_OFS, 28 // osRtxInfo.thread.run offset
|
||||
.equ I_T_RUN_OFS, 20 // osRtxInfo.thread.run offset
|
||||
.equ TCB_SP_OFS, 56 // TCB.SP offset
|
||||
|
||||
.section ".rodata"
|
|
@ -27,7 +27,15 @@
|
|||
.file "irq_armv8mml.S"
|
||||
.syntax unified
|
||||
|
||||
.equ I_T_RUN_OFS, 28 // osRtxInfo.thread.run offset
|
||||
.ifndef __DOMAIN_NS
|
||||
.equ __DOMAIN_NS, 0
|
||||
.endif
|
||||
|
||||
.ifndef __FPU_USED
|
||||
.equ __FPU_USED, 0
|
||||
.endif
|
||||
|
||||
.equ I_T_RUN_OFS, 20 // osRtxInfo.thread.run offset
|
||||
.equ TCB_SM_OFS, 48 // TCB.stack_mem offset
|
||||
.equ TCB_SP_OFS, 56 // TCB.SP offset
|
||||
.equ TCB_SF_OFS, 34 // TCB.stack_frame offset
|
||||
|
@ -70,7 +78,7 @@ SVC_Context:
|
|||
IT EQ
|
||||
BXEQ LR // Exit when threads are the same
|
||||
|
||||
#ifdef __FPU_USED
|
||||
.if __FPU_USED == 1
|
||||
CBNZ R1,SVC_ContextSave // Branch if running thread is not deleted
|
||||
TST LR,#0x10 // Check if extended stack frame
|
||||
BNE SVC_ContextSwitch
|
||||
|
@ -79,27 +87,27 @@ SVC_Context:
|
|||
BIC R0,#1 // Clear LSPACT (Lazy state)
|
||||
STR R0,[R1] // Store FPCCR
|
||||
B SVC_ContextSwitch
|
||||
#else
|
||||
.else
|
||||
CBZ R1,SVC_ContextSwitch // Branch if running thread is deleted
|
||||
#endif
|
||||
.endif
|
||||
|
||||
SVC_ContextSave:
|
||||
#ifdef __DOMAIN_NS
|
||||
.if __DOMAIN_NS == 1
|
||||
LDR R0,[R1,#TCB_TZM_OFS] // Load TrustZone memory identifier
|
||||
CBZ R0,SVC_ContextSave1 // Branch if there is no secure context
|
||||
PUSH {R1,R2,R3,LR} // Save registers and EXC_RETURN
|
||||
BL TZ_StoreContext_S // Store secure context
|
||||
POP {R1,R2,R3,LR} // Restore registers and EXC_RETURN
|
||||
#endif
|
||||
.endif
|
||||
|
||||
SVC_ContextSave1:
|
||||
MRS R0,PSP // Get PSP
|
||||
STMDB R0!,{R4-R11} // Save R4..R11
|
||||
#ifdef __FPU_USED
|
||||
.if __FPU_USED == 1
|
||||
TST LR,#0x10 // Check if extended stack frame
|
||||
IT EQ
|
||||
VSTMDBEQ R0!,{S16-S31} // Save VFP S16.S31
|
||||
#endif
|
||||
.endif
|
||||
|
||||
SVC_ContextSave2:
|
||||
STR R0,[R1,#TCB_SP_OFS] // Store SP
|
||||
|
@ -109,13 +117,13 @@ SVC_ContextSwitch:
|
|||
STR R2,[R3] // osRtxInfo.thread.run: curr = next
|
||||
|
||||
SVC_ContextRestore:
|
||||
#ifdef __DOMAIN_NS
|
||||
.if __DOMAIN_NS == 1
|
||||
LDR R0,[R2,#TCB_TZM_OFS] // Load TrustZone memory identifier
|
||||
CBZ R0,SVC_ContextRestore1 // Branch if there is no secure context
|
||||
PUSH {R2,R3} // Save registers
|
||||
BL TZ_LoadContext_S // Load secure context
|
||||
POP {R2,R3} // Restore registers
|
||||
#endif
|
||||
.endif
|
||||
|
||||
SVC_ContextRestore1:
|
||||
LDR R0,[R2,#TCB_SM_OFS] // Load stack memory base
|
||||
|
@ -124,16 +132,16 @@ SVC_ContextRestore1:
|
|||
LDR R0,[R2,#TCB_SP_OFS] // Load SP
|
||||
ORR LR,R1,#0xFFFFFF00 // Set EXC_RETURN
|
||||
|
||||
#ifdef __DOMAIN_NS
|
||||
.if __DOMAIN_NS == 1
|
||||
TST LR,#0x40 // Check domain of interrupted thread
|
||||
BNE SVC_ContextRestore2 // Branch if secure
|
||||
#endif
|
||||
.endif
|
||||
|
||||
#ifdef __FPU_USED
|
||||
.if __FPU_USED == 1
|
||||
TST LR,#0x10 // Check if extended stack frame
|
||||
IT EQ
|
||||
VLDMIAEQ R0!,{S16-S31} // Restore VFP S16..S31
|
||||
#endif
|
||||
.endif
|
||||
LDMIA R0!,{R4-R11} // Restore R4..R11
|
||||
|
||||
SVC_ContextRestore2:
|
||||
|
@ -209,7 +217,7 @@ Sys_Context:
|
|||
BXEQ LR // Exit when threads are the same
|
||||
|
||||
Sys_ContextSave:
|
||||
#ifdef __DOMAIN_NS
|
||||
.if __DOMAIN_NS == 1
|
||||
LDR R0,[R1,#TCB_TZM_OFS] // Load TrustZone memory identifier
|
||||
CBZ R0,Sys_ContextSave1 // Branch if there is no secure context
|
||||
PUSH {R1,R2,R3,LR} // Save registers and EXC_RETURN
|
||||
|
@ -219,16 +227,16 @@ Sys_ContextSave:
|
|||
IT NE
|
||||
MRSNE R0,PSP // Get PSP
|
||||
BNE Sys_ContextSave2 // Branch if secure
|
||||
#endif
|
||||
.endif
|
||||
|
||||
Sys_ContextSave1:
|
||||
MRS R0,PSP // Get PSP
|
||||
STMDB R0!,{R4-R11} // Save R4..R11
|
||||
#ifdef __FPU_USED
|
||||
.if __FPU_USED == 1
|
||||
TST LR,#0x10 // Check if extended stack frame
|
||||
IT EQ
|
||||
VSTMDBEQ R0!,{S16-S31} // Save VFP S16.S31
|
||||
#endif
|
||||
.endif
|
||||
|
||||
Sys_ContextSave2:
|
||||
STR R0,[R1,#TCB_SP_OFS] // Store SP
|
||||
|
@ -238,13 +246,13 @@ Sys_ContextSwitch:
|
|||
STR R2,[R3] // osRtxInfo.run: curr = next
|
||||
|
||||
Sys_ContextRestore:
|
||||
#ifdef __DOMAIN_NS
|
||||
.if __DOMAIN_NS == 1
|
||||
LDR R0,[R2,#TCB_TZM_OFS] // Load TrustZone memory identifier
|
||||
CBZ R0,Sys_ContextRestore1 // Branch if there is no secure context
|
||||
PUSH {R2,R3} // Save registers
|
||||
BL TZ_LoadContext_S // Load secure context
|
||||
POP {R2,R3} // Restore registers
|
||||
#endif
|
||||
.endif
|
||||
|
||||
Sys_ContextRestore1:
|
||||
LDR R0,[R2,#TCB_SM_OFS] // Load stack memory base
|
||||
|
@ -253,16 +261,16 @@ Sys_ContextRestore1:
|
|||
LDR R0,[R2,#TCB_SP_OFS] // Load SP
|
||||
ORR LR,R1,#0xFFFFFF00 // Set EXC_RETURN
|
||||
|
||||
#ifdef __DOMAIN_NS
|
||||
.if __DOMAIN_NS == 1
|
||||
TST LR,#0x40 // Check domain of interrupted thread
|
||||
BNE Sys_ContextRestore2 // Branch if secure
|
||||
#endif
|
||||
.endif
|
||||
|
||||
#ifdef __FPU_USED
|
||||
.if __FPU_USED == 1
|
||||
TST LR,#0x10 // Check if extended stack frame
|
||||
IT EQ
|
||||
VLDMIAEQ R0!,{S16-S31} // Restore VFP S16..S31
|
||||
#endif
|
||||
.endif
|
||||
LDMIA R0!,{R4-R11} // Restore R4..R11
|
||||
|
||||
Sys_ContextRestore2:
|
|
@ -0,0 +1,3 @@
|
|||
.equ __FPU_USED, 1
|
||||
.include "../Source/GCC/irq_armv8mml.S"
|
||||
.end
|
|
@ -0,0 +1,4 @@
|
|||
.equ __FPU_USED, 1
|
||||
.equ __DOMAIN_NS, 1
|
||||
.include "../Source/GCC/irq_armv8mml.S"
|
||||
.end
|
|
@ -0,0 +1,3 @@
|
|||
.equ __DOMAIN_NS, 1
|
||||
.include "../Source/GCC/irq_armv8mml.S"
|
||||
.end
|
|
@ -27,7 +27,7 @@
|
|||
.file "irq_cm4f.S"
|
||||
.syntax unified
|
||||
|
||||
.equ I_T_RUN_OFS, 28 // osRtxInfo.thread.run offset
|
||||
.equ I_T_RUN_OFS, 20 // osRtxInfo.thread.run offset
|
||||
.equ TCB_SP_OFS, 56 // TCB.SP offset
|
||||
.equ TCB_SF_OFS, 34 // TCB.stack_frame offset
|
||||
|
||||
|
@ -80,7 +80,6 @@ SVC_Context:
|
|||
|
||||
SVC_ContextSave:
|
||||
STMDB R12!,{R4-R11} // Save R4..R11
|
||||
|
||||
#ifdef __FPU_PRESENT
|
||||
TST LR,#0x10 // Check if extended stack frame
|
||||
IT EQ
|
|
@ -0,0 +1,431 @@
|
|||
;/*
|
||||
; * Copyright (c) 2013-2017 ARM Limited. All rights reserved.
|
||||
; *
|
||||
; * SPDX-License-Identifier: Apache-2.0
|
||||
; *
|
||||
; * Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
; * not use this file except in compliance with the License.
|
||||
; * You may obtain a copy of the License at
|
||||
; *
|
||||
; * www.apache.org/licenses/LICENSE-2.0
|
||||
; *
|
||||
; * Unless required by applicable law or agreed to in writing, software
|
||||
; * distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
; * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
; * See the License for the specific language governing permissions and
|
||||
; * limitations under the License.
|
||||
; *
|
||||
; * -----------------------------------------------------------------------------
|
||||
; *
|
||||
; * Project: CMSIS-RTOS RTX
|
||||
; * Title: Cortex-A Exception handlers
|
||||
; *
|
||||
; * -----------------------------------------------------------------------------
|
||||
; */
|
||||
|
||||
NAME irq_ca.s
|
||||
|
||||
MODE_FIQ EQU 0x11
|
||||
MODE_IRQ EQU 0x12
|
||||
MODE_SVC EQU 0x13
|
||||
MODE_ABT EQU 0x17
|
||||
MODE_UND EQU 0x1B
|
||||
|
||||
CPSR_BIT_T EQU 0x20
|
||||
|
||||
K_STATE_RUNNING EQU 2 ; osKernelState_t::osKernelRunning
|
||||
I_K_STATE_OFS EQU 8 ; osRtxInfo.kernel.state offset
|
||||
I_TICK_IRQN_OFS EQU 16 ; osRtxInfo.tick_irqn offset
|
||||
I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset
|
||||
TCB_SP_FRAME EQU 34 ; osRtxThread_t.stack_frame offset
|
||||
TCB_SP_OFS EQU 56 ; osRtxThread_t.sp offset
|
||||
|
||||
|
||||
PRESERVE8
|
||||
ARM
|
||||
|
||||
|
||||
SECTION .rodata:DATA:NOROOT(2)
|
||||
EXPORT irqRtxLib
|
||||
irqRtxLib DCB 0 ; Non weak library reference
|
||||
|
||||
|
||||
SECTION .data:DATA:NOROOT(2)
|
||||
EXPORT IRQ_PendSV
|
||||
IRQ_NestLevel DCD 0 ; IRQ nesting level counter
|
||||
IRQ_PendSV DCB 0 ; Pending SVC flag
|
||||
SVC_Active DCB 0 ; SVC handler execution active flag
|
||||
|
||||
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
|
||||
|
||||
Undef_Handler
|
||||
EXPORT Undef_Handler
|
||||
IMPORT CUndefHandler
|
||||
|
||||
SRSFD SP!, #MODE_UND
|
||||
PUSH {R0-R4, R12} ; Save APCS corruptible registers to UND mode stack
|
||||
|
||||
MRS R0, SPSR
|
||||
TST R0, #CPSR_BIT_T ; Check mode
|
||||
MOVEQ R1, #4 ; R1 = 4 ARM mode
|
||||
MOVNE R1, #2 ; R1 = 2 Thumb mode
|
||||
SUB R0, LR, R1
|
||||
LDREQ R0, [R0] ; ARM mode - R0 points to offending instruction
|
||||
BEQ Undef_Cont
|
||||
|
||||
; Thumb instruction
|
||||
; Determine if it is a 32-bit Thumb instruction
|
||||
LDRH R0, [R0]
|
||||
MOV R2, #0x1C
|
||||
CMP R2, R0, LSR #11
|
||||
BHS Undef_Cont ; 16-bit Thumb instruction
|
||||
|
||||
; 32-bit Thumb instruction. Unaligned - reconstruct the offending instruction
|
||||
LDRH R2, [LR]
|
||||
ORR R0, R2, R0, LSL #16
|
||||
Undef_Cont
|
||||
MOV R2, LR ; Set LR to third argument
|
||||
|
||||
AND R12, SP, #4 ; Ensure stack is 8-byte aligned
|
||||
SUB SP, SP, R12 ; Adjust stack
|
||||
PUSH {R12, LR} ; Store stack adjustment and dummy LR
|
||||
|
||||
; R0 =Offending instruction, R1 =2(Thumb) or =4(ARM)
|
||||
BL CUndefHandler
|
||||
|
||||
POP {R12, LR} ; Get stack adjustment & discard dummy LR
|
||||
ADD SP, SP, R12 ; Unadjust stack
|
||||
|
||||
LDR LR, [SP, #24] ; Restore stacked LR and possibly adjust for retry
|
||||
SUB LR, LR, R0
|
||||
LDR R0, [SP, #28] ; Restore stacked SPSR
|
||||
MSR SPSR_CXSF, R0
|
||||
POP {R0-R4, R12} ; Restore stacked APCS registers
|
||||
ADD SP, SP, #8 ; Adjust SP for already-restored banked registers
|
||||
MOVS PC, LR
|
||||
|
||||
|
||||
PAbt_Handler
|
||||
EXPORT PAbt_Handler
|
||||
IMPORT CPAbtHandler
|
||||
|
||||
SUB LR, LR, #4 ; Pre-adjust LR
|
||||
SRSFD SP!, #MODE_ABT ; Save LR and SPRS to ABT mode stack
|
||||
PUSH {R0-R4, R12} ; Save APCS corruptible registers to ABT mode stack
|
||||
MRC p15, 0, R0, c5, c0, 1 ; IFSR
|
||||
MRC p15, 0, R1, c6, c0, 2 ; IFAR
|
||||
|
||||
MOV R2, LR ; Set LR to third argument
|
||||
|
||||
AND R12, SP, #4 ; Ensure stack is 8-byte aligned
|
||||
SUB SP, SP, R12 ; Adjust stack
|
||||
PUSH {R12, LR} ; Store stack adjustment and dummy LR
|
||||
|
||||
BL CPAbtHandler
|
||||
|
||||
POP {R12, LR} ; Get stack adjustment & discard dummy LR
|
||||
ADD SP, SP, R12 ; Unadjust stack
|
||||
|
||||
POP {R0-R4, R12} ; Restore stack APCS registers
|
||||
RFEFD SP! ; Return from exception
|
||||
|
||||
|
||||
DAbt_Handler
|
||||
EXPORT DAbt_Handler
|
||||
IMPORT CDAbtHandler
|
||||
|
||||
SUB LR, LR, #8 ; Pre-adjust LR
|
||||
SRSFD SP!, #MODE_ABT ; Save LR and SPRS to ABT mode stack
|
||||
PUSH {R0-R4, R12} ; Save APCS corruptible registers to ABT mode stack
|
||||
CLREX ; State of exclusive monitors unknown after taken data abort
|
||||
MRC p15, 0, R0, c5, c0, 0 ; DFSR
|
||||
MRC p15, 0, R1, c6, c0, 0 ; DFAR
|
||||
|
||||
MOV R2, LR ; Set LR to third argument
|
||||
|
||||
AND R12, SP, #4 ; Ensure stack is 8-byte aligned
|
||||
SUB SP, SP, R12 ; Adjust stack
|
||||
PUSH {R12, LR} ; Store stack adjustment and dummy LR
|
||||
|
||||
BL CDAbtHandler
|
||||
|
||||
POP {R12, LR} ; Get stack adjustment & discard dummy LR
|
||||
ADD SP, SP, R12 ; Unadjust stack
|
||||
|
||||
POP {R0-R4, R12} ; Restore stacked APCS registers
|
||||
RFEFD SP! ; Return from exception
|
||||
|
||||
|
||||
IRQ_Handler
|
||||
EXPORT IRQ_Handler
|
||||
IMPORT osRtxInfo
|
||||
IMPORT IRQ_GetActiveIRQ
|
||||
IMPORT IRQ_GetHandler
|
||||
IMPORT IRQ_EndOfInterrupt
|
||||
|
||||
SUB LR, LR, #4 ; Pre-adjust LR
|
||||
SRSFD SP!, #MODE_SVC ; Save LR_irq and SPRS_irq on to the SVC stack
|
||||
CPS #MODE_SVC ; Change to SVC mode
|
||||
PUSH {R0-R3, R12, LR} ; Save APCS corruptible registers
|
||||
|
||||
MOV R3, SP ; Move SP into R3
|
||||
AND R3, R3, #4 ; Get stack adjustment to ensure 8-byte alignment
|
||||
SUB SP, SP, R3 ; Adjust stack
|
||||
PUSH {R3, R4} ; Store stack adjustment(R3) and user data(R4)
|
||||
|
||||
BLX IRQ_GetActiveIRQ ; Retrieve interrupt ID into R0
|
||||
MOV R4, R0 ; Move interrupt ID to R4
|
||||
|
||||
LDR R1, =IRQ_NestLevel
|
||||
LDR R3, [R1] ; Load IRQ nest level and increment it
|
||||
ADD R3, R3, #1
|
||||
STR R3, [R1]
|
||||
|
||||
BLX IRQ_GetHandler ; Retrieve interrupt handler address for current ID
|
||||
CMP R0, #0 ; Check if handler address is 0
|
||||
BEQ IRQ_End ; If 0, end interrupt and return
|
||||
|
||||
CPSIE i ; Re-enable interrupts
|
||||
BLX R0 ; Call IRQ handler
|
||||
CPSID i ; Disable interrupts
|
||||
|
||||
IRQ_End
|
||||
MOV R0, R4 ; Move interrupt ID to R0
|
||||
BLX IRQ_EndOfInterrupt ; Signal end of interrupt
|
||||
|
||||
LDR R2, =IRQ_NestLevel
|
||||
LDR R1, [R2] ; Load IRQ nest level and
|
||||
SUBS R1, R1, #1 ; decrement it
|
||||
STR R1, [R2]
|
||||
BNE IRQ_Exit ; Not zero, exit from IRQ handler
|
||||
|
||||
LDR R0, =SVC_Active
|
||||
LDRB R0, [R0] ; Load SVC_Active flag
|
||||
CMP R0, #0
|
||||
BNE IRQ_SwitchCheck ; Skip post processing when SVC active
|
||||
|
||||
; RTX IRQ post processing check
|
||||
PUSH {R5, R6} ; Save user R5 and R6
|
||||
MOV R6, #0
|
||||
LDR R5, =IRQ_PendSV ; Load address of IRQ_PendSV flag
|
||||
B IRQ_PendCheck
|
||||
IRQ_PendExec
|
||||
STRB R6, [R5] ; Clear PendSV flag
|
||||
CPSIE i ; Re-enable interrupts
|
||||
BLX osRtxPendSV_Handler ; Post process pending objects
|
||||
CPSID i ; Disable interrupts
|
||||
IRQ_PendCheck
|
||||
LDRB R0, [R5] ; Load PendSV flag
|
||||
CMP R0, #1 ; Compare PendSV value
|
||||
BEQ IRQ_PendExec ; Branch to IRQ_PendExec if PendSV is set
|
||||
POP {R5, R6} ; Restore user R5 and R6
|
||||
|
||||
IRQ_SwitchCheck
|
||||
; RTX IRQ context switch check
|
||||
LDR R12, =osRtxInfo+I_T_RUN_OFS ; Load address of osRtxInfo.run
|
||||
LDM R12, {R0, R1} ; Load osRtxInfo.thread.run: curr & next
|
||||
CMP R0, R1 ; Check if context switch is required
|
||||
BEQ IRQ_Exit
|
||||
|
||||
POP {R3, R4} ; Restore stack adjustment(R3) and user data(R4)
|
||||
ADD SP, SP, R3 ; Unadjust stack
|
||||
B osRtxContextSwitch
|
||||
|
||||
IRQ_Exit
|
||||
POP {R3, R4} ; Restore stack adjustment(R3) and user data(R4)
|
||||
ADD SP, SP, R3 ; Unadjust stack
|
||||
|
||||
POP {R0-R3, R12, LR} ; Restore stacked APCS registers
|
||||
RFEFD SP! ; Return from IRQ handler
|
||||
|
||||
|
||||
SVC_Handler
|
||||
EXPORT SVC_Handler
|
||||
IMPORT IRQ_Disable
|
||||
IMPORT IRQ_Enable
|
||||
IMPORT osRtxPendSV_Handler
|
||||
IMPORT osRtxUserSVC
|
||||
IMPORT osRtxInfo
|
||||
|
||||
SRSFD SP!, #MODE_SVC ; Store SPSR_svc and LR_svc onto SVC stack
|
||||
PUSH {R12, LR}
|
||||
|
||||
MRS R12, SPSR ; Load SPSR
|
||||
TST R12, #CPSR_BIT_T ; Thumb bit set?
|
||||
LDRHNE R12, [LR,#-2] ; Thumb: load halfword
|
||||
BICNE R12, R12, #0xFF00 ; extract SVC number
|
||||
LDREQ R12, [LR,#-4] ; ARM: load word
|
||||
BICEQ R12, R12, #0xFF000000 ; extract SVC number
|
||||
CMP R12, #0 ; Compare SVC number
|
||||
BNE SVC_User ; Branch if User SVC
|
||||
|
||||
PUSH {R0-R3}
|
||||
|
||||
LDR R3, =osRtxInfo
|
||||
LDR R1, [R3, #I_K_STATE_OFS] ; Load RTX5 kernel state
|
||||
CMP R1, #K_STATE_RUNNING ; Check osKernelRunning
|
||||
BLT SVC_FuncCall ; Continue if kernel is not running
|
||||
LDR R0, [R3, #I_TICK_IRQN_OFS] ; Load OS Tick irqn
|
||||
BLX IRQ_Disable ; Disable OS Tick interrupt
|
||||
SVC_FuncCall
|
||||
LDR R0, =SVC_Active
|
||||
MOV R1, #1
|
||||
STRB R1, [R0] ; Set SVC_Active flag
|
||||
POP {R0-R3}
|
||||
|
||||
LDR R12, [SP] ; Reload R12 from stack
|
||||
|
||||
CPSIE i ; Re-enable interrupts
|
||||
BLX R12 ; Branch to SVC function
|
||||
CPSID i ; Disable interrupts
|
||||
|
||||
SUB SP, SP, #4 ; Adjust SP
|
||||
STM SP, {SP}^ ; Store SP_usr onto stack
|
||||
POP {R12} ; Pop SP_usr into R12
|
||||
SUB R12, R12, #16 ; Adjust pointer to SP_usr
|
||||
LDMDB R12, {R2,R3} ; Load return values from SVC function
|
||||
PUSH {R0-R3} ; Push return values to stack
|
||||
|
||||
PUSH {R4, R5} ; Save R4 and R5
|
||||
MOV R5, #0
|
||||
LDR R4, =IRQ_PendSV ; Load address of IRQ_PendSV
|
||||
B SVC_PendCheck
|
||||
SVC_PendExec
|
||||
STRB R5, [R4] ; Clear IRQ_PendSV flag
|
||||
CPSIE i ; Re-enable interrupts
|
||||
BLX osRtxPendSV_Handler ; Post process pending objects
|
||||
CPSID i ; Disable interrupts
|
||||
SVC_PendCheck
|
||||
LDRB R0, [R4] ; Load IRQ_PendSV flag
|
||||
CMP R0, #1 ; Compare IRQ_PendSV value
|
||||
BEQ SVC_PendExec ; Branch to SVC_PendExec if IRQ_PendSV is set
|
||||
POP {R4, R5} ; Restore R4 and R5
|
||||
|
||||
LDR R0, =SVC_Active
|
||||
MOV R1, #0
|
||||
STRB R1, [R0] ; Clear SVC_Active flag
|
||||
|
||||
LDR R12, =osRtxInfo
|
||||
LDR R1, [R12, #I_K_STATE_OFS] ; Load RTX5 kernel state
|
||||
CMP R1, #K_STATE_RUNNING ; Check osKernelRunning
|
||||
BLT SVC_ContextCheck ; Continue if kernel is not running
|
||||
LDR R0, [R12, #I_TICK_IRQN_OFS] ; Load OS Tick irqn
|
||||
BLX IRQ_Enable ; Enable OS Tick interrupt
|
||||
SVC_ContextCheck
|
||||
ADD R12, R12, #I_T_RUN_OFS ; Load address of osRtxInfo.thread.run
|
||||
LDM R12, {R0, R1} ; Load osRtxInfo.thread.run: curr & next
|
||||
CMP R0, R1 ; Check if context switch is required
|
||||
BEQ osRtxContextExit ; Exit if curr and next are equal
|
||||
B osRtxContextSwitch ; Continue in context switcher
|
||||
|
||||
SVC_User
|
||||
PUSH {R4, R5}
|
||||
LDR R5,=osRtxUserSVC ; Load address of SVC table
|
||||
LDR R4,[R5] ; Load SVC maximum number
|
||||
CMP R12,R4 ; Check SVC number range
|
||||
BHI SVC_Done ; Branch if out of range
|
||||
|
||||
LDR R12,[R5,R12,LSL #2] ; Load SVC Function Address
|
||||
BLX R12 ; Call SVC Function
|
||||
|
||||
SVC_Done
|
||||
POP {R4, R5, R12, LR}
|
||||
RFEFD SP! ; Return from exception
|
||||
|
||||
|
||||
osRtxContextSwitch
|
||||
EXPORT osRtxContextSwitch
|
||||
|
||||
; R0 = osRtxInfo.thread.run.curr
|
||||
; R1 = osRtxInfo.thread.run.next
|
||||
; R12 = &osRtxInfo.thread.run
|
||||
|
||||
CMP R0, #0 ; Is osRtxInfo.thread.run.curr == 0
|
||||
ADDEQ SP, SP, #32 ; Equal, curr deleted, adjust current SP
|
||||
BEQ osRtxContextRestore ; Restore context, run.curr = run.next;
|
||||
|
||||
osRtxContextSave
|
||||
SUB SP, SP, #4
|
||||
STM SP, {SP}^ ; Save SP_usr to current stack
|
||||
POP {R3} ; Pop SP_usr into R3
|
||||
|
||||
SUB R3, R3, #64 ; Adjust user sp to end of basic frame (R4)
|
||||
STMIA R3!, {R4-R11} ; Save R4-R11 to user
|
||||
POP {R4-R8} ; Pop current R0-R12 into R4-R8
|
||||
STMIA R3!, {R4-R8} ; Store them to user stack
|
||||
STM R3, {LR}^ ; Store LR_usr directly
|
||||
ADD R3, R3, #4 ; Adjust user sp to PC
|
||||
POP {R4-R6} ; Pop current LR, PC, CPSR
|
||||
STMIA R3!, {R5-R6} ; Restore user PC and CPSR
|
||||
|
||||
SUB R3, R3, #64 ; Adjust user sp to R4
|
||||
|
||||
; Check if VFP state need to be saved
|
||||
MRC p15, 0, R2, c1, c0, 2 ; VFP/NEON access enabled? (CPACR)
|
||||
AND R2, R2, #0x00F00000
|
||||
CMP R2, #0x00F00000
|
||||
BNE osRtxContextSave1 ; Continue, no VFP
|
||||
|
||||
VMRS R2, FPSCR
|
||||
STMDB R3!, {R2,R12} ; Push FPSCR, maintain 8-byte alignment
|
||||
IF {TARGET_FEATURE_EXTENSION_REGISTER_COUNT} == 16
|
||||
VSTMDB R3!, {D0-D15}
|
||||
LDRB R2, [R0, #TCB_SP_FRAME] ; Record in TCB that VFP/D16 state is stacked
|
||||
ORR R2, R2, #2
|
||||
STRB R2, [R0, #TCB_SP_FRAME]
|
||||
ENDIF
|
||||
IF {TARGET_FEATURE_EXTENSION_REGISTER_COUNT} == 32
|
||||
VSTMDB R3!, {D0-D15}
|
||||
VSTMDB R3!, {D16-D31}
|
||||
LDRB R2, [R0, #TCB_SP_FRAME] ; Record in TCB that NEON/D32 state is stacked
|
||||
ORR R2, R2, #4
|
||||
STRB R2, [R0, #TCB_SP_FRAME]
|
||||
ENDIF
|
||||
|
||||
osRtxContextSave1
|
||||
STR R3, [R0, #TCB_SP_OFS] ; Store user sp to osRtxInfo.thread.run.curr
|
||||
|
||||
osRtxContextRestore
|
||||
STR R1, [R12] ; Store run.next to run.curr
|
||||
LDR R3, [R1, #TCB_SP_OFS] ; Load next osRtxThread_t.sp
|
||||
LDRB R2, [R1, #TCB_SP_FRAME] ; Load next osRtxThread_t.stack_frame
|
||||
|
||||
ANDS R2, R2, #0x6 ; Check stack frame for VFP context
|
||||
MRC p15, 0, R2, c1, c0, 2 ; Read CPACR
|
||||
ANDEQ R2, R2, #0xFF0FFFFF ; Disable VFP/NEON access if incoming task does not have stacked VFP/NEON state
|
||||
ORRNE R2, R2, #0x00F00000 ; Enable VFP/NEON access if incoming task does have stacked VFP/NEON state
|
||||
MCR p15, 0, R2, c1, c0, 2 ; Write CPACR
|
||||
BEQ osRtxContextRestore1 ; No VFP
|
||||
ISB ; Only sync if we enabled VFP, otherwise we will context switch before next VFP instruction anyway
|
||||
IF {TARGET_FEATURE_EXTENSION_REGISTER_COUNT} == 32
|
||||
VLDMIA R3!, {D16-D31}
|
||||
ENDIF
|
||||
VLDMIA R3!, {D0-D15}
|
||||
LDR R2, [R3]
|
||||
VMSR FPSCR, R2
|
||||
ADD R3, R3, #8
|
||||
|
||||
osRtxContextRestore1
|
||||
LDMIA R3!, {R4-R11} ; Restore R4-R11
|
||||
MOV R12, R3 ; Move sp pointer to R12
|
||||
ADD R3, R3, #32 ; Adjust sp
|
||||
PUSH {R3} ; Push sp onto stack
|
||||
LDMIA SP, {SP}^ ; Restore SP_usr
|
||||
ADD SP, SP, #4 ; Adjust SP_svc
|
||||
LDMIA R12!, {R0-R3} ; Restore User R0-R3
|
||||
LDR LR, [R12, #12] ; Load SPSR into LR
|
||||
MSR SPSR_CXSF, LR ; Restore SPSR
|
||||
ADD R12, R12, #4 ; Adjust pointer to LR
|
||||
LDM R12, {LR}^ ; Restore LR_usr directly into LR
|
||||
LDR LR, [R12, #4] ; Restore LR
|
||||
LDR R12, [R12, #-4] ; Restore R12
|
||||
|
||||
MOVS PC, LR ; Return from exception
|
||||
|
||||
osRtxContextExit
|
||||
POP {R0-R3, R12, LR} ; Restore stacked APCS registers
|
||||
RFEFD SP! ; Return from exception
|
||||
|
||||
END
|
|
@ -27,7 +27,7 @@
|
|||
NAME irq_cm0.s
|
||||
|
||||
|
||||
I_T_RUN_OFS EQU 28 ; osRtxInfo.thread.run offset
|
||||
I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset
|
||||
TCB_SP_OFS EQU 56 ; TCB.SP offset
|
||||
|
||||
|
|
@ -27,7 +27,7 @@
|
|||
NAME irq_cm0.s
|
||||
|
||||
|
||||
I_T_RUN_OFS EQU 28 ; osRtxInfo.thread.run offset
|
||||
I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset
|
||||
TCB_SP_OFS EQU 56 ; TCB.SP offset
|
||||
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
NAME irq_armv8mbl.s
|
||||
#define __DOMAIN_NS 0
|
||||
INCLUDE irq_armv8mbl_common.s
|
||||
|
||||
END
|
|
@ -24,9 +24,11 @@
|
|||
; */
|
||||
|
||||
|
||||
NAME irq_armv8mbl.s
|
||||
#ifndef __DOMAIN_NS
|
||||
#define __DOMAIN_NS 0
|
||||
#endif
|
||||
|
||||
I_T_RUN_OFS EQU 28 ; osRtxInfo.thread.run offset
|
||||
I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset
|
||||
TCB_SM_OFS EQU 48 ; TCB.stack_mem offset
|
||||
TCB_SP_OFS EQU 56 ; TCB.SP offset
|
||||
TCB_SF_OFS EQU 34 ; TCB.stack_frame offset
|
||||
|
@ -34,21 +36,23 @@ TCB_TZM_OFS EQU 64 ; TCB.tz_memory offset
|
|||
|
||||
|
||||
PRESERVE8
|
||||
SECTION .rodata:DATA:NOROOT(2)
|
||||
|
||||
|
||||
SECTION .rodata:DATA:NOROOT(2)
|
||||
EXPORT irqRtxLib
|
||||
irqRtxLib DCB 0 ; Non weak library reference
|
||||
|
||||
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
|
||||
THUMB
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
|
||||
|
||||
SVC_Handler
|
||||
EXPORT SVC_Handler
|
||||
IMPORT osRtxUserSVC
|
||||
IMPORT osRtxInfo
|
||||
#ifdef __DOMAIN_NS
|
||||
#if (__DOMAIN_NS == 1)
|
||||
IMPORT TZ_LoadContext_S
|
||||
IMPORT TZ_StoreContext_S
|
||||
#endif
|
||||
|
@ -76,7 +80,7 @@ SVC_Context
|
|||
CBZ R1,SVC_ContextSwitch ; Branch if running thread is deleted
|
||||
|
||||
SVC_ContextSave
|
||||
#ifdef __DOMAIN_NS
|
||||
#if (__DOMAIN_NS == 1)
|
||||
LDR R0,[R1,#TCB_TZM_OFS] ; Load TrustZone memory identifier
|
||||
CBZ R0,SVC_ContextSave1 ; Branch if there is no secure context
|
||||
PUSH {R1,R2,R3,R7} ; Save registers
|
||||
|
@ -107,7 +111,7 @@ SVC_ContextSwitch
|
|||
STR R2,[R3] ; osRtxInfo.thread.run: curr = next
|
||||
|
||||
SVC_ContextRestore
|
||||
#ifdef __DOMAIN_NS
|
||||
#if (__DOMAIN_NS == 1)
|
||||
LDR R0,[R2,#TCB_TZM_OFS] ; Load TrustZone memory identifier
|
||||
CBZ R0,SVC_ContextRestore1 ; Branch if there is no secure context
|
||||
PUSH {R2,R3} ; Save registers
|
||||
|
@ -124,7 +128,7 @@ SVC_ContextRestore1
|
|||
ORRS R0,R1
|
||||
MOV LR,R0 ; Set EXC_RETURN
|
||||
|
||||
#ifdef __DOMAIN_NS
|
||||
#if (__DOMAIN_NS == 1)
|
||||
LSLS R0,R0,#25 ; Check domain of interrupted thread
|
||||
BPL SVC_ContextRestore2 ; Branch if non-secure
|
||||
LDR R0,[R2,#TCB_SP_OFS] ; Load SP
|
||||
|
@ -191,10 +195,11 @@ SysTick_Handler
|
|||
B Sys_Context
|
||||
|
||||
|
||||
|
||||
Sys_Context
|
||||
EXPORT Sys_Context
|
||||
IMPORT osRtxInfo
|
||||
#ifdef __DOMAIN_NS
|
||||
#if (__DOMAIN_NS == 1)
|
||||
IMPORT TZ_LoadContext_S
|
||||
IMPORT TZ_StoreContext_S
|
||||
#endif
|
||||
|
@ -204,9 +209,8 @@ Sys_Context
|
|||
CMP R1,R2 ; Check if thread switch is required
|
||||
BEQ Sys_ContextExit ; Branch when threads are the same
|
||||
|
||||
|
||||
Sys_ContextSave
|
||||
#ifdef __DOMAIN_NS
|
||||
#if (__DOMAIN_NS == 1)
|
||||
LDR R0,[R1,#TCB_TZM_OFS] ; Load TrustZone memory identifier
|
||||
CBZ R0,Sys_ContextSave1 ; Branch if there is no secure context
|
||||
PUSH {R1,R2,R3,R7} ; Save registers
|
||||
|
@ -242,7 +246,7 @@ Sys_ContextSwitch
|
|||
STR R2,[R3] ; osRtxInfo.run: curr = next
|
||||
|
||||
Sys_ContextRestore
|
||||
#ifdef __DOMAIN_NS
|
||||
#if (__DOMAIN_NS == 1)
|
||||
LDR R0,[R2,#TCB_TZM_OFS] ; Load TrustZone memory identifier
|
||||
CBZ R0,Sys_ContextRestore1 ; Branch if there is no secure context
|
||||
PUSH {R2,R3} ; Save registers
|
||||
|
@ -259,7 +263,7 @@ Sys_ContextRestore1
|
|||
ORRS R0,R1
|
||||
MOV LR,R0 ; Set EXC_RETURN
|
||||
|
||||
#ifdef __DOMAIN_NS
|
||||
#if (__DOMAIN_NS == 1)
|
||||
LSLS R0,R0,#25 ; Check domain of interrupted thread
|
||||
BPL Sys_ContextRestore2 ; Branch if non-secure
|
||||
LDR R0,[R2,#TCB_SP_OFS] ; Load SP
|
||||
|
@ -284,5 +288,3 @@ Sys_ContextRestore2
|
|||
|
||||
Sys_ContextExit
|
||||
BX LR ; Exit from handler
|
||||
|
||||
END
|
|
@ -0,0 +1,5 @@
|
|||
NAME irq_armv8mbl_ns.s
|
||||
#define __DOMAIN_NS 1
|
||||
INCLUDE irq_armv8mbl_common.s
|
||||
|
||||
END
|
|
@ -27,7 +27,7 @@
|
|||
NAME irq_cm3.s
|
||||
|
||||
|
||||
I_T_RUN_OFS EQU 28 ; osRtxInfo.thread.run offset
|
||||
I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset
|
||||
TCB_SP_OFS EQU 56 ; TCB.SP offset
|
||||
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
NAME irq_armv8mml.s
|
||||
#define __DOMAIN_NS 0
|
||||
INCLUDE irq_armv8mml_common.s
|
||||
END
|
||||
|
|
@ -23,9 +23,19 @@
|
|||
; * -----------------------------------------------------------------------------
|
||||
; */
|
||||
|
||||
NAME irq_armv8mml.S
|
||||
|
||||
I_T_RUN_OFS EQU 28 ; osRtxInfo.thread.run offset
|
||||
|
||||
#ifndef __DOMAIN_NS
|
||||
#define __DOMAIN_NS 0
|
||||
#endif
|
||||
|
||||
#ifdef __ARMVFP__
|
||||
__FPU_USED EQU 1
|
||||
#else
|
||||
__FPU_USED EQU 0
|
||||
#endif
|
||||
|
||||
I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset
|
||||
TCB_SM_OFS EQU 48 ; TCB.stack_mem offset
|
||||
TCB_SP_OFS EQU 56 ; TCB.SP offset
|
||||
TCB_SF_OFS EQU 34 ; TCB.stack_frame offset
|
||||
|
@ -33,20 +43,22 @@ TCB_TZM_OFS EQU 64 ; TCB.tz_memory offset
|
|||
|
||||
|
||||
PRESERVE8
|
||||
SECTION .rodata:DATA:NOROOT(2)
|
||||
|
||||
|
||||
SECTION .rodata:DATA:NOROOT(2)
|
||||
EXPORT irqRtxLib
|
||||
irqRtxLib DCB 0 ; Non weak library reference
|
||||
|
||||
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
THUMB
|
||||
SECTION .text:CODE:NOROOT(2)
|
||||
|
||||
|
||||
SVC_Handler
|
||||
EXPORT SVC_Handler
|
||||
IMPORT osRtxUserSVC
|
||||
IMPORT osRtxInfo
|
||||
#ifdef __DOMAIN_NS
|
||||
#if (__DOMAIN_NS == 1)
|
||||
IMPORT TZ_LoadContext_S
|
||||
IMPORT TZ_StoreContext_S
|
||||
#endif
|
||||
|
@ -67,9 +79,10 @@ SVC_Context
|
|||
LDR R3,=osRtxInfo+I_T_RUN_OFS; Load address of osRtxInfo.run
|
||||
LDM R3,{R1,R2} ; Load osRtxInfo.thread.run: curr & next
|
||||
CMP R1,R2 ; Check if thread switch is required
|
||||
IT EQ
|
||||
BXEQ LR ; Exit when threads are the same
|
||||
|
||||
#ifdef __FPU_USED
|
||||
#if (__FPU_USED == 1)
|
||||
CBNZ R1,SVC_ContextSave ; Branch if running thread is not deleted
|
||||
TST LR,#0x10 ; Check if extended stack frame
|
||||
BNE SVC_ContextSwitch
|
||||
|
@ -83,7 +96,7 @@ SVC_Context
|
|||
#endif
|
||||
|
||||
SVC_ContextSave
|
||||
#ifdef __DOMAIN_NS
|
||||
#if (__DOMAIN_NS == 1)
|
||||
LDR R0,[R1,#TCB_TZM_OFS] ; Load TrustZone memory identifier
|
||||
CBZ R0,SVC_ContextSave1 ; Branch if there is no secure context
|
||||
PUSH {R1,R2,R3,LR} ; Save registers and EXC_RETURN
|
||||
|
@ -94,7 +107,7 @@ SVC_ContextSave
|
|||
SVC_ContextSave1
|
||||
MRS R0,PSP ; Get PSP
|
||||
STMDB R0!,{R4-R11} ; Save R4..R11
|
||||
#ifdef __FPU_USED
|
||||
#if (__FPU_USED == 1)
|
||||
TST LR,#0x10 ; Check if extended stack frame
|
||||
VSTMDBEQ R0!,{S16-S31} ; Save VFP S16.S31
|
||||
#endif
|
||||
|
@ -107,7 +120,7 @@ SVC_ContextSwitch
|
|||
STR R2,[R3] ; osRtxInfo.thread.run: curr = next
|
||||
|
||||
SVC_ContextRestore
|
||||
#ifdef __DOMAIN_NS
|
||||
#if (__DOMAIN_NS == 1)
|
||||
LDR R0,[R2,#TCB_TZM_OFS] ; Load TrustZone memory identifier
|
||||
CBZ R0,SVC_ContextRestore1 ; Branch if there is no secure context
|
||||
PUSH {R2,R3} ; Save registers
|
||||
|
@ -122,12 +135,12 @@ SVC_ContextRestore1
|
|||
LDR R0,[R2,#TCB_SP_OFS] ; Load SP
|
||||
ORR LR,R1,#0xFFFFFF00 ; Set EXC_RETURN
|
||||
|
||||
#ifdef __DOMAIN_NS
|
||||
#if (__DOMAIN_NS == 1)
|
||||
TST LR,#0x40 ; Check domain of interrupted thread
|
||||
BNE SVC_ContextRestore2 ; Branch if secure
|
||||
#endif
|
||||
|
||||
#ifdef __FPU_USED
|
||||
#if (__FPU_USED == 1)
|
||||
TST LR,#0x10 ; Check if extended stack frame
|
||||
VLDMIAEQ R0!,{S16-S31} ; Restore VFP S16..S31
|
||||
#endif
|
||||
|
@ -177,10 +190,11 @@ SysTick_Handler
|
|||
B Sys_Context
|
||||
|
||||
|
||||
|
||||
Sys_Context
|
||||
EXPORT Sys_Context
|
||||
IMPORT osRtxInfo
|
||||
#ifdef __DOMAIN_NS
|
||||
#if (__DOMAIN_NS == 1)
|
||||
IMPORT TZ_LoadContext_S
|
||||
IMPORT TZ_StoreContext_S
|
||||
#endif
|
||||
|
@ -188,16 +202,18 @@ Sys_Context
|
|||
LDR R3,=osRtxInfo+I_T_RUN_OFS; Load address of osRtxInfo.run
|
||||
LDM R3,{R1,R2} ; Load osRtxInfo.thread.run: curr & next
|
||||
CMP R1,R2 ; Check if thread switch is required
|
||||
IT EQ
|
||||
BXEQ LR ; Exit when threads are the same
|
||||
|
||||
Sys_ContextSave
|
||||
#ifdef __DOMAIN_NS
|
||||
#if (__DOMAIN_NS == 1)
|
||||
LDR R0,[R1,#TCB_TZM_OFS] ; Load TrustZone memory identifier
|
||||
CBZ R0,Sys_ContextSave1 ; Branch if there is no secure context
|
||||
PUSH {R1,R2,R3,LR} ; Save registers and EXC_RETURN
|
||||
BL TZ_StoreContext_S ; Store secure context
|
||||
POP {R1,R2,R3,LR} ; Restore registers and EXC_RETURN
|
||||
TST LR,#0x40 ; Check domain of interrupted thread
|
||||
IT NE
|
||||
MRSNE R0,PSP ; Get PSP
|
||||
BNE Sys_ContextSave2 ; Branch if secure
|
||||
#endif
|
||||
|
@ -205,7 +221,7 @@ Sys_ContextSave
|
|||
Sys_ContextSave1
|
||||
MRS R0,PSP ; Get PSP
|
||||
STMDB R0!,{R4-R11} ; Save R4..R11
|
||||
#ifdef __FPU_USED
|
||||
#if (__FPU_USED == 1)
|
||||
TST LR,#0x10 ; Check if extended stack frame
|
||||
VSTMDBEQ R0!,{S16-S31} ; Save VFP S16.S31
|
||||
#endif
|
||||
|
@ -218,7 +234,7 @@ Sys_ContextSwitch
|
|||
STR R2,[R3] ; osRtxInfo.run: curr = next
|
||||
|
||||
Sys_ContextRestore
|
||||
#ifdef __DOMAIN_NS
|
||||
#if (__DOMAIN_NS == 1)
|
||||
LDR R0,[R2,#TCB_TZM_OFS] ; Load TrustZone memory identifier
|
||||
CBZ R0,Sys_ContextRestore1 ; Branch if there is no secure context
|
||||
PUSH {R2,R3} ; Save registers
|
||||
|
@ -233,12 +249,12 @@ Sys_ContextRestore1
|
|||
LDR R0,[R2,#TCB_SP_OFS] ; Load SP
|
||||
ORR LR,R1,#0xFFFFFF00 ; Set EXC_RETURN
|
||||
|
||||
#ifdef __DOMAIN_NS
|
||||
#if (__DOMAIN_NS == 1)
|
||||
TST LR,#0x40 ; Check domain of interrupted thread
|
||||
BNE Sys_ContextRestore2 ; Branch if secure
|
||||
#endif
|
||||
|
||||
#ifdef __FPU_USED
|
||||
#if (__FPU_USED == 1)
|
||||
TST LR,#0x10 ; Check if extended stack frame
|
||||
VLDMIAEQ R0!,{S16-S31} ; Restore VFP S16..S31
|
||||
#endif
|
||||
|
@ -249,5 +265,3 @@ Sys_ContextRestore2
|
|||
|
||||
Sys_ContextExit
|
||||
BX LR ; Exit from handler
|
||||
|
||||
END
|
|
@ -0,0 +1,5 @@
|
|||
NAME irq_armv8mml_ns.s
|
||||
#define __DOMAIN_NS 1
|
||||
INCLUDE irq_armv8mml_common.s
|
||||
END
|
||||
|
|
@ -27,7 +27,7 @@
|
|||
NAME irq_cm4f.s
|
||||
|
||||
|
||||
I_T_RUN_OFS EQU 28 ; osRtxInfo.thread.run offset
|
||||
I_T_RUN_OFS EQU 20 ; osRtxInfo.thread.run offset
|
||||
TCB_SP_OFS EQU 56 ; TCB.SP offset
|
||||
TCB_SF_OFS EQU 34 ; TCB.stack_frame offset
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (c) 2013-2017 ARM Limited. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an AS IS BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*
|
||||
* Project: CMSIS-RTOS RTX
|
||||
* Title: Cortex Core definitions
|
||||
*
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef RTX_CORE_C_H_
|
||||
#define RTX_CORE_C_H_
|
||||
|
||||
#include <cmsis.h>
|
||||
|
||||
#ifndef __ARM_ARCH_6M__
|
||||
#define __ARM_ARCH_6M__ 0U
|
||||
#endif
|
||||
#ifndef __ARM_ARCH_7A__
|
||||
#define __ARM_ARCH_7A__ 0U
|
||||
#endif
|
||||
#ifndef __ARM_ARCH_7M__
|
||||
#define __ARM_ARCH_7M__ 0U
|
||||
#endif
|
||||
#ifndef __ARM_ARCH_7EM__
|
||||
#define __ARM_ARCH_7EM__ 0U
|
||||
#endif
|
||||
#ifndef __ARM_ARCH_8M_BASE__
|
||||
#define __ARM_ARCH_8M_BASE__ 0U
|
||||
#endif
|
||||
#ifndef __ARM_ARCH_8M_MAIN__
|
||||
#define __ARM_ARCH_8M_MAIN__ 0U
|
||||
#endif
|
||||
|
||||
#if ((__ARM_ARCH_6M__ + \
|
||||
__ARM_ARCH_7A__ + \
|
||||
__ARM_ARCH_7M__ + \
|
||||
__ARM_ARCH_7EM__ + \
|
||||
__ARM_ARCH_8M_BASE__ + \
|
||||
__ARM_ARCH_8M_MAIN__) != 1U)
|
||||
#error "Unknown ARM Architecture!"
|
||||
#endif
|
||||
|
||||
#if (__ARM_ARCH_7A__ != 0U)
|
||||
#include "rtx_core_ca.h"
|
||||
#else
|
||||
#include "rtx_core_cm.h"
|
||||
#endif
|
||||
|
||||
#endif // RTX_CORE_C_H_
|
File diff suppressed because it is too large
Load Diff
|
@ -1,5 +1,3 @@
|
|||
/** \addtogroup rtos */
|
||||
/** @{*/
|
||||
/*
|
||||
* Copyright (c) 2013-2017 ARM Limited. All rights reserved.
|
||||
*
|
||||
|
@ -25,37 +23,10 @@
|
|||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
#ifndef CORE_CM_H_
|
||||
#define CORE_CM_H_
|
||||
#ifndef RTX_CORE_CM_H_
|
||||
#define RTX_CORE_CM_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "cmsis.h"
|
||||
#include "cmsis_compiler.h"
|
||||
#include "arm_math.h"
|
||||
|
||||
#ifndef __ARM_ARCH_6M__
|
||||
#define __ARM_ARCH_6M__ 0U
|
||||
#endif
|
||||
#ifndef __ARM_ARCH_7M__
|
||||
#define __ARM_ARCH_7M__ 0U
|
||||
#endif
|
||||
#ifndef __ARM_ARCH_7EM__
|
||||
#define __ARM_ARCH_7EM__ 0U
|
||||
#endif
|
||||
#ifndef __ARM_ARCH_8M_BASE__
|
||||
#define __ARM_ARCH_8M_BASE__ 0U
|
||||
#endif
|
||||
#ifndef __ARM_ARCH_8M_MAIN__
|
||||
#define __ARM_ARCH_8M_MAIN__ 0U
|
||||
#endif
|
||||
|
||||
#if ((__ARM_ARCH_6M__ + \
|
||||
__ARM_ARCH_7M__ + \
|
||||
__ARM_ARCH_7EM__ + \
|
||||
__ARM_ARCH_8M_BASE__ + \
|
||||
__ARM_ARCH_8M_MAIN__) != 1U)
|
||||
#error "Unknown ARM Architecture!"
|
||||
#endif
|
||||
#include <cmsis.h>
|
||||
|
||||
#ifdef RTE_CMSIS_RTOS2_RTX5_ARMV8M_NS
|
||||
#define __DOMAIN_NS 1U
|
||||
|
@ -81,7 +52,6 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#define IS_PRIVILEGED() ((__get_CONTROL() & 1U) == 0U)
|
||||
|
||||
#define IS_IRQ_MODE() (__get_IPSR() != 0U)
|
||||
|
@ -94,7 +64,7 @@
|
|||
#define IS_IRQ_MASKED() (__get_PRIMASK() != 0U)
|
||||
#endif
|
||||
|
||||
#define XPSR_INITIAL_VALUE 0x01000000U
|
||||
#define xPSR_INIT(...) 0x01000000U
|
||||
|
||||
#if (__DOMAIN_NS == 1U)
|
||||
#define STACK_FRAME_INIT 0xBCU
|
||||
|
@ -102,7 +72,18 @@
|
|||
#define STACK_FRAME_INIT 0xFDU
|
||||
#endif
|
||||
|
||||
#define IS_EXTENDED_STACK_FRAME(n) (((n) & 0x10U) == 0U)
|
||||
// Stack Frame:
|
||||
// - Extended: S16-S31, R4-R11, R0-R3, R12, LR, PC, xPSR, S0-S15, FPSCR
|
||||
// - Basic: R4-R11, R0-R3, R12, LR, PC, xPSR
|
||||
#if (__FPU_USED == 1U)
|
||||
#define STACK_OFFSET_R0(stack_frame) \
|
||||
((((stack_frame) & 0x10U) == 0U) ? ((16U+8U)*4U) : \
|
||||
(8U *4U))
|
||||
#else
|
||||
#define STACK_OFFSET_R0(stack_frame) (8U *4U)
|
||||
#endif
|
||||
|
||||
#define OS_TICK_HANDLER SysTick_Handler
|
||||
|
||||
|
||||
// ==== Service Calls definitions ====
|
||||
|
@ -157,8 +138,6 @@ __STATIC_INLINE t __svc##f (void) { \
|
|||
return svc##f(svcRtx##f); \
|
||||
}
|
||||
|
||||
#define SVC0_0D SVC0_0
|
||||
|
||||
#define SVC0_1N(f,t,t1) \
|
||||
__SVC_INDIRECT(0) t svc##f (t(*)(t1),t1); \
|
||||
t svcRtx##f (t1 a1); \
|
||||
|
@ -299,8 +278,6 @@ __STATIC_INLINE t __svc##f (void) { \
|
|||
return svc##f(); \
|
||||
}
|
||||
|
||||
#define SVC0_0D SVC0_0
|
||||
|
||||
#define SVC0_1N(f,t,t1) \
|
||||
__SVC_INDIRECT(0) t svc##f (t1 a1); \
|
||||
t svcRtx##f (t1 a1); \
|
||||
|
@ -504,16 +481,6 @@ __STATIC_INLINE t __svc##f (void) { \
|
|||
return (t) __r0; \
|
||||
}
|
||||
|
||||
#define SVC0_0D(f,t) \
|
||||
__attribute__((always_inline)) \
|
||||
__STATIC_INLINE t __svc##f (void) { \
|
||||
SVC_ArgN(0); \
|
||||
SVC_ArgN(1); \
|
||||
SVC_ArgF(svcRtx##f); \
|
||||
SVC_Call0(SVC_In0, SVC_Out2, SVC_CL0); \
|
||||
return (((t) __r0) | (((t) __r1) << 32)); \
|
||||
}
|
||||
|
||||
#define SVC0_1N(f,t,t1) \
|
||||
__attribute__((always_inline)) \
|
||||
__STATIC_INLINE t __svc##f (t1 a1) { \
|
||||
|
@ -611,9 +578,6 @@ __STATIC_INLINE t __svc##f (t1 a1, t2 a2, t3 a3, t4 a4) { \
|
|||
|
||||
// ==== Core Peripherals functions ====
|
||||
|
||||
extern uint32_t SystemCoreClock; // System Clock Frequency (Core Clock)
|
||||
|
||||
|
||||
/// Initialize SVC and PendSV System Service Calls
|
||||
__STATIC_INLINE void SVC_Initialize (void) {
|
||||
#if ((__ARM_ARCH_8M_MAIN__ == 1U) || (defined(__CORTEX_M) && (__CORTEX_M == 7U)))
|
||||
|
@ -627,8 +591,11 @@ __STATIC_INLINE void SVC_Initialize (void) {
|
|||
}
|
||||
SCB->SHPR[7] = (uint8_t)(0xFEU << n);
|
||||
#elif (__ARM_ARCH_8M_BASE__ == 1U)
|
||||
uint32_t n;
|
||||
|
||||
SCB->SHPR[1] |= 0x00FF0000U;
|
||||
SCB->SHPR[0] |= (SCB->SHPR[1] << (8+1)) & 0xFC000000U;
|
||||
n = SCB->SHPR[1];
|
||||
SCB->SHPR[0] |= (n << (8+1)) & 0xFC000000U;
|
||||
#elif ((__ARM_ARCH_7M__ == 1U) || \
|
||||
(__ARM_ARCH_7EM__ == 1U))
|
||||
uint32_t p, n;
|
||||
|
@ -640,110 +607,25 @@ __STATIC_INLINE void SVC_Initialize (void) {
|
|||
n = p + 1U;
|
||||
}
|
||||
|
||||
/* Only change the SVCall priority if uVisor is not present. */
|
||||
#if !(defined(FEATURE_UVISOR) && defined(TARGET_UVISOR_SUPPORTED))
|
||||
/* Only change the SVCall priority if uVisor is not present. */
|
||||
#if !(defined(FEATURE_UVISOR) && defined(TARGET_UVISOR_SUPPORTED))
|
||||
SCB->SHP[7] = (uint8_t)(0xFEU << n);
|
||||
#endif
|
||||
#endif
|
||||
#elif (__ARM_ARCH_6M__ == 1U)
|
||||
uint32_t n;
|
||||
|
||||
SCB->SHP[1] |= 0x00FF0000U;
|
||||
SCB->SHP[0] |= (SCB->SHP[1] << (8+1)) & 0xFC000000U;
|
||||
n = SCB->SHP[1];
|
||||
SCB->SHP[0] |= (n << (8+1)) & 0xFC000000U;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Setup SysTick Timer
|
||||
/// \param[in] period Timer Load value
|
||||
__STATIC_INLINE void SysTick_Setup (uint32_t period) {
|
||||
SysTick->LOAD = period - 1U;
|
||||
SysTick->VAL = 0U;
|
||||
#if ((__ARM_ARCH_8M_MAIN__ == 1U) || (defined(__CORTEX_M) && (__CORTEX_M == 7U)))
|
||||
SCB->SHPR[11] = 0xFFU;
|
||||
#elif (__ARM_ARCH_8M_BASE__ == 1U)
|
||||
SCB->SHPR[1] |= 0xFF000000U;
|
||||
#elif ((__ARM_ARCH_7M__ == 1U) || \
|
||||
(__ARM_ARCH_7EM__ == 1U))
|
||||
SCB->SHP[11] = 0xFFU;
|
||||
#elif (__ARM_ARCH_6M__ == 1U)
|
||||
SCB->SHP[1] |= 0xFF000000U;
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Get SysTick Period
|
||||
/// \return SysTick Period
|
||||
__STATIC_INLINE uint32_t SysTick_GetPeriod (void) {
|
||||
return (SysTick->LOAD + 1U);
|
||||
}
|
||||
|
||||
/// Get SysTick Value
|
||||
/// \return SysTick Value
|
||||
__STATIC_INLINE uint32_t SysTick_GetVal (void) {
|
||||
uint32_t load = SysTick->LOAD;
|
||||
return (load - SysTick->VAL);
|
||||
}
|
||||
|
||||
/// Get SysTick Overflow (Auto Clear)
|
||||
/// \return SysTick Overflow flag
|
||||
__STATIC_INLINE uint32_t SysTick_GetOvf (void) {
|
||||
return ((SysTick->CTRL >> 16) & 1U);
|
||||
}
|
||||
|
||||
/// Enable SysTick Timer
|
||||
__STATIC_INLINE void SysTick_Enable (void) {
|
||||
SysTick->CTRL = SysTick_CTRL_ENABLE_Msk |
|
||||
SysTick_CTRL_TICKINT_Msk |
|
||||
SysTick_CTRL_CLKSOURCE_Msk;
|
||||
}
|
||||
|
||||
/// Disable SysTick Timer
|
||||
__STATIC_INLINE void SysTick_Disable (void) {
|
||||
SysTick->CTRL = 0U;
|
||||
}
|
||||
|
||||
/// Setup External Tick Timer Interrupt
|
||||
/// \param[in] irqn Interrupt number
|
||||
__STATIC_INLINE void ExtTick_SetupIRQ (int32_t irqn) {
|
||||
#if (__ARM_ARCH_8M_MAIN__ == 1U)
|
||||
NVIC->IPR[irqn] = 0xFFU;
|
||||
#elif (__ARM_ARCH_8M_BASE__ == 1U)
|
||||
NVIC->IPR[irqn >> 2] = (NVIC->IPR[irqn >> 2] & ~(0xFFU << ((irqn & 3) << 3))) |
|
||||
(0xFFU << ((irqn & 3) << 3));
|
||||
#elif ((__ARM_ARCH_7M__ == 1U) || \
|
||||
(__ARM_ARCH_7EM__ == 1U))
|
||||
NVIC->IP[irqn] = 0xFFU;
|
||||
#elif (__ARM_ARCH_6M__ == 1U)
|
||||
NVIC->IP[irqn >> 2] = (NVIC->IP[irqn >> 2] & ~(0xFFU << ((irqn & 3) << 3))) |
|
||||
(0xFFU << ((irqn & 3) << 3));
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Enable External Tick Timer Interrupt
|
||||
/// \param[in] irqn Interrupt number
|
||||
__STATIC_INLINE void ExtTick_EnableIRQ (int32_t irqn) {
|
||||
NVIC->ISER[irqn >> 5] = 1U << (irqn & 0x1F);
|
||||
}
|
||||
|
||||
/// Disable External Tick Timer Interrupt
|
||||
/// \param[in] irqn Interrupt number
|
||||
__STATIC_INLINE void ExtTick_DisableIRQ (int32_t irqn) {
|
||||
NVIC->ICER[irqn >> 5] = 1U << (irqn & 0x1F);
|
||||
}
|
||||
|
||||
/// Get Pending SV (Service Call) and ST (SysTick) Flags
|
||||
/// \return Pending SV&ST Flags
|
||||
__STATIC_INLINE uint8_t GetPendSV_ST (void) {
|
||||
return ((uint8_t)((SCB->ICSR & (SCB_ICSR_PENDSVSET_Msk | SCB_ICSR_PENDSTSET_Msk)) >> 24));
|
||||
}
|
||||
|
||||
/// Get Pending SV (Service Call) Flag
|
||||
/// \return Pending SV Flag
|
||||
__STATIC_INLINE uint8_t GetPendSV (void) {
|
||||
return ((uint8_t)((SCB->ICSR & (SCB_ICSR_PENDSVSET_Msk)) >> 24));
|
||||
}
|
||||
|
||||
/// Clear Pending SV (Service Call) and ST (SysTick) Flags
|
||||
__STATIC_INLINE void ClrPendSV_ST (void) {
|
||||
SCB->ICSR = SCB_ICSR_PENDSVCLR_Msk | SCB_ICSR_PENDSTCLR_Msk;
|
||||
}
|
||||
|
||||
/// Clear Pending SV (Service Call) Flag
|
||||
__STATIC_INLINE void ClrPendSV (void) {
|
||||
SCB->ICSR = SCB_ICSR_PENDSVCLR_Msk;
|
||||
|
@ -754,12 +636,6 @@ __STATIC_INLINE void SetPendSV (void) {
|
|||
SCB->ICSR = SCB_ICSR_PENDSVSET_Msk;
|
||||
}
|
||||
|
||||
/// Set Pending Flags
|
||||
/// \param[in] flags Flags to set
|
||||
__STATIC_INLINE void SetPendFlags (uint8_t flags) {
|
||||
SCB->ICSR = ((uint32_t)flags << 24);
|
||||
}
|
||||
|
||||
|
||||
// ==== Exclusive Access Operation ====
|
||||
|
||||
|
@ -1529,6 +1405,4 @@ __STATIC_INLINE void atomic_link_put (void **root, void *link) {
|
|||
#endif // (__EXCLUSIVE_ACCESS == 1U)
|
||||
|
||||
|
||||
#endif // CORE_CM_H_
|
||||
|
||||
/** @}*/
|
||||
#endif // RTX_CORE_CM_H_
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
// Service Calls definitions
|
||||
SVC0_1(Delay, osStatus_t, uint32_t)
|
||||
SVC0_2(DelayUntil, osStatus_t, uint32_t, uint32_t)
|
||||
SVC0_1(DelayUntil, osStatus_t, uint32_t)
|
||||
|
||||
/// Wait for Timeout (Time Delay).
|
||||
/// \note API identical to osDelay
|
||||
|
@ -47,11 +47,10 @@ osStatus_t svcRtxDelay (uint32_t ticks) {
|
|||
|
||||
/// Wait until specified time.
|
||||
/// \note API identical to osDelayUntil
|
||||
osStatus_t svcRtxDelayUntil (uint32_t ticks_l, uint32_t ticks_h) {
|
||||
uint64_t ticks = ((uint64_t)ticks_l) | ((uint64_t)ticks_h << 32);
|
||||
osStatus_t svcRtxDelayUntil (uint32_t ticks) {
|
||||
|
||||
ticks -= osRtxInfo.kernel.tick;
|
||||
if (ticks >= 0xFFFFFFFFU) {
|
||||
if (ticks == 0xFFFFFFFFU) {
|
||||
EvrRtxThreadError(NULL, osErrorParameter);
|
||||
return osErrorParameter;
|
||||
}
|
||||
|
@ -59,7 +58,7 @@ osStatus_t svcRtxDelayUntil (uint32_t ticks_l, uint32_t ticks_h) {
|
|||
return osOK;
|
||||
}
|
||||
|
||||
osRtxThreadWaitEnter(osRtxThreadWaitingDelay, (uint32_t)ticks);
|
||||
osRtxThreadWaitEnter(osRtxThreadWaitingDelay, ticks);
|
||||
|
||||
return osOK;
|
||||
}
|
||||
|
@ -78,11 +77,11 @@ osStatus_t osDelay (uint32_t ticks) {
|
|||
}
|
||||
|
||||
/// Wait until specified time.
|
||||
osStatus_t osDelayUntil (uint64_t ticks) {
|
||||
osStatus_t osDelayUntil (uint32_t ticks) {
|
||||
EvrRtxThreadDelayUntil(ticks);
|
||||
if (IS_IRQ_MODE() || IS_IRQ_MASKED()) {
|
||||
EvrRtxThreadError(NULL, osErrorISR);
|
||||
return osErrorISR;
|
||||
}
|
||||
return __svcDelayUntil((uint32_t)ticks, (uint32_t)(ticks >> 32));
|
||||
return __svcDelayUntil(ticks);
|
||||
}
|
|
@ -501,9 +501,9 @@ __WEAK void EvrRtxKernelResumed (void) {
|
|||
#endif
|
||||
|
||||
#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_KERNEL != 0) && !defined(EVR_RTX_KERNEL_GET_TICK_COUNT_DISABLE))
|
||||
__WEAK void EvrRtxKernelGetTickCount (uint64_t count) {
|
||||
__WEAK void EvrRtxKernelGetTickCount (uint32_t count) {
|
||||
#if defined(RTE_Compiler_EventRecorder)
|
||||
EventRecord2(EvtRtxKernelGetTickCount, (uint32_t)count, (uint32_t)(count>>32));
|
||||
EventRecord2(EvtRtxKernelGetTickCount, count, 0U);
|
||||
#else
|
||||
(void)count;
|
||||
#endif
|
||||
|
@ -958,9 +958,9 @@ __WEAK void EvrRtxThreadDelay (uint32_t ticks) {
|
|||
#endif
|
||||
|
||||
#if (!defined(EVR_RTX_DISABLE) && (OS_EVR_THREAD != 0) && !defined(EVR_RTX_THREAD_DELAY_UNTIL_DISABLE))
|
||||
__WEAK void EvrRtxThreadDelayUntil (uint64_t ticks) {
|
||||
__WEAK void EvrRtxThreadDelayUntil (uint32_t ticks) {
|
||||
#if defined(RTE_Compiler_EventRecorder)
|
||||
EventRecord2(EvtRtxThreadDelayUntil, (uint32_t)ticks, (uint32_t)(ticks >> 32));
|
||||
EventRecord2(EvtRtxThreadDelayUntil, ticks, 0U);
|
||||
#else
|
||||
(void)ticks;
|
||||
#endif
|
|
@ -37,18 +37,14 @@ osRtxInfo_t osRtxInfo __attribute__((section(".data.os"))) =
|
|||
/// Block Kernel (disable: thread switching, time tick, post ISR processing).
|
||||
static void KernelBlock (void) {
|
||||
|
||||
if (osRtxInfo.tick_irqn >= 0) {
|
||||
ExtTick_DisableIRQ(osRtxInfo.tick_irqn);
|
||||
}
|
||||
osRtxSysTimerDisable();
|
||||
OS_Tick_Disable();
|
||||
|
||||
osRtxInfo.kernel.blocked = 1U;
|
||||
__DSB();
|
||||
if (osRtxInfo.tick_irqn < 0) {
|
||||
osRtxInfo.kernel.pendISR = GetPendSV_ST();
|
||||
ClrPendSV_ST();
|
||||
} else {
|
||||
osRtxInfo.kernel.pendISR = GetPendSV();
|
||||
|
||||
if (GetPendSV() != 0U) {
|
||||
ClrPendSV();
|
||||
osRtxInfo.kernel.pendSV = 1U;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,17 +53,13 @@ static void KernelUnblock (void) {
|
|||
|
||||
osRtxInfo.kernel.blocked = 0U;
|
||||
__DSB();
|
||||
|
||||
if (osRtxInfo.kernel.pendSV != 0U) {
|
||||
osRtxInfo.kernel.pendSV = 0U;
|
||||
SetPendSV();
|
||||
}
|
||||
if (osRtxInfo.kernel.pendISR != 0U) {
|
||||
SetPendFlags(osRtxInfo.kernel.pendISR);
|
||||
}
|
||||
if (osRtxInfo.tick_irqn >= 0) {
|
||||
ExtTick_EnableIRQ(osRtxInfo.tick_irqn);
|
||||
}
|
||||
osRtxSysTimerEnable();
|
||||
|
||||
OS_Tick_Enable();
|
||||
}
|
||||
|
||||
|
||||
|
@ -83,7 +75,7 @@ SVC0_1 (KernelRestoreLock, int32_t, int32_t)
|
|||
SVC0_0 (KernelSuspend, uint32_t)
|
||||
SVC0_1N(KernelResume, void, uint32_t)
|
||||
SVC0_0 (KernelGetState, osKernelState_t)
|
||||
SVC0_0D(KernelGetTickCount, uint64_t)
|
||||
SVC0_0 (KernelGetTickCount, uint32_t)
|
||||
SVC0_0 (KernelGetTickFreq, uint32_t)
|
||||
SVC0_0 (KernelGetSysTimerCount, uint32_t)
|
||||
SVC0_0 (KernelGetSysTimerFreq, uint32_t)
|
||||
|
@ -272,6 +264,17 @@ osStatus_t svcRtxKernelStart (void) {
|
|||
}
|
||||
}
|
||||
|
||||
// Setup RTOS Tick
|
||||
if (OS_Tick_Setup(osRtxConfig.tick_freq, OS_TICK_HANDLER) != 0U) {
|
||||
return osError;
|
||||
}
|
||||
osRtxInfo.tick_irqn = OS_Tick_GetIRQn();
|
||||
|
||||
// Enable RTOS Tick
|
||||
if (OS_Tick_Enable() != 0U) {
|
||||
return osError;
|
||||
}
|
||||
|
||||
// Switch to Ready Thread with highest Priority
|
||||
thread = osRtxThreadListGet(&osRtxInfo.thread.ready);
|
||||
if (thread == NULL) {
|
||||
|
@ -288,16 +291,6 @@ osStatus_t svcRtxKernelStart (void) {
|
|||
__set_CONTROL(0x03U);
|
||||
}
|
||||
|
||||
osRtxInfo.kernel.sys_freq = SystemCoreClock;
|
||||
|
||||
// Setup and Enable System Timer
|
||||
osRtxInfo.tick_irqn = osRtxSysTimerSetup();
|
||||
if (osRtxInfo.tick_irqn >= 0) {
|
||||
ExtTick_SetupIRQ (osRtxInfo.tick_irqn);
|
||||
ExtTick_EnableIRQ(osRtxInfo.tick_irqn);
|
||||
}
|
||||
osRtxSysTimerEnable();
|
||||
|
||||
osRtxInfo.kernel.state = osRtxKernelRunning;
|
||||
|
||||
EvrRtxKernelStarted();
|
||||
|
@ -467,7 +460,7 @@ void svcRtxKernelResume (uint32_t sleep_ticks) {
|
|||
|
||||
/// Get the RTOS kernel tick count.
|
||||
/// \note API identical to osKernelGetTickCount
|
||||
uint64_t svcRtxKernelGetTickCount (void) {
|
||||
uint32_t svcRtxKernelGetTickCount (void) {
|
||||
EvrRtxKernelGetTickCount(osRtxInfo.kernel.tick);
|
||||
return osRtxInfo.kernel.tick;
|
||||
}
|
||||
|
@ -482,7 +475,16 @@ uint32_t svcRtxKernelGetTickFreq (void) {
|
|||
/// Get the RTOS kernel system timer count.
|
||||
/// \note API identical to osKernelGetSysTimerCount
|
||||
uint32_t svcRtxKernelGetSysTimerCount (void) {
|
||||
uint32_t count = osRtxSysTimerGetCount();
|
||||
uint32_t tick;
|
||||
uint32_t count;
|
||||
|
||||
tick = (uint32_t)osRtxInfo.kernel.tick;
|
||||
count = OS_Tick_GetCount();
|
||||
if (OS_Tick_GetOverflow()) {
|
||||
count = OS_Tick_GetCount();
|
||||
tick++;
|
||||
}
|
||||
count += tick * OS_Tick_GetInterval();
|
||||
EvrRtxKernelGetSysTimerCount(count);
|
||||
return count;
|
||||
}
|
||||
|
@ -490,7 +492,7 @@ uint32_t svcRtxKernelGetSysTimerCount (void) {
|
|||
/// Get the RTOS kernel system timer frequency.
|
||||
/// \note API identical to osKernelGetSysTimerFreq
|
||||
uint32_t svcRtxKernelGetSysTimerFreq (void) {
|
||||
uint32_t freq = osRtxSysTimerGetFreq();
|
||||
uint32_t freq = OS_Tick_GetClock();
|
||||
EvrRtxKernelGetSysTimerFreq(freq);
|
||||
return freq;
|
||||
}
|
||||
|
@ -605,7 +607,7 @@ void osKernelResume (uint32_t sleep_ticks) {
|
|||
}
|
||||
|
||||
/// Get the RTOS kernel tick count.
|
||||
uint64_t osKernelGetTickCount (void) {
|
||||
uint32_t osKernelGetTickCount (void) {
|
||||
if (IS_IRQ_MODE() || IS_IRQ_MASKED()) {
|
||||
return svcRtxKernelGetTickCount();
|
||||
} else {
|
|
@ -609,33 +609,27 @@ __WEAK int _mutex_initialize(mutex *m) {
|
|||
}
|
||||
|
||||
// Acquire mutex
|
||||
#if !defined(__ARMCC_VERSION) || __ARMCC_VERSION < 6010050
|
||||
__USED
|
||||
#endif
|
||||
void _mutex_acquire(mutex *m);
|
||||
__WEAK void _mutex_acquire(mutex *m) {
|
||||
void _mutex_acquire(mutex *m) {
|
||||
if (os_kernel_is_active()) {
|
||||
osMutexAcquire(*m, osWaitForever);
|
||||
}
|
||||
}
|
||||
|
||||
// Release mutex
|
||||
#if !defined(__ARMCC_VERSION) || __ARMCC_VERSION < 6010050
|
||||
__USED
|
||||
#endif
|
||||
void _mutex_release(mutex *m);
|
||||
__WEAK void _mutex_release(mutex *m) {
|
||||
void _mutex_release(mutex *m) {
|
||||
if (os_kernel_is_active()) {
|
||||
osMutexRelease(*m);
|
||||
}
|
||||
}
|
||||
|
||||
// Free mutex
|
||||
#if !defined(__ARMCC_VERSION) || __ARMCC_VERSION < 6010050
|
||||
__USED
|
||||
#endif
|
||||
void _mutex_free(mutex *m);
|
||||
__WEAK void _mutex_free(mutex *m) {
|
||||
void _mutex_free(mutex *m) {
|
||||
osMutexDelete(*m);
|
||||
}
|
||||
|
|
@ -1,5 +1,3 @@
|
|||
/** \addtogroup rtos */
|
||||
/** @{*/
|
||||
/*
|
||||
* Copyright (c) 2013-2017 ARM Limited. All rights reserved.
|
||||
*
|
||||
|
@ -30,8 +28,11 @@
|
|||
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include "core_cm.h" // Cortex-M definitions
|
||||
#include "rtx_core_c.h" // Cortex core definitions
|
||||
#if ((__ARM_ARCH_8M_BASE__ != 0) || (__ARM_ARCH_8M_MAIN__ != 0))
|
||||
#include "tz_context.h" // TrustZone Context API
|
||||
#endif
|
||||
#include "os_tick.h"
|
||||
#include "cmsis_os2.h" // CMSIS RTOS API
|
||||
#include "rtx_os.h" // RTX OS definitions
|
||||
#include "rtx_evr.h" // RTX Event Recorder definitions
|
||||
|
@ -124,7 +125,7 @@ extern int32_t svcRtxKernelUnlock (void);
|
|||
extern int32_t svcRtxKernelRestoreLock (int32_t lock);
|
||||
extern uint32_t svcRtxKernelSuspend (void);
|
||||
extern void svcRtxKernelResume (uint32_t sleep_ticks);
|
||||
extern uint64_t svcRtxKernelGetTickCount (void);
|
||||
extern uint32_t svcRtxKernelGetTickCount (void);
|
||||
extern uint32_t svcRtxKernelGetTickFreq (void);
|
||||
extern uint32_t svcRtxKernelGetSysTimerCount (void);
|
||||
extern uint32_t svcRtxKernelGetSysTimerFreq (void);
|
||||
|
@ -154,7 +155,7 @@ extern uint32_t svcRtxThreadFlagsWait (uint32_t flags, uint32_t optio
|
|||
|
||||
// Delay Service Calls
|
||||
extern osStatus_t svcRtxDelay (uint32_t ticks);
|
||||
extern osStatus_t svcRtxDelayUntil (uint32_t ticks_l, uint32_t ticks_h);
|
||||
extern osStatus_t svcRtxDelayUntil (uint32_t ticks);
|
||||
|
||||
// Timer Service Calls
|
||||
extern osTimerId_t svcRtxTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr);
|
||||
|
@ -212,5 +213,5 @@ extern uint32_t svcRtxMessageQueueGetSpace (osMessageQueueId_t mq_i
|
|||
extern osStatus_t svcRtxMessageQueueReset (osMessageQueueId_t mq_id);
|
||||
extern osStatus_t svcRtxMessageQueueDelete (osMessageQueueId_t mq_id);
|
||||
|
||||
|
||||
#endif // RTX_LIB_H_
|
||||
/** @}*/
|
|
@ -252,8 +252,7 @@ osMessageQueueId_t svcRtxMessageQueueNew (uint32_t msg_count, uint32_t msg_size,
|
|||
EvrRtxMessageQueueError(NULL, osErrorParameter);
|
||||
return NULL;
|
||||
}
|
||||
msg_size = (msg_size + 3U) & ~3UL;
|
||||
block_size = msg_size + sizeof(os_message_t);
|
||||
block_size = ((msg_size + 3U) & ~3UL) + sizeof(os_message_t);
|
||||
if ((__CLZ(msg_count) + __CLZ(block_size)) < 32) {
|
||||
EvrRtxMessageQueueError(NULL, osErrorParameter);
|
||||
return NULL;
|
|
@ -161,10 +161,10 @@ const char *svcRtxMutexGetName (osMutexId_t mutex_id) {
|
|||
/// \note API identical to osMutexAcquire
|
||||
osStatus_t svcRtxMutexAcquire (osMutexId_t mutex_id, uint32_t timeout) {
|
||||
os_mutex_t *mutex = (os_mutex_t *)mutex_id;
|
||||
os_thread_t *running_thread;
|
||||
os_thread_t *runnig_thread;
|
||||
|
||||
running_thread = osRtxThreadGetRunning();
|
||||
if (running_thread == NULL) {
|
||||
runnig_thread = osRtxThreadGetRunning();
|
||||
if (runnig_thread == NULL) {
|
||||
EvrRtxMutexError(mutex, osRtxErrorKernelNotRunning);
|
||||
return osError;
|
||||
}
|
||||
|
@ -184,20 +184,20 @@ osStatus_t svcRtxMutexAcquire (osMutexId_t mutex_id, uint32_t timeout) {
|
|||
// Check if Mutex is not locked
|
||||
if (mutex->lock == 0U) {
|
||||
// Acquire Mutex
|
||||
mutex->owner_thread = running_thread;
|
||||
mutex->owner_next = running_thread->mutex_list;
|
||||
mutex->owner_thread = runnig_thread;
|
||||
mutex->owner_next = runnig_thread->mutex_list;
|
||||
mutex->owner_prev = NULL;
|
||||
if (running_thread->mutex_list != NULL) {
|
||||
running_thread->mutex_list->owner_prev = mutex;
|
||||
if (runnig_thread->mutex_list != NULL) {
|
||||
runnig_thread->mutex_list->owner_prev = mutex;
|
||||
}
|
||||
running_thread->mutex_list = mutex;
|
||||
runnig_thread->mutex_list = mutex;
|
||||
mutex->lock = 1U;
|
||||
EvrRtxMutexAcquired(mutex, mutex->lock);
|
||||
return osOK;
|
||||
}
|
||||
|
||||
// Check if Mutex is recursive and running Thread is the owner
|
||||
if ((mutex->attr & osMutexRecursive) && (mutex->owner_thread == running_thread)) {
|
||||
if ((mutex->attr & osMutexRecursive) && (mutex->owner_thread == runnig_thread)) {
|
||||
// Increment lock counter
|
||||
if (mutex->lock == osRtxMutexLockLimit) {
|
||||
EvrRtxMutexError(mutex, osRtxErrorMutexLockLimit);
|
||||
|
@ -213,14 +213,14 @@ osStatus_t svcRtxMutexAcquire (osMutexId_t mutex_id, uint32_t timeout) {
|
|||
// Check if Priority inheritance protocol is enabled
|
||||
if (mutex->attr & osMutexPrioInherit) {
|
||||
// Raise priority of owner Thread if lower than priority of running Thread
|
||||
if (mutex->owner_thread->priority < running_thread->priority) {
|
||||
mutex->owner_thread->priority = running_thread->priority;
|
||||
if (mutex->owner_thread->priority < runnig_thread->priority) {
|
||||
mutex->owner_thread->priority = runnig_thread->priority;
|
||||
osRtxThreadListSort(mutex->owner_thread);
|
||||
}
|
||||
}
|
||||
EvrRtxMutexAcquirePending(mutex, timeout);
|
||||
// Suspend current Thread
|
||||
osRtxThreadListPut((os_object_t*)mutex, running_thread);
|
||||
osRtxThreadListPut((os_object_t*)mutex, runnig_thread);
|
||||
osRtxThreadWaitEnter(osRtxThreadWaitingMutex, timeout);
|
||||
return osErrorTimeout;
|
||||
}
|
||||
|
@ -237,11 +237,11 @@ osStatus_t svcRtxMutexRelease (osMutexId_t mutex_id) {
|
|||
os_mutex_t *mutex = (os_mutex_t *)mutex_id;
|
||||
os_mutex_t *mutex0;
|
||||
os_thread_t *thread;
|
||||
os_thread_t *running_thread;
|
||||
os_thread_t *runnig_thread;
|
||||
int8_t priority;
|
||||
|
||||
running_thread = osRtxThreadGetRunning();
|
||||
if (running_thread == NULL) {
|
||||
runnig_thread = osRtxThreadGetRunning();
|
||||
if (runnig_thread == NULL) {
|
||||
EvrRtxMutexError(mutex, osRtxErrorKernelNotRunning);
|
||||
return osError;
|
||||
}
|
||||
|
@ -259,7 +259,7 @@ osStatus_t svcRtxMutexRelease (osMutexId_t mutex_id) {
|
|||
}
|
||||
|
||||
// Check if running Thread is not the owner
|
||||
if (mutex->owner_thread != running_thread) {
|
||||
if (mutex->owner_thread != runnig_thread) {
|
||||
EvrRtxMutexError(mutex, osRtxErrorMutexNotOwned);
|
||||
return osErrorResource;
|
||||
}
|
||||
|
@ -286,13 +286,13 @@ osStatus_t svcRtxMutexRelease (osMutexId_t mutex_id) {
|
|||
if (mutex->owner_prev != NULL) {
|
||||
mutex->owner_prev->owner_next = mutex->owner_next;
|
||||
} else {
|
||||
running_thread->mutex_list = mutex->owner_next;
|
||||
runnig_thread->mutex_list = mutex->owner_next;
|
||||
}
|
||||
|
||||
// Restore running Thread priority
|
||||
if (mutex->attr & osMutexPrioInherit) {
|
||||
priority = running_thread->priority_base;
|
||||
mutex0 = running_thread->mutex_list;
|
||||
priority = runnig_thread->priority_base;
|
||||
mutex0 = runnig_thread->mutex_list;
|
||||
while (mutex0) {
|
||||
// Mutexes owned by running Thread
|
||||
if ((mutex0->thread_list != NULL) && (mutex0->thread_list->priority > priority)) {
|
||||
|
@ -301,7 +301,7 @@ osStatus_t svcRtxMutexRelease (osMutexId_t mutex_id) {
|
|||
}
|
||||
mutex0 = mutex0->owner_next;
|
||||
}
|
||||
running_thread->priority = priority;
|
||||
runnig_thread->priority = priority;
|
||||
}
|
||||
|
||||
// Check if Thread is waiting for a Mutex
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue