xref: /rk3399_rockchip-uboot/lib/initcall.c (revision 36ba3f8d39ecc8eca0b0ed34154f08be164b93a3)
1c8a311d9SSimon Glass /*
2c8a311d9SSimon Glass  * Copyright (c) 2013 The Chromium OS Authors.
3c8a311d9SSimon Glass  *
41a459660SWolfgang Denk  * SPDX-License-Identifier:	GPL-2.0+
5c8a311d9SSimon Glass  */
6c8a311d9SSimon Glass 
7c8a311d9SSimon Glass #include <common.h>
8c8a311d9SSimon Glass #include <initcall.h>
9f134ed7dSSimon Glass #include <efi.h>
10c8a311d9SSimon Glass 
112f43f854SSimon Glass DECLARE_GLOBAL_DATA_PTR;
122f43f854SSimon Glass 
13*36ba3f8dSJoseph Chen #define SYS_TICKS_TO_US(ticks)	 ((ticks) / (COUNTER_FREQUENCY / 1000000))
14*36ba3f8dSJoseph Chen 
15*36ba3f8dSJoseph Chen #ifdef DEBUG
16*36ba3f8dSJoseph Chen static inline void call_get_ticks(ulong *ticks) { *ticks = get_ticks(); }
17*36ba3f8dSJoseph Chen #else
18*36ba3f8dSJoseph Chen static inline void call_get_ticks(ulong *ticks) { }
19*36ba3f8dSJoseph Chen #endif
20*36ba3f8dSJoseph Chen 
212f43f854SSimon Glass int initcall_run_list(const init_fnc_t init_sequence[])
22c8a311d9SSimon Glass {
232f43f854SSimon Glass 	const init_fnc_t *init_fnc_ptr;
24*36ba3f8dSJoseph Chen 	__maybe_unused ulong start = 0, end = 0;
25c8a311d9SSimon Glass 
26c8a311d9SSimon Glass 	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
272f43f854SSimon Glass 		unsigned long reloc_ofs = 0;
28aacc6c5dSSimon Glass 		int ret;
292f43f854SSimon Glass 
302f43f854SSimon Glass 		if (gd->flags & GD_FLG_RELOC)
312f43f854SSimon Glass 			reloc_ofs = gd->reloc_off;
32f134ed7dSSimon Glass #ifdef CONFIG_EFI_APP
33f134ed7dSSimon Glass 		reloc_ofs = (unsigned long)image_base;
34f134ed7dSSimon Glass #endif
35e38d1cb2SAlexey Brodkin 		debug("initcall: %p", (char *)*init_fnc_ptr - reloc_ofs);
36e38d1cb2SAlexey Brodkin 		if (gd->flags & GD_FLG_RELOC)
37e38d1cb2SAlexey Brodkin 			debug(" (relocated to %p)\n", (char *)*init_fnc_ptr);
38e38d1cb2SAlexey Brodkin 		else
39e38d1cb2SAlexey Brodkin 			debug("\n");
40*36ba3f8dSJoseph Chen 		call_get_ticks(&start);
41aacc6c5dSSimon Glass 		ret = (*init_fnc_ptr)();
42*36ba3f8dSJoseph Chen 		call_get_ticks(&end);
43*36ba3f8dSJoseph Chen 		if (start != end)
44*36ba3f8dSJoseph Chen 			debug("\t\t\t\t\t\t\t\t#%6ld us\n", SYS_TICKS_TO_US(end - start));
45aacc6c5dSSimon Glass 		if (ret) {
46aacc6c5dSSimon Glass 			printf("initcall sequence %p failed at call %p (err=%d)\n",
472f43f854SSimon Glass 			       init_sequence,
48aacc6c5dSSimon Glass 			       (char *)*init_fnc_ptr - reloc_ofs, ret);
49c8a311d9SSimon Glass 			return -1;
50c8a311d9SSimon Glass 		}
51c8a311d9SSimon Glass 	}
52c8a311d9SSimon Glass 	return 0;
53c8a311d9SSimon Glass }
54