Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / src / include / ipxe / tables.h
diff --git a/qemu/roms/ipxe/src/include/ipxe/tables.h b/qemu/roms/ipxe/src/include/ipxe/tables.h
new file mode 100644 (file)
index 0000000..e35ce82
--- /dev/null
@@ -0,0 +1,518 @@
+#ifndef _IPXE_TABLES_H
+#define _IPXE_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 )                            \
+               __attribute__ (( unused ));                             \
+       __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 ) ) )
+
+/**
+ * Get index of entry within linker table
+ *
+ * @v table            Linker table
+ * @v entry            Table entry
+ *
+ * Example usage:
+ *
+ * @code
+ *
+ *   #define FROBNICATORS __table ( struct frobnicator, "frobnicators" )
+ *
+ *   #define __frobnicator __table_entry ( FROBNICATORS, 01 )
+ *
+ *   struct frobnicator my_frob __frobnicator = {
+ *      ...
+ *   };
+ *
+ *   unsigned int my_frob_idx = table_index ( FROBNICATORS, &my_frob );
+ *
+ * @endcode
+ */
+#define table_index( table, entry )                                    \
+       ( ( unsigned int ) ( (entry) - 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 remaining entries within a linker table
+ *
+ * @v pointer          Entry pointer, preset to most recent entry
+ * @v table            Linker table
+ *
+ * Example usage:
+ *
+ * @code
+ *
+ *   #define FROBNICATORS __table ( struct frobnicator, "frobnicators" )
+ *   #define __frobnicator __table_entry ( FROBNICATORS, 01 )
+ *
+ *   struct frob my_frobnicator __frobnicator;
+ *   struct frobnicator *frob;
+ *
+ *   frob = &my_frobnicator;
+ *   for_each_table_entry_continue ( frob, FROBNICATORS ) {
+ *     ...
+ *   }
+ *
+ * @endcode
+ *
+ */
+#define for_each_table_entry_continue( pointer, table )                        \
+       for ( pointer++ ;                                               \
+             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-- )
+
+/**
+ * Iterate through all remaining entries within a linker table in reverse order
+ *
+ * @v pointer          Entry pointer, preset to most recent entry
+ * @v table            Linker table
+ *
+ * Example usage:
+ *
+ * @code
+ *
+ *   #define FROBNICATORS __table ( struct frobnicator, "frobnicators" )
+ *   #define __frobnicator __table_entry ( FROBNICATORS, 01 )
+ *
+ *   struct frob my_frobnicator __frobnicator;
+ *   struct frobnicator *frob;
+ *
+ *   frob = &my_frobnicator;
+ *   for_each_table_entry_continue_reverse ( frob, FROBNICATORS ) {
+ *     ...
+ *   }
+ *
+ * @endcode
+ *
+ */
+#define for_each_table_entry_continue_reverse( pointer, table )                \
+       for ( pointer-- ;                                               \
+             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 /* _IPXE_TABLES_H */