Hi Martin, On 27 November 2014 at 01:42, Martin Dorwig <dor...@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 <dor...@tetronik.com> Good to get rid of the XF macros. I tested this on x86 and it still works fine. Tested-by: Simon Glass <s...@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 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot