1.. _mpu_test:
2
3Memory Protection Unit (MPU) Sample
4###################################
5
6Overview
7********
8This application provides a set options to check the correct MPU configuration
9against the following security issues:
10
11* Read at an address that is reserved in the memory map.
12* Write into the boot Flash/ROM.
13* Run code located in SRAM.
14
15If the MPU configuration is correct each option selected ends up in an MPU
16fault.
17
18Building and Running
19********************
20
21This project can be built and executed as follows:
22
23.. zephyr-app-commands::
24   :zephyr-app: samples/arch/mpu/mpu_test
25   :board: v2m_beetle
26   :goals: build flash
27   :compact:
28
29To build the single thread version, use the supplied configuration file for
30single thread: :file:`prj_single.conf`:
31
32.. zephyr-app-commands::
33   :zephyr-app: samples/arch/mpu/mpu_test
34   :board: v2m_beetle
35   :conf: prj_single.conf
36   :goals: run
37   :compact:
38
39To build a version that allows writes to the flash device, edit
40``prj.conf``, and follow the directions in the comments to enable the
41proper configs.
42
43Sample Output
44=============
45
46When running the above on an ARMv7 or ARMv8 CPU, the output of each command may look
47like the following.
48
49.. code-block:: console
50
51  uart:~$ mpu read
52  <err> os: ***** BUS FAULT *****
53  <err> os:   Precise data bus error
54  <err> os:   BFAR Address: 0x24000000
55  <err> os: r0/a1:  0x00009a5c  r1/a2:  0x00000008  r2/a3:  0x20001aa8
56  <err> os: r3/a4:  0x24000000 r12/ip:  0x00000000 r14/lr:  0x000029b7
57  <err> os:  xpsr:  0x21000000
58  <err> os: Faulting instruction address (r15/pc): 0x000003c8
59  <err> os: >>> ZEPHYR FATAL ERROR 0: CPU exception on CPU 0
60  <err> os: Current thread: 0x20000708 (shell_uart)
61  <err> os: Halting system
62
63
64.. code-block:: console
65
66  uart:~$ mpu write
67  write address: 0x4000
68  <err> os: ***** MPU FAULT *****
69  <err> os:   Data Access Violation
70  <err> os:   MMFAR Address: 0x4000
71  <err> os: r0/a1:  0x00000000  r1/a2:  0x0000000e  r2/a3:  0x0badc0de
72  <err> os: r3/a4:  0x00004000 r12/ip:  0x00000004 r14/lr:  0x000003ab
73  <err> os:  xpsr:  0x61000000
74  <err> os: Faulting instruction address (r15/pc): 0x000003b2
75  <err> os: >>> ZEPHYR FATAL ERROR 0: CPU exception on CPU 0
76  <err> os: Current thread: 0x20000708 (shell_uart)
77  <err> os: Halting system
78
79
80.. code-block:: console
81
82  uart:~$ mpu run
83  <err> os: ***** MPU FAULT *****
84  <err> os:   Instruction Access Violation
85  <err> os: r0/a1:  0x00009a5c  r1/a2:  0x00000001  r2/a3:  0x20001aa8
86  <err> os: r3/a4:  0x20000000 r12/ip:  0x00000000 r14/lr:  0x00006673
87  <err> os:  xpsr:  0x60000000
88  <err> os: Faulting instruction address (r15/pc): 0x20000000
89  <err> os: >>> ZEPHYR FATAL ERROR 0: CPU exception on CPU 0
90  <err> os: Current thread: 0x20000708 (shell_uart)
91  <err> os: Halting system
92
93
94When running this test on an ARMv6 CPU (specifically on a Cortex-M0+), the output will
95look different, as ARMv6 handles MPU faults as generic hard faults. Moreover, when
96running the ``mpu run`` command, Zephyr's hard fault handler for AArch32 tries to
97dereference the program counter from the exception stack frame, causing a second fault
98and silently placing the processor into a lockup state.
99
100To verify that the ``mpu run`` test in particular is running correctly, one can
101
102* start the MPU test under gdb with ``west debug``
103* execute ``mpu run`` over UART
104* then interrupt gdb with Ctrl-C and show the program counter by running ``l`` in gdb.
105
106The program counter should display as ``0xfffffffe``, indicating a lockup state.
107
108
109.. code-block:: console
110
111  uart:~$ mpu read
112  <err> os: ***** HARD FAULT *****
113  <err> os: r0/a1:  0x0800a54c  r1/a2:  0x00000008  r2/a3:  0x08003
114  <err> os: r3/a4:  0x24000000 r12/ip:  0x00000040 r14/lr:  0x0800d
115  <err> os:  xpsr:  0x01000000
116  <err> os: Faulting instruction address (r15/pc): 0x08000486
117  <err> os: >>> ZEPHYR FATAL ERROR 0: CPU exception on CPU 0
118  <err> os: Current thread: 0x200006a8 (shell_uart)
119  <err> os: Halting system
120
121
122.. code-block:: console
123
124  uart:~$ mpu write
125  <err> os: ***** HARD FAULT *****
126  <err> os: r0/a1:  0x00000000  r1/a2:  0x0000000e  r2/a3:  0x0000e
127  <err> os: r3/a4:  0x0badc0de r12/ip:  0x00000000 r14/lr:  0x08009
128  <err> os:  xpsr:  0x61000000
129  <err> os: Faulting instruction address (r15/pc): 0x0800046a
130  <err> os: >>> ZEPHYR FATAL ERROR 0: CPU exception on CPU 0
131  <err> os: Current thread: 0x200006a8 (shell_uart)
132  <err> os: Halting system
133
134
135.. code-block:: console
136
137  uart~$ mpu run
138  <no output>
139