From 302a31e8d2015510b899b53ed0cab0e6cf5eaacc Mon Sep 17 00:00:00 2001 From: Pavol Rusnak Date: Tue, 13 Feb 2018 19:34:48 +0100 Subject: [PATCH] embed/bootloader: enable mpu and drop to unprivileged mode before running a firmware --- SConscript.bootloader | 1 + embed/bootloader/main.c | 2 ++ embed/bootloader/mpu.c | 60 +++++++++++++++++++++++++++++++++++++++++ embed/bootloader/mpu.h | 6 +++++ 4 files changed, 69 insertions(+) create mode 100644 embed/bootloader/mpu.c create mode 100644 embed/bootloader/mpu.h diff --git a/SConscript.bootloader b/SConscript.bootloader index 2d2375ae6..c369aa573 100644 --- a/SConscript.bootloader +++ b/SConscript.bootloader @@ -84,6 +84,7 @@ SOURCE_BOOTLOADER = [ 'embed/bootloader/bootui.c', 'embed/bootloader/main.c', 'embed/bootloader/messages.c', + 'embed/bootloader/mpu.c', 'embed/bootloader/nanopb/pb_common.c', 'embed/bootloader/nanopb/pb_decode.c', 'embed/bootloader/nanopb/pb_encode.c', diff --git a/embed/bootloader/main.c b/embed/bootloader/main.c index 74445cbcc..67ff9588d 100644 --- a/embed/bootloader/main.c +++ b/embed/bootloader/main.c @@ -13,6 +13,7 @@ #include "bootui.h" #include "messages.h" +#include "mpu.h" const uint8_t BOOTLOADER_KEY_M = 2; const uint8_t BOOTLOADER_KEY_N = 3; @@ -353,6 +354,7 @@ main_start: ui_fadeout(); } + mpu_config(); jump_to(FIRMWARE_START + vhdr.hdrlen + IMAGE_HEADER_SIZE); return 0; diff --git a/embed/bootloader/mpu.c b/embed/bootloader/mpu.c new file mode 100644 index 000000000..c2bb4c5bd --- /dev/null +++ b/embed/bootloader/mpu.c @@ -0,0 +1,60 @@ +#include STM32_HAL_H +#include "stm32f4xx_ll_cortex.h" + +// http://infocenter.arm.com/help/topic/com.arm.doc.dui0552a/BABDJJGF.html +#define MPU_RASR_ATTR_FLASH (MPU_RASR_C_Msk) +#define MPU_RASR_ATTR_SRAM (MPU_RASR_C_Msk | MPU_RASR_S_Msk) +#define MPU_RASR_ATTR_PERIPH (MPU_RASR_B_Msk | MPU_RASR_S_Msk) + +#define MPU_SUBREGION_DISABLE(X) ((X) << MPU_RASR_SRD_Pos) + +void mpu_config(void) +{ + // Disable MPU + HAL_MPU_Disable(); + +/* + // Boardloader (0x08000000 - 0x0800FFFF, 64 KiB, read-only, execute never) + MPU->RBAR = FLASH_BASE | MPU_RBAR_VALID_Msk | MPU_REGION_NUMBER0; + MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_PRIV_RO_URO | MPU_RASR_XN_Msk; +*/ + + // Bootloader (0x08020000 - 0x0803FFFF, 64 KiB, read-only) + MPU->RBAR = FLASH_BASE | 0x20000 | MPU_RBAR_VALID_Msk | MPU_REGION_NUMBER0; + MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_PRIV_RO_URO; + + // Storage#1 (0x08010000 - 0x0801FFFF, 64 KiB, read-write, execute never) + MPU->RBAR = FLASH_BASE | 0x10000 | MPU_RBAR_VALID_Msk | MPU_REGION_NUMBER1; + MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_FULL_ACCESS | MPU_RASR_XN_Msk; + // Storage#2 (0x08110000 - 0x0811FFFF, 64 KiB, read-write, execute never) + MPU->RBAR = FLASH_BASE | 0x110000 | MPU_RBAR_VALID_Msk | MPU_REGION_NUMBER2; + MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_FULL_ACCESS | MPU_RASR_XN_Msk; + + // Firmware (0x08040000 - 0x080FFFFF, 6 * 128 KiB = 1024 KiB except 2/8 at start = 768 KiB, read-only) + MPU->RBAR = FLASH_BASE | MPU_RBAR_VALID_Msk | MPU_REGION_NUMBER3; + MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | LL_MPU_REGION_SIZE_1MB | LL_MPU_REGION_PRIV_RO_URO | MPU_SUBREGION_DISABLE(0x03); + + // Firmware extra (0x08120000 - 0x081FFFFF, 7 * 128 KiB = 1024 KiB except 1/8 at start = 896 KiB, read-only) + MPU->RBAR = FLASH_BASE | 0x100000 | MPU_RBAR_VALID_Msk | MPU_REGION_NUMBER4; + MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | LL_MPU_REGION_SIZE_1MB | LL_MPU_REGION_PRIV_RO_URO | MPU_SUBREGION_DISABLE(0x01); + + // CCMRAM (0x10000000 - 0x1000FFFF, read-write, execute never) + MPU->RBAR = CCMDATARAM_BASE | MPU_RBAR_VALID_Msk | MPU_REGION_NUMBER5; + MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_SRAM | LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_FULL_ACCESS | MPU_RASR_XN_Msk; + + // SRAM (0x20000000 - 0x2002FFFF, read-write, execute never) + MPU->RBAR = SRAM_BASE | MPU_RBAR_VALID_Msk | MPU_REGION_NUMBER6; + MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_SRAM | LL_MPU_REGION_SIZE_256KB | LL_MPU_REGION_FULL_ACCESS | MPU_RASR_XN_Msk | MPU_SUBREGION_DISABLE(0xC0); + + // Peripherals (0x40000000 - 0x5FFFFFFF, read-write, execute never) + // External RAM (0x60000000 - 0x7FFFFFFF, read-write, execute never) + MPU->RBAR = PERIPH_BASE | MPU_RBAR_VALID_Msk | MPU_REGION_NUMBER7; + MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_PERIPH | LL_MPU_REGION_SIZE_1GB | LL_MPU_REGION_FULL_ACCESS | MPU_RASR_XN_Msk; + + // Enable MPU + HAL_MPU_Enable(0); + + // Switch to unprivileged mode + // http://infocenter.arm.com/help/topic/com.arm.doc.dui0552a/CHDBIBGJ.html + __asm__ volatile("msr control, %0" :: "r" (0x1)); +} diff --git a/embed/bootloader/mpu.h b/embed/bootloader/mpu.h new file mode 100644 index 000000000..9fe4d766f --- /dev/null +++ b/embed/bootloader/mpu.h @@ -0,0 +1,6 @@ +#ifndef __MPU_H__ +#define __MPU_H__ + +void mpu_config(void); + +#endif