summaryrefslogtreecommitdiff
path: root/gpxe/src/include/gpxe/tables.h
diff options
context:
space:
mode:
Diffstat (limited to 'gpxe/src/include/gpxe/tables.h')
-rw-r--r--gpxe/src/include/gpxe/tables.h434
1 files changed, 0 insertions, 434 deletions
diff --git a/gpxe/src/include/gpxe/tables.h b/gpxe/src/include/gpxe/tables.h
deleted file mode 100644
index 7dfced8c..00000000
--- a/gpxe/src/include/gpxe/tables.h
+++ /dev/null
@@ -1,434 +0,0 @@
-#ifndef _GPXE_TABLES_H
-#define _GPXE_TABLES_H
-
-FILE_LICENCE ( GPL2_OR_LATER );
-
-/** @page ifdef_harmful #ifdef considered harmful
- *
- * Overuse of @c #ifdef has long been a problem in Etherboot.
- * Etherboot provides a rich array of features, but all these features
- * take up valuable space in a ROM image. The traditional solution to
- * this problem has been for each feature to have its own @c #ifdef
- * option, allowing the feature to be compiled in only if desired.
- *
- * The problem with this is that it becomes impossible to compile, let
- * alone test, all possible versions of Etherboot. Code that is not
- * typically used tends to suffer from bit-rot over time. It becomes
- * extremely difficult to predict which combinations of compile-time
- * options will result in code that can even compile and link
- * correctly.
- *
- * To solve this problem, we have adopted a new approach from
- * Etherboot 5.5 onwards. @c #ifdef is now "considered harmful", and
- * its use should be minimised. Separate features should be
- * implemented in separate @c .c files, and should \b always be
- * compiled (i.e. they should \b not be guarded with a @c #ifdef @c
- * MY_PET_FEATURE statement). By making (almost) all code always
- * compile, we avoid the problem of bit-rot in rarely-used code.
- *
- * The file config.h, in combination with the @c make command line,
- * specifies the objects that will be included in any particular build
- * of Etherboot. For example, suppose that config.h includes the line
- *
- * @code
- *
- * #define CONSOLE_SERIAL
- * #define DOWNLOAD_PROTO_TFTP
- *
- * @endcode
- *
- * When a particular Etherboot image (e.g. @c bin/rtl8139.zdsk) is
- * built, the options specified in config.h are used to drag in the
- * relevant objects at link-time. For the above example, serial.o and
- * tftp.o would be linked in.
- *
- * There remains one problem to solve: how do these objects get used?
- * Traditionally, we had code such as
- *
- * @code
- *
- * #ifdef CONSOLE_SERIAL
- * serial_init();
- * #endif
- *
- * @endcode
- *
- * in main.c, but this reintroduces @c #ifdef and so is a Bad Idea.
- * We cannot simply remove the @c #ifdef and make it
- *
- * @code
- *
- * serial_init();
- *
- * @endcode
- *
- * because then serial.o would end up always being linked in.
- *
- * The solution is to use @link tables.h linker tables @endlink.
- *
- */
-
-/** @file
- *
- * Linker tables
- *
- * Read @ref ifdef_harmful first for some background on the motivation
- * for using linker tables.
- *
- * This file provides macros for dealing with linker-generated tables
- * of fixed-size symbols. We make fairly extensive use of these in
- * order to avoid @c #ifdef spaghetti and/or linker symbol pollution.
- * For example, instead of having code such as
- *
- * @code
- *
- * #ifdef CONSOLE_SERIAL
- * serial_init();
- * #endif
- *
- * @endcode
- *
- * we make serial.c generate an entry in the initialisation function
- * table, and then have a function call_init_fns() that simply calls
- * all functions present in this table. If and only if serial.o gets
- * linked in, then its initialisation function will be called. We
- * avoid linker symbol pollution (i.e. always dragging in serial.o
- * just because of a call to serial_init()) and we also avoid @c
- * #ifdef spaghetti (having to conditionalise every reference to
- * functions in serial.c).
- *
- * The linker script takes care of assembling the tables for us. All
- * our table sections have names of the format @c .tbl.NAME.NN where
- * @c NAME designates the data structure stored in the table (e.g. @c
- * init_fns) and @c NN is a two-digit decimal number used to impose an
- * ordering upon the tables if required. @c NN=00 is reserved for the
- * symbol indicating "table start", and @c NN=99 is reserved for the
- * symbol indicating "table end".
- *
- * As an example, suppose that we want to create a "frobnicator"
- * feature framework, and allow for several independent modules to
- * provide frobnicating services. Then we would create a frob.h
- * header file containing e.g.
- *
- * @code
- *
- * struct frobnicator {
- * const char *name; // Name of the frobnicator
- * void ( *frob ) ( void ); // The frobnicating function itself
- * };
- *
- * #define FROBNICATORS __table ( struct frobnicator, "frobnicators" )
- *
- * #define __frobnicator __table_entry ( FROBNICATORS, 01 )
- *
- * @endcode
- *
- * Any module providing frobnicating services would look something
- * like
- *
- * @code
- *
- * #include "frob.h"
- *
- * static void my_frob ( void ) {
- * // Do my frobnicating
- * ...
- * }
- *
- * struct frob my_frobnicator __frobnicator = {
- * .name = "my_frob",
- * .frob = my_frob,
- * };
- *
- * @endcode
- *
- * The central frobnicator code (frob.c) would use the frobnicating
- * modules as follows
- *
- * @code
- *
- * #include "frob.h"
- *
- * // Call all linked-in frobnicators
- * void frob_all ( void ) {
- * struct frob *frob;
- *
- * for_each_table ( frob, FROBNICATORS ) {
- * printf ( "Calling frobnicator \"%s\"\n", frob->name );
- * frob->frob ();
- * }
- * }
- *
- * @endcode
- *
- * See init.h and init.c for a real-life example.
- *
- */
-
-#ifdef DOXYGEN
-#define __attribute__( x )
-#endif
-
-/**
- * Declare a linker table
- *
- * @v type Data type
- * @v name Table name
- * @ret table Linker table
- */
-#define __table( type, name ) ( type, name )
-
-/**
- * Get linker table data type
- *
- * @v table Linker table
- * @ret type Data type
- */
-#define __table_type( table ) __table_extract_type table
-#define __table_extract_type( type, name ) type
-
-/**
- * Get linker table name
- *
- * @v table Linker table
- * @ret name Table name
- */
-#define __table_name( table ) __table_extract_name table
-#define __table_extract_name( type, name ) name
-
-/**
- * Get linker table section name
- *
- * @v table Linker table
- * @v idx Sub-table index
- * @ret section Section name
- */
-#define __table_section( table, idx ) \
- ".tbl." __table_name ( table ) "." __table_str ( idx )
-#define __table_str( x ) #x
-
-/**
- * Get linker table alignment
- *
- * @v table Linker table
- * @ret align Alignment
- */
-#define __table_alignment( table ) __alignof__ ( __table_type ( table ) )
-
-/**
- * Declare a linker table entry
- *
- * @v table Linker table
- * @v idx Sub-table index
- *
- * Example usage:
- *
- * @code
- *
- * #define FROBNICATORS __table ( struct frobnicator, "frobnicators" )
- *
- * #define __frobnicator __table_entry ( FROBNICATORS, 01 )
- *
- * struct frobnicator my_frob __frobnicator = {
- * ...
- * };
- *
- * @endcode
- */
-#define __table_entry( table, idx ) \
- __attribute__ (( __section__ ( __table_section ( table, idx ) ),\
- __aligned__ ( __table_alignment ( table ) ) ))
-
-/**
- * Get start of linker table entries
- *
- * @v table Linker table
- * @v idx Sub-table index
- * @ret entries Start of entries
- */
-#define __table_entries( table, idx ) ( { \
- static __table_type ( table ) __table_entries[0] \
- __table_entry ( table, idx ); \
- __table_entries; } )
-
-/**
- * Get start of linker table
- *
- * @v table Linker table
- * @ret start Start of linker table
- *
- * Example usage:
- *
- * @code
- *
- * #define FROBNICATORS __table ( struct frobnicator, "frobnicators" )
- *
- * struct frobnicator *frobs = table_start ( FROBNICATORS );
- *
- * @endcode
- */
-#define table_start( table ) __table_entries ( table, 00 )
-
-/**
- * Get end of linker table
- *
- * @v table Linker table
- * @ret end End of linker table
- *
- * Example usage:
- *
- * @code
- *
- * #define FROBNICATORS __table ( struct frobnicator, "frobnicators" )
- *
- * struct frobnicator *frobs_end = table_end ( FROBNICATORS );
- *
- * @endcode
- */
-#define table_end( table ) __table_entries ( table, 99 )
-
-/**
- * Get number of entries in linker table
- *
- * @v table Linker table
- * @ret num_entries Number of entries in linker table
- *
- * Example usage:
- *
- * @code
- *
- * #define FROBNICATORS __table ( struct frobnicator, "frobnicators" )
- *
- * unsigned int num_frobs = table_num_entries ( FROBNICATORS );
- *
- * @endcode
- *
- */
-#define table_num_entries( table ) \
- ( ( unsigned int ) ( table_end ( table ) - \
- table_start ( table ) ) )
-
-/**
- * Iterate through all entries within a linker table
- *
- * @v pointer Entry pointer
- * @v table Linker table
- *
- * Example usage:
- *
- * @code
- *
- * #define FROBNICATORS __table ( struct frobnicator, "frobnicators" )
- *
- * struct frobnicator *frob;
- *
- * for_each_table_entry ( frob, FROBNICATORS ) {
- * ...
- * }
- *
- * @endcode
- *
- */
-#define for_each_table_entry( pointer, table ) \
- for ( pointer = table_start ( table ) ; \
- pointer < table_end ( table ) ; \
- pointer++ )
-
-/**
- * Iterate through all entries within a linker table in reverse order
- *
- * @v pointer Entry pointer
- * @v table Linker table
- *
- * Example usage:
- *
- * @code
- *
- * #define FROBNICATORS __table ( struct frobnicator, "frobnicators" )
- *
- * struct frobnicator *frob;
- *
- * for_each_table_entry_reverse ( frob, FROBNICATORS ) {
- * ...
- * }
- *
- * @endcode
- *
- */
-#define for_each_table_entry_reverse( pointer, table ) \
- for ( pointer = ( table_end ( table ) - 1 ) ; \
- pointer >= table_start ( table ) ; \
- pointer-- )
-
-/******************************************************************************
- *
- * Intel's C compiler chokes on several of the constructs used in this
- * file. The workarounds are ugly, so we use them only for an icc
- * build.
- *
- */
-#define ICC_ALIGN_HACK_FACTOR 128
-#ifdef __ICC
-
-/*
- * icc miscompiles zero-length arrays by inserting padding to a length
- * of two array elements. We therefore have to generate the
- * __table_entries() symbols by hand in asm.
- *
- */
-#undef __table_entries
-#define __table_entries( table, idx ) ( { \
- extern __table_type ( table ) \
- __table_temp_sym ( idx, __LINE__ ) [] \
- __table_entry ( table, idx ) \
- asm ( __table_entries_sym ( table, idx ) ); \
- __asm__ ( ".ifndef %c0\n\t" \
- ".section " __table_section ( table, idx ) "\n\t" \
- ".align %c1\n\t" \
- "\n%c0:\n\t" \
- ".previous\n\t" \
- ".endif\n\t" \
- : : "i" ( __table_temp_sym ( idx, __LINE__ ) ), \
- "i" ( __table_alignment ( table ) ) ); \
- __table_temp_sym ( idx, __LINE__ ); } )
-#define __table_entries_sym( table, idx ) \
- "__tbl_" __table_name ( table ) "_" #idx
-#define __table_temp_sym( a, b ) \
- ___table_temp_sym( __table_, a, _, b )
-#define ___table_temp_sym( a, b, c, d ) a ## b ## c ## d
-
-/*
- * icc ignores __attribute__ (( aligned (x) )) when it is used to
- * decrease the compiler's default choice of alignment (which may be
- * higher than the alignment actually required by the structure). We
- * work around this by forcing the alignment to a large multiple of
- * the required value (so that we are never attempting to decrease the
- * default alignment) and then postprocessing the object file to
- * reduce the alignment back down to the "real" value.
- *
- */
-#undef __table_alignment
-#define __table_alignment( table ) \
- ( ICC_ALIGN_HACK_FACTOR * __alignof__ ( __table_type ( table ) ) )
-
-/*
- * Because of the alignment hack, we must ensure that the compiler
- * never tries to place multiple objects within the same section,
- * otherwise the assembler will insert padding to the (incorrect)
- * alignment boundary. Do this by appending the line number to table
- * section names.
- *
- * Note that we don't need to worry about padding between array
- * elements, since the alignment is declared on the variable (i.e. the
- * whole array) rather than on the type (i.e. on all individual array
- * elements).
- */
-#undef __table_section
-#define __table_section( table, idx ) \
- ".tbl." __table_name ( table ) "." __table_str ( idx ) \
- "." __table_xstr ( __LINE__ )
-#define __table_xstr( x ) __table_str ( x )
-
-#endif /* __ICC */
-
-#endif /* _GPXE_TABLES_H */