10#ifndef STK_ARCH_ARM_CORTEX_M_H_
11#define STK_ARCH_ARM_CORTEX_M_H_
14#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE != 0)
21#ifndef STK_ARCH_ARMV6_M
22 #if defined(__ARM_ARCH_6M__)
23 #define STK_ARCH_ARMV6_M (1)
25 #define STK_ARCH_ARMV6_M (0)
28 #if (STK_ARCH_ARMV6_M == 0) && defined(__ARM_ARCH_6M__)
29 #error "STK_ARCH_ARMV6_M must be defined as 1 on ARMv6-M platform!"
36#ifndef STK_ARCH_ARMV7_M
37 #if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__)
38 #define STK_ARCH_ARMV7_M (1)
40 #define STK_ARCH_ARMV7_M (0)
43 #if (STK_ARCH_ARMV7_M == 0) && (defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__))
44 #error "STK_ARCH_ARMV7_M must be defined as 1 on ARMv7-M platform!"
51#ifndef STK_ARCH_ARMV8_M
52 #if defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8M_BASE__)
53 #define STK_ARCH_ARMV8_M (1)
55 #define STK_ARCH_ARMV8_M (0)
58 #if (STK_ARCH_ARMV8_M == 0) && (defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8M_BASE__))
59 #error "STK_ARCH_ARMV8_M must be defined as 1 on ARMv8-M platform!"
64#if !STK_ARCH_ARMV6_M && !STK_ARCH_ARMV7_M && !STK_ARCH_ARMV8_M
65 #error "Unsupported ARM architecture target!"
69#if (STK_ARCH_ARMV6_M + STK_ARCH_ARMV7_M + STK_ARCH_ARMV8_M) > 1
70 #error "Multiple STK_ARCH_ARMvX flags active simultaneously! Check build environment definitions."
76#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)
77 #define STK_TZ_SECURE (1)
79 #define STK_TZ_SECURE (0)
85#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 1)
86 #define STK_TZ_NON_SECURE (1)
88 #define STK_TZ_NON_SECURE (0)
95#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)
96 #define __stk_tz_nsc_entry __attribute__((cmse_nonsecure_entry))
98 #define __stk_tz_nsc_entry
104#if defined(__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)
105 #define __stk_tz_ns_call __attribute__((cmse_nonsecure_call))
107 #define __stk_tz_ns_call
113#define STK_TZ_NSC_GATEWAY extern "C" __stk_tz_nsc_entry
116#ifdef _STK_CORTEX_M_TRUSTZONE_NON_SECURE
117#if !STK_TZ_NON_SECURE
118 #error "Do not use -cmse compiler flag for Non-Secure binary compilation!"
123#if STK_MPU_STACK_GUARD && !STK_MPU
124 #error "Enable MPU support (STK_MPU=1) to use per-task MPU feature (STK_MPU_STACK_GUARD=1)!"
130#ifndef STK_CORTEX_M_MPU_REGIONS_MAX
131 #define STK_CORTEX_M_MPU_REGIONS_MAX (8U)
186#if STK_TLS && STK_TLS_PREFER_REGISTER
205 __asm
volatile(
"MOV %0, r9" :
"=r"(tp) : : );
219 __asm
volatile(
"MOV r9, %0" : :
"r"(tp) : );
223#define STK_INLINE_TLS 1
268enum EMpuAccess : uint8_t
272 ACCESS_PRIV_RW_USER_NO = (0x0U << 1U),
273 ACCESS_FULL = (0x1U << 1U),
274 ACCESS_PRIV_RO_USER_NO = (0x2U << 1U),
275 ACCESS_PRIV_RO_USER_RO = (0x3U << 1U)
282enum EMpuExec : uint8_t
284 EXEC_ALLOWED = (0x0U << 0U),
285 EXEC_NEVER = (0x1U << 0U)
293enum EMpuType : uint8_t
295 TYPE_STRONGLY_ORDERED = 0U,
297 TYPE_NORMAL_NON_CACHE = 2U,
298 TYPE_NORMAL_CACHEABLE = 3U
306enum EMpuShare : uint8_t
308 SHARE_NON = (0x0U << 3U),
309 SHARE_OUTER = (0x2U << 3U),
310 SHARE_INNER = (0x3U << 3U)
320enum EMpuAccess : uint32_t
322 ACCESS_NONE = 0xFFFFFFFFU,
324 ACCESS_HW_NO_ACCESS = (0x0U << 24U),
325 ACCESS_PRIV_RW_USER_NO = (0x1U << 24U),
326 ACCESS_PRIV_RW_USER_RO = (0x2U << 24U),
327 ACCESS_FULL = (0x3U << 24U),
328 ACCESS_PRIV_RO_USER_NO = (0x5U << 24U),
329 ACCESS_PRIV_RO_USER_RO = (0x6U << 24U)
335enum EMpuExec : uint32_t
337 EXEC_ALLOWED = (0x0U << 28U),
338 EXEC_NEVER = (0x1U << 28U)
344enum EMpuType : uint32_t
346 TYPE_STRONGLY_ORDERED = 0x000000U,
347 TYPE_DEVICE = 0x010000U,
348 TYPE_NORMAL_NON_CACHE = 0x080000U,
349 TYPE_NORMAL_CACHEABLE = 0x030000U
358enum EMpuShare : uint32_t
360 SHARE_NON = (0x0U << 18U),
361 SHARE_OUTER = (0x1U << 18U),
362 SHARE_INNER = (0x1U << 18U)
370enum EMpuConfigFlags : uint32_t
373 MPU_CFG_PRIVILEGED_BG_MEM = (1U << 0),
374 MPU_CFG_IN_FAULTS = (1U << 1),
375 MPU_CFG_CLEAR_ON_INIT = (1U << 2),
376 MPU_CFG_NONSECURE_MPU = (1U << 3)
385struct MpuRegionConfig
389 hw::mpu::EMpuAccess access_perm;
390 hw::mpu::EMpuType mem_type;
391 hw::mpu::EMpuShare share;
392 hw::mpu::EMpuExec exec;
438#define STK_MPU_SHARED_DATA_SECTION __attribute__((section(".stk_mpu_shared_data")))
448#define STK_MPU_SHARED_CODE_SECTION __attribute__((section(".stk_mpu_shared_code")))
465#define STK_MPU_SHARED_BSS_SECTION __attribute__((section(".stk_mpu_shared_bss")))
469#define STK_MPU_SHARED_DATA_SECTION
470#define STK_MPU_SHARED_CODE_SECTION
471#define STK_MPU_SHARED_BSS_SECTION
519 #if STK_ARCH_ARMV8_M && STK_TZ_SECURE
static void __stk_dmb()
Hardware memory barrier: ensures visibility across cores and bus masters.
#define STK_CORTEX_M_MPU_REGIONS_MAX
Number of MPU regions supported by MPU peripheral.
Contains interface definitions of the library.
#define __stk_forceinline
Forces compiler to always inline the decorated function, regardless of optimisation level.
#define STK_VIRT_DTOR
Makes destructors virtual and compliant to strict rules if STK_STRICT_COMPLIANCY=0.
Namespace of STK package.
uintptr_t Word
Native processor word type.
EWaitResult
Wait result (see IKernelService::Wait).
int64_t Ticks
Ticks value.
int32_t Timeout
Timeout time (ticks).
PlatformArmCortexM PlatformDefault
Default platform implementation.
uint64_t Cycles
Cycles value.
Word TId
Task (thread) id.
Hardware Abstraction Layer (HAL) for architecture-specific operations.
Concrete implementation of IPlatform driver for the Arm Cortex-M0, M3, M4, M7 processors.
void SwitchToNext() override
Switch to a next task.
void Sleep(Timeout ticks) override
Put calling process into a sleep state.
void ProcessTick() override
Process one tick.
Word GetCallerSP() const override
Get caller's Stack Pointer (SP).
void ProcessHardFault() override
Cause a hard fault of the system.
uint32_t GetTickResolution() const override
Get resolution of the system tick timer in microseconds. Resolution means a number of microseconds be...
Timeout Suspend() override
Suspend scheduling.
void Start() override
Start scheduling.
void Stop() override
Stop scheduling.
TId GetTid() const override
Get thread Id.
void SetEventOverrider(IEventOverrider *overrider, bool non_secure) override
Set platform event overrider.
uint32_t GetSysTimerFrequency() const override
Get system timer frequency.
Cycles GetSysTimerCount() const override
Get system timer count value.
void InitStack(EStackType stack_type, Stack *stack, IStackMemory *stack_memory, ITask *user_task) override
Initialize stack memory of the user task.
EWaitResult Wait(ISyncObject *sync_obj, IMutex *mutex, Timeout timeout) override
Put calling process into a waiting state until synchronization object is signaled or timeout occurs.
void Resume(Timeout elapsed_ticks) override
Resume scheduling after a prior Suspend() call.
void Initialize(IEventHandler *event_handler, IKernelService *service, uint32_t resolution_us, Stack *exit_trap) override
Initialize scheduler's context.
~PlatformArmCortexM()=default
Destructor.
bool SleepUntil(Ticks timestamp) override
Put calling process into a sleep state until the specified timestamp.
ARMv7-M/ARMv8-M hardware exception frame (8 words, highest address on the stack).
ARMv7-M/ARMv8-M system fault exception context state capture.
Word BFAR
BusFault Address Register (BFAR).
Word AFSR
Auxiliary Fault Status Register (AFSR).
Word HFSR
HardFault Status Register (HFSR).
hw::ExceptionFrame frame
Saved hardware exception stack frame.
Word MMFAR
Memory Management Fault Address Register (MMFAR).
Word CFSR
Configurable Fault Status Register (CFSR: MemManage, BusFault, UsageFault).
Word CONTROL
Core CONTROL register state snapshot.
bool mmfar_valid
Flag indicating validity of MMFAR address value (derived from CFSR.MMARVALID).
Word EXC_RETURN
Exception return magic value (EXC_RETURN).
bool bfar_valid
Flag indicating validity of BFAR address value (derived from CFSR.BFARVALID).
void Fill(const Word *stacked_regs, Word exc_return)
Populate fault context registers and hardware MPU state from an exception stack frame.
Hardware Memory Protection Unit (MPU) status register snapshot.
Region regions[(8U)]
Active hardware MPU region register state table.
Word CTRL
MPU Control Register (MPU_CTRL).
Register snapshot for an individual hardware MPU region slot.
Word RNR
Region Number Register (RNR).
Word ATTR
Region Attribute and Size Register (RASR / RLAR / MPU_RLAR).
Word RBAR
Region Base Address Register (RBAR).
Interface for a stack memory region.
Synchronization object interface.
Interface for mutex synchronization primitive.
Interface for a user task.
Interface for a platform driver.
Interface for a back-end event handler.
Interface for a platform event overrider.
Interface for the kernel services exposed to the user processes during run-time when Kernel started s...