Skip to content
Permalink
Browse files

bootloader: enable MPU, introduce delays to USB stack

  • Loading branch information...
prusnak committed Feb 21, 2019
1 parent 5560a35 commit 828ba7b5b01f9997a2f8e63e2e5f19d4a3f607af
@@ -83,6 +83,7 @@ SOURCE_TREZORHAL = [
'embed/trezorhal/image.c',
'embed/trezorhal/flash.c',
'embed/trezorhal/mini_printf.c',
'embed/trezorhal/mpu.c',
'embed/trezorhal/rng.c',
'embed/trezorhal/stm32.c',
'embed/trezorhal/touch.c',
@@ -21,6 +21,7 @@
#include <sys/types.h>

#include "common.h"
#include "mpu.h"
#include "image.h"
#include "flash.h"
#include "display.h"
@@ -224,6 +225,8 @@ static void check_bootloader_version(void)

int main(void)
{
mpu_config_bootloader();

main_start:
display_clear();

@@ -379,9 +382,10 @@ int main(void)
ui_fadeout();
}

// mpu_config();
// mpu_config_firmware();
// jump_to_unprivileged(FIRMWARE_START + vhdr.hdrlen + IMAGE_HEADER_SIZE);

mpu_config_off();
jump_to(FIRMWARE_START + vhdr.hdrlen + IMAGE_HEADER_SIZE);

return 0;
@@ -54,7 +54,7 @@ int main(void)
#if TREZOR_MODEL == T
check_and_replace_bootloader();
// Enable MPU
mpu_config();
mpu_config_firmware();
#endif

// Init peripherals
@@ -29,7 +29,8 @@

#include "stm32f4xx_ll_utils.h"

void shutdown(void);
// from util.s
extern void shutdown(void);

#define COLOR_FATAL_ERROR RGB16(0x7F, 0x00, 0x00)

@@ -115,6 +116,24 @@ void hal_delay(uint32_t ms)
HAL_Delay(ms);
}

void delay_random(void)
{
int wait = rng_get() & 0xff;
volatile int i = 0;
volatile int j = wait;
while (i < wait) {
if (i + j != wait) {
shutdown();
}
++i;
--j;
}
// Double-check loop completion.
if (i != wait || j != 0) {
shutdown();
}
}

// reference RM0090 section 35.12.1 Figure 413
#define USB_OTG_HS_DATA_FIFO_RAM (USB_OTG_HS_PERIPH_BASE + 0x20000U)
#define USB_OTG_HS_DATA_FIFO_SIZE (4096U)
@@ -26,11 +26,14 @@
#define XSTR(s) STR(s)
#define STR(s) #s

#ifndef MIN_8bits
#define MIN_8bits(a, b) ({ typeof(a) _a = (a); typeof(b) _b = (b); _a < _b ? (_a & 0xFF) : (_b & 0xFF); })
#endif
#ifndef MIN
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define MIN(a, b) ({ typeof(a) _a = (a); typeof(b) _b = (b); _a < _b ? _a : _b; })
#endif
#ifndef MAX
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#define MAX(a, b) ({ typeof(a) _a = (a); typeof(b) _b = (b); _a > _b ? _a : _b; })
#endif

void __attribute__((noreturn)) __fatal_error(const char *expr, const char *msg, const char *file, int line, const char *func);
@@ -40,6 +43,8 @@ void __attribute__((noreturn)) error_shutdown(const char *line1, const char *lin

void hal_delay(uint32_t ms);

void delay_random(void);

void clear_otg_hs_memory(void);

extern uint32_t __stack_chk_guard;
@@ -27,10 +27,61 @@

#define MPU_SUBREGION_DISABLE(X) ((X) << MPU_RASR_SRD_Pos)

void mpu_config(void)
void mpu_config_off(void)
{
// Disable MPU
HAL_MPU_Disable();
}

void mpu_config_bootloader(void)
{
// Disable MPU
HAL_MPU_Disable();

// Note: later entries overwrite previous ones

// Flash (0x08000000 - 0x081FFFFF, 2 MiB, read-write)
MPU->RBAR = FLASH_BASE | MPU_RBAR_VALID_Msk | MPU_REGION_NUMBER0;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | LL_MPU_REGION_SIZE_2MB | LL_MPU_REGION_PRIV_RO_URO;

// Flash (0x0800C000 - 0x0800FFFF, 16 KiB, no access)
MPU->RBAR = FLASH_BASE | 0xC000 | MPU_RBAR_VALID_Msk | MPU_REGION_NUMBER1;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | LL_MPU_REGION_SIZE_16KB | LL_MPU_REGION_NO_ACCESS;

// Flash (0x0810C000 - 0x0810FFFF, 16 KiB, no access)
MPU->RBAR = FLASH_BASE | 0x10C000 | MPU_RBAR_VALID_Msk | MPU_REGION_NUMBER2;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_FLASH | LL_MPU_REGION_SIZE_16KB | LL_MPU_REGION_NO_ACCESS;

// SRAM (0x20000000 - 0x2002FFFF, 192 KiB = 256 KiB except 2/8 at end, read-write, execute never)
MPU->RBAR = SRAM_BASE | MPU_RBAR_VALID_Msk | MPU_REGION_NUMBER3;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_SRAM | LL_MPU_REGION_SIZE_256KB | LL_MPU_REGION_FULL_ACCESS | MPU_RASR_XN_Msk | MPU_SUBREGION_DISABLE(0xC0);

// Peripherals (0x40000000 - 0x5FFFFFFF, read-write, execute never)
// External RAM (0x60000000 - 0x7FFFFFFF, read-write, execute never)
MPU->RBAR = PERIPH_BASE | MPU_RBAR_VALID_Msk | MPU_REGION_NUMBER4;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_PERIPH | LL_MPU_REGION_SIZE_1GB | LL_MPU_REGION_FULL_ACCESS | MPU_RASR_XN_Msk;

#ifdef STM32F427xx
// CCMRAM (0x10000000 - 0x1000FFFF, read-write, execute never)
MPU->RBAR = CCMDATARAM_BASE | MPU_RBAR_VALID_Msk | MPU_REGION_NUMBER5;
MPU->RASR = MPU_RASR_ENABLE_Msk | MPU_RASR_ATTR_SRAM | LL_MPU_REGION_SIZE_64KB | LL_MPU_REGION_FULL_ACCESS | MPU_RASR_XN_Msk;
#elif STM32F405xx
// no CCMRAM
#else
#error Unsupported MCU
#endif

// Enable MPU
HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI);
}


