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