From 9b07d38c7e5919c8f26ee12b7bba71214ac43289 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 18 Mar 2022 16:22:26 +1100 Subject: [PATCH] stm32/mboot: Add support for 64-bit mboot address space for reads. If enabled via MBOOT_ADDRESS_SPACE_64BIT (it's disabled by default) then read addresses will be 64-bit. Signed-off-by: Damien George --- ports/stm32/mboot/README.md | 6 +++++- ports/stm32/mboot/fsload.c | 27 ++++++++++++++++++--------- ports/stm32/mboot/fwupdate.py | 7 +++++-- ports/stm32/mboot/main.c | 11 ++++++++--- ports/stm32/mboot/mboot.h | 16 ++++++++++++++-- ports/stm32/mboot/vfs.h | 14 +++++++------- ports/stm32/mboot/vfs_fat.c | 11 ++++++----- ports/stm32/mboot/vfs_lfs.c | 5 +++-- 8 files changed, 66 insertions(+), 31 deletions(-) diff --git a/ports/stm32/mboot/README.md b/ports/stm32/mboot/README.md index b85bc3e2eedb..49385047a433 100644 --- a/ports/stm32/mboot/README.md +++ b/ports/stm32/mboot/README.md @@ -137,9 +137,13 @@ are located and what filename to program. The elements to use are: * MOUNT: type=2, len=10, payload=( ) +* MOUNT: type=2, len=14, payload=( ) + +* MOUNT: type=2, len=22, payload=( ) + * FSLOAD: type=3, len=1+n, payload=( ) -`u32` means unsigned 32-bit little-endian integer. +`u32`/`u64` mean unsigned 32-bit/64-bit little-endian integers. The firmware to load must be a gzip'd DfuSe file (.dfu.gz) and stored within a FAT or littlefs formatted partition. diff --git a/ports/stm32/mboot/fsload.c b/ports/stm32/mboot/fsload.c index 9ecc25b0be92..14864bb8956b 100644 --- a/ports/stm32/mboot/fsload.c +++ b/ports/stm32/mboot/fsload.c @@ -222,20 +222,29 @@ int fsload_process(void) { // End of elements. return -MBOOT_ERRNO_FSLOAD_NO_MOUNT; } - uint32_t block_size; - if (elem[-1] == 10) { - // No block size given, use default. - block_size = MBOOT_FSLOAD_DEFAULT_BLOCK_SIZE; - } else if (elem[-1] == 14) { - // Block size given, extract it. - block_size = get_le32(&elem[10]); + mboot_addr_t base_addr; + mboot_addr_t byte_len; + uint32_t block_size = MBOOT_FSLOAD_DEFAULT_BLOCK_SIZE; + if (elem[-1] == 10 || elem[-1] == 14) { + // 32-bit base and length given, extract them. + base_addr = get_le32(&elem[2]); + byte_len = get_le32(&elem[6]); + if (elem[-1] == 14) { + // Block size given, extract it. + block_size = get_le32(&elem[10]); + } + #if MBOOT_ADDRESS_SPACE_64BIT + } else if (elem[-1] == 22) { + // 64-bit base and length given, and block size, so extract them. + base_addr = get_le64(&elem[2]); + byte_len = get_le64(&elem[10]); + block_size = get_le32(&elem[18]); + #endif } else { // Invalid MOUNT element. return -MBOOT_ERRNO_FSLOAD_INVALID_MOUNT; } if (elem[0] == mount_point) { - uint32_t base_addr = get_le32(&elem[2]); - uint32_t byte_len = get_le32(&elem[6]); int ret; union { #if MBOOT_VFS_FAT diff --git a/ports/stm32/mboot/fwupdate.py b/ports/stm32/mboot/fwupdate.py index 0e7ea014189d..df1ff6284627 100644 --- a/ports/stm32/mboot/fwupdate.py +++ b/ports/stm32/mboot/fwupdate.py @@ -227,7 +227,9 @@ def _create_element(kind, body): return bytes([kind, len(body)]) + body -def update_mpy(filename, fs_base, fs_len, fs_type=VFS_FAT, fs_blocksize=0, status_addr=None): +def update_mpy( + filename, fs_base, fs_len, fs_type=VFS_FAT, fs_blocksize=0, status_addr=None, addr_64bit=False +): # Check firmware is of .dfu or .dfu.gz type try: with open(filename, "rb") as f: @@ -243,9 +245,10 @@ def update_mpy(filename, fs_base, fs_len, fs_type=VFS_FAT, fs_blocksize=0, statu raise Exception("littlefs requires fs_blocksize parameter") mount_point = 1 + mount_encoding = "bdev_byte_len / 512) { - hw_read(ctx->bdev_base_addr + sector * SECSIZE, count * SECSIZE, buf); + if (0 <= sector && sector < ctx->bdev_num_blocks) { + mboot_addr_t addr = ctx->bdev_base_addr + (mboot_addr_t)sector * (mboot_addr_t)SECSIZE; + hw_read(addr, count * SECSIZE, buf); return RES_OK; } @@ -57,7 +58,7 @@ DRESULT disk_ioctl(void *pdrv, BYTE cmd, void *buf) { return RES_OK; case GET_SECTOR_COUNT: - *((DWORD*)buf) = ctx->bdev_byte_len / SECSIZE; + *((DWORD*)buf) = ctx->bdev_num_blocks; return RES_OK; case GET_SECTOR_SIZE: @@ -78,9 +79,9 @@ DRESULT disk_ioctl(void *pdrv, BYTE cmd, void *buf) { } } -int vfs_fat_mount(vfs_fat_context_t *ctx, uint32_t base_addr, uint32_t byte_len) { +int vfs_fat_mount(vfs_fat_context_t *ctx, mboot_addr_t base_addr, mboot_addr_t byte_len) { ctx->bdev_base_addr = base_addr; - ctx->bdev_byte_len = byte_len; + ctx->bdev_num_blocks = byte_len / SECSIZE; ctx->fatfs.drv = ctx; FRESULT res = f_mount(&ctx->fatfs); if (res != FR_OK) { diff --git a/ports/stm32/mboot/vfs_lfs.c b/ports/stm32/mboot/vfs_lfs.c index e7fd8ce63c07..5aa400df4050 100644 --- a/ports/stm32/mboot/vfs_lfs.c +++ b/ports/stm32/mboot/vfs_lfs.c @@ -70,7 +70,8 @@ static uint8_t lfs_lookahead_buffer[LFS_LOOKAHEAD_SIZE]; static int dev_read(const struct LFSx_API (config) * c, LFSx_API(block_t) block, LFSx_API(off_t) off, void *buffer, LFSx_API(size_t) size) { VFS_LFSx_CONTEXT_T *ctx = c->context; if (0 <= block && block < ctx->config.block_count) { - hw_read(ctx->bdev_base_addr + block * ctx->config.block_size + off, size, buffer); + mboot_addr_t addr = ctx->bdev_base_addr + (mboot_addr_t)block * (mboot_addr_t)ctx->config.block_size + (mboot_addr_t)off; + hw_read(addr, size, buffer); return LFSx_MACRO(_ERR_OK); } return LFSx_MACRO(_ERR_IO); @@ -88,7 +89,7 @@ static int dev_sync(const struct LFSx_API (config) * c) { return LFSx_MACRO(_ERR_OK); } -int VFS_LFSx_MOUNT(VFS_LFSx_CONTEXT_T *ctx, uint32_t base_addr, uint32_t byte_len, uint32_t block_size) { +int VFS_LFSx_MOUNT(VFS_LFSx_CONTEXT_T *ctx, mboot_addr_t base_addr, mboot_addr_t byte_len, uint32_t block_size) { ctx->bdev_base_addr = base_addr; struct LFSx_API (config) *config = &ctx->config;