xref: /openbmc/u-boot/doc/README.standalone (revision 3fafced74df234c708e645a373a70db665e4e6ce)
127b207fdSwdenkDesign Notes on Exporting U-Boot Functions to Standalone Applications:
227b207fdSwdenk======================================================================
327b207fdSwdenk
477846748Swdenk1. The functions are exported by U-Boot via a jump table. The jump
577846748Swdenk   table is allocated and initialized in the jumptable_init() routine
677846748Swdenk   (common/exports.c). Other routines may also modify the jump table,
777846748Swdenk   however. The jump table can be accessed as the 'jt' field of the
849cad547SMartin Dorwig   'global_data' structure. The struct members for the jump table are
977846748Swdenk   defined in the <include/exports.h> header. E.g., to substitute the
1077846748Swdenk   malloc() and free() functions that will be available to standalone
1177846748Swdenk   applications, one should do the following:
1227b207fdSwdenk
1377846748Swdenk	DECLARE_GLOBAL_DATA_PTR;
1427b207fdSwdenk
1549cad547SMartin Dorwig	gd->jt->malloc	= my_malloc;
1649cad547SMartin Dorwig	gd->jt->free = my_free;
1727b207fdSwdenk
1849cad547SMartin Dorwig   Note that the pointers to the functions are real function pointers
1949cad547SMartin Dorwig   so the compiler can perform type checks on these assignments.
2027b207fdSwdenk
2177846748Swdenk2. The pointer to the jump table is passed to the application in a
220df01fd3SThomas Chou   machine-dependent way. PowerPC, ARM, MIPS, Blackfin and Nios II
230df01fd3SThomas Chou   architectures use a dedicated register to hold the pointer to the
246a10560cSMasahiro Yamada   'global_data' structure: r2 on PowerPC, r9 on ARM, k0 on MIPS,
250df01fd3SThomas Chou   P3 on Blackfin and gp on Nios II. The x86 architecture does not
260df01fd3SThomas Chou   use such a register; instead, the pointer to the 'global_data'
270df01fd3SThomas Chou   structure is passed as 'argv[-1]' pointer.
2827b207fdSwdenk
2977846748Swdenk   The application can access the 'global_data' structure in the same
3077846748Swdenk   way as U-Boot does:
3127b207fdSwdenk
3277846748Swdenk	DECLARE_GLOBAL_DATA_PTR;
3327b207fdSwdenk
3477846748Swdenk	printf("U-Boot relocation offset: %x\n", gd->reloc_off);
3527b207fdSwdenk
3677846748Swdenk3. The application should call the app_startup() function before any
3777846748Swdenk   call to the exported functions. Also, implementor of the
3877846748Swdenk   application may want to check the version of the ABI provided by
3977846748Swdenk   U-Boot. To facilitate this, a get_version() function is exported
4077846748Swdenk   that returns the ABI version of the running U-Boot. I.e., a
4177846748Swdenk   typical application startup may look like this:
4227b207fdSwdenk
4354841ab5SWolfgang Denk	int my_app (int argc, char * const argv[])
4477846748Swdenk	{
4577846748Swdenk		app_startup (argv);
4677846748Swdenk		if (get_version () != XF_VERSION)
4777846748Swdenk			return 1;
4877846748Swdenk	}
4927b207fdSwdenk
5077846748Swdenk4. The default load and start addresses of the applications are as
5177846748Swdenk   follows:
5227b207fdSwdenk
5377846748Swdenk			Load address	Start address
5477846748Swdenk	x86		0x00040000	0x00040000
5577846748Swdenk	PowerPC		0x00040000	0x00040004
5677846748Swdenk	ARM		0x0c100000	0x0c100000
5777846748Swdenk	MIPS		0x80200000	0x80200000
584c58eb55SMike Frysinger	Blackfin	0x00001000	0x00001000
59afc1ce82SMacpaul Lin	NDS32		0x00300000	0x00300000
600df01fd3SThomas Chou	Nios II		0x02000000	0x02000000
61*3fafced7SRick Chen	RISC-V		0x00600000	0x00600000
6227b207fdSwdenk
6377846748Swdenk   For example, the "hello world" application may be loaded and
6477846748Swdenk   executed on a PowerPC board with the following commands:
6527b207fdSwdenk
6677846748Swdenk   => tftp 0x40000 hello_world.bin
6727b207fdSwdenk   => go 0x40004
6827b207fdSwdenk
6949cad547SMartin Dorwig5. To export some additional function long foobar(int i,char c), the following steps
7077846748Swdenk   should be undertaken:
7127b207fdSwdenk
7277846748Swdenk   - Append the following line at the end of the include/_exports.h
7377846748Swdenk     file:
7427b207fdSwdenk
7549cad547SMartin Dorwig	EXPORT_FUNC(foobar, long, foobar, int, char)
7649cad547SMartin Dorwig
7749cad547SMartin Dorwig	Parameters to EXPORT_FUNC:
7849cad547SMartin Dorwig	 - the first parameter is the function that is exported (default implementation)
7949cad547SMartin Dorwig	 - the second parameter is the return value type
8049cad547SMartin Dorwig	 - the third  parameter is the name of the member in struct jt_funcs
8149cad547SMartin Dorwig	   this is also the name that the standalone application will used.
8249cad547SMartin Dorwig	   the rest of the parameters are the function arguments
8327b207fdSwdenk
8477846748Swdenk   - Add the prototype for this function to the include/exports.h
8577846748Swdenk     file:
8627b207fdSwdenk
8749cad547SMartin Dorwig	long foobar(int i, char c);
8827b207fdSwdenk
8949cad547SMartin Dorwig	Initialization with the default implementation is done in jumptable_init()
9027b207fdSwdenk
9149cad547SMartin Dorwig	You can override the default implementation using:
9249cad547SMartin Dorwig
9349cad547SMartin Dorwig	gd->jt->foobar = another_foobar;
9449cad547SMartin Dorwig
9549cad547SMartin Dorwig	The signature of another_foobar must then match the declaration of foobar.
9627b207fdSwdenk
9777846748Swdenk   - Increase the XF_VERSION value by one in the include/exports.h
9877846748Swdenk     file
9927b207fdSwdenk
10049cad547SMartin Dorwig   - If you want to export a function which depends on a CONFIG_XXX
10149cad547SMartin Dorwig	use 2 lines like this:
10249cad547SMartin Dorwig	#ifdef CONFIG_FOOBAR
10349cad547SMartin Dorwig		EXPORT_FUNC(foobar, long, foobar, int, char)
10449cad547SMartin Dorwig	#else
10549cad547SMartin Dorwig		EXPORT_FUNC(dummy, void, foobar, void)
10649cad547SMartin Dorwig	#endif
10749cad547SMartin Dorwig
10849cad547SMartin Dorwig
10977846748Swdenk6. The code for exporting the U-Boot functions to applications is
11077846748Swdenk   mostly machine-independent. The only places written in assembly
11177846748Swdenk   language are stub functions that perform the jump through the jump
11277846748Swdenk   table. That said, to port this code to a new architecture, the
11377846748Swdenk   only thing to be provided is the code in the examples/stubs.c
11477846748Swdenk   file. If this architecture, however, uses some uncommon method of
11577846748Swdenk   passing the 'global_data' pointer (like x86 does), one should add
11677846748Swdenk   the respective code to the app_startup() function in that file.
11727b207fdSwdenk
11877846748Swdenk   Note that these functions may only use call-clobbered registers;
11977846748Swdenk   those registers that are used to pass the function's arguments,
12077846748Swdenk   the stack contents and the return address should be left intact.
121