1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-12-18 04:18:10 +00:00

feat(core): use flash bursts for faster flashing

[no changelog]
This commit is contained in:
tychovrahe 2024-02-26 14:56:30 +01:00 committed by TychoVrahe
parent e1161866da
commit 70a673fabc
9 changed files with 67 additions and 39 deletions

View File

@ -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);
}

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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]);

View File

@ -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;
}

View File

@ -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) *

View File

@ -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]);

View File

@ -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)) {