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:`CONFIG_STACK_ALIGN_DOUBLE_WORD`. If MPU-based HW-assisted stack overflow detection (:kconfig:`CONFIG_MPU_STACK_GUARD`)
101is enabled, thread stacks need to be aligned with a larger value, reflected by :kconfig:`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:`CONFIG_USERSPACE`). The thread stack sizes in that case need to be a power
104of two. This is all reflected by :kconfig:`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. Deverlopers can modify the interrupt
117stack size using :kconfig:`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        * presense 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:`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:`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/aarch32/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:`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:`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 conigurable 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:`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/aarch32/exc.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:`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:`CONFIG_DYNAMIC_DIRECT_INTERRUPTS`.
313
314Note that enabling direct dynamic interrupts requires enabling support for
315dynamic interrupts in the kernel, as well (see :kconfig:`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:`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/aarch32/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:`CONFIG_ARCH_HAS_USERSPACE` is selected if :kconfig:`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:`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:`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:`CONFIG_MPU_STACK_GUARD` will normally reserve one MPU region for programming
415  the stack guard (in certain Arm v8-M configurations with :kconfig:`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:`CONFIG_BUILTIN_STACK_GUARD` feature,
419  no re-programming occurs during system calls.
420* When :kconfig:`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:`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:`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:`CONFIG_MPU_ALLOW_FLASH_WRITE`,
436  which programs the flash with RWX permissions. If :kconfig:`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:`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
444The above MPU regions are defined in :file:`soc/arm/common/arm_mpu_regions.c`.
445Alternative MPU configurations are allowed by enabling :kconfig:`CONFIG_CPU_HAS_CUSTOM_FIXED_SOC_MPU_REGIONS`.
446When enabled, this option signifies that the Cortex-M SoC will define and
447configure its own fixed MPU regions in the SoC definition.
448
449Static MPU regions
450------------------
451
452Additional *static* MPU regions may be programmed once during system boot. These regions
453are required to enable certain features
454
455* a RX region to allow execution from SRAM, when :kconfig:`CONFIG_ARCH_HAS_RAMFUNC_SUPPORT` is
456  enabled and users have defined functions to execute from SRAM.
457* a RX region for relocating text sections to SRAM, when :kconfig:`CONFIG_CODE_DATA_RELOCATION_SRAM` is enabled
458* a no-cache region to allow for a none-cacheable SRAM area, when :kconfig:`CONFIG_NOCACHE_MEMORY` is enabled
459* a possibly unprivileged RW region for GCOV code coverage accounting area, when :kconfig:`CONFIG_COVERAGE_GCOV` is enabled
460* a no-access region to implement null pointer dereference detection, when :kconfig:`CONFIG_NULL_POINTER_EXCEPTION_DETECTION_MPU` is enabled
461
462The boundaries of these static MPU regions are derived from symbols exposed by the linker, in
463:file:`include/linker/linker-defs.h`.
464
465Dynamic MPU regions
466-------------------
467
468Certain thread-specific MPU regions may be re-programmed dynamically, at each thread context switch:
469
470* an unprivileged RW region for the current thread's stack area (for user threads)
471* a read-only region for the MPU stack guard
472* unprivileged RW regions for the partitions of the currentl thread's application memory
473  domain.
474
475
476Considerations
477--------------
478
479The number of available MPU regions for a Cortex-M platform is a limited resource.
480Most platforms have 8 MPU regions, while some Cortex-M33 or Cortex-M7 platforms may
481have up to 16 MPU regions. Therefore there is a relatively strict limitation on how
482many fixed, static and dynamic MPU regions may be programmed simultaneously. For platforms
483with 8 available MPU regions it might not be possible to enable all the aforementioned
484features that require MPU region programming. In most practical applications, however,
485only a certain set of features is required and 8 MPU regions are, in many cases, sufficient.
486
487In Arm v8-M processors the MPU architecture does not allow programmed MPU regions to
488overlap. :kconfig:`CONFIG_MPU_GAP_FILLING` controls whether the fixed MPU region
489covering the entire SRAM is programmed. When it does, a full SRAM area partitioning
490is required, in order to program the  static and the dynamic MPU regions. This increases
491the total number of required MPU regions. When :kconfig:`CONFIG_MPU_GAP_FILLING` is not
492enabled the fixed MPU region convering the entire SRAM is not programmed, thus, the static
493and dynamic regions are simply programmed on top of the always-existing background region
494(full-SRAM partitioning is not required).
495Note, however, that the background SRAM region allows execution from SRAM, so when
496:kconfig:`CONFIG_MPU_GAP_FILLING` is not set Zephyr is not protected against attacks
497that attempt to execute malicious code from SRAM.
498
499
500Floating point Services
501=======================
502
503Both unshared and shared FP registers mode are supported in Cortex-M (see
504:ref:`float_v2` for more details).
505
506When FPU support is enabled in the build
507(:kconfig:`CONFIG_FPU` is enabled), the
508sharing FP registers mode (:kconfig:`CONFIG_FPU_SHARING`)
509is enabled by default. This is done as some compiler configurations
510may activate a floating point context by generating FP instructions
511for any thread, regardless of whether floating point calculations are
512performed, and that context must be preserved when switching such
513threads in and out.
514
515The developers can still disable the FP sharing mode in their
516application projects, and switch to Unshared FP registers mode,
517if it is guaranteed that the image code does not generate FP
518instructions outside the single thread context that is allowed
519(and supposed) to do so.
520
521Under FPU sharing mode, the callee-saved FPU registers are saved
522and restored in context-switch, if the corresponding threads have
523an active FP context. This adds some runtime overhead on the swap
524routine. In addition to the runtime overhead, the sharing FPU mode
525
526* requires additional memory for each thread to save the callee-saved
527  FP registers
528* requires additional stack memory for each thread, to stack the caller-saved
529  FP registers, upon exception entry, if an FP context is active. Note, however,
530  that since lazy stacking is enabled, there is no runtime overhead of FP context
531  stacking in regular interrupts (FP state preservation is only activated in the
532  swap routine in PendSV interrupt).
533
534
535Misc
536****
537
538Chain-loadable images
539=====================
540
541Cortex-M applications may either be standalone images or chain-loadable, for instance,
542by a bootloader. Application images chain-loadable by bootloaders (or other applications)
543normally occupy a specific area in the flash denoted as their *code partition*.
544:kconfig:`CONFIG_USE_DT_CODE_PARTITION` will ensure that a Zephyr chain-loadable image
545will be linked into its code partition, specified in DeviceTree.
546
547HW initialization at boot
548-------------------------
549
550In order to boot properly, chain-loaded applications may require that the core Arm
551hardware registers and peripherals are initialized in their reset values. Enabling
552:kconfig:`CONFIG_INIT_ARCH_HW_AT_BOOT` Zephyr to force the initialization of the
553internal Cortex-M architectural state during boot to the reset values as specified
554by the corresponding Arm architecture manual.
555
556Software vector relaying
557------------------------
558
559In Cortex-M platforms that implement the VTOR register (see :kconfig:`CONFIG_CPU_CORTEX_M_HAS_VTOR`),
560chain-loadable images relocate the Cortex-M vector table by updating the VTOR register with the offset
561of the image vector table.
562
563Baseline Cortex-M platforms without VTOR register might not be able to relocate their
564vector table which remains at a fixed location. Therefore, a chain-loadable image will
565require an alternative way to route HW interrupts and system exeptions to its own vector
566table; this is achieved with software vector relaying.
567
568When a bootloader image enables :kconfig:`CONFIG_SW_VECTOR_RELAY`
569it is able to relay exceptions and interrupts based on a vector table
570pointer that is set by the chain-loadable application. The latter sets
571the :kconfig:`CONFIG_SW_VECTOR_RELAY_CLIENT` option to instruct the boot
572sequence to set the vector table pointer in SRAM so that the bootloader can
573forward the exceptions and interrupts to the chain-loadable image's software
574vector table.
575
576While this feature is intended for processors without VTOR register, it
577may also be used in Mainline Cortex-M platforms.
578
579Code relocation
580===============
581
582Cortex-M support the code relocation feature. When
583:kconfig:`CONFIG_CODE_DATA_RELOCATION_SRAM` is selected,
584Zephyr will relocate .text, data and .bss sections
585from the specified files and place it in SRAM. It is
586possible to relocate only parts of the code sections
587into SRAM, without relocating the whole image text
588and data sections. More details on the code relocation
589feature can be found in :ref:`code_data_relocation`.
590
591
592Linking Cortex-M applications
593*****************************
594
595Most Cortex-M platforms make use of the default Cortex-M
596GCC linker script in :file:`include/arch/arm/aarch32/cortex-m/scripts/linked.ld`,
597although it is possible for platforms to use a custom linker
598script as well.
599
600
601CMSIS
602*****
603
604Cortex-M CMSIS headers are hosted in a standalone module repository:
605`zephyrproject-rtos/cmsis <https://github.com/zephyrproject-rtos/cmsis>`_.
606
607:kconfig:`CONFIG_CPU_CORTEX_M` selects :kconfig:`CONFIG_HAS_CMSIS_CORE` to signify that
608CMSIS headers are available for all supported Cortex-M variants.
609
610Testing
611*******
612
613A list of unit tests for the Cortex-M porting and miscellaneous features
614is present in :file:`tests/arch/arm/`. The tests suites are continuously
615extended and new test suites are added, in an effort to increase the coverage
616of the Cortex-M architecture support in Zephyr.
617
618QEMU
619****
620
621We use QEMU to verify the implemented features of the Cortex-M architecture port in Zephyr.
622Adequate coverage is achieved by defining and utilizing a list of QEMU targets,
623each with a specific architecture variant and Arm peripheral support list.
624
625The table below lists the QEMU platform targets defined in Zephyr
626along with the corresponding Cortex-M implementation variant and the peripherals
627these targets emulate.
628
629+---------------------------------+--------------------+--------------------+----------------+-----------------+----------------+
630|                                 | **QEMU target**                                                                             |
631+---------------------------------+--------------------+--------------------+----------------+-----------------+----------------+
632| Architecture variant            | Arm v6-M           | Arm v7-M                            | Arm v8-M        | Arm v8.1-M     |
633+---------------------------------+--------------------+--------------------+----------------+-----------------+----------------+
634|                                 | **qemu_cortex_m0** | **qemu_cortex_m3** | **mps2_an385** | **mps2_an521**  | **mps3_an547** |
635+---------------------------------+--------------------+--------------------+----------------+-----------------+----------------+
636| **Emulated features**           |                                                                                             |
637+---------------------------------+--------------------+--------------------+----------------+-----------------+----------------+
638| NVIC                            | Y                  | Y                  | Y              | Y               | Y              |
639+---------------------------------+--------------------+--------------------+----------------+-----------------+----------------+
640| BASEPRI                         | N                  | Y                  | Y              | Y               | Y              |
641+---------------------------------+--------------------+--------------------+----------------+-----------------+----------------+
642| SysTick                         | N                  | Y                  | Y              | Y               | Y              |
643+---------------------------------+--------------------+--------------------+----------------+-----------------+----------------+
644| MPU                             | N                  | N                  | Y              | Y               | Y              |
645+---------------------------------+--------------------+--------------------+----------------+-----------------+----------------+
646| FPU                             | N                  | N                  | N              | Y               | N              |
647+---------------------------------+--------------------+--------------------+----------------+-----------------+----------------+
648| SPLIM                           | N                  | N                  | N              | Y               | Y              |
649+---------------------------------+--------------------+--------------------+----------------+-----------------+----------------+
650| TrustZone-M                     | N                  | N                  | N              | Y               | N              |
651+---------------------------------+--------------------+--------------------+----------------+-----------------+----------------+
652
653Maintainers & Collaborators
654***************************
655
656The status of the Arm Cortex-M architecture port in Zephyr is: *maintained*.
657The updated list of maintainers and collaborators for Cortex-M can be found
658in :file:`MAINTAINERS.yml`.
659