From 70a673fabc63e65f2821c72d5cdfeff13d69edeb Mon Sep 17 00:00:00 2001 From: tychovrahe Date: Mon, 26 Feb 2024 14:56:30 +0100 Subject: [PATCH] feat(core): use flash bursts for faster flashing [no changelog] --- core/embed/boardloader/main.c | 9 +++------ core/embed/bootloader/messages.c | 8 ++++---- core/embed/firmware/bl_check.c | 12 ++++++------ core/embed/trezorhal/flash.h | 3 ++- core/embed/trezorhal/stm32f4/flash.c | 14 ++++++++++++++ core/embed/trezorhal/stm32u5/flash.c | 11 +++++------ core/embed/trezorhal/unix/flash.c | 14 ++++++++++++++ legacy/flash.c | 17 +++++++++++++++++ storage/flash_area.c | 18 ++---------------- 9 files changed, 67 insertions(+), 39 deletions(-) diff --git a/core/embed/boardloader/main.c b/core/embed/boardloader/main.c index f73b64c00..43044ec62 100644 --- a/core/embed/boardloader/main.c +++ b/core/embed/boardloader/main.c @@ -227,12 +227,9 @@ static secbool copy_sdcard(void) { // copy bootloader from SD card to Flash term_printf("copying new bootloader from SD card\n\n"); - for (int j = 0; j < (IMAGE_HEADER_SIZE + codelen) / - (FLASH_BURST_LENGTH * sizeof(uint32_t)); - j++) { - ensure(flash_area_write_burst(&BOOTLOADER_AREA, - j * FLASH_BURST_LENGTH * sizeof(uint32_t), - &sdcard_buf[j * FLASH_BURST_LENGTH]), + for (int j = 0; j < (IMAGE_HEADER_SIZE + codelen) / FLASH_BURST_SIZE; j++) { + ensure(flash_area_write_burst(&BOOTLOADER_AREA, j * FLASH_BURST_SIZE, + &sdcard_buf[j * FLASH_BURST_WORDS]), NULL); } diff --git a/core/embed/bootloader/messages.c b/core/embed/bootloader/messages.c index 76fa4d5f7..08621bb3a 100644 --- a/core/embed/bootloader/messages.c +++ b/core/embed/bootloader/messages.c @@ -730,7 +730,7 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size, // offset into the FIRMWARE_AREA part of the flash uint32_t write_offset = firmware_block * IMAGE_CHUNK_SIZE; - ensure((chunk_size % FLASH_BLOCK_SIZE == 0) * sectrue, NULL); + ensure((chunk_size % FLASH_BURST_SIZE == 0) * sectrue, NULL); while (bytes_remaining > 0) { // erase flash before writing @@ -754,9 +754,9 @@ int process_msg_FirmwareUpload(uint8_t iface_num, uint32_t msg_size, ensure(flash_unlock_write(), NULL); while (write_offset < write_end) { // write a block to the flash - ensure(flash_area_write_block(&FIRMWARE_AREA, write_offset, src), NULL); - write_offset += FLASH_BLOCK_SIZE; - src += FLASH_BLOCK_WORDS; + ensure(flash_area_write_burst(&FIRMWARE_AREA, write_offset, src), NULL); + write_offset += FLASH_BURST_SIZE; + src += FLASH_BURST_WORDS; } ensure(flash_lock_write(), NULL); diff --git a/core/embed/firmware/bl_check.c b/core/embed/firmware/bl_check.c index c87bf25ca..72500051e 100644 --- a/core/embed/firmware/bl_check.c +++ b/core/embed/firmware/bl_check.c @@ -220,24 +220,24 @@ void check_and_replace_bootloader(void) { uint32_t last_whole_word_addr = (((uint32_t)decomp.dest) & ~0x7F); while ((uint32_t)p < last_whole_word_addr) { ensure(flash_area_write_burst(&BOOTLOADER_AREA, offset, p), NULL); - p += FLASH_BURST_LENGTH; - offset += FLASH_BURST_LENGTH * sizeof(uint32_t); + p += FLASH_BURST_WORDS; + offset += FLASH_BURST_WORDS * sizeof(uint32_t); } if ((uint8_t *)p < decomp.dest) { // last few bytes in case of unaligned data - uint32_t d[FLASH_BURST_LENGTH] = {0}; + uint32_t d[FLASH_BURST_WORDS] = {0}; memcpy(&d, p, (uint32_t)decomp.dest - (uint32_t)p); ensure(flash_area_write_burst(&BOOTLOADER_AREA, offset, d), NULL); - offset += FLASH_BURST_LENGTH * sizeof(uint32_t); + offset += FLASH_BURST_WORDS * sizeof(uint32_t); } decomp.dest = (uint8_t *)decomp_out; } while (uzlib_uncompress(&decomp) >= 0); - uint32_t d[FLASH_BURST_LENGTH] = {0}; + uint32_t d[FLASH_BURST_WORDS] = {0}; // fill the rest of the bootloader area with 0x00 while (offset < bl_len) { ensure(flash_area_write_burst(&BOOTLOADER_AREA, offset, d), NULL); - offset += FLASH_BURST_LENGTH * sizeof(uint32_t); + offset += FLASH_BURST_WORDS * sizeof(uint32_t); } ensure(flash_lock_write(), NULL); diff --git a/core/embed/trezorhal/flash.h b/core/embed/trezorhal/flash.h index c02a2fea9..e014c01aa 100644 --- a/core/embed/trezorhal/flash.h +++ b/core/embed/trezorhal/flash.h @@ -28,7 +28,8 @@ #include "flash_ll.h" -#define FLASH_BURST_LENGTH (4 * 8) +#define FLASH_BURST_WORDS (4 * 8) +#define FLASH_BURST_SIZE (FLASH_BURST_WORDS * sizeof(uint32_t)) void flash_init(void); diff --git a/core/embed/trezorhal/stm32f4/flash.c b/core/embed/trezorhal/stm32f4/flash.c index 8a34cc694..7d0761f10 100644 --- a/core/embed/trezorhal/stm32f4/flash.c +++ b/core/embed/trezorhal/stm32f4/flash.c @@ -194,6 +194,20 @@ secbool flash_write_word(uint16_t sector, uint32_t offset, uint32_t data) { return sectrue; } +secbool flash_write_burst(uint16_t sector, uint32_t offset, + const uint32_t *data) { + if ((offset % FLASH_BURST_SIZE) != 0) { + return secfalse; + } + for (int i = 0; i < FLASH_BURST_WORDS; i++) { + if (sectrue != + flash_write_word(sector, offset + i * sizeof(uint32_t), data[i])) { + return secfalse; + } + } + return sectrue; +} + secbool flash_write_block(uint16_t sector, uint32_t offset, const flash_block_t block) { return flash_write_word(sector, offset, block[0]); diff --git a/core/embed/trezorhal/stm32u5/flash.c b/core/embed/trezorhal/stm32u5/flash.c index 9285336fc..808caa1a9 100644 --- a/core/embed/trezorhal/stm32u5/flash.c +++ b/core/embed/trezorhal/stm32u5/flash.c @@ -171,23 +171,22 @@ secbool flash_write_quadword(uint16_t sector, uint32_t offset, secbool flash_write_burst(uint16_t sector, uint32_t offset, const uint32_t *data) { uint32_t address = - (uint32_t)flash_get_address(sector, offset, 8 * 4 * sizeof(uint32_t)); + (uint32_t)flash_get_address(sector, offset, FLASH_BURST_SIZE); if (address == 0) { return secfalse; } - if (offset % - (8 * 4 * sizeof(uint32_t))) { // we write only at 16-byte boundary + if (offset % FLASH_BURST_SIZE) { return secfalse; } - for (int i = 0; i < 8 * 4; i++) { + for (int i = 0; i < FLASH_BURST_WORDS; i++) { if (data[i] != (data[i] & *((const uint32_t *)address + i))) { return secfalse; } } secbool all_match = sectrue; - for (int i = 0; i < 8 * 4; i++) { + for (int i = 0; i < FLASH_BURST_WORDS; i++) { if (data[i] != *((const uint32_t *)address + i)) { all_match = secfalse; break; @@ -202,7 +201,7 @@ secbool flash_write_burst(uint16_t sector, uint32_t offset, return secfalse; } - for (int i = 0; i < 8 * 4; i++) { + for (int i = 0; i < FLASH_BURST_WORDS; i++) { if (data[i] != *((const uint32_t *)address + i)) { return secfalse; } diff --git a/core/embed/trezorhal/unix/flash.c b/core/embed/trezorhal/unix/flash.c index afee94018..59dca876e 100644 --- a/core/embed/trezorhal/unix/flash.c +++ b/core/embed/trezorhal/unix/flash.c @@ -228,6 +228,20 @@ secbool flash_write_word(uint16_t sector, uint32_t offset, uint32_t data) { return sectrue; } +secbool flash_write_burst(uint16_t sector, uint32_t offset, + const uint32_t *data) { + if ((offset % FLASH_BURST_SIZE) != 0) { + return secfalse; + } + for (int i = 0; i < FLASH_BURST_WORDS; i++) { + if (sectrue != + flash_write_word(sector, offset + i * sizeof(uint32_t), data[i])) { + return secfalse; + } + } + return sectrue; +} + secbool flash_write_block(uint16_t sector, uint32_t offset, const flash_block_t block) { if (offset % (sizeof(uint32_t) * diff --git a/legacy/flash.c b/legacy/flash.c index 37a9f62d3..b43954fd3 100644 --- a/legacy/flash.c +++ b/legacy/flash.c @@ -26,6 +26,9 @@ #include "memory.h" #include "supervise.h" +#define FLASH_BURST_WORDS (4 * 8) +#define FLASH_BURST_SIZE (FLASH_BURST_WORDS * sizeof(uint32_t)) + #define STORAGE_AREAS_COUNT 2 static const uint32_t FLASH_SECTOR_TABLE[FLASH_SECTOR_COUNT + 1] = { @@ -158,6 +161,20 @@ secbool flash_write_word(uint16_t sector, uint32_t offset, uint32_t data) { return sectrue; } +secbool flash_write_burst(uint16_t sector, uint32_t offset, + const uint32_t *data) { + if ((offset % FLASH_BURST_SIZE) != 0) { + return secfalse; + } + for (int i = 0; i < FLASH_BURST_WORDS; i++) { + if (sectrue != + flash_write_word(sector, offset + i * sizeof(uint32_t), data[i])) { + return secfalse; + } + } + return sectrue; +} + secbool flash_write_block(uint16_t sector, uint32_t offset, const flash_block_t block) { return flash_write_word(sector, offset, block[0]); diff --git a/storage/flash_area.c b/storage/flash_area.c index a979489a9..bf7691177 100644 --- a/storage/flash_area.c +++ b/storage/flash_area.c @@ -106,20 +106,6 @@ secbool flash_area_write_word(const flash_area_t *area, uint32_t offset, return flash_write_word(sector, sector_offset, data); } -secbool flash_area_write_burst(const flash_area_t *area, uint32_t offset, - const uint32_t *data) { - if (offset % (8 * 16) != 0) { - return secfalse; - } - for (int i = 0; i < (8 * 4); i++) { - if (sectrue != - flash_area_write_word(area, offset + i * sizeof(uint32_t), data[i])) { - return secfalse; - } - } - return sectrue; -} - #else // not defined FLASH_BIT_ACCESS secbool flash_area_write_quadword(const flash_area_t *area, uint32_t offset, @@ -132,6 +118,8 @@ secbool flash_area_write_quadword(const flash_area_t *area, uint32_t offset, return flash_write_quadword(sector, sector_offset, data); } +#endif // not defined FLASH_BIT_ACCESS + secbool flash_area_write_burst(const flash_area_t *area, uint32_t offset, const uint32_t *data) { uint16_t sector; @@ -142,8 +130,6 @@ secbool flash_area_write_burst(const flash_area_t *area, uint32_t offset, return flash_write_burst(sector, sector_offset, data); } -#endif // not defined FLASH_BIT_ACCESS - secbool flash_area_write_block(const flash_area_t *area, uint32_t offset, const flash_block_t block) { if (!FLASH_IS_ALIGNED(offset)) {