diff --git a/core/embed/sys/mpu/inc/sys/mpu.h b/core/embed/sys/mpu/inc/sys/mpu.h index ede82b4c4e..6b74ba325c 100644 --- a/core/embed/sys/mpu/inc/sys/mpu.h +++ b/core/embed/sys/mpu/inc/sys/mpu.h @@ -17,8 +17,7 @@ * along with this program. If not, see . */ -#ifndef TREZORHAL_MPU_H -#define TREZORHAL_MPU_H +#pragma once #include @@ -68,6 +67,28 @@ mpu_mode_t mpu_reconfig(mpu_mode_t mode); // Same as `mpu_reconfig()`, but with a more descriptive name. void mpu_restore(mpu_mode_t mode); +typedef struct { + uint32_t start; + uint32_t size; +} mpu_area_t; + +// Applet memory layout +typedef struct { + // Read/write data area #1 + mpu_area_t data1; + // Read/write data area #2 + mpu_area_t data2; + // Read-only code area #1 + mpu_area_t code1; + // Read-only code area #2 + mpu_area_t code2; + +} applet_layout_t; + +// Sets the MPU to allow unprivileged access to the given applet +// (just one applet at a time can be visible) +void mpu_set_active_applet(applet_layout_t* layout); + // Sets the MPU to allow access to the // framebuffer at the given address and size. // @@ -83,5 +104,3 @@ void mpu_set_active_fb(const void* addr, size_t size); bool mpu_inside_active_fb(const void* addr, size_t size); #endif // KERNEL_MODE - -#endif // TREZORHAL_MPU_H diff --git a/core/embed/sys/mpu/stm32f4/mpu.c b/core/embed/sys/mpu/stm32f4/mpu.c index 213e840cfd..3e61c06e31 100644 --- a/core/embed/sys/mpu/stm32f4/mpu.c +++ b/core/embed/sys/mpu/stm32f4/mpu.c @@ -218,6 +218,10 @@ mpu_mode_t mpu_get_mode(void) { return drv->mode; } +void mpu_set_active_applet(applet_layout_t* layout) { + // On STM32F4 one coreapp applet is allowed to run at a time +} + void mpu_set_active_fb(const void* addr, size_t size) { mpu_driver_t* drv = &g_mpu_driver; diff --git a/core/embed/sys/mpu/stm32u5/mpu.c b/core/embed/sys/mpu/stm32u5/mpu.c index 79fa1efc54..bb850f76b8 100644 --- a/core/embed/sys/mpu/stm32u5/mpu.c +++ b/core/embed/sys/mpu/stm32u5/mpu.c @@ -152,24 +152,12 @@ extern uint8_t _uflash_start; extern uint8_t _uflash_end; #define KERNEL_FLASH_U_START (uint32_t) & _uflash_start #define KERNEL_FLASH_U_SIZE ((uint32_t) & _uflash_end - KERNEL_FLASH_U_START) - #define KERNEL_FLASH_SIZE (KERNEL_SIZE - KERNEL_FLASH_U_SIZE) - -#define COREAPP_FLASH_START \ - (COREAPP_CODE_ALIGN(KERNEL_FLASH_START + KERNEL_SIZE) - KERNEL_FLASH_U_SIZE) - #else - #define KERNEL_FLASH_SIZE KERNEL_SIZE - -#define COREAPP_FLASH_START \ - (COREAPP_CODE_ALIGN(KERNEL_FLASH_START + KERNEL_SIZE)) #endif -#define COREAPP_FLASH_SIZE \ - (FIRMWARE_MAXSIZE - (COREAPP_FLASH_START - FIRMWARE_START)) - -#endif +#endif // KERNEL typedef struct { // Set if the driver is initialized @@ -224,13 +212,9 @@ static void mpu_init_fixed_regions(void) { // REGION ADDRESS SIZE TYPE WRITE UNPRIV SET_REGRUN( 0, KERNEL_FLASH_START, KERNEL_FLASH_SIZE, FLASH_CODE, NO, NO ); // Kernel Code SET_REGION( 1, MAIN_RAM_START, MAIN_RAM_SIZE, SRAM, YES, NO ); // Kernel RAM - SET_REGRUN( 2, COREAPP_FLASH_START, COREAPP_FLASH_SIZE, FLASH_CODE, NO, YES ); // CoreApp Code - SET_REGION( 3, AUX1_RAM_START, AUX1_RAM_SIZE, SRAM, YES, YES ); // CoraApp RAM -#ifdef STM32U585xx - SET_REGION( 4, AUX2_RAM_START, AUX2_RAM_SIZE, SRAM, YES, YES ); // CoraAPP RAM2 -#else - DIS_REGION( 4 ); -#endif + DIS_REGION( 2 ); // reserved for applets + DIS_REGION( 3 ); // reserved for applets + DIS_REGION( 4 ); // reserved for applets #elif defined(FIRMWARE) // REGION ADDRESS SIZE TYPE WRITE UNPRIV @@ -288,6 +272,50 @@ mpu_mode_t mpu_get_mode(void) { return drv->mode; } +void mpu_set_active_applet(applet_layout_t* layout) { + mpu_driver_t* drv = &g_mpu_driver; + + if (!drv->initialized) { + return; + } + + irq_key_t irq_key = irq_lock(); + + mpu_disable(); + + if (layout != NULL) { + // clang-format off + if (layout->code1.start != 0 && layout->code1.size != 0) { + SET_REGRUN( 2, layout->code1.start, layout->code1.size, FLASH_CODE, NO, YES ); + } else { + DIS_REGION( 2 ); + } + + if (layout->data1.start != 0 && layout->data1.size != 0) { + SET_REGRUN( 3, layout->data1.start, layout->data1.size, SRAM, YES, YES ); + } else { + DIS_REGION( 3 ); + } + + if (layout->data2.start != 0 && layout->data2.size != 0) { + SET_REGRUN( 4, layout->data2.start, layout->data2.size, SRAM, YES, YES ); + } else { + DIS_REGION( 4 ); + } + // clang-format on + } else { + DIS_REGION(2); + DIS_REGION(3); + DIS_REGION(4); + } + + if (drv->mode != MPU_MODE_DISABLED) { + mpu_enable(); + } + + irq_unlock(irq_key); +} + void mpu_set_active_fb(const void* addr, size_t size) { mpu_driver_t* drv = &g_mpu_driver; diff --git a/core/embed/sys/syscall/stm32/syscall_probe.c b/core/embed/sys/syscall/stm32/syscall_probe.c index 935fbd77a5..c4fd9d1180 100644 --- a/core/embed/sys/syscall/stm32/syscall_probe.c +++ b/core/embed/sys/syscall/stm32/syscall_probe.c @@ -30,7 +30,7 @@ #ifdef KERNEL static inline bool inside_area(const void *addr, size_t len, - const applet_memory_t *area) { + const mpu_area_t *area) { return ((uintptr_t)addr >= area->start) && ((uintptr_t)addr + len <= area->start + area->size); } @@ -73,7 +73,7 @@ bool probe_read_access(const void *addr, size_t len) { return true; } - static const applet_memory_t assets = { + static const mpu_area_t assets = { .start = ASSETS_START, .size = ASSETS_MAXSIZE, }; diff --git a/core/embed/sys/task/inc/sys/applet.h b/core/embed/sys/task/inc/sys/applet.h index 79c09bf186..f074d5a265 100644 --- a/core/embed/sys/task/inc/sys/applet.h +++ b/core/embed/sys/task/inc/sys/applet.h @@ -17,8 +17,7 @@ * along with this program. If not, see . */ -#ifndef TREZORHAL_APPLET_H -#define TREZORHAL_APPLET_H +#pragma once #include @@ -29,32 +28,14 @@ // Applet entry point typedef void (*applet_startup_t)(const char* args, uint32_t random); -typedef struct { - uint32_t start; - uint32_t size; -} applet_memory_t; - // Applet header found at the beginning of the applet binary typedef struct { // Stack area - applet_memory_t stack; + mpu_area_t stack; // Applet entry point applet_startup_t startup; } applet_header_t; -// Applet memory layout -typedef struct { - // Read/write data area #1 - applet_memory_t data1; - // Read/write data area #2 - applet_memory_t data2; - // Read-only code area #1 - applet_memory_t code1; - // Read-only code area #2 - applet_memory_t code2; - -} applet_layout_t; - // Applet privileges typedef struct { bool assets_area_access; @@ -102,5 +83,3 @@ bool applet_is_alive(applet_t* applet); applet_t* applet_active(void); #endif // KERNEL - -#endif // TREZORHAL_APPLET_H diff --git a/core/embed/sys/task/stm32/applet.c b/core/embed/sys/task/stm32/applet.c index 272ed3317e..a9e6c6a0fc 100644 --- a/core/embed/sys/task/stm32/applet.c +++ b/core/embed/sys/task/stm32/applet.c @@ -42,6 +42,8 @@ void applet_init(applet_t* applet, applet_header_t* header, } static void applet_clear_memory(applet_t* applet) { + mpu_set_active_applet(&applet->layout); + if (applet->layout.data1.size > 0) { memset((void*)applet->layout.data1.start, 0, applet->layout.data1.size); } diff --git a/core/embed/sys/task/stm32/systask.c b/core/embed/sys/task/stm32/systask.c index b8250335c5..1194af233d 100644 --- a/core/embed/sys/task/stm32/systask.c +++ b/core/embed/sys/task/stm32/systask.c @@ -22,6 +22,7 @@ #include #include +#include #include #include #include @@ -432,6 +433,13 @@ __attribute((no_stack_protector, used)) static uint32_t scheduler_pendsv( // Setup the MPU for the new task mpu_reconfig(next_task->mpu_mode); +#ifdef KERNEL + if (next_task->applet != NULL) { + applet_t* applet = (applet_t*)next_task->applet; + mpu_set_active_applet(&applet->layout); + } +#endif + IRQ_LOG_EXIT(); return (uint32_t)next_task;