Merge pull request #5342 from ARMmbed/feature_cortex_a

Update CMSIS/RTX with Cortex-A support
pull/5497/merge
Martin Kojtal 2017-11-15 11:24:36 +00:00 committed by GitHub
commit 41eb565d9c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
118 changed files with 8919 additions and 6281 deletions

View File

@ -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>

View File

@ -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 */

View File

@ -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 */

View File

@ -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
*/

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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_

View File

@ -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

View File

@ -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
*/

View File

@ -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)) ) */

View File

@ -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)) ) */

View File

@ -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

View File

@ -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)) ) */

View File

@ -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__ */

View File

@ -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

View File

@ -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 #################################### */
/**

View File

@ -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 #################################### */
/**

View File

@ -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 */

View File

@ -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 #################################### */
/**

View File

@ -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 #################################### */
/**

View File

@ -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 #################################### */
/**

View File

@ -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 #################################### */
/**

View File

@ -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 #################################### */
/**

View File

@ -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 #################################### */
/**

View File

@ -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 */

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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
*---------------------------------------------------------------------------*/

View 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
*---------------------------------------------------------------------------*/

View 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
*/

View File

@ -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)

View File

@ -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;
}

View File

@ -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;

View File

@ -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), \

View File

@ -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_
/** @}*/

View File

@ -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 */

View File

@ -24,7 +24,7 @@
*
* -----------------------------------------------------------------------------
*/
#include "cmsis_compiler.h"
#include "rtx_os.h"

View File

@ -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_
/** @}*/

View File

@ -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);
}

View File

@ -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_
/** @}*/

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,3 @@
__DOMAIN_NS EQU 1
INCLUDE irq_armv8mbl.s
END

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,3 @@
__DOMAIN_NS EQU 1
INCLUDE irq_armv8mml.s
END

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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"

View File

@ -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

View File

@ -0,0 +1,3 @@
.equ __DOMAIN_NS, 1
.include "../Source/GCC/irq_armv8mbl.S"
.end

View File

@ -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"

View File

@ -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:

View File

@ -0,0 +1,3 @@
.equ __FPU_USED, 1
.include "../Source/GCC/irq_armv8mml.S"
.end

View File

@ -0,0 +1,4 @@
.equ __FPU_USED, 1
.equ __DOMAIN_NS, 1
.include "../Source/GCC/irq_armv8mml.S"
.end

View File

@ -0,0 +1,3 @@
.equ __DOMAIN_NS, 1
.include "../Source/GCC/irq_armv8mml.S"
.end

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,5 @@
NAME irq_armv8mbl.s
#define __DOMAIN_NS 0
INCLUDE irq_armv8mbl_common.s
END

View File

@ -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

View File

@ -0,0 +1,5 @@
NAME irq_armv8mbl_ns.s
#define __DOMAIN_NS 1
INCLUDE irq_armv8mbl_common.s
END

View File

@ -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

View File

@ -0,0 +1,5 @@
NAME irq_armv8mml.s
#define __DOMAIN_NS 0
INCLUDE irq_armv8mml_common.s
END

View File

@ -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

View File

@ -0,0 +1,5 @@
NAME irq_armv8mml_ns.s
#define __DOMAIN_NS 1
INCLUDE irq_armv8mml_common.s
END

View File

@ -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

View File

@ -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

View File

@ -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_

View File

@ -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);
}

View File

@ -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

View File

@ -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 {

View File

@ -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);
}

View File

@ -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_
/** @}*/

View File

@ -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;

View File

@ -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