1.. _arm_cortex_m_developer_guide: 2 3Arm Cortex-M Developer Guide 4############################ 5 6Overview 7******** 8 9This page contains detailed information about the status of the Arm Cortex-M 10architecture porting in the Zephyr RTOS and describes key aspects when 11developing Zephyr applications for Arm Cortex-M-based platforms. 12 13Key supported features 14********************** 15 16The table below summarizes the status of key OS features in the different 17Arm Cortex-M implementation variants. 18 19 20+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+ 21| | | **Processor families** | 22+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+ 23| Architecture variant | | Arm v6-M | Arm v7-M | Arm v8-M | Arm v8.1-M | 24+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+ 25| | | **M0/M1** | **M0+** | **M3** | **M4** | **M7** | **M23** | **M33** | **M55** | 26+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+ 27| **OS Features** | | | 28+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+ 29| Programmable fault | | | | | | | | | | 30| IRQ priorities | | Y | N | Y | Y | Y | N | Y | Y | 31+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+ 32| Single-thread kernel support | | Y | Y | Y | Y | Y | Y | Y | Y | 33+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+ 34| Thread local storage support | | Y | Y | Y | Y | Y | Y | Y | Y | 35+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+ 36| Interrupt handling | | | 37+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+ 38| | Regular interrupts | Y | Y | Y | Y | Y | Y | Y | Y | 39+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+ 40| | Dynamic interrupts | Y | Y | Y | Y | Y | Y | Y | Y | 41+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+ 42| | Direct interrupts | Y | Y | Y | Y | Y | Y | Y | Y | 43+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+ 44| | Zero Latency interrupts | N | N | Y | Y | Y | Y | Y | Y | 45+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+ 46| CPU idling | | Y | Y | Y | Y | Y | Y | Y | Y | 47+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+ 48| Native system timer (SysTick) | | N [#f1]_ | Y | Y | Y | Y | Y | Y | Y | 49+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+ 50| Memory protection | | | 51+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+ 52| | User mode | N | Y | Y | Y | Y | Y | Y | Y | 53+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+ 54| | HW stack protection (MPU) | N | N | Y | Y | Y | Y | Y | Y | 55+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+ 56| | HW-assisted stack limit checking | N | N | N | N | N |Y [#f2]_ | Y | Y | 57+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+ 58| HW-assisted null-pointer | | | | | | | | | | 59| dereference detection | | N | N | Y | Y | Y | Y | Y | Y | 60+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+ 61| HW-assisted atomic operations | | N | N | Y | Y | Y | N | Y | Y | 62+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+ 63|Support for non-cacheable regions| | N | N | Y | Y | Y | N | Y | Y | 64+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+ 65| Execute SRAM functions | | N | N | Y | Y | Y | N | Y | Y | 66+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+ 67| Floating Point Services | | N | N | N | Y | Y | N | Y | Y | 68+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+ 69| DSP ISA | | N | N | N | Y | Y | N | Y | Y | 70+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+ 71| Trusted-Execution | | 72+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+ 73| | Native TrustZone-M support | N | N | N | N | N | Y | Y | Y | 74+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+ 75| | TF-M integration | N | N | N | N | N | N | Y | N | 76+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+ 77| Code relocation | | Y | Y | Y | Y | Y | Y | Y | Y | 78+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+ 79| SW-based vector table relaying | | Y | Y | Y | Y | Y | Y | Y | Y | 80+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+ 81| HW-assisted timing functions | | N | N | Y | Y | Y | N | Y | Y | 82+---------------------------------+-----------------------------------+-----------------+---------+--------+-----------+--------+---------+------------+------------+ 83 84Notes 85===== 86 87.. [#f1] SysTick is optional in Cortex-M1 88.. [#f2] Stack limit checking only in Secure builds in Cortex-M23 89 90OS features 91*********** 92 93Threads 94======= 95 96Thread stack alignment 97---------------------- 98 99Each Zephyr thread is defined with its own stack memory. By default, Cortex-M enforces a double word thread stack alignment, see 100:kconfig:option:`CONFIG_STACK_ALIGN_DOUBLE_WORD`. If MPU-based HW-assisted stack overflow detection (:kconfig:option:`CONFIG_MPU_STACK_GUARD`) 101is enabled, thread stacks need to be aligned with a larger value, reflected by :kconfig:option:`CONFIG_ARM_MPU_REGION_MIN_ALIGN_AND_SIZE`. 102In Arm v6-M and Arm v7-M architecture variants, thread stacks are additionally required to be align with a value equal to their size, 103in applications that need to support user mode (:kconfig:option:`CONFIG_USERSPACE`). The thread stack sizes in that case need to be a power 104of two. This is all reflected by :kconfig:option:`CONFIG_MPU_REQUIRES_POWER_OF_TWO_ALIGNMENT`, that is enforced in Arm v6-M and Arm v7-M 105builds with user mode support. 106 107Stack pointers 108-------------- 109 110While executing in thread mode the processor is using the Process Stack Pointer (PSP). The processor uses the Main Stack Pointer (MSP) 111while executing in handler mode, that is, while servicing exceptions and HW interrupts. Using PSP in thread mode *facilitates thread 112stack pointer manipulation* during thread context switching, without affecting the current execution context flow in 113handler mode. 114 115In Arm Cortex-M builds a single interrupt stack memory is shared among exceptions and interrupts. The size of the interrupt stack needs 116to be selected taking into consideration nested interrupts, each pushing an additional stack frame. Developers can modify the interrupt 117stack size using :kconfig:option:`CONFIG_ISR_STACK_SIZE`. 118 119The interrupt stack is also used during early boot so the kernel can initialize the main thread's stack before switching to the main thread. 120 121Thread context switching 122======================== 123 124In Arm Cortex-M builds, the PendSV exception is used in order to trigger a context switch to a different thread. 125PendSV exception is always present in Cortex-M implementations. PendSV is configured with the lowest possible 126interrupt priority level, in all Cortex-M variants. The main reasons for that design are 127 128* to utilize the tail chaining feature of Cortex-M processors, and thus limit the number of context switch 129 operations that occur. 130* to not impact the interrupt latency observed by HW interrupts. 131 132As a result, context switch in Cortex-M is non-atomic, i.e. it may be *preempted* by HW interrupts, 133however, a context-switch operation must be completed before a new thread context-switch may start. 134 135Typically a thread context-switch will perform the following operations 136 137* When switching-out the current thread, the processor stores 138 139 * the callee-saved registers (R4 - R11) in the thread's container for callee-saved registers, 140 which is located in kernel memory 141 * the thread's current operation *mode* 142 143 * user or privileged execution mode 144 * presence of an active floating point context 145 * the EXC_RETURN value of the current handler context (PendSV) 146 147 * the floating point callee-saved registers (S16 - S31) in the thread's container for FP 148 callee-saved registers, if the current thread has an active FP context 149 * the PSP of the current thread which points to the beginning of the current thread's exception 150 stack frame. The latter contains the caller-saved context and the return address of the switched-out 151 thread. 152 153* When switching-in a new thread the processor 154 155 * restores the new thread's callee-saved registers from the thread's 156 container for callee-saved registers 157 * restores the new thread's operation *mode* 158 * restores the FP callee-saved registers if the switched-in thread had 159 an active FP context before being switched-out 160 * re-programs the dynamic MPU regions to allow a user thread access its stack and application 161 memories, and/or programs a stack-overflow MPU guard at the bottom of the thread's 162 privileged stack 163 * restores the PSP for the incoming thread and re-programs the stack pointer limit 164 register (if applicable, see :kconfig:option:`CONFIG_BUILTIN_STACK_GUARD`) 165 * optionally does a stack limit checking for the switched-in thread, if 166 sentinel-based stack limit checking is enabled (see :kconfig:option:`CONFIG_STACK_SENTINEL`). 167 168PendSV exception return sequence restores the new thread's caller-saved registers and the 169return address, as part of unstacking the exception stack frame. 170 171The implementation of the context-switch mechanism is present in 172:file:`arch/arm/core/swap_helper.S`. 173 174Stack limit checking (Arm v8-M) 175------------------------------- 176 177Armv8-M and Armv8.1-M variants support stack limit checking using the MSPLIM and PSPLIM 178core registers. The feature is enabled when :kconfig:option:`CONFIG_BUILTIN_STACK_GUARD` is set. 179When stack limit checking is enabled, both the thread's privileged or user stack, as well 180as the interrupt stack are guarded by PSPLIM and MSPLIM registers, respectively. MSPLIM is 181configured *once* during kernel boot, while PSLIM is re-programmed during every thread 182context-switch or during system calls, when the thread switches from using its default 183stack to using its privileged stack, and vice versa. PSPLIM re-programming 184 185* has a relatively low runtime overhead (programming is done with MSR instructions) 186* does not impact interrupt latency 187* does not require any memory areas to be reserved for stack guards 188* does not make use of MPU regions 189 190It is, therefore, considered as a lightweight but very efficient stack overflow 191detection mechanism in Cortex-M applications. 192 193Stack overflows trigger the dedicated UsageFault exception provided by Arm v8-M. 194 195Interrupt handling features 196=========================== 197 198This section describes certain aspects around exception and interrupt 199handling in Arm Cortex-M. 200 201Interrupt priority levels 202------------------------- 203 204The number of available (configurable) interrupt priority levels is 205determined by the number of implemented interrupt priority bits in 206NVIC; this needs to be described for each Cortex-M platform using 207DeviceTree: 208 209.. code-block:: devicetree 210 211 &nvic { 212 arm,num-irq-priority-bits = <#priority-bits>; 213 }; 214 215 216Reserved priority levels 217------------------------ 218 219A number of interrupt priority levels are reserved for the OS. 220 221By design, system fault exceptions have the highest priority level. In 222*Baseline* Cortex-M, this is actually enforced by hardware, as HardFault 223is the only available processor fault exception, and its priority is 224higher than any configurable exception priority. 225 226In *Mainline* Cortex-M, the available fault exceptions (e.g. MemManageFault, 227UsageFault, etc.) are assigned the highest *configurable* priority level. 228(:kconfig:option:`CONFIG_CPU_CORTEX_M_HAS_PROGRAMMABLE_FAULT_PRIOS` signifies explicitly 229that the Cortex-M implementation supports configurable fault priorities.) 230 231This priority level is never shared with HW interrupts (an exception to 232this rule is described below). As a result, processor faults occurring in regular 233ISRs will be handled by the corresponding fault handler and will not escalate to 234a HardFault, *similar to processor faults occurring in thread mode*. 235 236SVC exception is normally configured with the highest configurable priority level 237(an exception to this rule will be described below). 238SVCs are used by the Zephyr kernel to dispatch system calls, trigger runtime 239system errors (e.g. Kernel oops or panic), or implement IRQ offloading. 240 241In Baseline Cortex-M the priority level of SVC may be shared with other exceptions 242or HW interrupts that are also given the highest configurable priority level (As a 243result of this, kernel runtime errors during interrupt handling will escalate to 244HardFault. Additional logic in the fault handling routines ensures that such 245runtime errors are detected successfully). 246 247In Mainline Cortex-M, however, the SVC priority level is *reserved*, thus normally it 248is only shared with the fault exceptions of configurable priority. This simplifies the 249fault handling routines in Mainline Cortex-M architecture, since runtime kernel errors 250are serviced by the SVC handler (i.e no HardFault escalation, even if the kernel errors 251occur in ISR context). 252 253HW interrupts in Mainline Cortex-M builds are allocated a priority level lower than the SVC. 254 255One exception to the above rules is when Zephyr applications support Zero Latency Interrupts 256(ZLIs). Such interrupts are designed to have a priority level higher than any HW or system 257interrupt. If the ZLI feature is enabled in Mainline Cortex-M builds (see 258:kconfig:option:`CONFIG_ZERO_LATENCY_IRQS`), then 259 260* ZLIs are assigned the highest configurable priority level 261* SVCs are assigned the second highest configurable priority level 262* Regular HW interrupts are assigned priority levels lower than SVC. 263 264The priority level configuration in Cortex-M is implemented in 265:file:`include/arch/arm/exception.h`. 266 267Locking and unlocking IRQs 268-------------------------- 269 270In Baseline Cortex-M locking interrupts is implemented using the PRIMASK register. 271 272.. code-block:: c 273 274 arch_irq_lock() 275 276will set the PRIMASK register to 1, eventually, masking all IRQs with configurable 277priority. While this fulfils the OS requirement of locking interrupts, the consequence 278is that kernel runtime errors (triggering SVCs) will escalate to HardFault. 279 280In Mainline Cortex-M locking interrupts is implemented using the BASEPRI register (Mainline 281Cortex-M builds select :kconfig:option:`CONFIG_CPU_CORTEX_M_HAS_BASEPRI` to signify that BASEPRI register is 282implemented.). By modifying BASEPRI (or BASEPRI_MAX) arch_irq_lock() masks all system and HW 283interrupts with the exception of 284 285* SVCs 286* processor faults 287* ZLIs 288 289This allows zero latency interrupts to be triggered inside OS critical sections. 290Additionally, this allows system (processor and kernel) faults to be handled by Zephyr 291in *exactly the same way*, regardless of whether IRQs have been locked or not when the 292error occurs. It also allows for system calls to be dispatched while IRQs are locked. 293 294.. note:: 295 296 Mainline Cortex-M fault handling is designed and configured in a way that all processor 297 and kernel faults are handled by the corresponding exception handlers and never result 298 in HardFault escalation. In other words, a HardFault may only occur in Zephyr applications 299 that have modified the default fault handling configurations. The main reason for this 300 design was to reserve the HardFault exception for handling exceptional error conditions 301 in safety critical applications. 302 303Dynamic direct interrupts 304------------------------- 305 306Cortex-M builds support the installation of direct interrupt service routines during 307runtime. Direct interrupts are designed for performance-critical interrupt 308handling and do not go through all of the common Zephyr interrupt handling 309code. 310 311Direct dynamic interrupts are enabled via switching on 312:kconfig:option:`CONFIG_DYNAMIC_DIRECT_INTERRUPTS`. 313 314Note that enabling direct dynamic interrupts requires enabling support for 315dynamic interrupts in the kernel, as well (see :kconfig:option:`CONFIG_DYNAMIC_INTERRUPTS`). 316 317Zero Latency interrupts 318----------------------- 319 320As described above, in Mainline Cortex-M applications, the Zephyr kernel reserves 321the highest configurable interrupt priority level for its own use (SVC). SVCs will 322not be masked by interrupt locking. Zero-latency interrupt can be used to set up 323an interrupt at the highest interrupt priority which will not be blocked by interrupt 324locking. To use the ZLI feature :kconfig:option:`CONFIG_ZERO_LATENCY_IRQS` needs to be enabled. 325 326Zero latency IRQs have minimal interrupt latency, as they will always preempt regular HW 327or system interrupts. 328 329Note, however, that since ZLI ISRs will run at a priority level higher than the kernel 330exceptions they **cannot use** any kernel functionality. Additionally, since the ZLI 331interrupt priority level is equal to processor fault priority level, faults occurring 332in ZLI ISRs will escalate to HardFault and will not be handled in the same way as regular 333processor faults. Developers need to be aware of this limitation. 334 335CPU Idling 336========== 337 338The Cortex-M architecture port implements both k_cpu_idle() 339and k_cpu_atomic_idle(). The implementation is present in 340:file:`arch/arm/core/cpu_idle.S`. 341 342In both implementations, the processor 343will attempt to put the core to low power mode. 344In k_cpu_idle() the processor ends up executing WFI (Wait For Interrupt) 345instruction, while in k_cpu_atomic_idle() the processor will 346execute a WFE (Wait For Event) instruction. 347 348When using the CPU idling API in Cortex-M it is important to note the 349following: 350 351* Both k_cpu_idle() and k_cpu_atomic_idle() are *assumed* to be invoked 352 with interrupts locked. This is taken care of by the kernel if the APIs 353 are called by the idle thread. 354* After waking up from low power mode, both functions will *restore* 355 interrupts unconditionally, that is, regardless of the interrupt lock 356 status before the CPU idle API was called. 357 358The Zephyr CPU Idling mechanism is detailed in :ref:`cpu_idle`. 359 360Memory protection features 361========================== 362 363This section describes certain aspects around memory protection features 364in Arm Cortex-M applications. 365 366User mode system calls 367---------------------- 368 369User mode is supported in Cortex-M platforms that implement the standard (Arm) MPU 370or a similar core peripheral logic for memory access policy configuration and 371control, such as the NXP MPU for Kinetis platforms. (Currently, 372:kconfig:option:`CONFIG_ARCH_HAS_USERSPACE` is selected if :kconfig:option:`CONFIG_ARM_MPU` is enabled 373by the user in the board default Kconfig settings). 374 375A thread performs a system call by triggering a (synchronous) SVC exception, where 376 377* up to 5 arguments are placed on registers R1 - R5 378* system call ID is placed on register R6. 379 380The SVC Handler will branch to the system call preparation logic, which will perform 381the following operations 382 383* switch the thread's PSP to point to the beginning of the thread's privileged 384 stack area, optionally reprogramming the PSPLIM if stack limit checking is enabled 385* modify CONTROL register to switch to privileged mode 386* modify the return address in the SVC exception stack frame, so that after exception 387 return the system call dispatcher is executed (in thread privileged mode) 388 389Once the system call execution is completed the system call dispatcher will restore the 390user's original PSP and PSPLIM and switch the CONTROL register back to unprivileged mode 391before returning back to the caller of the system call. 392 393System calls execute in thread mode and can be preempted by interrupts at any time. A 394thread may also be context-switched-out while doing a system call; the system call will 395resume as soon as the thread is switched-in again. 396 397The system call dispatcher executes at SVC priority, therefore it cannot be preempted 398by HW interrupts (with the exception of ZLIs), which may observe some additional interrupt 399latency if they occur during a system call preparation. 400 401MPU-assisted stack overflow detection 402------------------------------------- 403 404Cortex-M platforms with MPU may enable :kconfig:option:`CONFIG_MPU_STACK_GUARD` to enable the MPU-based 405stack overflow detection mechanism. The following points need to be considered when enabling the 406MPU stack guards 407 408* stack overflows are triggering processor faults as soon as they occur 409* the mechanism is essential for detecting stack overflows in supervisor threads, or 410 user threads in privileged mode; stack overflows in threads in user mode will always be 411 detected regardless of :kconfig:option:`CONFIG_MPU_STACK_GUARD` being set. 412* stack overflows are always detected, however, the mechanism does not guarantee that 413 no memory corruption occurs when supervisor threads overflow their stack memory 414* :kconfig:option:`CONFIG_MPU_STACK_GUARD` will normally reserve one MPU region for programming 415 the stack guard (in certain Arm v8-M configurations with :kconfig:option:`CONFIG_MPU_GAP_FILLING` 416 enabled 2 MPU regions are required to implement the guard feature) 417* MPU guards are re-programmed at every context-switch, adding a small overhead to the 418 thread swap routine. Compared, however, to the :kconfig:option:`CONFIG_BUILTIN_STACK_GUARD` feature, 419 no re-programming occurs during system calls. 420* When :kconfig:option:`CONFIG_HW_STACK_PROTECTION` is enabled on Arm v8-M platforms the native 421 stack limit checking mechanism is used by default instead of the MPU-based stack overflow 422 detection mechanism; users may override this setting by manually enabling :kconfig:option:`CONFIG_MPU_STACK_GUARD` 423 in these scenarios. 424 425Memory map and MPU considerations 426================================= 427 428Fixed MPU regions 429----------------- 430 431By default, when :kconfig:option:`CONFIG_ARM_MPU` is enabled a set of *fixed* MPU regions 432are programmed during system boot. 433 434* One MPU region programs the entire flash area as read-execute. 435 User can override this setting by enabling :kconfig:option:`CONFIG_MPU_ALLOW_FLASH_WRITE`, 436 which programs the flash with RWX permissions. If :kconfig:option:`CONFIG_USERSPACE` is 437 enabled unprivileged access on the entire flash area is allowed. 438* One MPU region programs the entire SRAM area with privileged-only 439 RW permissions. That is, an MPU region is utilized to disallow execute permissions on 440 SRAM. (An exception to this setting is when :kconfig:option:`CONFIG_MPU_GAP_FILLING` is disabled (Arm v8-M only); 441 in that case no SRAM MPU programming is done so the access is determined by the default 442 Arm memory map policies, allowing for privileged-only RWX permissions on SRAM). 443* All the memory regions defined in the devicetree with the property 444 ``zephyr,memory-attr`` defining the MPU permissions for the memory region. 445 See the next section for more details. 446 447The above MPU regions are defined in :file:`soc/arm/common/cortex_m/arm_mpu_regions.c`. 448Alternative MPU configurations are allowed by enabling :kconfig:option:`CONFIG_CPU_HAS_CUSTOM_FIXED_SOC_MPU_REGIONS`. 449When enabled, this option signifies that the Cortex-M SoC will define and 450configure its own fixed MPU regions in the SoC definition. 451 452Fixed MPU regions defined in devicetree 453--------------------------------------- 454 455When the property ``zephyr,memory-attr`` is present in a memory node, a new MPU 456region will be allocated and programmed during system boot. When used with the 457:dtcompatible:`zephyr,memory-region` devicetree compatible, it will result in a 458linker section being generated associated to that MPU region. 459 460For example, to define a new non-cacheable memory region in devicetree: 461 462.. code-block:: devicetree 463 464 sram_no_cache: memory@20300000 { 465 compatible = "zephyr,memory-region", "mmio-sram"; 466 reg = <0x20300000 0x100000>; 467 zephyr,memory-region = "SRAM_NO_CACHE"; 468 zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM_NOCACHE) )>; 469 }; 470 471This will automatically create a new MPU entry in with the correct name, base, 472size and attributes gathered directly from the devicetree. 473 474Static MPU regions 475------------------ 476 477Additional *static* MPU regions may be programmed once during system boot. These regions 478are required to enable certain features 479 480* a RX region to allow execution from SRAM, when :kconfig:option:`CONFIG_ARCH_HAS_RAMFUNC_SUPPORT` is 481 enabled and users have defined functions to execute from SRAM. 482* a RX region for relocating text sections to SRAM, when :kconfig:option:`CONFIG_CODE_DATA_RELOCATION_SRAM` is enabled 483* a no-cache region to allow for a none-cacheable SRAM area, when :kconfig:option:`CONFIG_NOCACHE_MEMORY` is enabled 484* a possibly unprivileged RW region for GCOV code coverage accounting area, when :kconfig:option:`CONFIG_COVERAGE_GCOV` is enabled 485* a no-access region to implement null pointer dereference detection, when :kconfig:option:`CONFIG_NULL_POINTER_EXCEPTION_DETECTION_MPU` is enabled 486 487The boundaries of these static MPU regions are derived from symbols exposed by the linker, in 488:file:`include/linker/linker-defs.h`. 489 490Dynamic MPU regions 491------------------- 492 493Certain thread-specific MPU regions may be re-programmed dynamically, at each thread context switch: 494 495* an unprivileged RW region for the current thread's stack area (for user threads) 496* a read-only region for the MPU stack guard 497* unprivileged RW regions for the partitions of the current thread's application memory 498 domain. 499 500 501Considerations 502-------------- 503 504The number of available MPU regions for a Cortex-M platform is a limited resource. 505Most platforms have 8 MPU regions, while some Cortex-M33 or Cortex-M7 platforms may 506have up to 16 MPU regions. Therefore there is a relatively strict limitation on how 507many fixed, static and dynamic MPU regions may be programmed simultaneously. For platforms 508with 8 available MPU regions it might not be possible to enable all the aforementioned 509features that require MPU region programming. In most practical applications, however, 510only a certain set of features is required and 8 MPU regions are, in many cases, sufficient. 511 512In Arm v8-M processors the MPU architecture does not allow programmed MPU regions to 513overlap. :kconfig:option:`CONFIG_MPU_GAP_FILLING` controls whether the fixed MPU region 514covering the entire SRAM is programmed. When it does, a full SRAM area partitioning 515is required, in order to program the static and the dynamic MPU regions. This increases 516the total number of required MPU regions. When :kconfig:option:`CONFIG_MPU_GAP_FILLING` is not 517enabled the fixed MPU region covering the entire SRAM is not programmed, thus, the static 518and dynamic regions are simply programmed on top of the always-existing background region 519(full-SRAM partitioning is not required). 520Note, however, that the background SRAM region allows execution from SRAM, so when 521:kconfig:option:`CONFIG_MPU_GAP_FILLING` is not set Zephyr is not protected against attacks 522that attempt to execute malicious code from SRAM. 523 524 525Floating point Services 526======================= 527 528Both unshared and shared FP registers mode are supported in Cortex-M (see 529:ref:`float_v2` for more details). 530 531When FPU support is enabled in the build 532(:kconfig:option:`CONFIG_FPU` is enabled), the 533sharing FP registers mode (:kconfig:option:`CONFIG_FPU_SHARING`) 534is enabled by default. This is done as some compiler configurations 535may activate a floating point context by generating FP instructions 536for any thread, regardless of whether floating point calculations are 537performed, and that context must be preserved when switching such 538threads in and out. 539 540The developers can still disable the FP sharing mode in their 541application projects, and switch to Unshared FP registers mode, 542if it is guaranteed that the image code does not generate FP 543instructions outside the single thread context that is allowed 544(and supposed) to do so. 545 546Under FPU sharing mode, the callee-saved FPU registers are saved 547and restored in context-switch, if the corresponding threads have 548an active FP context. This adds some runtime overhead on the swap 549routine. In addition to the runtime overhead, the sharing FPU mode 550 551* requires additional memory for each thread to save the callee-saved 552 FP registers 553* requires additional stack memory for each thread, to stack the caller-saved 554 FP registers, upon exception entry, if an FP context is active. Note, however, 555 that since lazy stacking is enabled, there is no runtime overhead of FP context 556 stacking in regular interrupts (FP state preservation is only activated in the 557 swap routine in PendSV interrupt). 558 559 560Misc 561**** 562 563Chain-loadable images 564===================== 565 566Cortex-M applications may either be standalone images or chain-loadable, for instance, 567by a bootloader. Application images chain-loadable by bootloaders (or other applications) 568normally occupy a specific area in the flash denoted as their *code partition*. 569:kconfig:option:`CONFIG_USE_DT_CODE_PARTITION` will ensure that a Zephyr chain-loadable image 570will be linked into its code partition, specified in DeviceTree. 571 572HW initialization at boot 573------------------------- 574 575In order to boot properly, chain-loaded applications may require that the core Arm 576hardware registers and peripherals are initialized in their reset values. Enabling 577:kconfig:option:`CONFIG_INIT_ARCH_HW_AT_BOOT` Zephyr to force the initialization of the 578internal Cortex-M architectural state during boot to the reset values as specified 579by the corresponding Arm architecture manual. 580 581Software vector relaying 582------------------------ 583 584In Cortex-M platforms that implement the VTOR register (see :kconfig:option:`CONFIG_CPU_CORTEX_M_HAS_VTOR`), 585chain-loadable images relocate the Cortex-M vector table by updating the VTOR register with the offset 586of the image vector table. 587 588Baseline Cortex-M platforms without VTOR register might not be able to relocate their 589vector table which remains at a fixed location. Therefore, a chain-loadable image will 590require an alternative way to route HW interrupts and system exceptions to its own vector 591table; this is achieved with software vector relaying. 592 593When a bootloader image enables :kconfig:option:`CONFIG_SW_VECTOR_RELAY` 594it is able to relay exceptions and interrupts based on a vector table 595pointer that is set by the chain-loadable application. The latter sets 596the :kconfig:option:`CONFIG_SW_VECTOR_RELAY_CLIENT` option to instruct the boot 597sequence to set the vector table pointer in SRAM so that the bootloader can 598forward the exceptions and interrupts to the chain-loadable image's software 599vector table. 600 601While this feature is intended for processors without VTOR register, it 602may also be used in Mainline Cortex-M platforms. 603 604Code relocation 605=============== 606 607Cortex-M support the code relocation feature. When 608:kconfig:option:`CONFIG_CODE_DATA_RELOCATION_SRAM` is selected, 609Zephyr will relocate .text, data and .bss sections 610from the specified files and place it in SRAM. It is 611possible to relocate only parts of the code sections 612into SRAM, without relocating the whole image text 613and data sections. More details on the code relocation 614feature can be found in :ref:`code_data_relocation`. 615 616 617Linking Cortex-M applications 618***************************** 619 620Most Cortex-M platforms make use of the default Cortex-M 621GCC linker script in :file:`include/arch/arm/cortex-m/scripts/linked.ld`, 622although it is possible for platforms to use a custom linker 623script as well. 624 625 626CMSIS 627***** 628 629Cortex-M CMSIS headers are hosted in a standalone module repository: 630`zephyrproject-rtos/cmsis <https://github.com/zephyrproject-rtos/cmsis>`_. 631 632:kconfig:option:`CONFIG_CPU_CORTEX_M` selects :kconfig:option:`CONFIG_HAS_CMSIS_CORE` to signify that 633CMSIS headers are available for all supported Cortex-M variants. 634 635Testing 636******* 637 638A list of unit tests for the Cortex-M porting and miscellaneous features 639is present in :file:`tests/arch/arm/`. The tests suites are continuously 640extended and new test suites are added, in an effort to increase the coverage 641of the Cortex-M architecture support in Zephyr. 642 643QEMU 644**** 645 646We use QEMU to verify the implemented features of the Cortex-M architecture port in Zephyr. 647Adequate coverage is achieved by defining and utilizing a list of QEMU targets, 648each with a specific architecture variant and Arm peripheral support list. 649 650The table below lists the QEMU platform targets defined in Zephyr 651along with the corresponding Cortex-M implementation variant and the peripherals 652these targets emulate. 653 654+---------------------------------+--------------------+--------------------+----------------+-----------------+----------------+ 655| | **QEMU target** | 656+---------------------------------+--------------------+--------------------+----------------+-----------------+----------------+ 657| Architecture variant | Arm v6-M | Arm v7-M | Arm v8-M | Arm v8.1-M | 658+---------------------------------+--------------------+--------------------+----------------+-----------------+----------------+ 659| | **qemu_cortex_m0** | **qemu_cortex_m3** | **mps2_an385** | **mps2_an521** | **mps3_an547** | 660+---------------------------------+--------------------+--------------------+----------------+-----------------+----------------+ 661| **Emulated features** | | 662+---------------------------------+--------------------+--------------------+----------------+-----------------+----------------+ 663| NVIC | Y | Y | Y | Y | Y | 664+---------------------------------+--------------------+--------------------+----------------+-----------------+----------------+ 665| BASEPRI | N | Y | Y | Y | Y | 666+---------------------------------+--------------------+--------------------+----------------+-----------------+----------------+ 667| SysTick | N | Y | Y | Y | Y | 668+---------------------------------+--------------------+--------------------+----------------+-----------------+----------------+ 669| MPU | N | N | Y | Y | Y | 670+---------------------------------+--------------------+--------------------+----------------+-----------------+----------------+ 671| FPU | N | N | N | Y | N | 672+---------------------------------+--------------------+--------------------+----------------+-----------------+----------------+ 673| SPLIM | N | N | N | Y | Y | 674+---------------------------------+--------------------+--------------------+----------------+-----------------+----------------+ 675| TrustZone-M | N | N | N | Y | N | 676+---------------------------------+--------------------+--------------------+----------------+-----------------+----------------+ 677 678Maintainers & Collaborators 679*************************** 680 681The status of the Arm Cortex-M architecture port in Zephyr is: *maintained*. 682The updated list of maintainers and collaborators for Cortex-M can be found 683in :file:`MAINTAINERS.yml`. 684