183d290c5STom Rini /* SPDX-License-Identifier: GPL-2.0+ */ 242ebaae3SMarek Vasut /* 342ebaae3SMarek Vasut * include/linker_lists.h 442ebaae3SMarek Vasut * 542ebaae3SMarek Vasut * Implementation of linker-generated arrays 642ebaae3SMarek Vasut * 742ebaae3SMarek Vasut * Copyright (C) 2012 Marek Vasut <marex@denx.de> 842ebaae3SMarek Vasut */ 9ef123c52SAlbert ARIBAUD 10babb4440SMasahiro Yamada #ifndef __LINKER_LISTS_H__ 11babb4440SMasahiro Yamada #define __LINKER_LISTS_H__ 12babb4440SMasahiro Yamada 13dc7cb46fSMasahiro Yamada #include <linux/compiler.h> 14dc7cb46fSMasahiro Yamada 15ef123c52SAlbert ARIBAUD /* 16d72fd7b3SHeinrich Schuchardt * There is no use in including this from ASM files. 17ef123c52SAlbert ARIBAUD * So just don't define anything when included from ASM. 18ef123c52SAlbert ARIBAUD */ 19ef123c52SAlbert ARIBAUD 20ef123c52SAlbert ARIBAUD #if !defined(__ASSEMBLY__) 21ef123c52SAlbert ARIBAUD 22ef123c52SAlbert ARIBAUD /** 237e378b8bSBin Meng * llsym() - Access a linker-generated array entry 2472538f4cSSimon Glass * @_type: Data type of the entry 2572538f4cSSimon Glass * @_name: Name of the entry 2672538f4cSSimon Glass * @_list: name of the list. Should contain only characters allowed 2772538f4cSSimon Glass * in a C variable name! 2872538f4cSSimon Glass */ 2972538f4cSSimon Glass #define llsym(_type, _name, _list) \ 3072538f4cSSimon Glass ((_type *)&_u_boot_list_2_##_list##_2_##_name) 3172538f4cSSimon Glass 3272538f4cSSimon Glass /** 3342ebaae3SMarek Vasut * ll_entry_declare() - Declare linker-generated array entry 3442ebaae3SMarek Vasut * @_type: Data type of the entry 3542ebaae3SMarek Vasut * @_name: Name of the entry 36ef123c52SAlbert ARIBAUD * @_list: name of the list. Should contain only characters allowed 37ef123c52SAlbert ARIBAUD * in a C variable name! 3842ebaae3SMarek Vasut * 3942ebaae3SMarek Vasut * This macro declares a variable that is placed into a linker-generated 4042ebaae3SMarek Vasut * array. This is a basic building block for more advanced use of linker- 4142ebaae3SMarek Vasut * generated arrays. The user is expected to build their own macro wrapper 4242ebaae3SMarek Vasut * around this one. 4342ebaae3SMarek Vasut * 44ef123c52SAlbert ARIBAUD * A variable declared using this macro must be compile-time initialized. 4542ebaae3SMarek Vasut * 4642ebaae3SMarek Vasut * Special precaution must be made when using this macro: 4742ebaae3SMarek Vasut * 48ef123c52SAlbert ARIBAUD * 1) The _type must not contain the "static" keyword, otherwise the 49ef123c52SAlbert ARIBAUD * entry is generated and can be iterated but is listed in the map 50ef123c52SAlbert ARIBAUD * file and cannot be retrieved by name. 5142ebaae3SMarek Vasut * 52ef123c52SAlbert ARIBAUD * 2) In case a section is declared that contains some array elements AND 53ef123c52SAlbert ARIBAUD * a subsection of this section is declared and contains some elements, 54ef123c52SAlbert ARIBAUD * it is imperative that the elements are of the same type. 5542ebaae3SMarek Vasut * 56*78a88f79SMario Six * 3) In case an outer section is declared that contains some array elements 57ef123c52SAlbert ARIBAUD * AND an inner subsection of this section is declared and contains some 5842ebaae3SMarek Vasut * elements, then when traversing the outer section, even the elements of 5942ebaae3SMarek Vasut * the inner sections are present in the array. 6042ebaae3SMarek Vasut * 6142ebaae3SMarek Vasut * Example: 62*78a88f79SMario Six * 63*78a88f79SMario Six * :: 64*78a88f79SMario Six * 657e378b8bSBin Meng * ll_entry_declare(struct my_sub_cmd, my_sub_cmd, cmd_sub) = { 6642ebaae3SMarek Vasut * .x = 3, 6742ebaae3SMarek Vasut * .y = 4, 6842ebaae3SMarek Vasut * }; 6942ebaae3SMarek Vasut */ 70ef123c52SAlbert ARIBAUD #define ll_entry_declare(_type, _name, _list) \ 71ef123c52SAlbert ARIBAUD _type _u_boot_list_2_##_list##_2_##_name __aligned(4) \ 72ef123c52SAlbert ARIBAUD __attribute__((unused, \ 73ef123c52SAlbert ARIBAUD section(".u_boot_list_2_"#_list"_2_"#_name))) 74ef123c52SAlbert ARIBAUD 75ef123c52SAlbert ARIBAUD /** 763fcc3af4SSimon Glass * ll_entry_declare_list() - Declare a list of link-generated array entries 773fcc3af4SSimon Glass * @_type: Data type of each entry 783fcc3af4SSimon Glass * @_name: Name of the entry 793fcc3af4SSimon Glass * @_list: name of the list. Should contain only characters allowed 803fcc3af4SSimon Glass * in a C variable name! 813fcc3af4SSimon Glass * 823fcc3af4SSimon Glass * This is like ll_entry_declare() but creates multiple entries. It should 833fcc3af4SSimon Glass * be assigned to an array. 843fcc3af4SSimon Glass * 85*78a88f79SMario Six * :: 86*78a88f79SMario Six * 877e378b8bSBin Meng * ll_entry_declare_list(struct my_sub_cmd, my_sub_cmd, cmd_sub) = { 883fcc3af4SSimon Glass * { .x = 3, .y = 4 }, 893fcc3af4SSimon Glass * { .x = 8, .y = 2 }, 903fcc3af4SSimon Glass * { .x = 1, .y = 7 } 913fcc3af4SSimon Glass * }; 923fcc3af4SSimon Glass */ 933fcc3af4SSimon Glass #define ll_entry_declare_list(_type, _name, _list) \ 943fcc3af4SSimon Glass _type _u_boot_list_2_##_list##_2_##_name[] __aligned(4) \ 953fcc3af4SSimon Glass __attribute__((unused, \ 963fcc3af4SSimon Glass section(".u_boot_list_2_"#_list"_2_"#_name))) 973fcc3af4SSimon Glass 98*78a88f79SMario Six /* 99ef123c52SAlbert ARIBAUD * We need a 0-byte-size type for iterator symbols, and the compiler 100ef123c52SAlbert ARIBAUD * does not allow defining objects of C type 'void'. Using an empty 101ef123c52SAlbert ARIBAUD * struct is allowed by the compiler, but causes gcc versions 4.4 and 102ef123c52SAlbert ARIBAUD * below to complain about aliasing. Therefore we use the next best 103ef123c52SAlbert ARIBAUD * thing: zero-sized arrays, which are both 0-byte-size and exempt from 104ef123c52SAlbert ARIBAUD * aliasing warnings. 105ef123c52SAlbert ARIBAUD */ 10642ebaae3SMarek Vasut 10742ebaae3SMarek Vasut /** 10842ebaae3SMarek Vasut * ll_entry_start() - Point to first entry of linker-generated array 10942ebaae3SMarek Vasut * @_type: Data type of the entry 110ef123c52SAlbert ARIBAUD * @_list: Name of the list in which this entry is placed 11142ebaae3SMarek Vasut * 112*78a88f79SMario Six * This function returns ``(_type *)`` pointer to the very first entry of a 11342ebaae3SMarek Vasut * linker-generated array placed into subsection of .u_boot_list section 114ef123c52SAlbert ARIBAUD * specified by _list argument. 115ef123c52SAlbert ARIBAUD * 116ef123c52SAlbert ARIBAUD * Since this macro defines an array start symbol, its leftmost index 117ef123c52SAlbert ARIBAUD * must be 2 and its rightmost index must be 1. 11842ebaae3SMarek Vasut * 11942ebaae3SMarek Vasut * Example: 120*78a88f79SMario Six * 121*78a88f79SMario Six * :: 122*78a88f79SMario Six * 12342ebaae3SMarek Vasut * struct my_sub_cmd *msc = ll_entry_start(struct my_sub_cmd, cmd_sub); 12442ebaae3SMarek Vasut */ 125ef123c52SAlbert ARIBAUD #define ll_entry_start(_type, _list) \ 12642ebaae3SMarek Vasut ({ \ 127ef123c52SAlbert ARIBAUD static char start[0] __aligned(4) __attribute__((unused, \ 128ef123c52SAlbert ARIBAUD section(".u_boot_list_2_"#_list"_1"))); \ 129ef123c52SAlbert ARIBAUD (_type *)&start; \ 13042ebaae3SMarek Vasut }) 13142ebaae3SMarek Vasut 13242ebaae3SMarek Vasut /** 133ef123c52SAlbert ARIBAUD * ll_entry_end() - Point after last entry of linker-generated array 13442ebaae3SMarek Vasut * @_type: Data type of the entry 135ef123c52SAlbert ARIBAUD * @_list: Name of the list in which this entry is placed 13642ebaae3SMarek Vasut * (with underscores instead of dots) 13742ebaae3SMarek Vasut * 138*78a88f79SMario Six * This function returns ``(_type *)`` pointer after the very last entry of 139ef123c52SAlbert ARIBAUD * a linker-generated array placed into subsection of .u_boot_list 140ef123c52SAlbert ARIBAUD * section specified by _list argument. 141ef123c52SAlbert ARIBAUD * 142ef123c52SAlbert ARIBAUD * Since this macro defines an array end symbol, its leftmost index 143ef123c52SAlbert ARIBAUD * must be 2 and its rightmost index must be 3. 144ef123c52SAlbert ARIBAUD * 145ef123c52SAlbert ARIBAUD * Example: 146*78a88f79SMario Six * 147*78a88f79SMario Six * :: 148*78a88f79SMario Six * 149ef123c52SAlbert ARIBAUD * struct my_sub_cmd *msc = ll_entry_end(struct my_sub_cmd, cmd_sub); 150ef123c52SAlbert ARIBAUD */ 151ef123c52SAlbert ARIBAUD #define ll_entry_end(_type, _list) \ 152ef123c52SAlbert ARIBAUD ({ \ 153ef123c52SAlbert ARIBAUD static char end[0] __aligned(4) __attribute__((unused, \ 154ef123c52SAlbert ARIBAUD section(".u_boot_list_2_"#_list"_3"))); \ 155ef123c52SAlbert ARIBAUD (_type *)&end; \ 156ef123c52SAlbert ARIBAUD }) 157ef123c52SAlbert ARIBAUD /** 158ef123c52SAlbert ARIBAUD * ll_entry_count() - Return the number of elements in linker-generated array 159ef123c52SAlbert ARIBAUD * @_type: Data type of the entry 160ef123c52SAlbert ARIBAUD * @_list: Name of the list of which the number of elements is computed 161ef123c52SAlbert ARIBAUD * 16242ebaae3SMarek Vasut * This function returns the number of elements of a linker-generated array 163ef123c52SAlbert ARIBAUD * placed into subsection of .u_boot_list section specified by _list 16442ebaae3SMarek Vasut * argument. The result is of an unsigned int type. 16542ebaae3SMarek Vasut * 16642ebaae3SMarek Vasut * Example: 167*78a88f79SMario Six * 168*78a88f79SMario Six * :: 169*78a88f79SMario Six * 17042ebaae3SMarek Vasut * int i; 17142ebaae3SMarek Vasut * const unsigned int count = ll_entry_count(struct my_sub_cmd, cmd_sub); 17242ebaae3SMarek Vasut * struct my_sub_cmd *msc = ll_entry_start(struct my_sub_cmd, cmd_sub); 17342ebaae3SMarek Vasut * for (i = 0; i < count; i++, msc++) 17442ebaae3SMarek Vasut * printf("Entry %i, x=%i y=%i\n", i, msc->x, msc->y); 17542ebaae3SMarek Vasut */ 176ef123c52SAlbert ARIBAUD #define ll_entry_count(_type, _list) \ 17742ebaae3SMarek Vasut ({ \ 178ef123c52SAlbert ARIBAUD _type *start = ll_entry_start(_type, _list); \ 179ef123c52SAlbert ARIBAUD _type *end = ll_entry_end(_type, _list); \ 180ef123c52SAlbert ARIBAUD unsigned int _ll_result = end - start; \ 18142ebaae3SMarek Vasut _ll_result; \ 18242ebaae3SMarek Vasut }) 18342ebaae3SMarek Vasut 18442ebaae3SMarek Vasut /** 18542ebaae3SMarek Vasut * ll_entry_get() - Retrieve entry from linker-generated array by name 18642ebaae3SMarek Vasut * @_type: Data type of the entry 18742ebaae3SMarek Vasut * @_name: Name of the entry 188ef123c52SAlbert ARIBAUD * @_list: Name of the list in which this entry is placed 18942ebaae3SMarek Vasut * 1907e378b8bSBin Meng * This function returns a pointer to a particular entry in linker-generated 1917e378b8bSBin Meng * array identified by the subsection of u_boot_list where the entry resides 19242ebaae3SMarek Vasut * and it's name. 19342ebaae3SMarek Vasut * 19442ebaae3SMarek Vasut * Example: 195*78a88f79SMario Six * 196*78a88f79SMario Six * :: 197*78a88f79SMario Six * 198af41d6b4SMateusz Zalega * ll_entry_declare(struct my_sub_cmd, my_sub_cmd, cmd_sub) = { 19942ebaae3SMarek Vasut * .x = 3, 20042ebaae3SMarek Vasut * .y = 4, 20142ebaae3SMarek Vasut * }; 20242ebaae3SMarek Vasut * ... 20342ebaae3SMarek Vasut * struct my_sub_cmd *c = ll_entry_get(struct my_sub_cmd, my_sub_cmd, cmd_sub); 20442ebaae3SMarek Vasut */ 205ef123c52SAlbert ARIBAUD #define ll_entry_get(_type, _name, _list) \ 20642ebaae3SMarek Vasut ({ \ 207ef123c52SAlbert ARIBAUD extern _type _u_boot_list_2_##_list##_2_##_name; \ 208ef123c52SAlbert ARIBAUD _type *_ll_result = \ 209ef123c52SAlbert ARIBAUD &_u_boot_list_2_##_list##_2_##_name; \ 21042ebaae3SMarek Vasut _ll_result; \ 21142ebaae3SMarek Vasut }) 21242ebaae3SMarek Vasut 213ef123c52SAlbert ARIBAUD /** 214ef123c52SAlbert ARIBAUD * ll_start() - Point to first entry of first linker-generated array 215ef123c52SAlbert ARIBAUD * @_type: Data type of the entry 216ef123c52SAlbert ARIBAUD * 217*78a88f79SMario Six * This function returns ``(_type *)`` pointer to the very first entry of 218ef123c52SAlbert ARIBAUD * the very first linker-generated array. 219ef123c52SAlbert ARIBAUD * 220ef123c52SAlbert ARIBAUD * Since this macro defines the start of the linker-generated arrays, 221ef123c52SAlbert ARIBAUD * its leftmost index must be 1. 222ef123c52SAlbert ARIBAUD * 223ef123c52SAlbert ARIBAUD * Example: 224*78a88f79SMario Six * 225*78a88f79SMario Six * :: 226*78a88f79SMario Six * 227ef123c52SAlbert ARIBAUD * struct my_sub_cmd *msc = ll_start(struct my_sub_cmd); 228ef123c52SAlbert ARIBAUD */ 229ef123c52SAlbert ARIBAUD #define ll_start(_type) \ 230ef123c52SAlbert ARIBAUD ({ \ 231ef123c52SAlbert ARIBAUD static char start[0] __aligned(4) __attribute__((unused, \ 232ef123c52SAlbert ARIBAUD section(".u_boot_list_1"))); \ 233ef123c52SAlbert ARIBAUD (_type *)&start; \ 234ef123c52SAlbert ARIBAUD }) 235ef123c52SAlbert ARIBAUD 236ef123c52SAlbert ARIBAUD /** 2377e378b8bSBin Meng * ll_end() - Point after last entry of last linker-generated array 238ef123c52SAlbert ARIBAUD * @_type: Data type of the entry 239ef123c52SAlbert ARIBAUD * 240*78a88f79SMario Six * This function returns ``(_type *)`` pointer after the very last entry of 241ef123c52SAlbert ARIBAUD * the very last linker-generated array. 242ef123c52SAlbert ARIBAUD * 243ef123c52SAlbert ARIBAUD * Since this macro defines the end of the linker-generated arrays, 244ef123c52SAlbert ARIBAUD * its leftmost index must be 3. 245ef123c52SAlbert ARIBAUD * 246ef123c52SAlbert ARIBAUD * Example: 247*78a88f79SMario Six * 248*78a88f79SMario Six * :: 249*78a88f79SMario Six * 250ef123c52SAlbert ARIBAUD * struct my_sub_cmd *msc = ll_end(struct my_sub_cmd); 251ef123c52SAlbert ARIBAUD */ 252ef123c52SAlbert ARIBAUD #define ll_end(_type) \ 253ef123c52SAlbert ARIBAUD ({ \ 254ef123c52SAlbert ARIBAUD static char end[0] __aligned(4) __attribute__((unused, \ 255ef123c52SAlbert ARIBAUD section(".u_boot_list_3"))); \ 256ef123c52SAlbert ARIBAUD (_type *)&end; \ 257ef123c52SAlbert ARIBAUD }) 258ef123c52SAlbert ARIBAUD 259ef123c52SAlbert ARIBAUD #endif /* __ASSEMBLY__ */ 260ef123c52SAlbert ARIBAUD 26142ebaae3SMarek Vasut #endif /* __LINKER_LISTS_H__ */ 262