1 /*
2  * Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #ifndef _BOOT_PICOBIN_H
8 #define _BOOT_PICOBIN_H
9 
10 #ifndef NO_PICO_PLATFORM
11 #include "pico/platform.h"
12 #else
13 #ifndef _u
14 #ifdef __ASSEMBLER__
15 #define _u(x) x
16 #else
17 #define _u(x) x ## u
18 #endif
19 #endif
20 #endif
21 
22 /** \file picobin.h
23 *  \defgroup boot_picobin_headers boot_picobin_headers
24 *
25 * \brief Constants for PICOBIN format
26 */
27 
28 // these are designed to not look like (likely) 16/32-bit ARM or RISC-V instructions or look like valid pointers
29 #define PICOBIN_BLOCK_MARKER_START _u(0xffffded3)
30 #define PICOBIN_BLOCK_MARKER_END   _u(0xab123579)
31 
32 #define PICOBIN_MAX_BLOCK_SIZE _u(0x280)
33 #define PICOBIN_MAX_IMAGE_DEF_BLOCK_SIZE _u(0x180)
34 #define PICOBIN_MAX_PARTITION_TABLE_BLOCK_SIZE _u(0x280)
35 
36 // note bit 6 is used to make parity even
37 #define PICOBIN_BLOCK_ITEM_1BS_NEXT_BLOCK_OFFSET        _u(0x41)
38 #define PICOBIN_BLOCK_ITEM_1BS_IMAGE_TYPE               _u(0x42)
39 #define PICOBIN_BLOCK_ITEM_1BS_VECTOR_TABLE             _u(0x03)
40 #define PICOBIN_BLOCK_ITEM_1BS_ENTRY_POINT              _u(0x44)
41 #define PICOBIN_BLOCK_ITEM_1BS_ROLLING_WINDOW_DELTA     _u(0x05)
42 #define PICOBIN_BLOCK_ITEM_LOAD_MAP                     _u(0x06)
43 #define PICOBIN_BLOCK_ITEM_1BS_HASH_DEF                 _u(0x47)
44 #define PICOBIN_BLOCK_ITEM_1BS_VERSION                  _u(0x48)
45 #define PICOBIN_BLOCK_ITEM_SIGNATURE                    _u(0x09)
46 #define PICOBIN_BLOCK_ITEM_PARTITION_TABLE              _u(0x0a)
47 #define PICOBIN_BLOCK_ITEM_HASH_VALUE                   _u(0x4b)
48 #define PICOBIN_BLOCK_ITEM_SALT                         _u(0x0c)
49 
50 #define PICOBIN_BLOCK_ITEM_2BS_IGNORED          (_u(0x80) | _u(0x7e))
51 #define PICOBIN_BLOCK_ITEM_2BS_LAST             (_u(0x80) | _u(0x7f))
52 
53 // ----
54 
55 #define _PICOBIN_INDEX_TO_BITS(y, x) (y ## x << y ## _LSB)
56 #define PICOBIN_INDEX_TO_BITS(y, x) (y ## _ ## x << y ## _LSB)
57 
58 #define PICOBIN_IMAGE_TYPE_IMAGE_TYPE_LSB            _u(0)
59 #define PICOBIN_IMAGE_TYPE_IMAGE_TYPE_BITS           _u(0x000f)
60 #define PICOBIN_IMAGE_TYPE_IMAGE_TYPE_INVALID        _u(0x0)
61 #define PICOBIN_IMAGE_TYPE_IMAGE_TYPE_EXE            _u(0x1)
62 #define PICOBIN_IMAGE_TYPE_IMAGE_TYPE_DATA           _u(0x2)
63 #define PICOBIN_IMAGE_TYPE_IMAGE_TYPE_AS_BITS(x) _PICOBIN_INDEX_TO_BITS(PICOBIN_IMAGE_TYPE_IMAGE_TYPE, _ ## x)
64 
65 #define PICOBIN_IMAGE_TYPE_EXE_SECURITY_LSB          _u(4)
66 #define PICOBIN_IMAGE_TYPE_EXE_SECURITY_BITS         _u(0x0030)
67 #define PICOBIN_IMAGE_TYPE_EXE_SECURITY_UNSPECIFIED  _u(0x0)
68 #define PICOBIN_IMAGE_TYPE_EXE_SECURITY_NS           _u(0x1)
69 #define PICOBIN_IMAGE_TYPE_EXE_SECURITY_S            _u(0x2)
70 #define PICOBIN_IMAGE_TYPE_EXE_SECURITY_AS_BITS(x) _PICOBIN_INDEX_TO_BITS(PICOBIN_IMAGE_TYPE_EXE_SECURITY, _ ## x)
71 
72 #define PICOBIN_IMAGE_TYPE_EXE_CPU_LSB               _u(8)
73 #define PICOBIN_IMAGE_TYPE_EXE_CPU_BITS              _u(0x0700)
74 #define PICOBIN_IMAGE_TYPE_EXE_CPU_ARM               _u(0)
75 #define PICOBIN_IMAGE_TYPE_EXE_CPU_RISCV             _u(1)
76 #define PICOBIN_IMAGE_TYPE_EXE_CPU_VARMULET          _u(2)
77 #define PICOBIN_IMAGE_TYPE_EXE_CPU_AS_BITS(x) _PICOBIN_INDEX_TO_BITS(PICOBIN_IMAGE_TYPE_EXE_CPU, _ ## x)
78 
79 #define PICOBIN_IMAGE_TYPE_EXE_CHIP_LSB              _u(12)
80 #define PICOBIN_IMAGE_TYPE_EXE_CHIP_BITS             _u(0x7000)
81 #define PICOBIN_IMAGE_TYPE_EXE_CHIP_RP2040           _u(0)
82 #define PICOBIN_IMAGE_TYPE_EXE_CHIP_RP2350           _u(1)
83 #define PICOBIN_IMAGE_TYPE_EXE_CHIP_AS_BITS(x) _PICOBIN_INDEX_TO_BITS(PICOBIN_IMAGE_TYPE_EXE_CHIP, _ ## x)
84 
85 #define PICOBIN_IMAGE_TYPE_EXE_TBYB_BITS             _u(0x8000)
86 
87 // todo assert no overlap ^
88 
89 #define PICOBIN_PARTITION_PERMISSIONS_LSB                                   _u(26)
90 #define PICOBIN_PARTITION_PERMISSIONS_BITS                                  _u(0xfc000000)
91 
92 #define PICOBIN_PARTITION_PERMISSION_S_R_BITS                               _u(0x04000000)
93 #define PICOBIN_PARTITION_PERMISSION_S_W_BITS                               _u(0x08000000)
94 #define PICOBIN_PARTITION_PERMISSION_NS_R_BITS                              _u(0x10000000)
95 #define PICOBIN_PARTITION_PERMISSION_NS_W_BITS                              _u(0x20000000)
96 #define PICOBIN_PARTITION_PERMISSION_NSBOOT_R_BITS                          _u(0x40000000)
97 #define PICOBIN_PARTITION_PERMISSION_NSBOOT_W_BITS                          _u(0x80000000)
98 
99 #define PICOBIN_PARTITION_LOCATION_FIRST_SECTOR_LSB                         _u(0)
100 #define PICOBIN_PARTITION_LOCATION_FIRST_SECTOR_BITS                        _u(0x00001fff)
101 #define PICOBIN_PARTITION_LOCATION_LAST_SECTOR_LSB                          _u(13)
102 #define PICOBIN_PARTITION_LOCATION_LAST_SECTOR_BITS                         _u(0x03ffe000)
103 
104 #define PICOBIN_PARTITION_FLAGS_HAS_ID_BITS                                 _u(0x00000001)
105 #define PICOBIN_PARTITION_FLAGS_LINK_TYPE_LSB                               _u(1)
106 #define PICOBIN_PARTITION_FLAGS_LINK_TYPE_BITS                              _u(0x00000006)
107 #define PICOBIN_PARTITION_FLAGS_LINK_VALUE_LSB                              _u(3)
108 #define PICOBIN_PARTITION_FLAGS_LINK_VALUE_BITS                             _u(0x00000078)
109 
110 #define PICOBIN_PARTITION_MAX_EXTRA_FAMILIES                                _u(3)
111 #define PICOBIN_PARTITION_FLAGS_ACCEPTS_NUM_EXTRA_FAMILIES_LSB              _u(7)
112 #define PICOBIN_PARTITION_FLAGS_ACCEPTS_NUM_EXTRA_FAMILIES_BITS             _u(0x00000180)
113 // these are an optimization when booting in either ARM or RISC-V, to avoid looking at partitions
114 // which are known not to contain the right sort of binary, OR as a way to prevent
115 // auto-architecture-switch. NOTE: the first partition that can be booted, will be,
116 // so if you have a RISC-V binary in the first partition, and auto-arhcitecture-switch enabled, then
117 // even if booting under ARM, with an ARM binary in a later partition, the RISC-V binary
118 // will be booted by default; setting PICOBIN_PARTITION_FLAGS_IGNORED_DURING_ARM_BOOT_BITS
119 // on the partition, will have the RISC-V binary containing partition ignored under ARM
120 // boot
121 #define PICOBIN_PARTITION_FLAGS_IGNORED_DURING_ARM_BOOT_BITS                _u(0x00000200)
122 #define PICOBIN_PARTITION_FLAGS_IGNORED_DURING_RISCV_BOOT_BITS              _u(0x00000400)
123 #define PICOBIN_PARTITION_FLAGS_UF2_DOWNLOAD_AB_NON_BOOTABLE_OWNER_AFFINITY _u(0x00000800)
124 #define PICOBIN_PARTITION_FLAGS_HAS_NAME_BITS                               _u(0x00001000)
125 #define PICOBIN_PARTITION_FLAGS_UF2_DOWNLOAD_NO_REBOOT_BITS                 _u(0x00002000)
126 // we have a bit for each well known family-id .. note we expect there to be more in the future with new chips,
127 // but we have plenty of space for now.
128 #define PICOBIN_PARTITION_FLAGS_ACCEPTS_DEFAULT_FAMILIES_LSB                _u(14)
129 #define PICOBIN_PARTITION_FLAGS_ACCEPTS_DEFAULT_FAMILY_RP2040_BITS          _u(0x00004000)
130 #define PICOBIN_PARTITION_FLAGS_ACCEPTS_DEFAULT_FAMILY_ABSOLUTE_BITS        _u(0x00008000)
131 #define PICOBIN_PARTITION_FLAGS_ACCEPTS_DEFAULT_FAMILY_DATA_BITS            _u(0x00010000)
132 #define PICOBIN_PARTITION_FLAGS_ACCEPTS_DEFAULT_FAMILY_RP2350_ARM_S_BITS    _u(0x00020000)
133 #define PICOBIN_PARTITION_FLAGS_ACCEPTS_DEFAULT_FAMILY_RP2350_RISCV_BITS    _u(0x00040000)
134 #define PICOBIN_PARTITION_FLAGS_ACCEPTS_DEFAULT_FAMILY_RP2350_ARM_NS_BITS   _u(0x00080000)
135 
136 #define PICOBIN_PARTITION_FLAGS_LINK_TYPE_NONE                        _u(0)
137 #define PICOBIN_PARTITION_FLAGS_LINK_TYPE_A_PARTITION                 _u(1)
138 #define PICOBIN_PARTITION_FLAGS_LINK_TYPE_OWNER_PARTITION             _u(2)
139 #define PICOBIN_PARTITION_FLAGS_LINK_TYPE_AS_BITS(x) _PICOBIN_INDEX_TO_BITS(PICOBIN_PARTITION_FLAGS_LINK_TYPE, _ ## x)
140 
141 
142 #define PICOBIN_HASH_SHA256                    _u(0x01)
143 
144 #define PICOBIN_SIGNATURE_SECP256K1            _u(0x01)
145 
146 #ifndef __ASSEMBLER__
147 
148 #include <stdbool.h>
149 
150 typedef struct {
151     // these must all be word aligned
152     uint32_t storage_address_rel;
153     uint32_t runtime_address;
154     uint32_t size;
155 } picobin_load_map_entry;
156 
157 typedef struct {
158     uint32_t header;
159     picobin_load_map_entry entries[];
160 } picobin_load_map;
161 
picobin_load_map_entry_count(const picobin_load_map * lm)162 static inline unsigned int picobin_load_map_entry_count(const picobin_load_map *lm) {
163     return (lm->header << 1) >> 25;
164 }
165 
picobin_load_map_is_relative(const picobin_load_map * lm)166 static inline bool picobin_load_map_is_relative(const picobin_load_map *lm) {
167     return (int32_t)lm->header >= 0;
168 }
169 
170 #endif
171 
172 #endif
173