[U-Boot] [PATCH v2] Export redesign

Simon Glass sjg at chromium.org
Sun Nov 30 21:27:31 CET 2014


Hi Martin,

On 27 November 2014 at 01:42, Martin Dorwig <dorwig at tetronik.com> wrote:
> this is an atempt to make the export of functions typesafe.
> I replaced the jumptable void ** by a struct (jt_funcs) with function pointers.
> The EXPORT_FUNC macro now has 3 fixed parameters and one
> variadic parameter
> The first is the name of the exported function,
> the rest of the parameters are used to format a functionpointer

function pointer

> in the jumptable,
>
> the EXPORT_FUNC macros are expanded three times,
> 1. to declare the members of the struct
> 2. to initialize the structmember pointers
> 3. to call the functions in stubs.c
>
> Signed-off-by: Martin Dorwig <dorwig at tetronik.com>

Good to get rid of the XF macros.

I tested this on x86 and it still works fine.

Tested-by: Simon Glass <sjg at chromium.org>

I have a few minor things comments below too. Please make sure to
rebase to latest mainline before sending as I think there are a few
changes in common/console.c.

> ---
>
> Changes in v2:
> - redesign the way functions are exported to standalone applications
>
>  arch/blackfin/cpu/cpu.c           |  2 +-
>  board/BuS/eb_cpux9k2/cpux9k2.c    |  2 +-
>  common/cmd_load.c                 |  2 +-
>  common/console.c                  | 20 ++++-----
>  common/exports.c                  | 26 ++---------
>  doc/README.standalone             | 41 ++++++++++++-----
>  examples/standalone/stubs.c       | 64 ++++++++++++++-------------
>  include/_exports.h                | 93 +++++++++++++++++++++++++++------------
>  include/asm-generic/global_data.h |  2 +-
>  include/exports.h                 | 15 +++----
>  10 files changed, 151 insertions(+), 116 deletions(-)
>
> diff --git a/arch/blackfin/cpu/cpu.c b/arch/blackfin/cpu/cpu.c
> index b7f1188..59c470f 100644
> --- a/arch/blackfin/cpu/cpu.c
> +++ b/arch/blackfin/cpu/cpu.c
> @@ -121,7 +121,7 @@ static void display_global_data(void)
>         printf(" |-ram_size: %lx\n", gd->ram_size);
>         printf(" |-env_addr: %lx\n", gd->env_addr);
>         printf(" |-env_valid: %lx\n", gd->env_valid);
> -       printf(" |-jt(%p): %p\n", gd->jt, *(gd->jt));
> +       printf(" |-jt(%p): %p\n", gd->jt, gd->jt->get_version);
>         printf(" \\-bd: %p\n", gd->bd);
>         printf("   |-bi_boot_params: %lx\n", bd->bi_boot_params);
>         printf("   |-bi_memstart: %lx\n", bd->bi_memstart);
> diff --git a/board/BuS/eb_cpux9k2/cpux9k2.c b/board/BuS/eb_cpux9k2/cpux9k2.c
> index 5e4778e..76ad7c4 100644
> --- a/board/BuS/eb_cpux9k2/cpux9k2.c
> +++ b/board/BuS/eb_cpux9k2/cpux9k2.c
> @@ -98,7 +98,7 @@ int misc_init_r(void)
>                                 puts("Error: invalid MAC at EEPROM\n");
>                 }
>         }
> -       gd->jt[XF_do_reset] = (void *) do_reset;
> +       gd->jt->do_reset = do_reset;
>
>  #ifdef CONFIG_STATUS_LED
>         status_led_set(STATUS_LED_BOOT, STATUS_LED_BLINKING);
> diff --git a/common/cmd_load.c b/common/cmd_load.c
> index f6e522c..d043e6d 100644
> --- a/common/cmd_load.c
> +++ b/common/cmd_load.c
> @@ -222,7 +222,7 @@ static int read_record(char *buf, ulong len)
>                 }
>
>             /* Check for the console hangup (if any different from serial) */
> -           if (gd->jt[XF_getc] != getc) {
> +           if (gd->jt->getc != getc) {
>                 if (ctrlc()) {
>                     return (-1);
>                 }
> diff --git a/common/console.c b/common/console.c
> index 5a2f411..08cf188 100644
> --- a/common/console.c
> +++ b/common/console.c
> @@ -124,13 +124,13 @@ static int console_setfile(int file, struct stdio_dev * dev)
>                  */
>                 switch (file) {
>                 case stdin:
> -                       gd->jt[XF_getc] = dev->getc;
> -                       gd->jt[XF_tstc] = dev->tstc;
> +                       gd->jt->getc = getc;
> +                       gd->jt->tstc = tstc;
>                         break;
>                 case stdout:
> -                       gd->jt[XF_putc] = dev->putc;
> -                       gd->jt[XF_puts] = dev->puts;
> -                       gd->jt[XF_printf] = printf;
> +                       gd->jt->putc  = putc;
> +                       gd->jt->puts  = puts;
> +                       gd->jt->printf = printf;
>                         break;
>                 }
>                 break;
> @@ -722,11 +722,11 @@ int console_init_r(void)
>  #endif
>
>         /* set default handlers at first */
> -       gd->jt[XF_getc] = serial_getc;
> -       gd->jt[XF_tstc] = serial_tstc;
> -       gd->jt[XF_putc] = serial_putc;
> -       gd->jt[XF_puts] = serial_puts;
> -       gd->jt[XF_printf] = serial_printf;
> +       gd->jt->getc  = serial_getc;
> +       gd->jt->tstc  = serial_tstc;
> +       gd->jt->putc  = serial_putc;
> +       gd->jt->puts  = serial_puts;
> +       gd->jt->printf = serial_printf;
>
>         /* stdin stdout and stderr are in environment */
>         /* scan for it */
> diff --git a/common/exports.c b/common/exports.c
> index b97ca48..333107c 100644
> --- a/common/exports.c
> +++ b/common/exports.c
> @@ -1,6 +1,7 @@
>  #include <common.h>
>  #include <exports.h>
>  #include <spi.h>
> +#include <i2c.h>
>
>  DECLARE_GLOBAL_DATA_PTR;
>
> @@ -13,31 +14,10 @@ unsigned long get_version(void)
>         return XF_VERSION;
>  }
>
> -/* Reuse _exports.h with a little trickery to avoid bitrot */
> -#define EXPORT_FUNC(sym) gd->jt[XF_##sym] = (void *)sym;
> -
> -#if !defined(CONFIG_X86) && !defined(CONFIG_PPC)
> -# define install_hdlr      dummy
> -# define free_hdlr         dummy
> -#else /* kludge for non-standard function naming */
> -# define install_hdlr      irq_install_handler
> -# define free_hdlr         irq_free_handler
> -#endif
> -#ifndef CONFIG_CMD_I2C
> -# define i2c_write         dummy
> -# define i2c_read          dummy
> -#endif
> -#ifndef CONFIG_CMD_SPI

This is not the correct #ifdef now, and in fact there are separate
cases. Please see exports.c in mainline:

#if !defined(CONFIG_CMD_SPI) || defined(CONFIG_DM_SPI)
# define spi_init          dummy
# define spi_setup_slave   dummy
# define spi_free_slave    dummy
#endif
#ifndef CONFIG_CMD_SPI
# define spi_claim_bus     dummy
# define spi_release_bus   dummy
# define spi_xfer          dummy
#endif


> -# define spi_init          dummy
> -# define spi_setup_slave   dummy
> -# define spi_free_slave    dummy
> -# define spi_claim_bus     dummy
> -# define spi_release_bus   dummy
> -# define spi_xfer          dummy
> -#endif
> +#define EXPORT_FUNC(f, a, x, ...)  gd->jt->x = f;
>
>  void jumptable_init(void)
>  {
> -       gd->jt = malloc(XF_MAX * sizeof(void *));
> +       gd->jt = malloc(sizeof(struct jt_funcs));
>  #include <_exports.h>
>  }
> diff --git a/doc/README.standalone b/doc/README.standalone
> index 2be5f27..112b43d 100644
> --- a/doc/README.standalone
> +++ b/doc/README.standalone
> @@ -5,18 +5,18 @@ Design Notes on Exporting U-Boot Functions to Standalone Applications:
>     table is allocated and initialized in the jumptable_init() routine
>     (common/exports.c). Other routines may also modify the jump table,
>     however. The jump table can be accessed as the 'jt' field of the
> -   'global_data' structure. The slot numbers for the jump table are
> +   'global_data' structure. The struct members for the jump table are
>     defined in the <include/exports.h> header. E.g., to substitute the
>     malloc() and free() functions that will be available to standalone
>     applications, one should do the following:
>
>         DECLARE_GLOBAL_DATA_PTR;
>
> -       gd->jt[XF_malloc]       = my_malloc;
> -       gd->jt[XF_free]         = my_free;
> +       gd->jt->malloc  = my_malloc;
> +       gd->jt->free = my_free;
>
> -   Note that the pointers to the functions all have 'void *' type and
> -   thus the compiler cannot perform type checks on these assignments.
> +   Note that the pointers to the functions are real functionpointers

function prointer

> +   so the compiler can perform type checks on these assignments.
>
>  2. The pointer to the jump table is passed to the application in a
>     machine-dependent way. PowerPC, ARM, MIPS, Blackfin and Nios II
> @@ -65,27 +65,46 @@ Design Notes on Exporting U-Boot Functions to Standalone Applications:
>     => tftp 0x40000 hello_world.bin
>     => go 0x40004
>
> -5. To export some additional function foobar(), the following steps
> +5. To export some additional function long foobar(int i,char c), the following steps
>     should be undertaken:
>
>     - Append the following line at the end of the include/_exports.h
>       file:
>
> -       EXPORT_FUNC(foobar)
> +       EXPORT_FUNC(foobar, long, foobar, int, char)
> +
> +       Parameters to EXPORT_FUNC:
> +        - the first parameter is the function that is exported (default implementation)
> +        - the second parameter is the returnvalue type

return value

> +        - the third  parameter is the name of the member in struct jt_funcs
> +           this is also the name that the standalone application will used.
> +       the rest of the parameters are the function arguments
>
>     - Add the prototype for this function to the include/exports.h
>       file:
>
> -       void foobar(void);
> +       long foobar(int i, char c);
> +
> +       Initialization with the default implementation is done in jumptable_init()
> +
> +  You can override the default implementation using:
>
> -   - Add the initialization of the jump table slot wherever
> -     appropriate (most likely, to the jumptable_init() function):
> +       gd->jt->foobar = another_foobar;
>
> -       gd->jt[XF_foobar] = foobar;
> +       The signature of another_foobar must then match the declaration of foobar.
>
>     - Increase the XF_VERSION value by one in the include/exports.h
>       file
>
> +   If you want to export a function which depends on a CONFIG_XXX
> +   use 2 lines like this:
> +   #ifdef CONFIG_FOOBAR
> +       EXPORT_FUNC(foobar, long, foobar, int, char)
> +   #else
> +    EXPORT_FUNC(dummy, void, foobar, void)

You should indent this the same as the one two lines up.

> +   #endif
> +
> +
>  6. The code for exporting the U-Boot functions to applications is
>     mostly machine-independent. The only places written in assembly
>     language are stub functions that perform the jump through the jump
> diff --git a/examples/standalone/stubs.c b/examples/standalone/stubs.c
> index 0bf690e..920a0a9 100644
> --- a/examples/standalone/stubs.c
> +++ b/examples/standalone/stubs.c
> @@ -2,6 +2,8 @@
>  #include <exports.h>
>  #include <linux/compiler.h>
>
> +#define FO(x) offsetof(struct jt_funcs, x)
> +
>  #if defined(CONFIG_X86)
>  /*
>   * x86 does not have a dedicated register to store the pointer to
> @@ -10,23 +12,23 @@
>   * from flash memory. The global_data address is passed as argv[-1]
>   * to the application program.
>   */
> -static void **jt;
> +static struct jt_funcs *jt;
>  gd_t *global_data;
>
> -#define EXPORT_FUNC(x) \
> +#define EXPORT_FUNC(f, a, x, ...) \
>         asm volatile (                  \
>  "      .globl " #x "\n"                \
>  #x ":\n"                               \
>  "      movl    %0, %%eax\n"            \
>  "      movl    jt, %%ecx\n"            \
>  "      jmp     *(%%ecx, %%eax)\n"      \
> -       : : "i"(XF_ ## x * sizeof(void *)) : "eax", "ecx");
> +       : : "i"(FO(x)) : "eax", "ecx");
>  #elif defined(CONFIG_PPC)
>  /*
>   * r2 holds the pointer to the global_data, r11 is a call-clobbered
>   * register
>   */
> -#define EXPORT_FUNC(x) \
> +#define EXPORT_FUNC(f, a, x, ...) \
>         asm volatile (                  \
>  "      .globl " #x "\n"                \
>  #x ":\n"                               \
> @@ -34,33 +36,33 @@ gd_t *global_data;
>  "      lwz     %%r11, %1(%%r11)\n"     \
>  "      mtctr   %%r11\n"                \
>  "      bctr\n"                         \
> -       : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "r11");
> +       : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "r11");
>  #elif defined(CONFIG_ARM)
>  #ifdef CONFIG_ARM64
>  /*
>   * x18 holds the pointer to the global_data, x9 is a call-clobbered
>   * register
>   */
> -#define EXPORT_FUNC(x) \
> +#define EXPORT_FUNC(f, a, x, ...) \
>         asm volatile (                  \
>  "      .globl " #x "\n"                \
>  #x ":\n"                               \
>  "      ldr     x9, [x18, %0]\n"                \
>  "      ldr     x9, [x9, %1]\n"         \
>  "      br      x9\n"           \
> -       : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "x9");
> +       : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "x9");
>  #else
>  /*
>   * r9 holds the pointer to the global_data, ip is a call-clobbered
>   * register
>   */
> -#define EXPORT_FUNC(x) \
> +#define EXPORT_FUNC(f, a, x, ...) \
>         asm volatile (                  \
>  "      .globl " #x "\n"                \
>  #x ":\n"                               \
>  "      ldr     ip, [r9, %0]\n"         \
>  "      ldr     pc, [ip, %1]\n"         \
> -       : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "ip");
> +       : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "ip");
>  #endif
>  #elif defined(CONFIG_MIPS)
>  /*
> @@ -70,19 +72,19 @@ gd_t *global_data;
>   * it; however, GCC/mips generates an additional `nop' after each asm
>   * statement
>   */
> -#define EXPORT_FUNC(x) \
> +#define EXPORT_FUNC(f, a, x, ...) \
>         asm volatile (                  \
>  "      .globl " #x "\n"                \
>  #x ":\n"                               \
>  "      lw      $25, %0($26)\n"         \
>  "      lw      $25, %1($25)\n"         \
>  "      jr      $25\n"                  \
> -       : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "t9");
> +       : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "t9");
>  #elif defined(CONFIG_NIOS2)
>  /*
>   * gp holds the pointer to the global_data, r8 is call-clobbered
>   */
> -#define EXPORT_FUNC(x) \
> +#define EXPORT_FUNC(f, a, x, ...) \
>         asm volatile (                  \
>  "      .globl " #x "\n"                \
>  #x ":\n"                               \
> @@ -92,13 +94,13 @@ gd_t *global_data;
>  "      ldw     r8, 0(r8)\n"            \
>  "      ldw     r8, %1(r8)\n"           \
>  "      jmp     r8\n"                   \
> -       : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "gp");
> +       : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "gp");
>  #elif defined(CONFIG_M68K)
>  /*
>   * d7 holds the pointer to the global_data, a0 is a call-clobbered
>   * register
>   */
> -#define EXPORT_FUNC(x) \
> +#define EXPORT_FUNC(f, a, x, ...) \
>         asm volatile (                  \
>  "      .globl " #x "\n"                \
>  #x ":\n"                               \
> @@ -108,50 +110,50 @@ gd_t *global_data;
>  "      adda.l  %1, %%a0\n"             \
>  "      move.l  (%%a0), %%a0\n"         \
>  "      jmp     (%%a0)\n"                       \
> -       : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "a0");
> +       : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "a0");
>  #elif defined(CONFIG_MICROBLAZE)
>  /*
>   * r31 holds the pointer to the global_data. r5 is a call-clobbered.
>   */
> -#define EXPORT_FUNC(x)                         \
> +#define EXPORT_FUNC(f, a, x, ...)                              \
>         asm volatile (                          \
>  "      .globl " #x "\n"                        \
>  #x ":\n"                                       \
>  "      lwi     r5, r31, %0\n"                  \
>  "      lwi     r5, r5, %1\n"                   \
>  "      bra     r5\n"                           \
> -       : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "r5");
> +       : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "r5");
>  #elif defined(CONFIG_BLACKFIN)
>  /*
>   * P3 holds the pointer to the global_data, P0 is a call-clobbered
>   * register
>   */
> -#define EXPORT_FUNC(x)                 \
> +#define EXPORT_FUNC(f, a, x, ...)                      \
>         asm volatile (                  \
>  "      .globl _" #x "\n_"              \
>  #x ":\n"                               \
>  "      P0 = [P3 + %0]\n"               \
>  "      P0 = [P0 + %1]\n"               \
>  "      JUMP (P0)\n"                    \
> -       : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "P0");
> +       : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "P0");
>  #elif defined(CONFIG_AVR32)
>  /*
>   * r6 holds the pointer to the global_data. r8 is call clobbered.
>   */
> -#define EXPORT_FUNC(x)                                 \
> +#define EXPORT_FUNC(f, a, x, ...)                                      \
>         asm volatile(                                   \
>                 "       .globl\t" #x "\n"               \
>                 #x ":\n"                                \
>                 "       ld.w    r8, r6[%0]\n"           \
>                 "       ld.w    pc, r8[%1]\n"           \
>                 :                                       \
> -               : "i"(offsetof(gd_t, jt)), "i"(XF_ ##x) \
> +               : "i"(offsetof(gd_t, jt)), "i"(FO(x))   \
>                 : "r8");
>  #elif defined(CONFIG_SH)
>  /*
>   * r13 holds the pointer to the global_data. r1 is a call clobbered.
>   */
> -#define EXPORT_FUNC(x)                                 \
> +#define EXPORT_FUNC(f, a, x, ...)                                      \
>         asm volatile (                                  \
>                 "       .align  2\n"                    \
>                 "       .globl " #x "\n"                \
> @@ -164,12 +166,12 @@ gd_t *global_data;
>                 "       jmp     @r1\n"                  \
>                 "       nop\n"                          \
>                 "       nop\n"                          \
> -               : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "r1", "r2");
> +               : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "r1", "r2");
>  #elif defined(CONFIG_SPARC)
>  /*
>   * g7 holds the pointer to the global_data. g1 is call clobbered.
>   */
> -#define EXPORT_FUNC(x)                                 \
> +#define EXPORT_FUNC(f, a, x, ...)                                      \
>         asm volatile(                                   \
>  "      .globl\t" #x "\n"                               \
>  #x ":\n"                                               \
> @@ -179,26 +181,26 @@ gd_t *global_data;
>  "      ld [%%g1 + %1], %%g1\n"                         \
>  "      jmp %%g1\n"                                     \
>  "      nop\n"                                          \
> -       : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "g1" );
> +       : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "g1");
>  #elif defined(CONFIG_NDS32)
>  /*
>   * r16 holds the pointer to the global_data. gp is call clobbered.
>   * not support reduced register (16 GPR).
>   */
> -#define EXPORT_FUNC(x) \
> +#define EXPORT_FUNC(f, a, x, ...) \
>         asm volatile (                  \
>  "      .globl " #x "\n"                \
>  #x ":\n"                               \
>  "      lwi     $r16, [$gp + (%0)]\n"   \
>  "      lwi     $r16, [$r16 + (%1)]\n"  \
>  "      jr      $r16\n"                 \
> -       : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "$r16");
> +       : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "$r16");
>  #elif defined(CONFIG_OPENRISC)
>  /*
>   * r10 holds the pointer to the global_data, r13 is a call-clobbered
>   * register
>   */
> -#define EXPORT_FUNC(x) \
> +#define EXPORT_FUNC(f, a, x, ...) \
>         asm volatile (                  \
>  "      .globl " #x "\n"                \
>  #x ":\n"                               \
> @@ -206,12 +208,12 @@ gd_t *global_data;
>  "      l.lwz   r13, %1(r13)\n" \
>  "      l.jr    r13\n"          \
>  "      l.nop\n"                                \
> -       : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "r13");
> +       : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "r13");
>  #elif defined(CONFIG_ARC)
>  /*
>   * r25 holds the pointer to the global_data. r10 is call clobbered.
>    */
> -#define EXPORT_FUNC(x) \
> +#define EXPORT_FUNC(f, a, x, ...) \
>         asm volatile( \
>  "      .align 4\n" \
>  "      .globl " #x "\n" \
> @@ -219,7 +221,7 @@ gd_t *global_data;
>  "      ld      r10, [r25, %0]\n" \
>  "      ld      r10, [r10, %1]\n" \
>  "      j       [r10]\n" \
> -       : : "i"(offsetof(gd_t, jt)), "i"(XF_ ## x * sizeof(void *)) : "r10");
> +       : : "i"(offsetof(gd_t, jt)), "i"(FO(x)) : "r10");
>  #else
>  /*"    addi    $sp, $sp, -24\n"        \
>  "      br      $r16\n"                 \*/
> diff --git a/include/_exports.h b/include/_exports.h
> index 349a3c5..dcfbe44 100644
> --- a/include/_exports.h
> +++ b/include/_exports.h
> @@ -1,32 +1,67 @@
>  /*
> - * You do not need to use #ifdef around functions that may not exist
> + * You need to use #ifdef around functions that may not exist
>   * in the final configuration (such as i2c).
> + * use a dummyfunction as first parameter to EXPORT_FUNC.
> + * As an example see the CONFIG_CMD_I2C section below
>   */
> -EXPORT_FUNC(get_version)
> -EXPORT_FUNC(getc)
> -EXPORT_FUNC(tstc)
> -EXPORT_FUNC(putc)
> -EXPORT_FUNC(puts)
> -EXPORT_FUNC(printf)
> -EXPORT_FUNC(install_hdlr)
> -EXPORT_FUNC(free_hdlr)
> -EXPORT_FUNC(malloc)
> -EXPORT_FUNC(free)
> -EXPORT_FUNC(udelay)
> -EXPORT_FUNC(get_timer)
> -EXPORT_FUNC(vprintf)
> -EXPORT_FUNC(do_reset)
> -EXPORT_FUNC(getenv)
> -EXPORT_FUNC(setenv)
> -EXPORT_FUNC(simple_strtoul)
> -EXPORT_FUNC(strict_strtoul)
> -EXPORT_FUNC(simple_strtol)
> -EXPORT_FUNC(strcmp)
> -EXPORT_FUNC(i2c_write)
> -EXPORT_FUNC(i2c_read)
> -EXPORT_FUNC(spi_init)
> -EXPORT_FUNC(spi_setup_slave)
> -EXPORT_FUNC(spi_free_slave)
> -EXPORT_FUNC(spi_claim_bus)
> -EXPORT_FUNC(spi_release_bus)
> -EXPORT_FUNC(spi_xfer)
> +       EXPORT_FUNC(get_version, unsigned long, get_version, void)
> +       EXPORT_FUNC(getc, int, getc, void)
> +       EXPORT_FUNC(tstc, int, tstc, void)
> +       EXPORT_FUNC(putc, void, putc, const char)
> +       EXPORT_FUNC(puts, void, puts, const char *)
> +       EXPORT_FUNC(printf, int, printf, const char*, ...)
> +#if defined(CONFIG_X86) || defined(CONFIG_PPC)
> +       EXPORT_FUNC(irq_install_handler, void, install_hdlr,
> +                   int, interrupt_handler_t, void*)
> +
> +       EXPORT_FUNC(irq_free_handler, void, free_hdlr, int)
> +#else
> +       EXPORT_FUNC(install_hdlr, void, install_hdlr,
> +                   int, interrupt_handler_t, void*)
> +       EXPORT_FUNC(free_hdlr, void, free_hdlr, int)
> +#endif
> +       EXPORT_FUNC(malloc, void *, malloc, size_t)
> +       EXPORT_FUNC(free, void, free, void *)
> +       EXPORT_FUNC(udelay, void, udelay, unsigned long)
> +       EXPORT_FUNC(get_timer, unsigned long, get_timer, unsigned long)
> +       EXPORT_FUNC(vprintf, int, vprintf, const char *, va_list)
> +       EXPORT_FUNC(do_reset, int, do_reset, cmd_tbl_t *,
> +                   int , int , char * const [])
> +       EXPORT_FUNC(getenv, char  *, getenv, const char*)
> +       EXPORT_FUNC(setenv, int, setenv, const char *, const char *)
> +       EXPORT_FUNC(simple_strtoul, unsigned long, simple_strtoul,
> +                   const char *, char **, unsigned int)
> +       EXPORT_FUNC(strict_strtoul, int, strict_strtoul,
> +                   const char *, unsigned int , unsigned long *)
> +       EXPORT_FUNC(simple_strtol, long, simple_strtol,
> +                   const char *, char **, unsigned int)
> +       EXPORT_FUNC(strcmp, int, strcmp, const char *cs, const char *ct)
> +#ifdef CONFIG_CMD_I2C
> +       EXPORT_FUNC(i2c_write, int, i2c_write, uchar, uint, int , uchar * , int)
> +       EXPORT_FUNC(i2c_read, int, i2c_read, uchar, uint, int , uchar * , int)
> +#else
> +       EXPORT_FUNC(dummy, void, i2c_write, void)
> +       EXPORT_FUNC(dummy, void, i2c_read, void)
> +#endif
> +
> +#ifdef CONFIG_CMD_SPI
> +       EXPORT_FUNC(spi_init, void, spi_init, void)
> +       EXPORT_FUNC(spi_setup_slave, struct spi_slave *, spi_setup_slave,
> +                   unsigned int, unsigned int, unsigned int, unsigned int)
> +       EXPORT_FUNC(spi_free_slave, void, spi_free_slave, struct spi_slave *)
> +       EXPORT_FUNC(spi_claim_bus, int, spi_claim_bus, struct spi_slave *)
> +       EXPORT_FUNC(spi_release_bus, void, spi_release_bus, struct spi_slave *)
> +       EXPORT_FUNC(spi_xfer, int, spi_xfer, struct spi_slave *,
> +                   unsigned int, const void *, void *, unsigned long)
> +#else
> +       EXPORT_FUNC(dummy, void, spi_init, void)
> +       EXPORT_FUNC(dummy, void, spi_setup_slave, void)
> +       EXPORT_FUNC(dummy, void, spi_free_slave, void)
> +       EXPORT_FUNC(dummy, void, spi_claim_bus, void)
> +       EXPORT_FUNC(dummy, void, spi_release_bus, void)
> +       EXPORT_FUNC(dummy, void, spi_xfer, void)
> +#endif
> +       EXPORT_FUNC(ustrtoul, unsigned long, ustrtoul,
> +                   const char *, char **, unsigned int)
> +       EXPORT_FUNC(ustrtoull, unsigned long long, ustrtoull,
> +                   const char *, char **, unsigned int)
> diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h
> index 74df210..f8b1919 100644
> --- a/include/asm-generic/global_data.h
> +++ b/include/asm-generic/global_data.h
> @@ -73,7 +73,7 @@ typedef struct global_data {
>         const void *fdt_blob;   /* Our device tree, NULL if none */
>         void *new_fdt;          /* Relocated FDT */
>         unsigned long fdt_size; /* Space reserved for relocated FDT */
> -       void **jt;              /* jump table */
> +       struct jt_funcs *jt;            /* jump table */
>         char env_buf[32];       /* buffer for getenv() before reloc. */
>  #ifdef CONFIG_TRACE
>         void            *trace_buff;    /* The trace buffer */
> diff --git a/include/exports.h b/include/exports.h
> index 41d5085..48069b3 100644
> --- a/include/exports.h
> +++ b/include/exports.h
> @@ -10,19 +10,19 @@ int  tstc(void);
>  void putc(const char);
>  void puts(const char*);
>  int printf(const char* fmt, ...);
> -void install_hdlr(int, void (*interrupt_handler_t)(void *), void*);
> +void install_hdlr(int, interrupt_handler_t, void*);
>  void free_hdlr(int);
>  void *malloc(size_t);
>  void free(void*);
>  void __udelay(unsigned long);
>  unsigned long get_timer(unsigned long);
>  int vprintf(const char *, va_list);
> -unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base);
> +unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base);
>  int strict_strtoul(const char *cp, unsigned int base, unsigned long *res);
>  char *getenv (const char *name);
>  int setenv (const char *varname, const char *varvalue);
> -long simple_strtol(const char *cp,char **endp,unsigned int base);
> -int strcmp(const char * cs,const char * ct);
> +long simple_strtol(const char *cp, char **endp, unsigned int base);
> +int strcmp(const char *cs, const char *ct);
>  unsigned long ustrtoul(const char *cp, char **endp, unsigned int base);
>  unsigned long long ustrtoull(const char *cp, char **endp, unsigned int base);
>  #if defined(CONFIG_CMD_I2C)
> @@ -34,14 +34,13 @@ void app_startup(char * const *);
>
>  #endif    /* ifndef __ASSEMBLY__ */
>
> -enum {
> -#define EXPORT_FUNC(x) XF_ ## x ,
> +struct jt_funcs {
> +#define EXPORT_FUNC(impl, res, func, ...) res(*func)(__VA_ARGS__);
>  #include <_exports.h>
>  #undef EXPORT_FUNC
> -
> -       XF_MAX
>  };
>
> +
>  #define XF_VERSION     6
>
>  #if defined(CONFIG_X86)
> --
> 1.8.1.4
>

Regards,
Simon


More information about the U-Boot mailing list