Skip to content

Commit

Permalink
feat(core): added access control for framebuffer
Browse files Browse the repository at this point in the history
[no changelog]
  • Loading branch information
cepetr committed Oct 16, 2024
1 parent 91c5ea3 commit f8861b5
Show file tree
Hide file tree
Showing 9 changed files with 85 additions and 4 deletions.
12 changes: 12 additions & 0 deletions core/embed/trezorhal/mpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#ifndef TREZORHAL_MPU_H
#define TREZORHAL_MPU_H

#include <stddef.h>

#ifdef KERNEL_MODE

// The MPU driver can be set to on of the following modes.
Expand Down Expand Up @@ -66,6 +68,16 @@ 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);

// Sets the MPU to allow unprivileged access to the
// framebuffer at the given address and size.
//
// The changes are made effective after the next MPU reconfiguration
// to the `MPU_MODE_APP` mode.
//
// Addr and size must be aligned to the 32-byte boundary.
// If addr == 0, the framebuffer is not accessible in the unprivileged mode.
void mpu_set_unpriv_fb(void* addr, size_t size);

#endif // KERNEL_MODE

#endif // TREZORHAL_MPU_H
4 changes: 4 additions & 0 deletions core/embed/trezorhal/stm32f4/mpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,10 @@ mpu_mode_t mpu_get_mode(void) {
return drv->mode;
}

void mpu_set_unpriv_fb(void* addr, size_t size) {
// Not implemented on STM32F4
}

// STM32F4xx memory map
//
// 0x08000000 2MB FLASH
Expand Down
5 changes: 5 additions & 0 deletions core/embed/trezorhal/stm32f4/xdisplay/st-7789/display_fb.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,8 @@ bool display_get_frame_buffer(display_fb_info_t *fb) {

fb->ptr = get_fb_ptr(drv->queue.wix);
fb->stride = DISPLAY_RESX * sizeof(uint16_t);
// Enable access to the frame buffer from the unprivileged code
mpu_set_unpriv_fb(fb->ptr, PHYSICAL_FRAME_BUFFER_SIZE);

return true;
}
Expand Down Expand Up @@ -213,6 +215,9 @@ void display_refresh(void) {
return;
}

// Disable access to the frame buffer from the unprivileged code
mpu_set_unpriv_fb(NULL, 0);

#ifndef BOARDLOADER
if (is_mode_exception()) {
// Disable scheduling of any new background copying
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

#include "display_internal.h"
#include "ili9341_spi.h"
#include "mpu.h"
#include "xdisplay.h"

#if (DISPLAY_RESX != 240) || (DISPLAY_RESY != 320)
Expand Down Expand Up @@ -133,12 +134,17 @@ bool display_get_frame_buffer(display_fb_info_t *fb) {
} else {
fb->ptr = (void *)drv->framebuf;
fb->stride = DISPLAY_RESX * sizeof(uint16_t);
// Enable access to the frame buffer from the unprivileged code
mpu_set_unpriv_fb(fb->ptr, FRAME_BUFFER_SIZE);
return true;
}
}

void display_refresh(void) {
// Do nothing as using just a single frame buffer

// Disable access to the frame buffer from the unprivileged code
mpu_set_unpriv_fb(NULL, 0);
}

