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