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>
This commit is contained in:
parent
a92d45c3df
commit
9b07d38c7e
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue