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;