void display_fill(const gfx_bitblt_t *bb) {
Expand Down
14 changes: 13 additions & 1 deletion core/embed/trezorhal/stm32f4/xdisplay/ug-2828/display_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
#include TREZOR_BOARD
#include STM32_HAL_H

#include "mpu.h"
#include "xdisplay.h"

#if (DISPLAY_RESX != 128) || (DISPLAY_RESY != 128)
Expand All @@ -35,12 +36,16 @@
// This type of displayed was used on some preliminary dev kits for T3T1 (Trezor
// TS3)

#define FRAME_BUFFER_SIZE (DISPLAY_RESX * DISPLAY_RESY)

__attribute__((section(".fb1"))) uint8_t g_framebuf[FRAME_BUFFER_SIZE];

// Display driver context.
typedef struct {
// Set if the driver is initialized
bool initialized;
// Frame buffer (8-bit Mono)
uint8_t framebuf[DISPLAY_RESX * DISPLAY_RESY];
uint8_t *framebuf;
// Current display orientation (0 or 180)
int orientation_angle;
// Current backlight level ranging from 0 to 255
Expand Down Expand Up @@ -307,6 +312,7 @@ void display_init(display_content_mode_t mode) {
}

memset(drv, 0, sizeof(display_driver_t));
drv->framebuf = g_framebuf;

if (mode == DISPLAY_RESET_CONTENT) {
// Initialize GPIO & FSMC controller
Expand Down Expand Up @@ -400,6 +406,8 @@ bool display_get_frame_buffer(display_fb_info_t *fb) {
} else {
fb->ptr = &drv->framebuf[0];
fb->stride = DISPLAY_RESX;
// Enable access to the frame buffer from the unprivileged code
mpu_set_unpriv_fb(fb->ptr, FRAME_BUFFER_SIZE);
return true;
}
}
Expand All @@ -411,6 +419,10 @@ void display_refresh(void) {
return NULL;
}

// Disable access to the frame buffer from the unprivileged code
mpu_set_unpriv_fb(NULL, 0);

// Copy the frame buffer to the display
display_sync_with_fb();
}

Expand Down
14 changes: 11 additions & 3 deletions core/embed/trezorhal/stm32f4/xdisplay/vg-2864/display_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include TREZOR_BOARD
#include STM32_HAL_H

#include "mpu.h"
#include "xdisplay.h"

#ifdef USE_CONSUMPTION_MASK
Expand All @@ -41,7 +42,9 @@
//
// This type of display is used with T3B1 model (Trezor TS3)

__attribute__((section(".fb1"))) uint8_t framebuf[DISPLAY_RESX * DISPLAY_RESY];
#define FRAME_BUFFER_SIZE (DISPLAY_RESX * DISPLAY_RESY)

__attribute__((section(".fb1"))) uint8_t g_framebuf[FRAME_BUFFER_SIZE];

// Display driver context.
typedef struct {
Expand Down Expand Up @@ -236,7 +239,7 @@ void display_init(display_content_mode_t mode) {

memset(drv, 0, sizeof(display_driver_t));
drv->backlight_level = 255;
drv->framebuf = framebuf;
drv->framebuf = g_framebuf;

if (mode == DISPLAY_RESET_CONTENT) {
OLED_DC_CLK_ENA();
Expand Down Expand Up @@ -369,6 +372,8 @@ bool display_get_frame_buffer(display_fb_info_t *fb) {
} else {
fb->ptr = &drv->framebuf[0];
fb->stride = DISPLAY_RESX;
// Enable access to the frame buffer from the unprivileged code
mpu_set_unpriv_fb(fb->ptr, FRAME_BUFFER_SIZE);
return true;
}
}
Expand All @@ -386,7 +391,10 @@ void display_refresh(void) {
consumption_mask_randomize();
#endif

// Sends the current frame buffer to the display
// Disable access to the frame buffer from the unprivileged code
mpu_set_unpriv_fb(NULL, 0);

// Copy the frame buffer to the display
display_sync_with_fb(drv);
}

Expand Down
23 changes: 23 additions & 0 deletions core/embed/trezorhal/stm32u5/mpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,11 @@ typedef struct {
bool initialized;
// Current mode
mpu_mode_t mode;
// Address of the framebuffer visible to unprivileged code
// (if set to 0, the framebuffer is not accessible)
uint32_t unpriv_fb_addr;
// Size of the framebuffer in bytes
size_t unpriv_fb_size;

} mpu_driver_t;

Expand Down Expand Up @@ -287,6 +292,17 @@ mpu_mode_t mpu_get_mode(void) {
return drv->mode;
}

void mpu_set_unpriv_fb(void* addr, size_t size) {
mpu_driver_t* drv = &g_mpu_driver;

if (!drv->initialized) {
return;
}

drv->unpriv_fb_addr = (uint32_t)addr;
drv->unpriv_fb_size = size;
}

mpu_mode_t mpu_reconfig(mpu_mode_t mode) {
mpu_driver_t* drv = &g_mpu_driver;

Expand All @@ -307,6 +323,13 @@ mpu_mode_t mpu_reconfig(mpu_mode_t mode) {
case MPU_MODE_SAES:
SET_REGION( 5, PERIPH_BASE_NS, PERIPH_SIZE, PERIPHERAL, YES, YES ); // Peripherals - SAES, TAMP
break;
case MPU_MODE_APP:
if (drv->unpriv_fb_addr != 0) {
SET_REGION( 5, drv->unpriv_fb_addr, drv->unpriv_fb_size, SRAM, YES, YES ); // Frame buffer or display interface
} else {
DIS_REGION( 5 );
}
break;
default:
SET_REGION( 5, GRAPHICS_START, GRAPHICS_SIZE, SRAM, YES, YES ); // Frame buffer or display interface
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

#include <xdisplay.h>
#include "display_internal.h"
#include "mpu.h"

#ifdef KERNEL_MODE

Expand Down Expand Up @@ -67,6 +68,9 @@ bool display_get_frame_buffer(display_fb_info_t *fb) {
fb->ptr = (void *)addr;
fb->stride = fb_stride;

// Enable access to the frame buffer from the unprivileged code
mpu_set_unpriv_fb(fb->ptr, VIRTUAL_FRAME_BUFFER_SIZE);

return true;
}

Expand All @@ -77,6 +81,9 @@ void display_refresh(void) {
return;
}

// Disable access to the frame buffer from the unprivileged code
mpu_set_unpriv_fb(NULL, 0);

if (current_frame_buffer == 0) {
current_frame_buffer = 1;
BSP_LCD_SetFrameBuffer(0, GFXMMU_VIRTUAL_BUFFER1_BASE_S);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ extern display_driver_t g_display_driver;
// Pitch (in pixels) of the virtual frame buffer
#define FRAME_BUFFER_PIXELS_PER_LINE 768

// Size of the virtual frame buffer in bytes
#define VIRTUAL_FRAME_BUFFER_SIZE \
(FRAME_BUFFER_PIXELS_PER_LINE * DISPLAY_RESY * 4)

// Physical frame buffers in internal SRAM memory
//
// Both frame buffers layes in the fixed addresses that
Expand Down

0 comments on commit f8861b5

Please sign in to comment.