diff options
| author | Damien George <damien@micropython.org> | 2022-03-18 16:22:26 +1100 |
|---|---|---|
| committer | Damien George <damien@micropython.org> | 2022-03-22 13:33:43 +1100 |
| commit | 9b07d38c7e5919c8f26ee12b7bba71214ac43289 (patch) | |
| tree | e98c9080446be835e4d94b339935acc5b7d7359b | |
| parent | a92d45c3df893c845571506afe6fbbfb3e7a85aa (diff) | |
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 <damien@micropython.org>
| -rw-r--r-- | ports/stm32/mboot/README.md | 6 | ||||
| -rw-r--r-- | ports/stm32/mboot/fsload.c | 27 | ||||
| -rw-r--r-- | ports/stm32/mboot/fwupdate.py | 7 | ||||
| -rw-r--r-- | ports/stm32/mboot/main.c | 11 | ||||
| -rw-r--r-- | ports/stm32/mboot/mboot.h | 16 | ||||
| -rw-r--r-- | ports/stm32/mboot/vfs.h | 14 | ||||
| -rw-r--r-- | ports/stm32/mboot/vfs_fat.c | 11 | ||||
| -rw-r--r-- | 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 b85bc3e2e..49385047a 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-point:u8> <fs-type:u8> <base-addr:u32> <byte-len:u32>) +* MOUNT: type=2, len=14, payload=(<mount-point:u8> <fs-type:u8> <base-addr:u32> <byte-len:u32> <block-size:u32>) + +* MOUNT: type=2, len=22, payload=(<mount-point:u8> <fs-type:u8> <base-addr:u64> <byte-len:u64> <block-size:u32>) + * FSLOAD: type=3, len=1+n, payload=(<mount-point:u8> <filename...>) -`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 9ecc25b0b..14864bb89 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 0e7ea0141..df1ff6284 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 = "<BBQQL" if addr_64bit else "<BBLLL" elems = _create_element( _ELEM_TYPE_MOUNT, - struct.pack("<BBLLL", mount_point, fs_type, fs_base, fs_len, fs_blocksize), + struct.pack(mount_encoding, mount_point, fs_type, fs_base, fs_len, fs_blocksize), ) elems += _create_element( _ELEM_TYPE_FSLOAD, struct.pack("<B", mount_point) + bytes(filename, "ascii") diff --git a/ports/stm32/mboot/main.c b/ports/stm32/mboot/main.c index 341cf1817..714b20ff0 100644 --- a/ports/stm32/mboot/main.c +++ b/ports/stm32/mboot/main.c @@ -117,6 +117,11 @@ uint32_t get_le32(const uint8_t *b) { return b[0] | b[1] << 8 | b[2] << 16 | b[3] << 24; } +uint64_t get_le64(const uint8_t *b) { + return (uint64_t)b[0] | (uint64_t)b[1] << 8 | (uint64_t)b[2] << 16 | (uint64_t)b[3] << 24 + | (uint64_t)b[4] << 32 | (uint64_t)b[5] << 40 | (uint64_t)b[6] << 48 | (uint64_t)b[7] << 56; +} + mp_uint_t mp_hal_ticks_ms(void) { return systick_ms; } @@ -636,7 +641,7 @@ int hw_page_erase(uint32_t addr, uint32_t *next_addr) { return ret; } -void hw_read(uint32_t addr, int len, uint8_t *buf) { +void hw_read(mboot_addr_t addr, size_t len, uint8_t *buf) { led0_state(LED0_STATE_FAST_FLASH); #if defined(MBOOT_SPIFLASH_ADDR) if (MBOOT_SPIFLASH_ADDR <= addr && addr < MBOOT_SPIFLASH_ADDR + MBOOT_SPIFLASH_BYTE_SIZE) { @@ -650,7 +655,7 @@ void hw_read(uint32_t addr, int len, uint8_t *buf) { #endif { // Other addresses, just read directly from memory - memcpy(buf, (void*)addr, len); + memcpy(buf, (void *)(uintptr_t)addr, len); } led0_state(LED0_STATE_SLOW_FLASH); } @@ -688,7 +693,7 @@ int do_page_erase(uint32_t addr, uint32_t *next_addr) { #endif } -void do_read(uint32_t addr, int len, uint8_t *buf) { +void do_read(mboot_addr_t addr, size_t len, uint8_t *buf) { #if MBOOT_ENABLE_PACKING // Read disabled on packed (encrypted) mode. dfu_context.status = DFU_STATUS_ERROR_FILE; diff --git a/ports/stm32/mboot/mboot.h b/ports/stm32/mboot/mboot.h index 254c84265..36acb313b 100644 --- a/ports/stm32/mboot/mboot.h +++ b/ports/stm32/mboot/mboot.h @@ -42,6 +42,10 @@ #define MBOOT_BOARD_ENTRY_INIT mboot_entry_init #endif +#ifndef MBOOT_ADDRESS_SPACE_64BIT +#define MBOOT_ADDRESS_SPACE_64BIT (0) +#endif + enum { MBOOT_ERRNO_FLASH_ERASE_DISALLOWED = 200, MBOOT_ERRNO_FLASH_ERASE_FAILED, @@ -86,6 +90,13 @@ enum { ELEM_MOUNT_LFS2, }; +// Configure the type used to hold an address in the mboot address space. +#if MBOOT_ADDRESS_SPACE_64BIT +typedef uint64_t mboot_addr_t; +#else +typedef uint32_t mboot_addr_t; +#endif + extern uint8_t _estack[ELEM_DATA_SIZE]; void systick_init(void); @@ -93,14 +104,15 @@ void led_init(void); void SystemClock_Config(void); uint32_t get_le32(const uint8_t *b); +uint64_t get_le64(const uint8_t *b); void led_state_all(unsigned int mask); int hw_page_erase(uint32_t addr, uint32_t *next_addr); -void hw_read(uint32_t addr, int len, uint8_t *buf); +void hw_read(mboot_addr_t addr, size_t len, uint8_t *buf); int hw_write(uint32_t addr, const uint8_t *src8, size_t len); int do_page_erase(uint32_t addr, uint32_t *next_addr); -void do_read(uint32_t addr, int len, uint8_t *buf); +void do_read(mboot_addr_t addr, size_t len, uint8_t *buf); int do_write(uint32_t addr, const uint8_t *src8, size_t len); const uint8_t *elem_search(const uint8_t *elem, uint8_t elem_id); diff --git a/ports/stm32/mboot/vfs.h b/ports/stm32/mboot/vfs.h index 22bb98936..53dac8800 100644 --- a/ports/stm32/mboot/vfs.h +++ b/ports/stm32/mboot/vfs.h @@ -34,15 +34,15 @@ #include "lib/oofatfs/ff.h" typedef struct _vfs_fat_context_t { - uint32_t bdev_base_addr; - uint32_t bdev_byte_len; + mboot_addr_t bdev_base_addr; + uint32_t bdev_num_blocks; FATFS fatfs; FIL fp; } vfs_fat_context_t; extern const stream_methods_t vfs_fat_stream_methods; -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); #endif @@ -55,7 +55,7 @@ int vfs_fat_mount(vfs_fat_context_t *ctx, uint32_t base_addr, uint32_t byte_len) #define LFS_LOOKAHEAD_SIZE (32) typedef struct _vfs_lfs1_context_t { - uint32_t bdev_base_addr; + mboot_addr_t bdev_base_addr; struct lfs1_config config; lfs1_t lfs; struct lfs1_file_config filecfg; @@ -65,7 +65,7 @@ typedef struct _vfs_lfs1_context_t { extern const stream_methods_t vfs_lfs1_stream_methods; -int vfs_lfs1_mount(vfs_lfs1_context_t *ctx, uint32_t base_addr, uint32_t byte_len, uint32_t block_size); +int vfs_lfs1_mount(vfs_lfs1_context_t *ctx, mboot_addr_t base_addr, mboot_addr_t byte_len, uint32_t block_size); #endif @@ -79,7 +79,7 @@ int vfs_lfs1_mount(vfs_lfs1_context_t *ctx, uint32_t base_addr, uint32_t byte_le #define LFS_LOOKAHEAD_SIZE (32) typedef struct _vfs_lfs2_context_t { - uint32_t bdev_base_addr; + mboot_addr_t bdev_base_addr; struct lfs2_config config; lfs2_t lfs; struct lfs2_file_config filecfg; @@ -89,7 +89,7 @@ typedef struct _vfs_lfs2_context_t { extern const stream_methods_t vfs_lfs2_stream_methods; -int vfs_lfs2_mount(vfs_lfs2_context_t *ctx, uint32_t base_addr, uint32_t byte_len, uint32_t block_size); +int vfs_lfs2_mount(vfs_lfs2_context_t *ctx, mboot_addr_t base_addr, mboot_addr_t byte_len, uint32_t block_size); #endif diff --git a/ports/stm32/mboot/vfs_fat.c b/ports/stm32/mboot/vfs_fat.c index cfa30fb12..e31691046 100644 --- a/ports/stm32/mboot/vfs_fat.c +++ b/ports/stm32/mboot/vfs_fat.c @@ -41,8 +41,9 @@ DRESULT disk_read(void *pdrv, BYTE *buf, DWORD sector, UINT count) { vfs_fat_context_t *ctx = pdrv; - if (0 <= sector && sector < ctx->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 e7fd8ce63..5aa400df4 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; |
