]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | /* SPDX-License-Identifier: GPL-2.0+ */ |
42ebaae3 MV |
2 | /* |
3 | * include/linker_lists.h | |
4 | * | |
5 | * Implementation of linker-generated arrays | |
6 | * | |
7 | * Copyright (C) 2012 Marek Vasut <[email protected]> | |
42ebaae3 | 8 | */ |
ef123c52 | 9 | |
babb4440 MY |
10 | #ifndef __LINKER_LISTS_H__ |
11 | #define __LINKER_LISTS_H__ | |
12 | ||
dc7cb46f MY |
13 | #include <linux/compiler.h> |
14 | ||
ef123c52 | 15 | /* |
d72fd7b3 | 16 | * There is no use in including this from ASM files. |
ef123c52 AA |
17 | * So just don't define anything when included from ASM. |
18 | */ | |
19 | ||
20 | #if !defined(__ASSEMBLY__) | |
21 | ||
72538f4c | 22 | /** |
7e378b8b | 23 | * llsym() - Access a linker-generated array entry |
72538f4c SG |
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 | ||
42ebaae3 MV |
32 | /** |
33 | * ll_entry_declare() - Declare linker-generated array entry | |
34 | * @_type: Data type of the entry | |
35 | * @_name: Name of the entry | |
ef123c52 AA |
36 | * @_list: name of the list. Should contain only characters allowed |
37 | * in a C variable name! | |
42ebaae3 MV |
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 | * | |
ef123c52 | 44 | * A variable declared using this macro must be compile-time initialized. |
42ebaae3 MV |
45 | * |
46 | * Special precaution must be made when using this macro: | |
42ebaae3 | 47 | * |
ef123c52 AA |
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. | |
42ebaae3 | 51 | * |
ef123c52 AA |
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. | |
42ebaae3 | 55 | * |
78a88f79 | 56 | * 3) In case an outer section is declared that contains some array elements |
ef123c52 | 57 | * AND an inner subsection of this section is declared and contains some |
42ebaae3 MV |
58 | * elements, then when traversing the outer section, even the elements of |
59 | * the inner sections are present in the array. | |
60 | * | |
61 | * Example: | |
78a88f79 MS |
62 | * |
63 | * :: | |
64 | * | |
65 | * ll_entry_declare(struct my_sub_cmd, my_sub_cmd, cmd_sub) = { | |
66 | * .x = 3, | |
67 | * .y = 4, | |
68 | * }; | |
42ebaae3 | 69 | */ |
ef123c52 AA |
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 | ||
3fcc3af4 SG |
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 | * | |
78a88f79 MS |
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 | * }; | |
3fcc3af4 SG |
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 | ||
78a88f79 | 98 | /* |
ef123c52 AA |
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 | */ | |
42ebaae3 MV |
106 | |
107 | /** | |
108 | * ll_entry_start() - Point to first entry of linker-generated array | |
109 | * @_type: Data type of the entry | |
ef123c52 | 110 | * @_list: Name of the list in which this entry is placed |
42ebaae3 | 111 | * |
78a88f79 | 112 | * This function returns ``(_type *)`` pointer to the very first entry of a |
42ebaae3 | 113 | * linker-generated array placed into subsection of .u_boot_list section |
ef123c52 AA |
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. | |
42ebaae3 MV |
118 | * |
119 | * Example: | |
78a88f79 MS |
120 | * |
121 | * :: | |
122 | * | |
123 | * struct my_sub_cmd *msc = ll_entry_start(struct my_sub_cmd, cmd_sub); | |
42ebaae3 | 124 | */ |
ef123c52 AA |
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 | }) | |
42ebaae3 MV |
131 | |
132 | /** | |
ef123c52 | 133 | * ll_entry_end() - Point after last entry of linker-generated array |
42ebaae3 | 134 | * @_type: Data type of the entry |
ef123c52 | 135 | * @_list: Name of the list in which this entry is placed |
42ebaae3 MV |
136 | * (with underscores instead of dots) |
137 | * | |
78a88f79 | 138 | * This function returns ``(_type *)`` pointer after the very last entry of |
ef123c52 AA |
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: | |
78a88f79 MS |
146 | * |
147 | * :: | |
148 | * | |
149 | * struct my_sub_cmd *msc = ll_entry_end(struct my_sub_cmd, cmd_sub); | |
ef123c52 AA |
150 | */ |
151 | #define ll_entry_end(_type, _list) \ | |
152 | ({ \ | |
7e378b8b | 153 | static char end[0] __aligned(4) __attribute__((unused, \ |
ef123c52 AA |
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 | * | |
42ebaae3 | 162 | * This function returns the number of elements of a linker-generated array |
ef123c52 | 163 | * placed into subsection of .u_boot_list section specified by _list |
42ebaae3 MV |
164 | * argument. The result is of an unsigned int type. |
165 | * | |
166 | * Example: | |
78a88f79 MS |
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); | |
42ebaae3 | 175 | */ |
ef123c52 | 176 | #define ll_entry_count(_type, _list) \ |
42ebaae3 | 177 | ({ \ |
ef123c52 AA |
178 | _type *start = ll_entry_start(_type, _list); \ |
179 | _type *end = ll_entry_end(_type, _list); \ | |
180 | unsigned int _ll_result = end - start; \ | |
42ebaae3 MV |
181 | _ll_result; \ |
182 | }) | |
183 | ||
42ebaae3 MV |
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 | |
ef123c52 | 188 | * @_list: Name of the list in which this entry is placed |
42ebaae3 | 189 | * |
7e378b8b BM |
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 | |
42ebaae3 MV |
192 | * and it's name. |
193 | * | |
194 | * Example: | |
78a88f79 MS |
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); | |
42ebaae3 | 204 | */ |
ef123c52 | 205 | #define ll_entry_get(_type, _name, _list) \ |
42ebaae3 | 206 | ({ \ |
ef123c52 AA |
207 | extern _type _u_boot_list_2_##_list##_2_##_name; \ |
208 | _type *_ll_result = \ | |
7e378b8b | 209 | &_u_boot_list_2_##_list##_2_##_name; \ |
42ebaae3 MV |
210 | _ll_result; \ |
211 | }) | |
212 | ||
ef123c52 AA |
213 | /** |
214 | * ll_start() - Point to first entry of first linker-generated array | |
215 | * @_type: Data type of the entry | |
216 | * | |
78a88f79 | 217 | * This function returns ``(_type *)`` pointer to the very first entry of |
ef123c52 AA |
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: | |
78a88f79 MS |
224 | * |
225 | * :: | |
226 | * | |
227 | * struct my_sub_cmd *msc = ll_start(struct my_sub_cmd); | |
ef123c52 AA |
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 | /** | |
7e378b8b | 237 | * ll_end() - Point after last entry of last linker-generated array |
ef123c52 AA |
238 | * @_type: Data type of the entry |
239 | * | |
78a88f79 | 240 | * This function returns ``(_type *)`` pointer after the very last entry of |
ef123c52 AA |
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: | |
78a88f79 MS |
247 | * |
248 | * :: | |
249 | * | |
250 | * struct my_sub_cmd *msc = ll_end(struct my_sub_cmd); | |
ef123c52 AA |
251 | */ |
252 | #define ll_end(_type) \ | |
253 | ({ \ | |
7e378b8b | 254 | static char end[0] __aligned(4) __attribute__((unused, \ |
ef123c52 AA |
255 | section(".u_boot_list_3"))); \ |
256 | (_type *)&end; \ | |
257 | }) | |
258 | ||
259 | #endif /* __ASSEMBLY__ */ | |
260 | ||
42ebaae3 | 261 | #endif /* __LINKER_LISTS_H__ */ |