Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Framebuffer access control #4267

Merged
merged 1 commit into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@

#include <xdisplay.h>

#include "backlight_pwm.h"
#include "display_fb.h"
#include "display_internal.h"
#include "display_io.h"
#include "display_panel.h"

#include "backlight_pwm.h"
#include "mpu.h"

#ifndef BOARDLOADER
#include "bg_copy.h"
Expand Down Expand Up @@ -98,6 +98,8 @@ void display_deinit(display_content_mode_t mode) {
#endif
#endif

mpu_set_unpriv_fb(NULL, 0);

backlight_pwm_deinit(mode == DISPLAY_RESET_CONTENT ? BACKLIGHT_RESET
: BACKLIGHT_RETAIN);

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 @@ -177,6 +177,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 @@ -215,6 +217,9 @@ void display_refresh(void) {
return;
}

// Disable access to the frame buffer from the unprivileged code
mpu_set_unpriv_fb(NULL, 0);
TychoVrahe marked this conversation as resolved.
Show resolved Hide resolved

#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 @@ -73,6 +74,8 @@ void display_init(display_content_mode_t mode) {
void display_deinit(display_content_mode_t mode) {
display_driver_t *drv = &g_display_driver;

mpu_set_unpriv_fb(NULL, 0);

drv->initialized = false;
}

Expand Down Expand Up @@ -133,12 +136,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
16 changes: 15 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 All @@ -321,6 +327,8 @@ void display_init(display_content_mode_t mode) {
void display_deinit(display_content_mode_t mode) {
display_driver_t *drv = &g_display_driver;

mpu_set_unpriv_fb(NULL, 0);

drv->initialized = false;
}

Expand Down Expand Up @@ -400,6 +408,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 +421,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
16 changes: 13 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 @@ -308,6 +311,8 @@ void display_init(display_content_mode_t mode) {
void display_deinit(display_content_mode_t mode) {
display_driver_t *drv = &g_display_driver;

mpu_set_unpriv_fb(NULL, 0);

drv->initialized = false;
}

Expand Down Expand Up @@ -369,6 +374,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 +393,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
} 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 @@ -24,6 +24,7 @@
#include STM32_HAL_H

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

#if (DISPLAY_RESX != 240) || (DISPLAY_RESY != 240)
Expand Down Expand Up @@ -110,6 +111,8 @@ void display_deinit(display_content_mode_t mode) {
BSP_LCD_DeInit(0);
}

mpu_set_unpriv_fb(NULL, 0);

drv->initialized = false;
}

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
Loading