void mpu_config_firmware(void)
{
// Disable MPU
HAL_MPU_Disable();

// Note: later entries overwrite previous ones

/*
// Boardloader (0x08000000 - 0x0800FFFF, 64 KiB, read-only, execute never)
@@ -77,5 +128,5 @@ void mpu_config(void)
#endif

// Enable MPU
HAL_MPU_Enable(0);
HAL_MPU_Enable(LL_MPU_CTRL_HARDFAULT_NMI);
}
@@ -20,6 +20,8 @@
#ifndef __MPU_H__
#define __MPU_H__

void mpu_config(void);
void mpu_config_off(void);
void mpu_config_bootloader(void);
void mpu_config_firmware(void);

#endif
@@ -79,7 +79,8 @@ void SysTick_Handler(void)
uwTick++;
}

void shutdown(void);
// from util.s
extern void shutdown(void);

void PVD_IRQHandler(void)
{
@@ -314,6 +314,7 @@ static uint8_t usb_class_deinit(USBD_HandleTypeDef *dev, uint8_t cfg_idx) {
#define USB_WEBUSB_URL_SCHEME_HTTPS 1

static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *req) {
delay_random();
if (((req->bmRequest & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_CLASS) &&
((req->bmRequest & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_STANDARD) &&
((req->bmRequest & USB_REQ_TYPE_MASK) != USB_REQ_TYPE_VENDOR)) {
@@ -330,7 +331,7 @@ static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *re
USB_WEBUSB_URL_SCHEME_HTTPS, // uint8_t bScheme
't', 'r', 'e', 'z', 'o', 'r', '.', 'i', 'o', '/', 's', 't', 'a', 'r', 't', // char URL[]
};
USBD_CtlSendData(dev, UNCONST(webusb_url), MIN(req->wLength, sizeof(webusb_url)));
USBD_CtlSendData(dev, UNCONST(webusb_url), MIN_8bits(req->wLength, sizeof(webusb_url)));
return USBD_OK;
} else {
USBD_CtlError(dev, req);
@@ -354,7 +355,7 @@ static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *re
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // subCompatibleId
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // reserved
};
USBD_CtlSendData(dev, UNCONST(winusb_wcid), MIN(req->wLength, sizeof(winusb_wcid)));
USBD_CtlSendData(dev, UNCONST(winusb_wcid), MIN_8bits(req->wLength, sizeof(winusb_wcid)));
return USBD_OK;
} else {
USBD_CtlError(dev, req);
@@ -380,7 +381,7 @@ static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *re
0x50, 0x00, 0x00, 0x00, // dwPropertyDataLength
'{', 0x00, 'c', 0x00, '6', 0x00, 'c', 0x00, '3', 0x00, '7', 0x00, '4', 0x00, 'a', 0x00, '6', 0x00, '-', 0x00, '2', 0x00, '2', 0x00, '8', 0x00, '5', 0x00, '-', 0x00, '4', 0x00, 'c', 0x00, 'b', 0x00, '8', 0x00, '-', 0x00, 'a', 0x00, 'b', 0x00, '4', 0x00, '3', 0x00, '-', 0x00, '1', 0x00, '7', 0x00, '6', 0x00, '4', 0x00, '7', 0x00, 'c', 0x00, 'e', 0x00, 'a', 0x00, '5', 0x00, '0', 0x00, '3', 0x00, 'd', 0x00, '}', 0x00, 0x00, 0x00, 0x00, 0x00, // propertyData
};
USBD_CtlSendData(dev, UNCONST(winusb_guid), MIN(req->wLength, sizeof(winusb_guid)));
USBD_CtlSendData(dev, UNCONST(winusb_guid), MIN_8bits(req->wLength, sizeof(winusb_guid)));
return USBD_OK;
} else {
USBD_CtlError(dev, req);
@@ -410,6 +411,7 @@ static uint8_t usb_class_setup(USBD_HandleTypeDef *dev, USBD_SetupReqTypedef *re
}

static uint8_t usb_class_data_in(USBD_HandleTypeDef *dev, uint8_t ep_num) {
delay_random();
for (int i = 0; i < USBD_MAX_NUM_INTERFACES; i++) {
switch (usb_ifaces[i].type) {
case USB_IFACE_TYPE_HID:
@@ -429,6 +431,7 @@ static uint8_t usb_class_data_in(USBD_HandleTypeDef *dev, uint8_t ep_num) {
}

static uint8_t usb_class_data_out(USBD_HandleTypeDef *dev, uint8_t ep_num) {
delay_random();
for (int i = 0; i < USBD_MAX_NUM_INTERFACES; i++) {
switch (usb_ifaces[i].type) {
case USB_IFACE_TYPE_HID:
@@ -448,6 +451,7 @@ static uint8_t usb_class_data_out(USBD_HandleTypeDef *dev, uint8_t ep_num) {
}

static uint8_t usb_class_sof(USBD_HandleTypeDef *dev) {
delay_random();
for (int i = 0; i < USBD_MAX_NUM_INTERFACES; i++) {
switch (usb_ifaces[i].type) {
case USB_IFACE_TYPE_VCP:
@@ -254,7 +254,6 @@ static void usb_hid_class_deinit(USBD_HandleTypeDef *dev, usb_hid_state_t *state
}

static int usb_hid_class_setup(USBD_HandleTypeDef *dev, usb_hid_state_t *state, USBD_SetupReqTypedef *req) {

switch (req->bmRequest & USB_REQ_TYPE_MASK) {

// Class request
@@ -302,11 +301,11 @@ static int usb_hid_class_setup(USBD_HandleTypeDef *dev, usb_hid_state_t *state,
switch (req->wValue >> 8) {

case USB_DESC_TYPE_HID:
USBD_CtlSendData(dev, UNCONST(&state->desc_block->hid), MIN(req->wLength, sizeof(state->desc_block->hid)));
USBD_CtlSendData(dev, UNCONST(&state->desc_block->hid), MIN_8bits(req->wLength, sizeof(state->desc_block->hid)));
return USBD_OK;

case USB_DESC_TYPE_REPORT:
USBD_CtlSendData(dev, UNCONST(state->report_desc), MIN(req->wLength, state->report_desc_len));
USBD_CtlSendData(dev, UNCONST(state->report_desc), MIN_8bits(req->wLength, state->report_desc_len));
return USBD_OK;

default:
@@ -364,13 +364,13 @@ static int usb_vcp_class_setup(USBD_HandleTypeDef *dev, usb_vcp_state_t *state,

if ((req->bmRequest & USB_REQ_DIR_MASK) == USB_REQ_DIR_D2H) {
if (req->bRequest == USB_CDC_GET_LINE_CODING) {
USBD_CtlSendData(dev, UNCONST(&line_coding), MIN(req->wLength, sizeof(line_coding)));
USBD_CtlSendData(dev, UNCONST(&line_coding), MIN_8bits(req->wLength, sizeof(line_coding)));
} else {
USBD_CtlSendData(dev, state->cmd_buffer, MIN(req->wLength, USB_CDC_MAX_CMD_PACKET_LEN));
USBD_CtlSendData(dev, state->cmd_buffer, MIN_8bits(req->wLength, USB_CDC_MAX_CMD_PACKET_LEN));
}
} else { // USB_REQ_DIR_H2D
if (req->wLength > 0) {
USBD_CtlPrepareRx(dev, state->cmd_buffer, MIN(req->wLength, USB_CDC_MAX_CMD_PACKET_LEN));
USBD_CtlPrepareRx(dev, state->cmd_buffer, MIN_8bits(req->wLength, USB_CDC_MAX_CMD_PACKET_LEN));
}
}

@@ -263,9 +263,12 @@ typedef struct _USBD_HandleTypeDef

#define LOBYTE(x) ((uint8_t)(x & 0x00FF))
#define HIBYTE(x) ((uint8_t)((x & 0xFF00) >>8))
#ifndef MIN
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef MAX
#define MAX(a, b) (((a) > (b)) ? (a) : (b))

#endif

#if defined ( __GNUC__ )
#ifndef __weak
@@ -27,10 +27,10 @@
#define STR(s) #s

#ifndef MIN
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#define MIN(a, b) ({ typeof(a) _a = (a); typeof(b) _b = (b); _a < _b ? _a : _b; })
#endif
#ifndef MAX
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#define MAX(a, b) ({ typeof(a) _a = (a); typeof(b) _b = (b); _a > _b ? _a : _b; })
#endif

void __attribute__((noreturn)) __fatal_error(const char *expr, const char *msg, const char *file, int line, const char *func);

0 comments on commit 828ba7b

Please sign in to comment.
You can’t perform that action at this time.