mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-07-04 22:02:34 +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/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef TREZORHAL_MPU_H
|
#pragma once
|
||||||
#define TREZORHAL_MPU_H
|
|
||||||
|
|
||||||
#include <trezor_types.h>
|
#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.
|
// Same as `mpu_reconfig()`, but with a more descriptive name.
|
||||||
void mpu_restore(mpu_mode_t mode);
|
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
|
// Sets the MPU to allow access to the
|
||||||
// framebuffer at the given address and size.
|
// 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);
|
bool mpu_inside_active_fb(const void* addr, size_t size);
|
||||||
|
|
||||||
#endif // KERNEL_MODE
|
#endif // KERNEL_MODE
|
||||||
|
|
||||||
#endif // TREZORHAL_MPU_H
|
|
||||||
|
@ -218,6 +218,10 @@ mpu_mode_t mpu_get_mode(void) {
|
|||||||
return drv->mode;
|
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) {
|
void mpu_set_active_fb(const void* addr, size_t size) {
|
||||||
mpu_driver_t* drv = &g_mpu_driver;
|
mpu_driver_t* drv = &g_mpu_driver;
|
||||||
|
|
||||||
|
@ -152,24 +152,12 @@ extern uint8_t _uflash_start;
|
|||||||
extern uint8_t _uflash_end;
|
extern uint8_t _uflash_end;
|
||||||
#define KERNEL_FLASH_U_START (uint32_t) & _uflash_start
|
#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_U_SIZE ((uint32_t) & _uflash_end - KERNEL_FLASH_U_START)
|
||||||
|
|
||||||
#define KERNEL_FLASH_SIZE (KERNEL_SIZE - KERNEL_FLASH_U_SIZE)
|
#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
|
#else
|
||||||
|
|
||||||
#define KERNEL_FLASH_SIZE KERNEL_SIZE
|
#define KERNEL_FLASH_SIZE KERNEL_SIZE
|
||||||
|
|
||||||
#define COREAPP_FLASH_START \
|
|
||||||
(COREAPP_CODE_ALIGN(KERNEL_FLASH_START + KERNEL_SIZE))
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define COREAPP_FLASH_SIZE \
|
#endif // KERNEL
|
||||||
(FIRMWARE_MAXSIZE - (COREAPP_FLASH_START - FIRMWARE_START))
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
// Set if the driver is initialized
|
// Set if the driver is initialized
|
||||||
@ -224,13 +212,9 @@ static void mpu_init_fixed_regions(void) {
|
|||||||
// REGION ADDRESS SIZE TYPE WRITE UNPRIV
|
// REGION ADDRESS SIZE TYPE WRITE UNPRIV
|
||||||
SET_REGRUN( 0, KERNEL_FLASH_START, KERNEL_FLASH_SIZE, FLASH_CODE, NO, NO ); // Kernel Code
|
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_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
|
DIS_REGION( 2 ); // reserved for applets
|
||||||
SET_REGION( 3, AUX1_RAM_START, AUX1_RAM_SIZE, SRAM, YES, YES ); // CoraApp RAM
|
DIS_REGION( 3 ); // reserved for applets
|
||||||
#ifdef STM32U585xx
|
DIS_REGION( 4 ); // reserved for applets
|
||||||
SET_REGION( 4, AUX2_RAM_START, AUX2_RAM_SIZE, SRAM, YES, YES ); // CoraAPP RAM2
|
|
||||||
#else
|
|
||||||
DIS_REGION( 4 );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#elif defined(FIRMWARE)
|
#elif defined(FIRMWARE)
|
||||||
// REGION ADDRESS SIZE TYPE WRITE UNPRIV
|
// REGION ADDRESS SIZE TYPE WRITE UNPRIV
|
||||||
@ -288,6 +272,50 @@ mpu_mode_t mpu_get_mode(void) {
|
|||||||
return drv->mode;
|
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) {
|
void mpu_set_active_fb(const void* addr, size_t size) {
|
||||||
mpu_driver_t* drv = &g_mpu_driver;
|
mpu_driver_t* drv = &g_mpu_driver;
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
#ifdef KERNEL
|
#ifdef KERNEL
|
||||||
|
|
||||||
static inline bool inside_area(const void *addr, size_t len,
|
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) &&
|
return ((uintptr_t)addr >= area->start) &&
|
||||||
((uintptr_t)addr + len <= area->start + area->size);
|
((uintptr_t)addr + len <= area->start + area->size);
|
||||||
}
|
}
|
||||||
@ -73,7 +73,7 @@ bool probe_read_access(const void *addr, size_t len) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const applet_memory_t assets = {
|
static const mpu_area_t assets = {
|
||||||
.start = ASSETS_START,
|
.start = ASSETS_START,
|
||||||
.size = ASSETS_MAXSIZE,
|
.size = ASSETS_MAXSIZE,
|
||||||
};
|
};
|
||||||
|
@ -17,8 +17,7 @@
|
|||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef TREZORHAL_APPLET_H
|
#pragma once
|
||||||
#define TREZORHAL_APPLET_H
|
|
||||||
|
|
||||||
#include <trezor_types.h>
|
#include <trezor_types.h>
|
||||||
|
|
||||||
@ -29,32 +28,14 @@
|
|||||||
// Applet entry point
|
// Applet entry point
|
||||||
typedef void (*applet_startup_t)(const char* args, uint32_t random);
|
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
|
// Applet header found at the beginning of the applet binary
|
||||||
typedef struct {
|
typedef struct {
|
||||||
// Stack area
|
// Stack area
|
||||||
applet_memory_t stack;
|
mpu_area_t stack;
|
||||||
// Applet entry point
|
// Applet entry point
|
||||||
applet_startup_t startup;
|
applet_startup_t startup;
|
||||||
} applet_header_t;
|
} 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
|
// Applet privileges
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool assets_area_access;
|
bool assets_area_access;
|
||||||
@ -102,5 +83,3 @@ bool applet_is_alive(applet_t* applet);
|
|||||||
applet_t* applet_active(void);
|
applet_t* applet_active(void);
|
||||||
|
|
||||||
#endif // KERNEL
|
#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) {
|
static void applet_clear_memory(applet_t* applet) {
|
||||||
|
mpu_set_active_applet(&applet->layout);
|
||||||
|
|
||||||
if (applet->layout.data1.size > 0) {
|
if (applet->layout.data1.size > 0) {
|
||||||
memset((void*)applet->layout.data1.start, 0, applet->layout.data1.size);
|
memset((void*)applet->layout.data1.start, 0, applet->layout.data1.size);
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include <trezor_bsp.h>
|
#include <trezor_bsp.h>
|
||||||
#include <trezor_rtl.h>
|
#include <trezor_rtl.h>
|
||||||
|
|
||||||
|
#include <sys/applet.h>
|
||||||
#include <sys/bootutils.h>
|
#include <sys/bootutils.h>
|
||||||
#include <sys/irq.h>
|
#include <sys/irq.h>
|
||||||
#include <sys/linker_utils.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
|
// Setup the MPU for the new task
|
||||||
mpu_reconfig(next_task->mpu_mode);
|
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();
|
IRQ_LOG_EXIT();
|
||||||
|
|
||||||
return (uint32_t)next_task;
|
return (uint32_t)next_task;
|
||||||
|
Loading…
Reference in New Issue
Block a user