diff --git a/firmware/trezor.c b/firmware/trezor.c
index 9bb013e..e7e011f 100644
--- a/firmware/trezor.c
+++ b/firmware/trezor.c
@@ -102,6 +102,11 @@ int main(void)
}
#endif
+#ifdef APPVER
+ // enable MPU (Memory Protection Unit)
+ mpu_config();
+#endif
+
timer_init();
#if DEBUG_LINK
diff --git a/setup.c b/setup.c
index 28a9fc6..4fb75c5 100644
--- a/setup.c
+++ b/setup.c
@@ -17,16 +17,32 @@
* along with this library. If not, see .
*/
+#include
+#include
#include
#include
#include
#include
-#include
+#include
#include "rng.h"
#include "layout.h"
+#include "memory.h"
#include "util.h"
+#define MPU_RASR_SIZE_32B (0x04UL << MPU_RASR_SIZE_LSB)
+#define MPU_RASR_SIZE_32KB (0x0EUL << MPU_RASR_SIZE_LSB)
+#define MPU_RASR_SIZE_64KB (0x0FUL << MPU_RASR_SIZE_LSB)
+#define MPU_RASR_SIZE_128KB (0x10UL << MPU_RASR_SIZE_LSB)
+#define MPU_RASR_SIZE_256KB (0x11UL << MPU_RASR_SIZE_LSB)
+#define MPU_RASR_SIZE_512KB (0x12UL << MPU_RASR_SIZE_LSB)
+#define MPU_RASR_SIZE_512MB (0x1CUL << MPU_RASR_SIZE_LSB)
+
+// http://infocenter.arm.com/help/topic/com.arm.doc.dui0552a/BABDJJGF.html
+#define MPU_RASR_ATTR_FLASH (MPU_RASR_ATTR_C)
+#define MPU_RASR_ATTR_SRAM (MPU_RASR_ATTR_S | MPU_RASR_ATTR_C)
+#define MPU_RASR_ATTR_PERIPH (MPU_RASR_ATTR_S | MPU_RASR_ATTR_B)
+
uint32_t __stack_chk_guard;
static inline void __attribute__((noreturn)) fault_handler(const char *line1) {
@@ -46,6 +62,14 @@ void nmi_handler(void)
}
}
+void hard_fault_handler(void) {
+ fault_handler("Hard fault");
+}
+
+void mem_manage_handler(void) {
+ fault_handler("Memory fault");
+}
+
void setup(void)
{
// set SCB_CCR STKALIGN bit to make sure 8-byte stack alignment on exception entry is in effect.
@@ -130,3 +154,43 @@ void setupApp(void)
gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO10);
gpio_set_af(GPIOA, GPIO_AF10, GPIO10);
}
+
+// Never use in bootloader! Disables access to PPB (including MPU, NVIC, SCB)
+void mpu_config(void)
+{
+ // Enable memory fault handler
+ SCB_SHCSR |= SCB_SHCSR_MEMFAULTENA;
+
+ // Disable MPU
+ MPU_CTRL = 0;
+
+ // Bootloader (read-only, execute never)
+ MPU_RBAR = 0x08000000 | MPU_RBAR_VALID | (0 << MPU_RBAR_REGION_LSB);
+ MPU_RASR = MPU_RASR_ENABLE | MPU_RASR_ATTR_FLASH | MPU_RASR_SIZE_32KB | MPU_RASR_ATTR_AP_PRO_URO | MPU_RASR_ATTR_XN;
+
+ // Metadata (read-write, execute never)
+ MPU_RBAR = 0x08008000 | MPU_RBAR_VALID | (1 << MPU_RBAR_REGION_LSB);
+ MPU_RASR = MPU_RASR_ENABLE | MPU_RASR_ATTR_FLASH | MPU_RASR_SIZE_32KB | MPU_RASR_ATTR_AP_PRW_URW | MPU_RASR_ATTR_XN;
+
+ // Firmware (read-only)
+ MPU_RBAR = 0x08010000 | MPU_RBAR_VALID | (2 << MPU_RBAR_REGION_LSB);
+ MPU_RASR = MPU_RASR_ENABLE | MPU_RASR_ATTR_FLASH | MPU_RASR_SIZE_64KB | MPU_RASR_ATTR_AP_PRO_URO;
+ MPU_RBAR = 0x08020000 | MPU_RBAR_VALID | (3 << MPU_RBAR_REGION_LSB);
+ MPU_RASR = MPU_RASR_ENABLE | MPU_RASR_ATTR_FLASH | MPU_RASR_SIZE_128KB | MPU_RASR_ATTR_AP_PRO_URO;
+ MPU_RBAR = 0x08040000 | MPU_RBAR_VALID | (4 << MPU_RBAR_REGION_LSB);
+ MPU_RASR = MPU_RASR_ENABLE | MPU_RASR_ATTR_FLASH | MPU_RASR_SIZE_256KB | MPU_RASR_ATTR_AP_PRO_URO;
+
+ // SRAM (read-write, execute never)
+ MPU_RBAR = 0x20000000 | MPU_RBAR_VALID | (5 << MPU_RBAR_REGION_LSB);
+ MPU_RASR = MPU_RASR_ENABLE | MPU_RASR_ATTR_SRAM | MPU_RASR_SIZE_128KB | MPU_RASR_ATTR_AP_PRW_URW | MPU_RASR_ATTR_XN;
+
+ // Peripherals (read-write, execute never)
+ MPU_RBAR = PERIPH_BASE | MPU_RBAR_VALID | (6 << MPU_RBAR_REGION_LSB);
+ MPU_RASR = MPU_RASR_ENABLE | MPU_RASR_ATTR_PERIPH | MPU_RASR_SIZE_512MB | MPU_RASR_ATTR_AP_PRW_URW | MPU_RASR_ATTR_XN;
+
+ // Enable MPU
+ MPU_CTRL = MPU_CTRL_ENABLE;
+
+ __asm__ volatile("dsb");
+ __asm__ volatile("isb");
+}
diff --git a/setup.h b/setup.h
index c5236fc..34b88aa 100644
--- a/setup.h
+++ b/setup.h
@@ -27,4 +27,6 @@ extern uint32_t __stack_chk_guard;
void setup(void);
void setupApp(void);
+void mpu_config(void);
+
#endif