Skip to content

Commit

Permalink
Swap endian-ness in tools on big endian host
Browse files Browse the repository at this point in the history
  • Loading branch information
zeldin committed May 1, 2021
1 parent c6d70d5 commit b1a6158
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 64 deletions.
24 changes: 12 additions & 12 deletions src/common/boot_picoboot/include/boot/picoboot.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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;
Expand All @@ -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];
Expand Down
20 changes: 10 additions & 10 deletions src/common/boot_uf2/include/boot/uf2.h
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
55 changes: 38 additions & 17 deletions src/common/pico_binary_info/include/pico/binary_info/structure.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand All @@ -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;

Expand All @@ -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
Expand All @@ -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;

Expand All @@ -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;

Expand All @@ -148,4 +169,4 @@ enum {
#ifdef __cplusplus
}
#endif
#endif
#endif
16 changes: 16 additions & 0 deletions src/host/pico_platform/include/pico/platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,5 +135,21 @@ static inline void __compiler_memory_barrier(void) {
}
#ifdef __cplusplus
}

template<typename T> struct stored_little_endian {
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
#endif
3 changes: 2 additions & 1 deletion tools/elf2uf2/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
target_link_libraries(elf2uf2 boot_uf2_headers pico_platform_headers)
47 changes: 24 additions & 23 deletions tools/elf2uf2/elf.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
#endif
7 changes: 6 additions & 1 deletion tools/elf2uf2/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,12 @@
#include <vector>
#include <cstring>
#include <cstdarg>
#include <cstdint>
#include <algorithm>
#include "pico/platform.h"
#define le_uint16_t stored_little_endian<uint16_t>
#define le_uint32_t stored_little_endian<uint32_t>
#define le_int32_t stored_little_endian<int32_t>
#include "boot/uf2.h"
#include "elf.h"

Expand Down Expand Up @@ -303,7 +308,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<int>(block.block_no), static_cast<int>(block.num_blocks), static_cast<unsigned>(block.target_addr));
}
memset(block.data, 0, sizeof(block.data));
rc = realize_page(in, page_entry.second, block.data, sizeof(block.data));
Expand Down

0 comments on commit b1a6158

Please sign in to comment.