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:
parent
e1161866da
commit
70a673fabc
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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]);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) *
|
||||
|
@ -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]);
|
||||
|
@ -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)) {
|
||||
|
Loading…
Reference in New Issue
Block a user