diff --git a/src/common/boot_picoboot/include/boot/picoboot.h b/src/common/boot_picoboot/include/boot/picoboot.h index ddfa0aaad..a3457bd07 100644 --- a/src/common/boot_picoboot/include/boot/picoboot.h +++ b/src/common/boot_picoboot/include/boot/picoboot.h @@ -67,20 +67,20 @@ enum picoboot_status { }; struct __packed picoboot_reboot_cmd { - uint32_t dPC; // 0 means reset into bootrom - uint32_t dSP; - uint32_t dDelayMS; + le_uint32_t dPC; // 0 means reset into bootrom + le_uint32_t dSP; + le_uint32_t dDelayMS; }; // used for EXEC, VECTORIZE_FLASH struct __packed picoboot_address_only_cmd { - uint32_t dAddr; + le_uint32_t dAddr; }; // used for READ, WRITE, FLASH_ERASE struct __packed picoboot_range_cmd { - uint32_t dAddr; - uint32_t dSize; + le_uint32_t dAddr; + le_uint32_t dSize; }; enum picoboot_exclusive_type { @@ -95,12 +95,12 @@ struct __packed picoboot_exclusive_cmd { // little endian struct __packed __aligned(4) picoboot_cmd { - uint32_t dMagic; - uint32_t dToken; // an identifier for this token to correlate with a status response + le_uint32_t dMagic; + le_uint32_t dToken; // an identifier for this token to correlate with a status response uint8_t bCmdId; // top bit set for IN uint8_t bCmdSize; // bytes of actual data in the arg part of this structure - uint16_t _unused; - uint32_t dTransferLength; // length of IN/OUT transfer (or 0) if none + le_uint16_t _unused; + le_uint32_t dTransferLength; // length of IN/OUT transfer (or 0) if none union { uint8_t args[16]; struct picoboot_reboot_cmd reboot_cmd; @@ -113,8 +113,8 @@ struct __packed __aligned(4) picoboot_cmd { static_assert(32 == sizeof(struct picoboot_cmd), "picoboot_cmd must be 32 bytes big"); struct __packed __aligned(4) picoboot_cmd_status { - uint32_t dToken; - uint32_t dStatusCode; + le_uint32_t dToken; + le_uint32_t dStatusCode; uint8_t bCmdId; uint8_t bInProgress; uint8_t _pad[6]; diff --git a/src/common/boot_uf2/include/boot/uf2.h b/src/common/boot_uf2/include/boot/uf2.h index a040242bd..203e5a0fd 100644 --- a/src/common/boot_uf2/include/boot/uf2.h +++ b/src/common/boot_uf2/include/boot/uf2.h @@ -29,16 +29,16 @@ struct uf2_block { // 32 byte header - uint32_t magic_start0; - uint32_t magic_start1; - uint32_t flags; - uint32_t target_addr; - uint32_t payload_size; - uint32_t block_no; - uint32_t num_blocks; - uint32_t file_size; // or familyID; - uint8_t data[476]; - uint32_t magic_end; + le_uint32_t magic_start0; + le_uint32_t magic_start1; + le_uint32_t flags; + le_uint32_t target_addr; + le_uint32_t payload_size; + le_uint32_t block_no; + le_uint32_t num_blocks; + le_uint32_t file_size; // or familyID; + uint8_t data[476]; + le_uint32_t magic_end; }; static_assert(sizeof(struct uf2_block) == 512, "uf2_block not sector sized"); diff --git a/src/common/pico_binary_info/include/pico/binary_info/structure.h b/src/common/pico_binary_info/include/pico/binary_info/structure.h index 49d2fd690..4b679c480 100644 --- a/src/common/pico_binary_info/include/pico/binary_info/structure.h +++ b/src/common/pico_binary_info/include/pico/binary_info/structure.h @@ -21,6 +21,27 @@ extern "C" { #define __packed __attribute__((packed)) #endif +#if !defined(le_uint16_t) || !defined(le_uint32_t) || !defined(le_int32_t) + +#if defined(_MSC_VER) || __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + +#ifndef le_uint16_t +#define le_uint16_t uint16_t +#endif +#ifndef le_uint32_t +#define le_uint32_t uint32_t +#endif +#ifndef le_int32_t +#define le_int32_t int32_t +#endif + +#else +#error Must define le_uint16_t, le_uint32_t, and le_int32_t when compiling for big endian +#endif + +#endif + + typedef struct _binary_info_core binary_info_t; #define BINARY_INFO_TYPE_RAW_DATA 1 @@ -59,11 +80,11 @@ typedef struct _binary_info_core binary_info_t; #if PICO_ON_DEVICE #define bi_ptr_of(x) x * #else -#define bi_ptr_of(x) uint32_t +#define bi_ptr_of(x) le_uint32_t #endif typedef struct __packed _binary_info_core { - uint16_t type; - uint16_t tag; + le_uint16_t type; + le_uint16_t tag; } binary_info_core_t; typedef struct __packed _binary_info_raw_data { @@ -73,7 +94,7 @@ typedef struct __packed _binary_info_raw_data { typedef struct __packed _binary_info_sized_data { struct _binary_info_core core; - uint32_t length; + le_uint32_t length; uint8_t bytes[1]; } binary_info_sized_data_t; @@ -84,23 +105,23 @@ typedef struct __packed _binary_info_list_zero_terminated { typedef struct __packed _binary_info_id_and_int { struct _binary_info_core core; - uint32_t id; - int32_t value; + le_uint32_t id; + le_int32_t value; } binary_info_id_and_int_t; typedef struct __packed _binary_info_id_and_string { struct _binary_info_core core; - uint32_t id; + le_uint32_t id; bi_ptr_of(const char) value; } binary_info_id_and_string_t; typedef struct __packed _binary_info_block_device { struct _binary_info_core core; bi_ptr_of(const char) name; // optional static name (independent of what is formatted) - uint32_t address; - uint32_t size; + le_uint32_t address; + le_uint32_t size; bi_ptr_of(binary_info_t) extra; // additional info - uint16_t flags; + le_uint16_t flags; } binary_info_block_device_t; #define BI_PINS_ENCODING_RANGE 1 @@ -110,12 +131,12 @@ typedef struct __packed _binary_info_pins_with_func { struct _binary_info_core core; // p4_5 : p3_5 : p2_5 : p1_5 : p0_5 : func_4 : 001_3 //individual pins p0,p1,p2,p3,p4 ... if fewer than 5 then duplicate p // phi_5 : plo_5 : func_4 : 010_3 // pin range plo-phi inclusive - uint32_t pin_encoding; + le_uint32_t pin_encoding; } binary_info_pins_with_func_t; typedef struct __packed _binary_info_pins_with_name { struct _binary_info_core core; - uint32_t pin_mask; + le_uint32_t pin_mask; bi_ptr_of(const char) label; } binary_info_pins_with_name_t; @@ -126,10 +147,10 @@ typedef struct __packed _binary_info_pins_with_name { typedef struct __packed _binary_info_named_group { struct _binary_info_core core; - uint32_t parent_id; - uint16_t flags; - uint16_t group_tag; - uint32_t group_id; + le_uint32_t parent_id; + le_uint16_t flags; + le_uint16_t group_tag; + le_uint32_t group_id; bi_ptr_of(const char) label; } binary_info_named_group_t; @@ -148,4 +169,4 @@ enum { #ifdef __cplusplus } #endif -#endif \ No newline at end of file +#endif diff --git a/src/host/pico_platform/include/pico/platform.h b/src/host/pico_platform/include/pico/platform.h index da060a6a2..d05bdee70 100644 --- a/src/host/pico_platform/include/pico/platform.h +++ b/src/host/pico_platform/include/pico/platform.h @@ -135,5 +135,38 @@ static inline void __compiler_memory_barrier(void) { } #ifdef __cplusplus } + +template struct stored_little_endian { +#if defined(_MSC_VER) || __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + // Use identity functions if the system is natively little endian + T v; + inline stored_little_endian& operator= (const T& x) { v = x; return *this; } + inline operator T() const { return v; } +#else + uint8_t v[sizeof(T)]; + inline stored_little_endian& operator= (const T& x) { + for (unsigned i = 0; i < sizeof(T); i++) + v[i] = x >> 8*i; + return *this; + }; + inline operator T() const { + T x = v[0]; + for (unsigned i = 1; i < sizeof(T); i++) + x |= v[i] << 8*i; + return x; + } +#endif +}; + +#ifndef le_uint16_t +#define le_uint16_t stored_little_endian +#endif +#ifndef le_uint32_t +#define le_uint32_t stored_little_endian +#endif +#ifndef le_int32_t +#define le_int32_t stored_little_endian +#endif + #endif #endif diff --git a/tools/elf2uf2/CMakeLists.txt b/tools/elf2uf2/CMakeLists.txt index 070e114ef..dbeade1a7 100644 --- a/tools/elf2uf2/CMakeLists.txt +++ b/tools/elf2uf2/CMakeLists.txt @@ -4,6 +4,7 @@ project(elf2uf2) set(CMAKE_CXX_STANDARD 14) add_subdirectory(../../src/common/boot_uf2 boot_uf2_headers) +add_subdirectory(../../src/host/pico_platform pico_platform) add_executable(elf2uf2 main.cpp) -target_link_libraries(elf2uf2 boot_uf2_headers) \ No newline at end of file +target_link_libraries(elf2uf2 boot_uf2_headers pico_platform_headers) \ No newline at end of file diff --git a/tools/elf2uf2/elf.h b/tools/elf2uf2/elf.h index 32e3dbb40..9bc432f27 100644 --- a/tools/elf2uf2/elf.h +++ b/tools/elf2uf2/elf.h @@ -17,44 +17,45 @@ #define PT_LOAD 0x00000001u +/* Note, only little endian ELFs handled */ #pragma pack(push, 1) struct elf_header { - uint32_t magic; + le_uint32_t magic; uint8_t arch_class; uint8_t endianness; uint8_t version; uint8_t abi; uint8_t abi_version; uint8_t _pad[7]; - uint16_t type; - uint16_t machine; - uint32_t version2; + le_uint16_t type; + le_uint16_t machine; + le_uint32_t version2; }; struct elf32_header { struct elf_header common; - uint32_t entry; - uint32_t ph_offset; - uint32_t sh_offset; - uint32_t flags; - uint16_t eh_size; - uint16_t ph_entry_size; - uint16_t ph_num; - uint16_t sh_entry_size; - uint16_t sh_num; - uint16_t sh_str_index; + le_uint32_t entry; + le_uint32_t ph_offset; + le_uint32_t sh_offset; + le_uint32_t flags; + le_uint16_t eh_size; + le_uint16_t ph_entry_size; + le_uint16_t ph_num; + le_uint16_t sh_entry_size; + le_uint16_t sh_num; + le_uint16_t sh_str_index; }; struct elf32_ph_entry { - uint32_t type; - uint32_t offset; - uint32_t vaddr; - uint32_t paddr; - uint32_t filez; - uint32_t memsz; - uint32_t flags; - uint32_t align; + le_uint32_t type; + le_uint32_t offset; + le_uint32_t vaddr; + le_uint32_t paddr; + le_uint32_t filez; + le_uint32_t memsz; + le_uint32_t flags; + le_uint32_t align; }; #pragma pack(pop) -#endif \ No newline at end of file +#endif diff --git a/tools/elf2uf2/main.cpp b/tools/elf2uf2/main.cpp index b66f082ce..a204e554f 100644 --- a/tools/elf2uf2/main.cpp +++ b/tools/elf2uf2/main.cpp @@ -9,7 +9,9 @@ #include #include #include +#include #include +#include "pico/platform.h" #include "boot/uf2.h" #include "elf.h" @@ -303,7 +305,7 @@ int elf2uf2(FILE *in, FILE *out) { block.target_addr = page_entry.first; block.block_no = page_num++; if (verbose) { - printf("Page %d / %d %08x\n", block.block_no, block.num_blocks, block.target_addr); + printf("Page %d / %d %08x\n", static_cast(block.block_no), static_cast(block.num_blocks), static_cast(block.target_addr)); } memset(block.data, 0, sizeof(block.data)); rc = realize_page(in, page_entry.second, block.data, sizeof(block.data));