1 #ifndef _GPXE_TABLES_H 2 #define _GPXE_TABLES_H 3 4 FILE_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