1#ifndef _GPXE_TABLES_H
2#define _GPXE_TABLES_H
3
4FILE_LICENCE ( GPL2_OR_LATER );
5
6/** @page ifdef_harmful #ifdef considered harmful
7 *
8 * Overuse of @c #ifdef has long been a problem in Etherboot.
9 * Etherboot provides a rich array of features, but all these features
10 * take up valuable space in a ROM image.  The traditional solution to
11 * this problem has been for each feature to have its own @c #ifdef
12 * option, allowing the feature to be compiled in only if desired.
13 *
14 * The problem with this is that it becomes impossible to compile, let
15 * alone test, all possible versions of Etherboot.  Code that is not
16 * typically used tends to suffer from bit-rot over time.  It becomes
17 * extremely difficult to predict which combinations of compile-time
18 * options will result in code that can even compile and link
19 * correctly.
20 *
21 * To solve this problem, we have adopted a new approach from
22 * Etherboot 5.5 onwards.  @c #ifdef is now "considered harmful", and
23 * its use should be minimised.  Separate features should be
24 * implemented in separate @c .c files, and should \b always be
25 * compiled (i.e. they should \b not be guarded with a @c #ifdef @c
26 * MY_PET_FEATURE statement).  By making (almost) all code always
27 * compile, we avoid the problem of bit-rot in rarely-used code.
28 *
29 * The file config.h, in combination with the @c make command line,
30 * specifies the objects that will be included in any particular build
31 * of Etherboot.  For example, suppose that config.h includes the line
32 *
33 * @code
34 *
35 *   #define CONSOLE_SERIAL
36 *   #define DOWNLOAD_PROTO_TFTP
37 *
38 * @endcode
39 *
40 * When a particular Etherboot image (e.g. @c bin/rtl8139.zdsk) is
41 * built, the options specified in config.h are used to drag in the
42 * relevant objects at link-time.  For the above example, serial.o and
43 * tftp.o would be linked in.
44 *
45 * There remains one problem to solve: how do these objects get used?
46 * Traditionally, we had code such as
47 *
48 * @code
49 *
50 *    #ifdef CONSOLE_SERIAL
51 *      serial_init();
52 *    #endif
53 *
54 * @endcode
55 *
56 * in main.c, but this reintroduces @c #ifdef and so is a Bad Idea.
57 * We cannot simply remove the @c #ifdef and make it
58 *
59 * @code
60 *
61 *   serial_init();
62 *
63 * @endcode
64 *
65 * because then serial.o would end up always being linked in.
66 *
67 * The solution is to use @link tables.h linker tables @endlink.
68 *
69 */
70
71/** @file
72 *
73 * Linker tables
74 *
75 * Read @ref ifdef_harmful first for some background on the motivation
76 * for using linker tables.
77 *
78 * This file provides macros for dealing with linker-generated tables
79 * of fixed-size symbols.  We make fairly extensive use of these in
80 * order to avoid @c #ifdef spaghetti and/or linker symbol pollution.
81 * For example, instead of having code such as
82 *
83 * @code
84 *
85 *    #ifdef CONSOLE_SERIAL
86 *      serial_init();
87 *    #endif
88 *
89 * @endcode
90 *
91 * we make serial.c generate an entry in the initialisation function
92 * table, and then have a function call_init_fns() that simply calls
93 * all functions present in this table.  If and only if serial.o gets
94 * linked in, then its initialisation function will be called.  We
95 * avoid linker symbol pollution (i.e. always dragging in serial.o
96 * just because of a call to serial_init()) and we also avoid @c
97 * #ifdef spaghetti (having to conditionalise every reference to
98 * functions in serial.c).
99 *
100 * The linker script takes care of assembling the tables for us.  All
101 * our table sections have names of the format @c .tbl.NAME.NN where
102 * @c NAME designates the data structure stored in the table (e.g. @c
103 * init_fns) and @c NN is a two-digit decimal number used to impose an
104 * ordering upon the tables if required.  @c NN=00 is reserved for the
105 * symbol indicating "table start", and @c NN=99 is reserved for the
106 * symbol indicating "table end".
107 *
108 * As an example, suppose that we want to create a "frobnicator"
109 * feature framework, and allow for several independent modules to
110 * provide frobnicating services.  Then we would create a frob.h
111 * header file containing e.g.
112 *
113 * @code
114 *
115 *   struct frobnicator {
116 *      const char *name;		// Name of the frobnicator
117 *	void ( *frob ) ( void ); 	// The frobnicating function itself
118 *   };
119 *
120 *   #define FROBNICATORS __table ( struct frobnicator, "frobnicators" )
121 *
122 *   #define __frobnicator __table_entry ( FROBNICATORS, 01 )
123 *
124 * @endcode
125 *
126 * Any module providing frobnicating services would look something
127 * like
128 *
129 * @code
130 *
131 *   #include "frob.h"
132 *
133 *   static void my_frob ( void ) {
134 *	// Do my frobnicating
135 *	...
136 *   }
137 *
138 *   struct frob my_frobnicator __frobnicator = {
139 *	.name = "my_frob",
140 *	.frob = my_frob,
141 *   };
142 *
143 * @endcode
144 *
145 * The central frobnicator code (frob.c) would use the frobnicating
146 * modules as follows
147 *
148 * @code
149 *
150 *   #include "frob.h"
151 *
152 *   // Call all linked-in frobnicators
153 *   void frob_all ( void ) {
154 *	struct frob *frob;
155 *
156 *	for_each_table ( frob, FROBNICATORS ) {
157 *         printf ( "Calling frobnicator \"%s\"\n", frob->name );
158 *	   frob->frob ();
159 *	}
160 *   }
161 *
162 * @endcode
163 *
164 * See init.h and init.c for a real-life example.
165 *
166 */
167
168#ifdef DOXYGEN
169#define __attribute__( x )
170#endif
171
172/**
173 * Declare a linker table
174 *
175 * @v type		Data type
176 * @v name		Table name
177 * @ret table		Linker table
178 */
179#define __table( type, name ) ( type, name )
180
181/**
182 * Get linker table data type
183 *
184 * @v table		Linker table
185 * @ret type		Data type
186 */
187#define __table_type( table ) __table_extract_type table
188#define __table_extract_type( type, name ) type
189
190/**
191 * Get linker table name
192 *
193 * @v table		Linker table
194 * @ret name		Table name
195 */
196#define __table_name( table ) __table_extract_name table
197#define __table_extract_name( type, name ) name
198
199/**
200 * Get linker table section name
201 *
202 * @v table		Linker table
203 * @v idx		Sub-table index
204 * @ret section		Section name
205 */
206#define __table_section( table, idx ) \
207	".tbl." __table_name ( table ) "." __table_str ( idx )
208#define __table_str( x ) #x
209
210/**
211 * Get linker table alignment
212 *
213 * @v table		Linker table
214 * @ret align		Alignment
215 */
216#define __table_alignment( table ) __alignof__ ( __table_type ( table ) )
217
218/**
219 * Declare a linker table entry
220 *
221 * @v table		Linker table
222 * @v idx		Sub-table index
223 *
224 * Example usage:
225 *
226 * @code
227 *
228 *   #define FROBNICATORS __table ( struct frobnicator, "frobnicators" )
229 *
230 *   #define __frobnicator __table_entry ( FROBNICATORS, 01 )
231 *
232 *   struct frobnicator my_frob __frobnicator = {
233 *      ...
234 *   };
235 *
236 * @endcode
237 */
238#define __table_entry( table, idx )					\
239	__attribute__ (( __section__ ( __table_section ( table, idx ) ),\
240			 __aligned__ ( __table_alignment ( table ) ) ))
241
242/**
243 * Get start of linker table entries
244 *
245 * @v table		Linker table
246 * @v idx		Sub-table index
247 * @ret entries		Start of entries
248 */
249#define __table_entries( table, idx ) ( {				\
250	static __table_type ( table ) __table_entries[0]		\
251		__table_entry ( table, idx ); 				\
252	__table_entries; } )
253
254/**
255 * Get start of linker table
256 *
257 * @v table		Linker table
258 * @ret start		Start of linker table
259 *
260 * Example usage:
261 *
262 * @code
263 *
264 *   #define FROBNICATORS __table ( struct frobnicator, "frobnicators" )
265 *
266 *   struct frobnicator *frobs = table_start ( FROBNICATORS );
267 *
268 * @endcode
269 */
270#define table_start( table ) __table_entries ( table, 00 )
271
272/**
273 * Get end of linker table
274 *
275 * @v table		Linker table
276 * @ret end		End of linker table
277 *
278 * Example usage:
279 *
280 * @code
281 *
282 *   #define FROBNICATORS __table ( struct frobnicator, "frobnicators" )
283 *
284 *   struct frobnicator *frobs_end = table_end ( FROBNICATORS );
285 *
286 * @endcode
287 */
288#define table_end( table ) __table_entries ( table, 99 )
289
290/**
291 * Get number of entries in linker table
292 *
293 * @v table		Linker table
294 * @ret num_entries	Number of entries in linker table
295 *
296 * Example usage:
297 *
298 * @code
299 *
300 *   #define FROBNICATORS __table ( struct frobnicator, "frobnicators" )
301 *
302 *   unsigned int num_frobs = table_num_entries ( FROBNICATORS );
303 *
304 * @endcode
305 *
306 */
307#define table_num_entries( table )					\
308	( ( unsigned int ) ( table_end ( table ) -			\
309			     table_start ( table ) ) )
310
311/**
312 * Iterate through all entries within a linker table
313 *
314 * @v pointer		Entry pointer
315 * @v table		Linker table
316 *
317 * Example usage:
318 *
319 * @code
320 *
321 *   #define FROBNICATORS __table ( struct frobnicator, "frobnicators" )
322 *
323 *   struct frobnicator *frob;
324 *
325 *   for_each_table_entry ( frob, FROBNICATORS ) {
326 *     ...
327 *   }
328 *
329 * @endcode
330 *
331 */
332#define for_each_table_entry( pointer, table )				\
333	for ( pointer = table_start ( table ) ;				\
334	      pointer < table_end ( table ) ;				\
335	      pointer++ )
336
337/**
338 * Iterate through all entries within a linker table in reverse order
339 *
340 * @v pointer		Entry pointer
341 * @v table		Linker table
342 *
343 * Example usage:
344 *
345 * @code
346 *
347 *   #define FROBNICATORS __table ( struct frobnicator, "frobnicators" )
348 *
349 *   struct frobnicator *frob;
350 *
351 *   for_each_table_entry_reverse ( frob, FROBNICATORS ) {
352 *     ...
353 *   }
354 *
355 * @endcode
356 *
357 */
358#define for_each_table_entry_reverse( pointer, table )			\
359	for ( pointer = ( table_end ( table ) - 1 ) ;			\
360	      pointer >= table_start ( table ) ;			\
361	      pointer-- )
362
363/******************************************************************************
364 *
365 * Intel's C compiler chokes on several of the constructs used in this
366 * file.  The workarounds are ugly, so we use them only for an icc
367 * build.
368 *
369 */
370#define ICC_ALIGN_HACK_FACTOR 128
371#ifdef __ICC
372
373/*
374 * icc miscompiles zero-length arrays by inserting padding to a length
375 * of two array elements.  We therefore have to generate the
376 * __table_entries() symbols by hand in asm.
377 *
378 */
379#undef __table_entries
380#define __table_entries( table, idx ) ( {				\
381	extern __table_type ( table )					\
382		__table_temp_sym ( idx, __LINE__ ) []			\
383		__table_entry ( table, idx ) 				\
384		asm ( __table_entries_sym ( table, idx ) );		\
385	__asm__ ( ".ifndef %c0\n\t"					\
386		  ".section " __table_section ( table, idx ) "\n\t"	\
387		  ".align %c1\n\t"					\
388	          "\n%c0:\n\t"						\
389		  ".previous\n\t" 					\
390		  ".endif\n\t"						\
391		  : : "i" ( __table_temp_sym ( idx, __LINE__ ) ),	\
392		      "i" ( __table_alignment ( table ) ) );		\
393	__table_temp_sym ( idx, __LINE__ ); } )
394#define __table_entries_sym( table, idx )				\
395	"__tbl_" __table_name ( table ) "_" #idx
396#define __table_temp_sym( a, b )					\
397	___table_temp_sym( __table_, a, _, b )
398#define ___table_temp_sym( a, b, c, d ) a ## b ## c ## d
399
400/*
401 * icc ignores __attribute__ (( aligned (x) )) when it is used to
402 * decrease the compiler's default choice of alignment (which may be
403 * higher than the alignment actually required by the structure).  We
404 * work around this by forcing the alignment to a large multiple of
405 * the required value (so that we are never attempting to decrease the
406 * default alignment) and then postprocessing the object file to
407 * reduce the alignment back down to the "real" value.
408 *
409 */
410#undef __table_alignment
411#define __table_alignment( table ) \
412	( ICC_ALIGN_HACK_FACTOR * __alignof__ ( __table_type ( table ) ) )
413
414/*
415 * Because of the alignment hack, we must ensure that the compiler
416 * never tries to place multiple objects within the same section,
417 * otherwise the assembler will insert padding to the (incorrect)
418 * alignment boundary.  Do this by appending the line number to table
419 * section names.
420 *
421 * Note that we don't need to worry about padding between array
422 * elements, since the alignment is declared on the variable (i.e. the
423 * whole array) rather than on the type (i.e. on all individual array
424 * elements).
425 */
426#undef __table_section
427#define __table_section( table, idx ) \
428	".tbl." __table_name ( table ) "." __table_str ( idx ) \
429	"." __table_xstr ( __LINE__ )
430#define __table_xstr( x ) __table_str ( x )
431
432#endif /* __ICC */
433
434#endif /* _GPXE_TABLES_H */
435