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(4) __attribute__((unused,        \
 128                section(".u_boot_list_2_"#_list"_1")));                 \
 129        (_type *)&start;                                                \
 130})
 131
 132/**
 133 * ll_entry_end() - Point after last entry of linker-generated array
 134 * @_type:      Data type of the entry
 135 * @_list:      Name of the list in which this entry is placed
 136 *              (with underscores instead of dots)
 137 *
 138 * This function returns ``(_type *)`` pointer after the very last entry of
 139 * a linker-generated array placed into subsection of .u_boot_list
 140 * section specified by _list argument.
 141 *
 142 * Since this macro defines an array end symbol, its leftmost index
 143 * must be 2 and its rightmost index must be 3.
 144 *
 145 * Example:
 146 *
 147 * ::
 148 *
 149 *   struct my_sub_cmd *msc = ll_entry_end(struct my_sub_cmd, cmd_sub);
 150 */
 151#define ll_entry_end(_type, _list)                                      \
 152({                                                                      \
 153        static char end[0] __aligned(4) __attribute__((unused,          \
 154                section(".u_boot_list_2_"#_list"_3")));                 \
 155        (_type *)&end;                                                  \
 156})
 157/**
 158 * ll_entry_count() - Return the number of elements in linker-generated array
 159 * @_type:      Data type of the entry
 160 * @_list:      Name of the list of which the number of elements is computed
 161 *
 162 * This function returns the number of elements of a linker-generated array
 163 * placed into subsection of .u_boot_list section specified by _list
 164 * argument. The result is of an unsigned int type.
 165 *
 166 * Example:
 167 *
 168 * ::
 169 *
 170 *   int i;
 171 *   const unsigned int count = ll_entry_count(struct my_sub_cmd, cmd_sub);
 172 *   struct my_sub_cmd *msc = ll_entry_start(struct my_sub_cmd, cmd_sub);
 173 *   for (i = 0; i < count; i++, msc++)
 174 *           printf("Entry %i, x=%i y=%i\n", i, msc->x, msc->y);
 175 */
 176#define ll_entry_count(_type, _list)                                    \
 177        ({                                                              \
 178                _type *start = ll_entry_start(_type, _list);            \
 179                _type *end = ll_entry_end(_type, _list);                \
 180                unsigned int _ll_result = end - start;                  \
 181                _ll_result;                                             \
 182        })
 183
 184/**
 185 * ll_entry_get() - Retrieve entry from linker-generated array by name
 186 * @_type:      Data type of the entry
 187 * @_name:      Name of the entry
 188 * @_list:      Name of the list in which this entry is placed
 189 *
 190 * This function returns a pointer to a particular entry in linker-generated
 191 * array identified by the subsection of u_boot_list where the entry resides
 192 * and it's name.
 193 *
 194 * Example:
 195 *
 196 * ::
 197 *
 198 *   ll_entry_declare(struct my_sub_cmd, my_sub_cmd, cmd_sub) = {
 199 *           .x = 3,
 200 *           .y = 4,
 201 *   };
 202 *   ...
 203 *   struct my_sub_cmd *c = ll_entry_get(struct my_sub_cmd, my_sub_cmd, cmd_sub);
 204 */
 205#define ll_entry_get(_type, _name, _list)                               \
 206        ({                                                              \
 207                extern _type _u_boot_list_2_##_list##_2_##_name;        \
 208                _type *_ll_result =                                     \
 209                        &_u_boot_list_2_##_list##_2_##_name;            \
 210                _ll_result;                                             \
 211        })
 212
 213/**
 214 * ll_start() - Point to first entry of first linker-generated array
 215 * @_type:      Data type of the entry
 216 *
 217 * This function returns ``(_type *)`` pointer to the very first entry of
 218 * the very first linker-generated array.
 219 *
 220 * Since this macro defines the start of the linker-generated arrays,
 221 * its leftmost index must be 1.
 222 *
 223 * Example:
 224 *
 225 * ::
 226 *
 227 *   struct my_sub_cmd *msc = ll_start(struct my_sub_cmd);
 228 */
 229#define ll_start(_type)                                                 \
 230({                                                                      \
 231        static char start[0] __aligned(4) __attribute__((unused,        \
 232                section(".u_boot_list_1")));                            \
 233        (_type *)&start;                                                \
 234})
 235
 236/**
 237 * ll_end() - Point after last entry of last linker-generated array
 238 * @_type:      Data type of the entry
 239 *
 240 * This function returns ``(_type *)`` pointer after the very last entry of
 241 * the very last linker-generated array.
 242 *
 243 * Since this macro defines the end of the linker-generated arrays,
 244 * its leftmost index must be 3.
 245 *
 246 * Example:
 247 *
 248 * ::
 249 *
 250 *   struct my_sub_cmd *msc = ll_end(struct my_sub_cmd);
 251 */
 252#define ll_end(_type)                                                   \
 253({                                                                      \
 254        static char end[0] __aligned(4) __attribute__((unused,          \
 255                section(".u_boot_list_3")));                            \
 256        (_type *)&end;                                                  \
 257})
 258
 259#endif /* __ASSEMBLY__ */
 260
 261#endif  /* __LINKER_LISTS_H__ */
 262