summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien George <damien@micropython.org>2022-03-18 16:22:26 +1100
committerDamien George <damien@micropython.org>2022-03-22 13:33:43 +1100
commit9b07d38c7e5919c8f26ee12b7bba71214ac43289 (patch)
treee98c9080446be835e4d94b339935acc5b7d7359b
parenta92d45c3df893c845571506afe6fbbfb3e7a85aa (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.md6
-rw-r--r--ports/stm32/mboot/fsload.c27
-rw-r--r--ports/stm32/mboot/fwupdate.py7
-rw-r--r--ports/stm32/mboot/main.c11
-rw-r--r--ports/stm32/mboot/mboot.h16
-rw-r--r--ports/stm32/mboot/vfs.h14
-rw-r--r--ports/stm32/mboot/vfs_fat.c11
-rw-r--r--ports/stm32/mboot/vfs_lfs.c5
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;