|
|
|
@ -19,8 +19,11 @@
|
|
|
|
|
|
|
|
|
|
#include STM32_HAL_H
|
|
|
|
|
#include <stdbool.h>
|
|
|
|
|
|
|
|
|
|
#include "common.h"
|
|
|
|
|
#include "model.h"
|
|
|
|
|
#include "mpu.h"
|
|
|
|
|
|
|
|
|
|
#include "stm32u5xx_ll_cortex.h"
|
|
|
|
|
|
|
|
|
|
// region type
|
|
|
|
@ -152,106 +155,192 @@ static void mpu_set_attributes(void) {
|
|
|
|
|
|
|
|
|
|
#define OTP_AND_ID_SIZE 0x800
|
|
|
|
|
|
|
|
|
|
void mpu_config_boardloader(void) {
|
|
|
|
|
HAL_MPU_Disable();
|
|
|
|
|
mpu_set_attributes();
|
|
|
|
|
// clang-format on
|
|
|
|
|
|
|
|
|
|
#define KERNEL_RAM_START (SRAM2_BASE - SIZE_16K)
|
|
|
|
|
#define KERNEL_RAM_SIZE (SIZE_24K)
|
|
|
|
|
|
|
|
|
|
#define COREAPP_RAM1_START SRAM1_BASE
|
|
|
|
|
#define COREAPP_RAM1_SIZE (SIZE_192K - SIZE_16K)
|
|
|
|
|
|
|
|
|
|
#define COREAPP_RAM2_START (SRAM2_BASE + SIZE_8K)
|
|
|
|
|
#define COREAPP_RAM2_SIZE (SRAM_SIZE - (SIZE_192K + SIZE_8K))
|
|
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
|
// Set if the driver is initialized
|
|
|
|
|
bool initialized;
|
|
|
|
|
// Current mode
|
|
|
|
|
mpu_mode_t mode;
|
|
|
|
|
|
|
|
|
|
} mpu_driver_t;
|
|
|
|
|
|
|
|
|
|
mpu_driver_t g_mpu_driver = {
|
|
|
|
|
.initialized = false,
|
|
|
|
|
.mode = MPU_MODE_DISABLED,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static void mpu_init_fixed_regions(void) {
|
|
|
|
|
// Regions #0 to #5 are fixed for all targets
|
|
|
|
|
|
|
|
|
|
// clang-format off
|
|
|
|
|
#if defined(BOARDLOADER)
|
|
|
|
|
// REGION ADDRESS SIZE TYPE WRITE UNPRIV
|
|
|
|
|
SET_REGION( 0, BOARDLOADER_START, BOARDLOADER_SIZE, FLASH_CODE, NO, NO );
|
|
|
|
|
SET_REGION( 1, SRAM1_BASE, SRAM_SIZE, SRAM, YES, NO );
|
|
|
|
|
DIS_REGION( 2 );
|
|
|
|
|
DIS_REGION( 3 );
|
|
|
|
|
DIS_REGION( 4 );
|
|
|
|
|
SET_REGION( 5, GRAPHICS_START, GRAPHICS_SIZE, SRAM, YES, NO );
|
|
|
|
|
#endif
|
|
|
|
|
#if defined(BOOTLOADER)
|
|
|
|
|
// REGION ADDRESS SIZE TYPE WRITE UNPRIV
|
|
|
|
|
SET_REGION( 0, BOOTLOADER_START, BOOTLOADER_SIZE, FLASH_CODE, NO, NO );
|
|
|
|
|
SET_REGION( 1, SRAM1_BASE, SRAM_SIZE, SRAM, YES, NO );
|
|
|
|
|
DIS_REGION( 2 );
|
|
|
|
|
DIS_REGION( 3 );
|
|
|
|
|
DIS_REGION( 4 );
|
|
|
|
|
SET_REGION( 5, GRAPHICS_START, GRAPHICS_SIZE, SRAM, YES, NO );
|
|
|
|
|
#endif
|
|
|
|
|
#if defined(KERNEL)
|
|
|
|
|
// REGION ADDRESS SIZE TYPE WRITE UNPRIV
|
|
|
|
|
SET_REGION( 0, SECRET_START, SECRET_SIZE, FLASH_DATA, YES, NO ); // Secret
|
|
|
|
|
SET_REGION( 1, BOARDLOADER_START, BOARDLOADER_SIZE, FLASH_CODE, NO, NO ); // Boardloader code
|
|
|
|
|
SET_REGION( 2, BOOTLOADER_START, L1_REST_SIZE, FLASH_DATA, YES, NO ); // Bootloader + Storage + Firmware
|
|
|
|
|
SET_REGION( 3, SRAM1_BASE, SRAM_SIZE, SRAM, YES, NO ); // SRAM1/2/3/5
|
|
|
|
|
SET_REGION( 4, GRAPHICS_START, GRAPHICS_SIZE, SRAM, YES, NO ); // Frame buffer or display interface
|
|
|
|
|
SET_REGION( 5, PERIPH_BASE_NS, SIZE_512M, PERIPHERAL, YES, NO ); // Peripherals
|
|
|
|
|
SET_REGION( 0, KERNEL_START, KERNEL_SIZE, FLASH_CODE, NO, NO );
|
|
|
|
|
SET_REGION( 1, KERNEL_RAM_START, KERNEL_RAM_SIZE, SRAM, YES, NO );
|
|
|
|
|
SET_REGION( 2, COREAPP_START, COREAPP_SIZE, FLASH_CODE, NO, YES );
|
|
|
|
|
SET_REGION( 3, COREAPP_RAM1_START, COREAPP_RAM1_SIZE, SRAM, YES, YES );
|
|
|
|
|
SET_REGION( 4, COREAPP_RAM2_START, COREAPP_RAM2_SIZE, SRAM, YES, YES );
|
|
|
|
|
SET_REGION( 5, GRAPHICS_START, GRAPHICS_SIZE, SRAM, YES, YES );
|
|
|
|
|
#endif
|
|
|
|
|
#if defined(FIRMWARE)
|
|
|
|
|
// REGION ADDRESS SIZE TYPE WRITE UNPRIV
|
|
|
|
|
SET_REGION( 0, FIRMWARE_START, FIRMWARE_SIZE, FLASH_CODE, NO, NO );
|
|
|
|
|
SET_REGION( 1, SRAM1_BASE, SRAM_SIZE, SRAM, YES, NO );
|
|
|
|
|
DIS_REGION( 2 );
|
|
|
|
|
DIS_REGION( 3 );
|
|
|
|
|
DIS_REGION( 4 );
|
|
|
|
|
SET_REGION( 5, GRAPHICS_START, GRAPHICS_SIZE, SRAM, YES, NO );
|
|
|
|
|
#endif
|
|
|
|
|
#if defined(PRODTEST)
|
|
|
|
|
SET_REGION( 0, FIRMWARE_START, FIRMWARE_SIZE, FLASH_CODE, NO, NO );
|
|
|
|
|
SET_REGION( 1, SRAM1_BASE, SRAM_SIZE, SRAM, YES, NO );
|
|
|
|
|
DIS_REGION( 2 );
|
|
|
|
|
DIS_REGION( 3 );
|
|
|
|
|
DIS_REGION( 4 );
|
|
|
|
|
SET_REGION( 5, GRAPHICS_START, GRAPHICS_SIZE, SRAM, YES, NO );
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// Regions #6 and #7 are banked
|
|
|
|
|
|
|
|
|
|
DIS_REGION( 6 );
|
|
|
|
|
SET_REGION( 7, SRAM4_BASE, SIZE_16K, SRAM, YES, NO ); // SRAM4
|
|
|
|
|
DIS_REGION( 7 );
|
|
|
|
|
// clang-format on
|
|
|
|
|
HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void mpu_config_bootloader(void) {
|
|
|
|
|
HAL_MPU_Disable();
|
|
|
|
|
mpu_set_attributes();
|
|
|
|
|
// clang-format off
|
|
|
|
|
// REGION ADDRESS SIZE TYPE WRITE UNPRIV
|
|
|
|
|
SET_REGION( 0, SECRET_START, L2_PREV_SIZE, FLASH_DATA, YES, NO ); // Secret + Boardloader
|
|
|
|
|
SET_REGION( 1, BOOTLOADER_START, BOOTLOADER_SIZE, FLASH_CODE, NO, NO ); // Bootloader code
|
|
|
|
|
SET_REGION( 2, STORAGE_START, L2_REST_SIZE, FLASH_DATA, YES, NO ); // Storage + Firmware
|
|
|
|
|
SET_REGION( 3, SRAM1_BASE, SRAM_SIZE, SRAM, YES, NO ); // SRAM1/2/3/5
|
|
|
|
|
SET_REGION( 4, GRAPHICS_START, GRAPHICS_SIZE, SRAM, YES, NO ); // Frame buffer or display interface
|
|
|
|
|
SET_REGION( 5, PERIPH_BASE_NS, SIZE_512M, PERIPHERAL, YES, NO ); // Peripherals
|
|
|
|
|
SET_REGION( 6, FLASH_OTP_BASE, FLASH_OTP_SIZE, FLASH_DATA, YES, NO ); // OTP
|
|
|
|
|
SET_REGION( 7, SRAM4_BASE, SIZE_16K, SRAM, YES, NO ); // SRAM4
|
|
|
|
|
// clang-format on
|
|
|
|
|
HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI);
|
|
|
|
|
}
|
|
|
|
|
void mpu_init(void) {
|
|
|
|
|
mpu_driver_t* drv = &g_mpu_driver;
|
|
|
|
|
|
|
|
|
|
if (drv->initialized) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
irq_key_t irq_key = irq_lock();
|
|
|
|
|
|
|
|
|
|
void mpu_config_firmware_initial(void) {
|
|
|
|
|
HAL_MPU_Disable();
|
|
|
|
|
|
|
|
|
|
mpu_set_attributes();
|
|
|
|
|
// clang-format off
|
|
|
|
|
// REGION ADDRESS SIZE TYPE WRITE UNPRIV
|
|
|
|
|
SET_REGION( 0, BOOTLOADER_START, L3_PREV_SIZE_BLD, FLASH_DATA, YES, YES ); // Bootloader + Storage
|
|
|
|
|
SET_REGION( 1, FIRMWARE_START, FIRMWARE_SIZE, FLASH_CODE, NO, YES ); // Firmware
|
|
|
|
|
SET_REGION( 2, ASSETS_START, ASSETS_SIZE, FLASH_DATA, YES, YES ); // Assets
|
|
|
|
|
SET_REGION( 3, SRAM1_BASE, SRAM_SIZE, SRAM, YES, YES ); // SRAM1/2/3/5
|
|
|
|
|
SET_REGION( 4, GRAPHICS_START, GRAPHICS_SIZE, SRAM, YES, YES ); // Frame buffer or display interface
|
|
|
|
|
SET_REGION( 5, PERIPH_BASE_NS, SIZE_512M, PERIPHERAL, YES, YES ); // Peripherals
|
|
|
|
|
SET_REGION( 6, FLASH_OTP_BASE, SIZE_2K, FLASH_DATA, YES, YES ); // OTP
|
|
|
|
|
SET_REGION( 7, SRAM4_BASE, SIZE_16K, SRAM, YES, YES ); // SRAM4
|
|
|
|
|
// clang-format on
|
|
|
|
|
HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI);
|
|
|
|
|
|
|
|
|
|
mpu_init_fixed_regions();
|
|
|
|
|
|
|
|
|
|
drv->mode = MPU_MODE_DISABLED;
|
|
|
|
|
drv->initialized = true;
|
|
|
|
|
|
|
|
|
|
irq_unlock(irq_key);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void mpu_config_firmware(void) {
|
|
|
|
|
HAL_MPU_Disable();
|
|
|
|
|
mpu_set_attributes();
|
|
|
|
|
// clang-format off
|
|
|
|
|
// REGION ADDRESS SIZE TYPE WRITE UNPRIV
|
|
|
|
|
SET_REGION( 0, STORAGE_START, STORAGE_SIZE, FLASH_DATA, YES, YES ); // Storage
|
|
|
|
|
SET_REGION( 1, FIRMWARE_START, FIRMWARE_SIZE, FLASH_CODE, NO, YES ); // Firmware
|
|
|
|
|
SET_REGION( 2, ASSETS_START, ASSETS_SIZE, FLASH_DATA, YES, YES ); // Assets
|
|
|
|
|
SET_REGION( 3, SRAM1_BASE, SRAM_SIZE, SRAM, YES, YES ); // SRAM1/2/3/5
|
|
|
|
|
SET_REGION( 4, GRAPHICS_START, GRAPHICS_SIZE, SRAM, YES, YES ); // Frame buffer or display interface
|
|
|
|
|
SET_REGION( 5, PERIPH_BASE_NS, SIZE_512M, PERIPHERAL, YES, YES ); // Peripherals
|
|
|
|
|
SET_REGION( 6, FLASH_OTP_BASE, FLASH_OTP_SIZE, FLASH_DATA, YES, YES ); // OTP
|
|
|
|
|
SET_REGION( 7, SRAM4_BASE, SIZE_16K, SRAM, YES, YES ); // SRAM4
|
|
|
|
|
// clang-format on
|
|
|
|
|
HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI);
|
|
|
|
|
mpu_mode_t mpu_get_mode(void) {
|
|
|
|
|
mpu_driver_t* drv = &g_mpu_driver;
|
|
|
|
|
|
|
|
|
|
if (!drv->initialized) {
|
|
|
|
|
return MPU_MODE_DISABLED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return drv->mode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void mpu_config_prodtest_initial(void) {
|
|
|
|
|
mpu_mode_t mpu_reconfig(mpu_mode_t mode) {
|
|
|
|
|
mpu_driver_t* drv = &g_mpu_driver;
|
|
|
|
|
|
|
|
|
|
if (!drv->initialized) {
|
|
|
|
|
// Solves the issue when some IRQ handler tries to reconfigure
|
|
|
|
|
// MPU before it is initialized
|
|
|
|
|
return MPU_MODE_DISABLED;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
irq_key_t irq_key = irq_lock();
|
|
|
|
|
|
|
|
|
|
HAL_MPU_Disable();
|
|
|
|
|
mpu_set_attributes();
|
|
|
|
|
|
|
|
|
|
// Region #6 is banked
|
|
|
|
|
|
|
|
|
|
// clang-format off
|
|
|
|
|
// REGION ADDRESS SIZE TYPE WRITE UNPRIV
|
|
|
|
|
SET_REGION( 0, FLASH_BASE, L3_PREV_SIZE, FLASH_DATA, YES, YES ); // Secret, Bld, Storage
|
|
|
|
|
SET_REGION( 1, FIRMWARE_START, FIRMWARE_SIZE, FLASH_CODE, NO, YES ); // Firmware
|
|
|
|
|
SET_REGION( 2, ASSETS_START, ASSETS_SIZE, FLASH_DATA, YES, YES ); // Assets
|
|
|
|
|
SET_REGION( 3, SRAM1_BASE, SRAM_SIZE, SRAM, YES, YES ); // SRAM1/2/3/5
|
|
|
|
|
SET_REGION( 4, GRAPHICS_START, GRAPHICS_SIZE, SRAM, YES, YES ); // Frame buffer or display interface
|
|
|
|
|
SET_REGION( 5, PERIPH_BASE_NS, SIZE_512M, PERIPHERAL, YES, YES ); // Peripherals
|
|
|
|
|
SET_REGION( 6, FLASH_OTP_BASE, FLASH_OTP_SIZE, FLASH_DATA, YES, YES ); // OTP
|
|
|
|
|
SET_REGION( 7, SRAM4_BASE, SIZE_16K, SRAM, YES, YES ); // SRAM4
|
|
|
|
|
switch (mode) {
|
|
|
|
|
case MPU_MODE_DISABLED:
|
|
|
|
|
break;
|
|
|
|
|
case MPU_MODE_BOARDCAPS:
|
|
|
|
|
// REGION ADDRESS SIZE TYPE WRITE UNPRIV
|
|
|
|
|
SET_REGION( 6, BOARDLOADER_START, BOARDLOADER_SIZE, FLASH_DATA, NO, NO );
|
|
|
|
|
break;
|
|
|
|
|
case MPU_MODE_BOOTUPDATE:
|
|
|
|
|
SET_REGION( 6, BOOTLOADER_START, BOOTLOADER_SIZE, FLASH_DATA, YES, NO );
|
|
|
|
|
break;
|
|
|
|
|
case MPU_MODE_OTP:
|
|
|
|
|
SET_REGION( 6, FLASH_OTP_BASE, OTP_AND_ID_SIZE, FLASH_DATA, NO, NO );
|
|
|
|
|
break;
|
|
|
|
|
case MPU_MODE_SECRET:
|
|
|
|
|
SET_REGION( 6, SECRET_START, SECRET_SIZE, FLASH_DATA, YES, NO );
|
|
|
|
|
break;
|
|
|
|
|
case MPU_MODE_STORAGE:
|
|
|
|
|
SET_REGION( 6, STORAGE_START, STORAGE_SIZE, FLASH_DATA, YES, NO );
|
|
|
|
|
break;
|
|
|
|
|
case MPU_MODE_ASSETS:
|
|
|
|
|
SET_REGION( 6, ASSETS_START, ASSETS_SIZE, FLASH_DATA, YES, NO );
|
|
|
|
|
break;
|
|
|
|
|
case MPU_MODE_APP:
|
|
|
|
|
SET_REGION( 6, ASSETS_START, ASSETS_SIZE, FLASH_DATA, NO, YES );
|
|
|
|
|
break;
|
|
|
|
|
case MPU_MODE_DEFAULT:
|
|
|
|
|
case MPU_MODE_FSMC_REGS:
|
|
|
|
|
default:
|
|
|
|
|
DIS_REGION( 6 );
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
// clang-format on
|
|
|
|
|
HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void mpu_config_prodtest(void) {
|
|
|
|
|
HAL_MPU_Disable();
|
|
|
|
|
mpu_set_attributes();
|
|
|
|
|
// Region #7 is banked
|
|
|
|
|
|
|
|
|
|
// clang-format off
|
|
|
|
|
// REGION ADDRESS SIZE TYPE WRITE UNPRIV
|
|
|
|
|
SET_REGION( 0, STORAGE_START, STORAGE_SIZE, FLASH_DATA, YES, YES ); // Storage
|
|
|
|
|
SET_REGION( 1, FIRMWARE_START, FIRMWARE_SIZE, FLASH_CODE, YES, YES ); // Firmware
|
|
|
|
|
SET_REGION( 2, ASSETS_START, ASSETS_SIZE, FLASH_DATA, YES, YES ); // Assets
|
|
|
|
|
SET_REGION( 3, SRAM1_BASE, SRAM_SIZE, SRAM, YES, YES ); // SRAM1/2/3/5
|
|
|
|
|
SET_REGION( 4, GRAPHICS_START, GRAPHICS_SIZE, SRAM, YES, YES ); // Frame buffer or display interface
|
|
|
|
|
SET_REGION( 5, PERIPH_BASE_NS, SIZE_512M, PERIPHERAL, YES, YES ); // Peripherals
|
|
|
|
|
SET_REGION( 6, FLASH_OTP_BASE, OTP_AND_ID_SIZE, FLASH_DATA, YES, YES ); // OTP + device ID
|
|
|
|
|
SET_REGION( 7, SRAM4_BASE, SIZE_16K, SRAM, YES, YES ); // SRAM4
|
|
|
|
|
switch (mode) {
|
|
|
|
|
case MPU_MODE_APP:
|
|
|
|
|
// REGION ADDRESS SIZE TYPE WRITE UNPRIV
|
|
|
|
|
// DMA2D peripherals (Uprivileged, Read-Write, Non-Executable)
|
|
|
|
|
SET_REGION( 7, 0x5002B000, SIZE_3K, PERIPHERAL, YES, YES );
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
// All peripherals (Pivileged, Read-Write, Non-Executable)
|
|
|
|
|
SET_REGION( 7, PERIPH_BASE_NS, SIZE_512M, PERIPHERAL, YES, NO );
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
// clang-format on
|
|
|
|
|
HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI);
|
|
|
|
|
|
|
|
|
|
if (mode != MPU_MODE_DISABLED) {
|
|
|
|
|
HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
mpu_mode_t prev_mode = drv->mode;
|
|
|
|
|
drv->mode = mode;
|
|
|
|
|
|
|
|
|
|
irq_unlock(irq_key);
|
|
|
|
|
|
|
|
|
|
return prev_mode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void mpu_config_off(void) { HAL_MPU_Disable(); }
|
|
|
|
|
void mpu_restore(mpu_mode_t mode) { mpu_reconfig(mode); }
|
|
|
|
|