xref: /openbmc/u-boot/doc/README.standalone (revision 49cad54788a64a296567abadcd736fdbe47cc3a3)
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
8*49cad547SMartin 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
15*49cad547SMartin Dorwig	gd->jt->malloc	= my_malloc;
16*49cad547SMartin Dorwig	gd->jt->free = my_free;
1727b207fdSwdenk
18*49cad547SMartin Dorwig   Note that the pointers to the functions are real function pointers
19*49cad547SMartin 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
6127b207fdSwdenk
6277846748Swdenk   For example, the "hello world" application may be loaded and
6377846748Swdenk   executed on a PowerPC board with the following commands:
6427b207fdSwdenk
6577846748Swdenk   => tftp 0x40000 hello_world.bin
6627b207fdSwdenk   => go 0x40004
6727b207fdSwdenk
68*49cad547SMartin Dorwig5. To export some additional function long foobar(int i,char c), the following steps
6977846748Swdenk   should be undertaken:
7027b207fdSwdenk
7177846748Swdenk   - Append the following line at the end of the include/_exports.h
7277846748Swdenk     file:
7327b207fdSwdenk
74*49cad547SMartin Dorwig	EXPORT_FUNC(foobar, long, foobar, int, char)
75*49cad547SMartin Dorwig
76*49cad547SMartin Dorwig	Parameters to EXPORT_FUNC:
77*49cad547SMartin Dorwig	 - the first parameter is the function that is exported (default implementation)
78*49cad547SMartin Dorwig	 - the second parameter is the return value type
79*49cad547SMartin Dorwig	 - the third  parameter is the name of the member in struct jt_funcs
80*49cad547SMartin Dorwig	   this is also the name that the standalone application will used.
81*49cad547SMartin Dorwig	   the rest of the parameters are the function arguments
8227b207fdSwdenk
8377846748Swdenk   - Add the prototype for this function to the include/exports.h
8477846748Swdenk     file:
8527b207fdSwdenk
86*49cad547SMartin Dorwig	long foobar(int i, char c);
8727b207fdSwdenk
88*49cad547SMartin Dorwig	Initialization with the default implementation is done in jumptable_init()
8927b207fdSwdenk
90*49cad547SMartin Dorwig	You can override the default implementation using:
91*49cad547SMartin Dorwig
92*49cad547SMartin Dorwig	gd->jt->foobar = another_foobar;
93*49cad547SMartin Dorwig
94*49cad547SMartin Dorwig	The signature of another_foobar must then match the declaration of foobar.
9527b207fdSwdenk
9677846748Swdenk   - Increase the XF_VERSION value by one in the include/exports.h
9777846748Swdenk     file
9827b207fdSwdenk
99*49cad547SMartin Dorwig   - If you want to export a function which depends on a CONFIG_XXX
100*49cad547SMartin Dorwig	use 2 lines like this:
101*49cad547SMartin Dorwig	#ifdef CONFIG_FOOBAR
102*49cad547SMartin Dorwig		EXPORT_FUNC(foobar, long, foobar, int, char)
103*49cad547SMartin Dorwig	#else
104*49cad547SMartin Dorwig		EXPORT_FUNC(dummy, void, foobar, void)
105*49cad547SMartin Dorwig	#endif
106*49cad547SMartin Dorwig
107*49cad547SMartin Dorwig
10877846748Swdenk6. The code for exporting the U-Boot functions to applications is
10977846748Swdenk   mostly machine-independent. The only places written in assembly
11077846748Swdenk   language are stub functions that perform the jump through the jump
11177846748Swdenk   table. That said, to port this code to a new architecture, the
11277846748Swdenk   only thing to be provided is the code in the examples/stubs.c
11377846748Swdenk   file. If this architecture, however, uses some uncommon method of
11477846748Swdenk   passing the 'global_data' pointer (like x86 does), one should add
11577846748Swdenk   the respective code to the app_startup() function in that file.
11627b207fdSwdenk
11777846748Swdenk   Note that these functions may only use call-clobbered registers;
11877846748Swdenk   those registers that are used to pass the function's arguments,
11977846748Swdenk   the stack contents and the return address should be left intact.
120