mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-07-03 21:32:33 +00:00
feat(core): support mpu region setup per applet
[no changelog]
This commit is contained in:
parent
a48abdb577
commit
a133a01a1f
@ -17,8 +17,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TREZORHAL_MPU_H
|
||||
#define TREZORHAL_MPU_H
|
||||
#pragma once
|
||||
|
||||
#include <trezor_types.h>
|
||||
|
||||
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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,
|
||||
};
|
||||
|
@ -17,8 +17,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TREZORHAL_APPLET_H
|
||||
#define TREZORHAL_APPLET_H
|
||||
#pragma once
|
||||
|
||||
#include <trezor_types.h>
|
||||
|
||||
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <trezor_bsp.h>
|
||||
#include <trezor_rtl.h>
|
||||
|
||||
#include <sys/applet.h>
|
||||
#include <sys/bootutils.h>
|
||||
#include <sys/irq.h>
|
||||
#include <sys/linker_utils.h>
|
||||
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user