1 /* 2 * Copyright (c) 2020 Raspberry Pi (Trading) Ltd. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #ifndef _PICO_BINARY_INFO_CODE_H 8 #define _PICO_BINARY_INFO_CODE_H 9 10 // pico.h is not available when PICO_NO_BINARY_INFO=1 is used for builds outside of the SDK (e.g. picotool) 11 // and only needed anyway (because of macro definitions) in PICO_NO_BINARY_INFO=0 builds 12 #if !PICO_NO_BINARY_INFO 13 #include "pico.h" 14 #endif 15 16 #include "pico/binary_info/structure.h" 17 18 #if !PICO_NO_BINARY_INFO 19 #define __bi_decl(name, bi, section_prefix, attr) static const attr __attribute__((section(section_prefix __STRING(name)))) struct _binary_info_core *const name = bi 20 #define __bi_lineno_var_name __CONCAT(__bi_, __LINE__) 21 #define __bi_ptr_lineno_var_name __CONCAT(__bi_ptr, __LINE__) 22 #define __bi_enclosure_check_lineno_var_name __CONCAT(_error_bi_is_missing_enclosing_decl_,__LINE__) 23 #define __bi_mark_enclosure static const __unused int __bi_enclosure_check_lineno_var_name=0; 24 #if __cplusplus || __GNUC__ >= 8 25 #define __bi_enclosure_check(x) (x + __bi_enclosure_check_lineno_var_name) 26 #else 27 // skip the version check on older GCC non C++, as it doesn't compile.. this is only here to catch the 28 // user accidentally forgetting to enclose the binary item with bi_decl 29 #define __bi_enclosure_check(x) (x) 30 #endif 31 /** 32 * \brief Declare some binary information that will be included if the contain source file/line is compiled into the binary 33 * \ingroup pico_binary_info 34 */ 35 #define bi_decl(_decl) __bi_mark_enclosure _decl; __bi_decl(__bi_ptr_lineno_var_name, &__bi_lineno_var_name.core, ".binary_info.keep.", __used); 36 /** 37 * \brief Declare some binary information that will be included if the function containing the decl is linked into the binary. 38 * The SDK uses --gc-sections, so functions that are never called will be removed by the linker, and any associated 39 * binary information declared this way will also be stripped 40 * \ingroup pico_binary_info 41 */ 42 #define bi_decl_if_func_used(_decl) ({__bi_mark_enclosure _decl; __bi_decl(__bi_ptr_lineno_var_name, &__bi_lineno_var_name.core, ".binary_info.", ); *(const volatile uint8_t *)&__bi_ptr_lineno_var_name;}); 43 44 #define bi_decl_with_attr(_decl, _attr) __bi_mark_enclosure _attr _decl; __bi_decl(__bi_ptr_lineno_var_name, &__bi_lineno_var_name.core, ".binary_info.keep.", __used); 45 #define bi_decl_if_func_used_with_attr(_decl, _attr) ({__bi_mark_enclosure _attr _decl; __bi_decl(__bi_ptr_lineno_var_name, &__bi_lineno_var_name.core, ".binary_info.", ); *(const volatile uint8_t *)&__bi_ptr_lineno_var_name;}); 46 #else 47 #define __bi_decl(bi, name, attr) 48 #define bi_decl_with_attr(_decl, _attr) 49 #define bi_decl(_decl) 50 #define bi_decl_if_func_used_with_attr(_decl, _attr) ((void)0); 51 #define bi_decl_if_func_used(_decl) ((void)0); 52 #endif 53 54 #define bi_int(_tag, _id, _value) \ 55 static const struct _binary_info_id_and_int __bi_lineno_var_name = { \ 56 .core = { \ 57 .type = __bi_enclosure_check(BINARY_INFO_TYPE_ID_AND_INT), \ 58 .tag = _tag, \ 59 },\ 60 .id = _id, \ 61 .value = _value \ 62 }; 63 64 #define bi_string(_tag, _id, _value) \ 65 static const struct _binary_info_id_and_string __bi_lineno_var_name = { \ 66 .core = { \ 67 .type = __bi_enclosure_check(BINARY_INFO_TYPE_ID_AND_STRING), \ 68 .tag = _tag, \ 69 },\ 70 .id = _id, \ 71 .value = _value, \ 72 } 73 74 #define __bi_ptr_int32_with_name(_tag, _id, _label, _value) \ 75 static const struct _binary_info_ptr_int32_with_name __bi_lineno_var_name = { \ 76 .core = { \ 77 .type = __bi_enclosure_check(BINARY_INFO_TYPE_PTR_INT32_WITH_NAME), \ 78 .tag = _tag, \ 79 },\ 80 .id = _id, \ 81 .value = &_value, \ 82 .label = _label, \ 83 } 84 85 #define bi_ptr_int32(_tag, _id, _var, _default) __attribute__((section(".data"))) static int _var = _default; __bi_ptr_int32_with_name(_tag, _id, __STRING(_var), _var) 86 87 #define __bi_ptr_string_with_name(_tag, _id, _label, _value, _len) \ 88 static const struct _binary_info_ptr_string_with_name __bi_lineno_var_name = { \ 89 .core = { \ 90 .type = __bi_enclosure_check(BINARY_INFO_TYPE_PTR_STRING_WITH_NAME), \ 91 .tag = _tag, \ 92 },\ 93 .id = _id, \ 94 .value = _value, \ 95 .label = _label, \ 96 .len = _len, \ 97 } 98 99 #define bi_ptr_string(_tag, _id, _var, _default, _max_len) static char _var[_max_len] = _default; __bi_ptr_string_with_name(_tag, _id, __STRING(_var), _var, _max_len) 100 101 #define bi_block_device(_tag, _name, _address, _size, _extra, _flags) \ 102 static const struct _binary_info_block_device __bi_lineno_var_name = { \ 103 .core = { \ 104 .type = __bi_enclosure_check(BINARY_INFO_TYPE_BLOCK_DEVICE), \ 105 .tag = _tag, \ 106 },\ 107 .name = _name, \ 108 .address = _address, \ 109 .size = _size, \ 110 .extra = _extra, \ 111 .flags = _flags, \ 112 } 113 114 #define __bi_encoded_pins_with_func(_encoding) \ 115 static const struct _binary_info_pins_with_func __bi_lineno_var_name = { \ 116 .core = { \ 117 .type = __bi_enclosure_check(BINARY_INFO_TYPE_PINS_WITH_FUNC), \ 118 .tag = BINARY_INFO_TAG_RASPBERRY_PI, \ 119 },\ 120 .pin_encoding = _encoding \ 121 } 122 123 #define __bi_encoded_pins_64_with_func(_encoding) \ 124 static const struct _binary_info_pins64_with_func __bi_lineno_var_name = { \ 125 .core = { \ 126 .type = __bi_enclosure_check(BINARY_INFO_TYPE_PINS64_WITH_FUNC), \ 127 .tag = BINARY_INFO_TAG_RASPBERRY_PI, \ 128 },\ 129 .pin_encoding = _encoding \ 130 } 131 132 #define __bi_pins_with_name(_mask, _label) \ 133 static const struct _binary_info_pins_with_name __bi_lineno_var_name = { \ 134 .core = { \ 135 .type = __bi_enclosure_check(BINARY_INFO_TYPE_PINS_WITH_NAME), \ 136 .tag = BINARY_INFO_TAG_RASPBERRY_PI, \ 137 },\ 138 .pin_mask = _mask, \ 139 .label = _label \ 140 } 141 142 #define __bi_pins_64_with_name(_mask, _label) \ 143 static const struct _binary_info_pins64_with_name __bi_lineno_var_name = { \ 144 .core = { \ 145 .type = __bi_enclosure_check(BINARY_INFO_TYPE_PINS64_WITH_NAME), \ 146 .tag = BINARY_INFO_TAG_RASPBERRY_PI, \ 147 },\ 148 .pin_mask = _mask, \ 149 .label = _label \ 150 } 151 152 #define __bi_named_group(_parent_tag, _parent_id, _group_tag, _group_id, _label, _flags) \ 153 static const struct _binary_info_named_group __bi_lineno_var_name = { \ 154 .core = { \ 155 .type = __bi_enclosure_check(BINARY_INFO_TYPE_NAMED_GROUP), \ 156 .tag = _parent_tag, \ 157 },\ 158 .parent_id = _parent_id, \ 159 .group_tag = _group_tag, \ 160 .flags = _flags, \ 161 .group_id = _group_id, \ 162 .label = _label \ 163 } 164 165 #define bi_binary_end(end) bi_int(BINARY_INFO_TAG_RASPBERRY_PI, BINARY_INFO_ID_RP_BINARY_END, end) 166 #define bi_program_name(name) bi_string(BINARY_INFO_TAG_RASPBERRY_PI, BINARY_INFO_ID_RP_PROGRAM_NAME, name) 167 #define bi_program_description(description) bi_string(BINARY_INFO_TAG_RASPBERRY_PI, BINARY_INFO_ID_RP_PROGRAM_DESCRIPTION, description) 168 #define bi_program_version_string(version_string) bi_string(BINARY_INFO_TAG_RASPBERRY_PI, BINARY_INFO_ID_RP_PROGRAM_VERSION_STRING, version_string) 169 #define bi_program_build_date_string(date_string) bi_string(BINARY_INFO_TAG_RASPBERRY_PI, BINARY_INFO_ID_RP_PROGRAM_BUILD_DATE_STRING, date_string) 170 #define bi_program_url(url) bi_string(BINARY_INFO_TAG_RASPBERRY_PI, BINARY_INFO_ID_RP_PROGRAM_URL, url) 171 // multiple of these may be added 172 #define bi_program_feature(feature) bi_string(BINARY_INFO_TAG_RASPBERRY_PI, BINARY_INFO_ID_RP_PROGRAM_FEATURE, feature) 173 #define bi_program_build_attribute(attr) bi_string(BINARY_INFO_TAG_RASPBERRY_PI, BINARY_INFO_ID_RP_PROGRAM_BUILD_ATTRIBUTE, attr) 174 #define bi_program_feature_group(tag, id, name) __bi_named_group(BINARY_INFO_TAG_RASPBERRY_PI, BINARY_INFO_ID_RP_PROGRAM_FEATURE, tag, id, name, 0) 175 #define bi_program_feature_group_with_flags(tag, id, name, flags) __bi_named_group(BINARY_INFO_TAG_RASPBERRY_PI, BINARY_INFO_ID_RP_PROGRAM_FEATURE, tag, id, name, flags) 176 177 178 #ifndef PICO_BINARY_INFO_USE_PINS_64 179 #define PICO_BINARY_INFO_USE_PINS_64 (NUM_BANK0_GPIOS > 32) 180 #endif 181 182 #if !PICO_BINARY_INFO_USE_PINS_64 183 #define bi_1pin_with_func(p0, func) __bi_encoded_pins_with_func(BI_PINS_ENCODING_MULTI | ((func << 3)) | ((p0) << 7) | ((p0) << 12)) 184 #define bi_2pins_with_func(p0, p1, func) __bi_encoded_pins_with_func(BI_PINS_ENCODING_MULTI | ((func << 3)) | ((p0) << 7) | ((p1) << 12) | ((p1) << 17)) 185 #define bi_3pins_with_func(p0, p1, p2, func) __bi_encoded_pins_with_func(BI_PINS_ENCODING_MULTI | ((func << 3)) | ((p0) << 7) | ((p1) << 12) | ((p2) << 17) | ((p2) << 22)) 186 #define bi_4pins_with_func(p0, p1, p2, p3, func) __bi_encoded_pins_with_func(BI_PINS_ENCODING_MULTI | ((func << 3)) | ((p0) << 7) | ((p1) << 12) | ((p2) << 17) | ((p3) << 22) | ((p3) << 27)) 187 #define bi_5pins_with_func(p0, p1, p2, p3, p4, func) __bi_encoded_pins_with_func(BI_PINS_ENCODING_MULTI | ((func << 3)) | ((p0) << 7) | ((p1) << 12) | ((p2) << 17) | ((p3) << 22) | ((p4) << 27)) 188 #define bi_pin_range_with_func(plo, phi, func) __bi_encoded_pins_with_func(BI_PINS_ENCODING_RANGE | ((func << 3)) | ((plo) << 7) | ((phi) << 12)) 189 190 #define bi_pin_mask_with_name(pmask, label) __bi_pins_with_name((pmask), (label)) 191 // names are separated by | ... i.e. "name1|name2|name3" 192 #define bi_pin_mask_with_names(pmask, label) __bi_pins_with_name((pmask), (label)) 193 #else 194 #define bi_1pin_with_func(p0, func) __bi_encoded_pins_64_with_func(BI_PINS_ENCODING_MULTI | ((func << 3)) | ((p0) << 8) | ((p0) << 16)) 195 #define bi_2pins_with_func(p0, p1, func) __bi_encoded_pins_64_with_func(BI_PINS_ENCODING_MULTI | ((func << 3)) | ((p0) << 8) | ((p1) << 16) | ((p1) << 24)) 196 #define bi_3pins_with_func(p0, p1, p2, func) __bi_encoded_pins_64_with_func(BI_PINS_ENCODING_MULTI | ((func << 3)) | ((p0) << 8) | ((p1) << 16) | ((p2) << 24) | ((uint64_t)(p2) << 32)) 197 #define bi_4pins_with_func(p0, p1, p2, p3, func) __bi_encoded_pins_64_with_func(BI_PINS_ENCODING_MULTI | ((func << 3)) | ((p0) << 8) | ((p1) << 16) | ((p2) << 24) | ((uint64_t)(p3) << 32) | ((uint64_t)(p3) << 40)) 198 #define bi_5pins_with_func(p0, p1, p2, p3, p4, func) __bi_encoded_pins_64_with_func(BI_PINS_ENCODING_MULTI | ((func << 3)) | ((p0) << 8) | ((p1) << 16) | ((p2) << 24) | ((uint64_t)(p3) << 32) | ((uint64_t)(p4) << 40) | ((uint64_t)(p4) << 48)) 199 #define bi_pin_range_with_func(plo, phi, func) __bi_encoded_pins_64_with_func(BI_PINS_ENCODING_RANGE | ((func << 3)) | ((plo) << 8) | ((phi) << 16)) 200 201 #define bi_pin_mask_with_name(pmask, label) __bi_pins_64_with_name((uint64_t)(pmask), (label)) 202 // names are separated by | ... i.e. "name1|name2|name3" 203 #define bi_pin_mask_with_names(pmask, label) __bi_pins_64_with_name((uint64_t)(pmask), (label)) 204 #endif 205 206 // 6 and 7 pins require pins_64 207 #define bi_6pins_with_func(p0, p1, p2, p3, p4, p5, func) __bi_encoded_pins_64_with_func(BI_PINS_ENCODING_MULTI | ((func << 3)) | ((p0) << 8) | ((p1) << 16) | ((p2) << 24) | ((uint64_t)(p3) << 32) | ((uint64_t)(p4) << 40) | ((uint64_t)(p5) << 48) | ((uint64_t)(p5) << 56)) 208 #define bi_7pins_with_func(p0, p1, p2, p3, p4, p5, p6,func) __bi_encoded_pins_64_with_func(BI_PINS_ENCODING_MULTI | ((func << 3)) | ((p0) << 8) | ((p1) << 16) | ((p2) << 24) | ((uint64_t)(p3) << 32) | ((uint64_t)(p4) << 40) | ((uint64_t)(p5) << 48) | ((uint64_t)(p6) << 56)) 209 210 #define bi_1pin_with_name(p0, name) bi_pin_mask_with_name(1ull << (p0), name) 211 #define bi_2pins_with_names(p0, name0, p1, name1) bi_pin_mask_with_names((1ull << (p0)) | (1ull << (p1)), p0 < p1 ? name0 "|" name1 : name1 "|" name0) 212 #define bi_3pins_with_names(p0, name0, p1, name1, p2, name2) bi_pin_mask_with_names((1ull << (p0)) | (1ull << (p1)) | (1ull << (p2)),\ 213 p0 < p1 ?\ 214 (p1 < p2 ?\ 215 name0 "|" name1 "|" name2:\ 216 (p0 < p2 ? name0 "|" name2 "|" name1 : name2 "|" name0 "|" name1)):\ 217 (p1 < p2 ?\ 218 (p0 < p2 ? name1 "|" name0 "|" name2 : name1 "|" name2 "|" name0) :\ 219 name2 "|" name1 "|" name0)) 220 #define bi_4pins_with_names(p0, name0, p1, name1, p2, name2, p3, name3) bi_pin_mask_with_names((1ull << (p0)) | (1ull << (p1)) | (1ull << (p2)) | (1ull << (p3)),\ 221 p0 < p1 ?\ 222 (p1 < p2 ?\ 223 (p2 < p3 ?\ 224 name0 "|" name1 "|" name2 "|" name3:\ 225 (p0 < p3 ?\ 226 (p1 < p3 ?\ 227 name0 "|" name1 "|" name3 "|" name2:\ 228 name0 "|" name3 "|" name1 "|" name2):\ 229 name3 "|" name0 "|" name1 "|" name2)):\ 230 (p2 < p3 ?\ 231 (p0 < p2 ?\ 232 (p1 < p3 ?\ 233 name0 "|" name2 "|" name1 "|" name3:\ 234 name0 "|" name2 "|" name3 "|" name1):\ 235 (p0 < p3 ?\ 236 (p1 < p3 ?\ 237 name2 "|" name0 "|" name1 "|" name3:\ 238 name2 "|" name0 "|" name3 "|" name1):\ 239 name2 "|" name3 "|" name0 "|" name1)):\ 240 (p0 < p2 ?\ 241 (p0 < p3 ?\ 242 name0 "|" name3 "|" name2 "|" name1:\ 243 name3 "|" name0 "|" name2 "|" name1):\ 244 name3 "|" name2 "|" name0 "|" name1))):\ 245 (p1 < p2 ?\ 246 (p2 < p3 ?\ 247 (p0 < p2 ?\ 248 name1 "|" name0 "|" name2 "|" name3:\ 249 (p0 < p3 ?\ 250 name1 "|" name2 "|" name0 "|" name3:\ 251 name1 "|" name2 "|" name3 "|" name0)):\ 252 (p0 < p2 ?\ 253 (p0 < p3 ?\ 254 name1 "|" name0 "|" name3 "|" name2:\ 255 (p1 < p3 ?\ 256 name1 "|" name3 "|" name0 "|" name2:\ 257 name3 "|" name1 "|" name0 "|" name2)):\ 258 (p1 < p3 ?\ 259 name1 "|" name3 "|" name2 "|" name0:\ 260 name3 "|" name1 "|" name2 "|" name0))):\ 261 (p2 < p3 ?\ 262 (p0 < p3 ?\ 263 name2 "|" name1 "|" name0 "|" name3:\ 264 (p1 < p3 ?\ 265 name2 "|" name1 "|" name3 "|" name0:\ 266 name2 "|" name3 "|" name1 "|" name0)):\ 267 name3 "|" name2 "|" name1 "|" name0))) 268 269 #endif 270