From 7b7318c3aac354ae949fe4cb6193dbe850534756 Mon Sep 17 00:00:00 2001 From: Ondrej Mikle Date: Tue, 31 May 2022 13:29:04 +0200 Subject: [PATCH] feat(core/boardloader): add fixed-address boardloader capablities field --- core/.changelog.d/2324.added | 1 + core/SConscript.boardloader | 1 + core/SConscript.firmware | 1 + .../embed/boardloader/.changelog.d/2324.added | 1 + core/embed/boardloader/main.c | 22 +++++ core/embed/boardloader/memory.ld | 3 + core/embed/firmware/main.c | 5 ++ core/embed/trezorhal/board_capabilities.c | 82 +++++++++++++++++++ core/embed/trezorhal/board_capabilities.h | 82 +++++++++++++++++++ 9 files changed, 198 insertions(+) create mode 100644 core/.changelog.d/2324.added create mode 100644 core/embed/boardloader/.changelog.d/2324.added create mode 100644 core/embed/trezorhal/board_capabilities.c create mode 100644 core/embed/trezorhal/board_capabilities.h diff --git a/core/.changelog.d/2324.added b/core/.changelog.d/2324.added new file mode 100644 index 0000000000..c4a38a07c6 --- /dev/null +++ b/core/.changelog.d/2324.added @@ -0,0 +1 @@ +Boardloader capabilities structure diff --git a/core/SConscript.boardloader b/core/SConscript.boardloader index 82d14cad42..2b16ea2c50 100644 --- a/core/SConscript.boardloader +++ b/core/SConscript.boardloader @@ -81,6 +81,7 @@ SOURCE_BOARDLOADER = [ ] SOURCE_TREZORHAL = [ + 'embed/trezorhal/board_capabilities.c', 'embed/trezorhal/common.c', 'embed/trezorhal/dma.c', 'embed/trezorhal/image.c', diff --git a/core/SConscript.firmware b/core/SConscript.firmware index cc3a77acad..34cdd72d55 100644 --- a/core/SConscript.firmware +++ b/core/SConscript.firmware @@ -359,6 +359,7 @@ SOURCE_FIRMWARE = [ ] SOURCE_TREZORHAL = [ + 'embed/trezorhal/board_capabilities.c', 'embed/trezorhal/common.c', 'embed/trezorhal/dma.c', 'embed/trezorhal/image.c', diff --git a/core/embed/boardloader/.changelog.d/2324.added b/core/embed/boardloader/.changelog.d/2324.added new file mode 100644 index 0000000000..c4a38a07c6 --- /dev/null +++ b/core/embed/boardloader/.changelog.d/2324.added @@ -0,0 +1 @@ +Boardloader capabilities structure diff --git a/core/embed/boardloader/main.c b/core/embed/boardloader/main.c index 7244b41b8f..ec6f94217a 100644 --- a/core/embed/boardloader/main.c +++ b/core/embed/boardloader/main.c @@ -19,6 +19,7 @@ #include +#include "board_capabilities.h" #include "common.h" #include "compiler_traits.h" #include "display.h" @@ -48,6 +49,27 @@ static const uint8_t * const BOARDLOADER_KEYS[] = { #endif }; +struct BoardCapabilities capablities + __attribute__((section(".capabilities_section"))) = { + .header = CAPABILITIES_HEADER, + .model_tag = MODEL_NAME, + .model_length = MODEL_NAME_MAX_LENGTH, +#if defined TREZOR_MODEL_T + .model_name = "TREZORT", +#elif defined TREZOR_MODEL_R + .model_name = "TREZORR", +#else +#error Unknown model +#endif + .version_tag = BOARDLOADER_VERSION, + .version_length = sizeof(struct BoardloaderVersion), + .version = {.version_major = VERSION_MAJOR, + .version_minor = VERSION_MINOR, + .version_patch = VERSION_PATCH, + .version_build = VERSION_BUILD}, + .terminator_tag = TERMINATOR, + .terminator_length = 0}; + // we use SRAM as SD card read buffer (because DMA can't access the CCMRAM) extern uint32_t sram_start[]; #define sdcard_buf sram_start diff --git a/core/embed/boardloader/memory.ld b/core/embed/boardloader/memory.ld index 97ca264f24..328bcd0351 100644 --- a/core/embed/boardloader/memory.ld +++ b/core/embed/boardloader/memory.ld @@ -48,6 +48,9 @@ SECTIONS { . = ALIGN(4); /* make the section size a multiple of the word size */ } >CCMRAM + /* Hard-coded address for capabilities structure */ + .capabilities 0x0800BF00 : {KEEP(*(.capabilities_section))} + .stack : ALIGN(8) { . = 4K; /* this acts as a build time assertion that at least this much memory is available for stack use */ } >CCMRAM diff --git a/core/embed/firmware/main.c b/core/embed/firmware/main.c index 8e4ff9e2e4..c1ee7c2c47 100644 --- a/core/embed/firmware/main.c +++ b/core/embed/firmware/main.c @@ -36,6 +36,7 @@ #include "ports/stm32/pendsv.h" #include "bl_check.h" +#include "board_capabilities.h" #include "button.h" #include "common.h" #include "compiler_traits.h" @@ -76,6 +77,10 @@ int main(void) { enable_systemview(); #endif +#if !defined TREZOR_MODEL_1 + parse_boardloader_capabilities(); +#endif + #if defined TREZOR_MODEL_T #if PRODUCTION check_and_replace_bootloader(); diff --git a/core/embed/trezorhal/board_capabilities.c b/core/embed/trezorhal/board_capabilities.c new file mode 100644 index 0000000000..235f4b1e58 --- /dev/null +++ b/core/embed/trezorhal/board_capabilities.c @@ -0,0 +1,82 @@ +/* + * This file is part of the Trezor project, https://trezor.io/ + * + * Copyright (c) SatoshiLabs + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "board_capabilities.h" +#include +#include "common.h" + +#define handle_fault(msg) \ + (__fatal_error("Fault detected", msg, __FILE__, __LINE__, __func__)) + +static uint8_t board_name[MODEL_NAME_MAX_LENGTH + 1] = {0}; + +static struct BoardloaderVersion boardloader_version; + +const uint8_t *get_board_name() { return board_name; } + +const struct BoardloaderVersion *get_boardloader_version() { + return &boardloader_version; +} + +void parse_boardloader_capabilities() { + const uint8_t *pos = (const uint8_t *)BOARD_CAPABILITIES_ADDR; + const uint8_t *end = + (const uint8_t *)(BOARD_CAPABILITIES_ADDR + BOARD_CAPABILITIES_SIZE); + + if (memcmp(pos, CAPABILITIES_HEADER, 4) != 0) { + return; + } + + pos += 4; + + // -2 for possible tag without any data + while (pos <= end - 2) { + enum CapabilityTag tag = pos[0]; + uint8_t length = pos[1]; + uint8_t used_length; + pos += 2; + + if (pos + length > end) { + handle_fault("Bad capabilities format."); + } + + switch (tag) { + case CAPABILITY: + // not used yet, just advance pointer + break; + case MODEL_NAME: + used_length = MIN(MODEL_NAME_MAX_LENGTH, length); + memcpy(board_name, pos, used_length); + board_name[MODEL_NAME_MAX_LENGTH] = 0; + break; + case BOARDLOADER_VERSION: + if (length != sizeof(boardloader_version)) { + break; + } + memcpy(&boardloader_version, pos, length); + break; + case TERMINATOR: + return; + default: + break; + } + + pos += length; + } +} diff --git a/core/embed/trezorhal/board_capabilities.h b/core/embed/trezorhal/board_capabilities.h new file mode 100644 index 0000000000..ead351053a --- /dev/null +++ b/core/embed/trezorhal/board_capabilities.h @@ -0,0 +1,82 @@ +/* + * This file is part of the Trezor project, https://trezor.io/ + * + * Copyright (c) SatoshiLabs + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __TREZORHAL_BOARD_CAPABILITIES_H__ +#define __TREZORHAL_BOARD_CAPABILITIES_H__ + +/* +Simple key-tag-length-value structure at fixed boardloader address. + +* header 4 bytes `TRZC` +* each field is 4 bytes or multiple (because of alignment) +* 4 bytes are + * 1-byte tag+type - CapabilityTag + * 1 byte length - counting from next byte forward + * 0 or more bytes of data, doesn't have to be aligned + +Last tag must be terminator or all space used. +*/ + +#include + +#define BOARD_CAPABILITIES_ADDR 0x0800BF00 +#define BOARD_CAPABILITIES_SIZE 256 +#define CAPABILITIES_HEADER "TRZC" +#define MODEL_NAME_MAX_LENGTH 16 + +enum CapabilityTag { + TERMINATOR = 0x00, + CAPABILITY = 0x01, + MODEL_NAME = 0x02, + BOARDLOADER_VERSION = 0x03 +}; + +struct __attribute__((packed)) BoardloaderVersion { + uint8_t version_major; + uint8_t version_minor; + uint8_t version_patch; + uint8_t version_build; +}; + +/* + * Structure of current boardloader. Older boardloaders can have it missing, + * reordered. + */ +struct __attribute__((packed)) BoardCapabilities { + uint8_t header[4]; + uint8_t model_tag; + uint8_t model_length; + uint8_t model_name[MODEL_NAME_MAX_LENGTH]; + uint8_t version_tag; + uint8_t version_length; + struct BoardloaderVersion version; + enum CapabilityTag terminator_tag; + uint8_t terminator_length; +}; + +/* + * Parse capabilities into RAM. Use while boardloader is accessible, + * before MPU is active. + */ +void parse_boardloader_capabilities(); + +const uint8_t* get_board_name(); +const struct BoardloaderVersion* get_boardloader_version(); + +#endif