uboot/include/linker_lists.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0+ */
   2/*
   3 * include/linker_lists.h
   4 *
   5 * Implementation of linker-generated arrays
   6 *
   7 * Copyright (C) 2012 Marek Vasut <marex@denx.de>
   8 */
   9
  10#ifndef __LINKER_LISTS_H__
  11#define __LINKER_LISTS_H__
  12
  13#include <linux/compiler.h>
  14
  15/*
  16 * There is no use in including this from ASM files.
  17 * So just don't define anything when included from ASM.
  18 */
  19
  20#if !defined(__ASSEMBLY__)
  21
  22/**
  23 * llsym() - Access a linker-generated array entry
  24 * @_type:      Data type of the entry
  25 * @_name:      Name of the entry
  26 * @_list:      name of the list. Should contain only characters allowed
  27 *              in a C variable name!
  28 */
  29#define llsym(_type, _name, _list) \
  30                ((_type *)&_u_boot_list_2_##_list##_2_##_name)
  31
  32/**
  33 * ll_entry_declare() - Declare linker-generated array entry
  34 * @_type:      Data type of the entry
  35 * @_name:      Name of the entry
  36 * @_list:      name of the list. Should contain only characters allowed
  37 *              in a C variable name!
  38 *
  39 * This macro declares a variable that is placed into a linker-generated
  40 * array. This is a basic building block for more advanced use of linker-
  41 * generated arrays. The user is expected to build their own macro wrapper
  42 * around this one.
  43 *
  44 * A variable declared using this macro must be compile-time initialized.
  45 *
  46 * Special precaution must be made when using this macro:
  47 *
  48 * 1) The _type must not contain the "static" keyword, otherwise the
  49 *    entry is generated and can be iterated but is listed in the map
  50 *    file and cannot be retrieved by name.
  51 *
  52 * 2) In case a section is declared that contains some array elements AND
  53 *    a subsection of this section is declared and contains some elements,
  54 *    it is imperative that the elements are of the same type.
  55 *
  56 * 3) In case an outer section is declared that contains some array elements
  57 *    AND an inner subsection of this section is declared and contains some
  58 *    elements, then when traversing the outer section, even the elements of
  59 *    the inner sections are present in the array.
  60 *
  61 * Example:
  62 *
  63 * ::
  64 *
  65 *   ll_entry_declare(struct my_sub_cmd, my_sub_cmd, cmd_sub) = {
  66 *           .x = 3,
  67 *           .y = 4,
  68 *   };
  69 */
  70#define ll_entry_declare(_type, _name, _list)                           \
  71        _type _u_boot_list_2_##_list##_2_##_name __aligned(4)           \
  72                        __attribute__((unused))                         \
  73                        __section(".u_boot_list_2_"#_list"_2_"#_name)
  74
  75/**
  76 * ll_entry_declare_list() - Declare a list of link-generated array entries
  77 * @_type:      Data type of each entry
  78 * @_name:      Name of the entry
  79 * @_list:      name of the list. Should contain only characters allowed
  80 *              in a C variable name!
  81 *
  82 * This is like ll_entry_declare() but creates multiple entries. It should
  83 * be assigned to an array.
  84 *
  85 * ::
  86 *
  87 *   ll_entry_declare_list(struct my_sub_cmd, my_sub_cmd, cmd_sub) = {
  88 *        { .x = 3, .y = 4 },
  89 *        { .x = 8, .y = 2 },
  90 *        { .x = 1, .y = 7 }
  91 *   };
  92 */
  93#define ll_entry_declare_list(_type, _name, _list)                      \
  94        _type _u_boot_list_2_##_list##_2_##_name[] __aligned(4)         \
  95                        __attribute__((unused))                         \
  96                        __section(".u_boot_list_2_"#_list"_2_"#_name)
  97
  98/*
  99 * We need a 0-byte-size type for iterator symbols, and the compiler
 100 * does not allow defining objects of C type 'void'. Using an empty
 101 * struct is allowed by the compiler, but causes gcc versions 4.4 and
 102 * below to complain about aliasing. Therefore we use the next best
 103 * thing: zero-sized arrays, which are both 0-byte-size and exempt from
 104 * aliasing warnings.
 105 */
 106
 107/**
 108 * ll_entry_start() - Point to first entry of linker-generated array
 109 * @_type:      Data type of the entry
 110 * @_list:      Name of the list in which this entry is placed
 111 *
 112 * This function returns ``(_type *)`` pointer to the very first entry of a
 113 * linker-generated array placed into subsection of .u_boot_list section
 114 * specified by _list argument.
 115 *
 116 * Since this macro defines an array start symbol, its leftmost index
 117 * must be 2 and its rightmost index must be 1.
 118 *
 119 * Example:
 120 *
 121 * ::
 122 *
 123 *   struct my_sub_cmd *msc = ll_entry_start(struct my_sub_cmd, cmd_sub);
 124 */
 125#define ll_entry_start(_type, _list)                                    \
 126({                                                                      \
 127        static char start[0] __aligned(CONFIG_LINKER_LIST_ALIGN)        \
 128                __attribute__((unused))                                 \
 129                __section(".u_boot_list_2_"#_list"_1");                 \
 130        (_type *)&start;                                                \
 131})
 132
 133/**
 134 * ll_entry_end() - Point after last entry of linker-generated array
 135 * @_type:      Data type of the entry
 136 * @_list:      Name of the list in which this entry is placed
 137 *              (with underscores instead of dots)
 138 *
 139 * This function returns ``(_type *)`` pointer after the very last entry of
 140 * a linker-generated array placed into subsection of .u_boot_list
 141 * section specified by _list argument.
 142 *
 143 * Since this macro defines an array end symbol, its leftmost index
 144 * must be 2 and its rightmost index must be 3.
 145 *
 146 * Example:
 147 *
 148 * ::
 149 *
 150 *   struct my_sub_cmd *msc = ll_entry_end(struct my_sub_cmd, cmd_sub);
 151 */
 152#define ll_entry_end(_type, _list)                                      \
 153({                                                                      \
 154        static char end[0] __aligned(4) __attribute__((unused))         \
 155                __section(".u_boot_list_2_"#_list"_3");                 \
 156        (_type *)&end;                                                  \
 157})
 158/**
 159 * ll_entry_count() - Return the number of elements in linker-generated array
 160 * @_type:      Data type of the entry
 161 * @_list:      Name of the list of which the number of elements is computed
 162 *
 163 * This function returns the number of elements of a linker-generated array
 164 * placed into subsection of .u_boot_list section specified by _list
 165 * argument. The result is of an unsigned int type.
 166 *
 167 * Example:
 168 *
 169 * ::
 170 *
 171 *   int i;
 172 *   const unsigned int count = ll_entry_count(struct my_sub_cmd, cmd_sub);
 173 *   struct my_sub_cmd *msc = ll_entry_start(struct my_sub_cmd, cmd_sub);
 174 *   for (i = 0; i < count; i++, msc++)
 175 *           printf("Entry %i, x=%i y=%i\n", i, msc->x, msc->y);
 176 */
 177#define ll_entry_count(_type, _list)                                    \
 178        ({                                                              \
 179                _type *start = ll_entry_start(_type, _list);            \
 180                _type *end = ll_entry_end(_type, _list);                \
 181                unsigned int _ll_result = end - start;                  \
 182                _ll_result;                                             \
 183        })
 184
 185/**
 186 * ll_entry_get() - Retrieve entry from linker-generated array by name
 187 * @_type:      Data type of the entry
 188 * @_name:      Name of the entry
 189 * @_list:      Name of the list in which this entry is placed
 190 *
 191 * This function returns a pointer to a particular entry in linker-generated
 192 * array identified by the subsection of u_boot_list where the entry resides
 193 * and it's name.
 194 *
 195 * Example:
 196 *
 197 * ::
 198 *
 199 *   ll_entry_declare(struct my_sub_cmd, my_sub_cmd, cmd_sub) = {
 200 *           .x = 3,
 201 *           .y = 4,
 202 *   };
 203 *   ...
 204 *   struct my_sub_cmd *c = ll_entry_get(struct my_sub_cmd, my_sub_cmd, cmd_sub);
 205 */
 206#define ll_entry_get(_type, _name, _list)                               \
 207        ({                                                              \
 208                extern _type _u_boot_list_2_##_list##_2_##_name;        \
 209                _type *_ll_result =                                     \
 210                        &_u_boot_list_2_##_list##_2_##_name;            \
 211                _ll_result;                                             \
 212        })
 213
 214/**
 215 * ll_entry_ref() - Get a reference to a linker-generated array entry
 216 *
 217 * Once an extern ll_entry_declare() has been used to declare the reference,
 218 * this macro allows the entry to be accessed.
 219 *
 220 * This is like ll_entry_get(), but without the extra code, so it is suitable
 221 * for putting into data structures.
 222 *
 223 * @_type: C type of the list entry, e.g. 'struct foo'
 224 * @_name: name of the entry
 225 * @_list: name of the list
 226 */
 227#define ll_entry_ref(_type, _name, _list)                               \
 228        ((_type *)&_u_boot_list_2_##_list##_2_##_name)
 229
 230/**
 231 * ll_start() - Point to first entry of first linker-generated array
 232 * @_type:      Data type of the entry
 233 *
 234 * This function returns ``(_type *)`` pointer to the very first entry of
 235 * the very first linker-generated array.
 236 *
 237 * Since this macro defines the start of the linker-generated arrays,
 238 * its leftmost index must be 1.
 239 *
 240 * Example:
 241 *
 242 * ::
 243 *
 244 *   struct my_sub_cmd *msc = ll_start(struct my_sub_cmd);
 245 */
 246#define ll_start(_type)                                                 \
 247({                                                                      \
 248        static char start[0] __aligned(4) __attribute__((unused))       \
 249                __section(".u_boot_list_1");                            \
 250        (_type *)&start;                                                \
 251})
 252
 253/**
 254 * ll_end() - Point after last entry of last linker-generated array
 255 * @_type:      Data type of the entry
 256 *
 257 * This function returns ``(_type *)`` pointer after the very last entry of
 258 * the very last linker-generated array.
 259 *
 260 * Since this macro defines the end of the linker-generated arrays,
 261 * its leftmost index must be 3.
 262 *
 263 * Example:
 264 *
 265 * ::
 266 *
 267 *   struct my_sub_cmd *msc = ll_end(struct my_sub_cmd);
 268 */
 269#define ll_end(_type)                                                   \
 270({                                                                      \
 271        static char end[0] __aligned(4) __attribute__((unused))         \
 272                __section(".u_boot_list_3");                            \
 273        (_type *)&end;                                                  \
 274})
 275
 276#endif /* __ASSEMBLY__ */
 277
 278#endif  /* __LINKER_LISTS_H__ */
 279