linker_lists.h 8.3 KB

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