xref: /rk3399_rockchip-uboot/lib/initcall.c (revision 13ceb2afdcb6f5114908e39f0d2453728eb24e0f)
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*13ceb2afSXuhui Lin #define TICKS_TO_US(ticks)	((ticks) / (gd->arch.timer_rate_hz / 1000000))
140a53d515SJoseph Chen #define US_TO_MS(ticks)		((ticks) / 1000)
150a53d515SJoseph Chen #define US_TO_US(ticks)		((ticks) % 1000)
1636ba3f8dSJoseph Chen 
1736ba3f8dSJoseph Chen #ifdef DEBUG
call_get_ticks(ulong * ticks)1836ba3f8dSJoseph Chen static inline void call_get_ticks(ulong *ticks) { *ticks = get_ticks(); }
1936ba3f8dSJoseph Chen #else
call_get_ticks(ulong * ticks)2036ba3f8dSJoseph Chen static inline void call_get_ticks(ulong *ticks) { }
2136ba3f8dSJoseph Chen #endif
2236ba3f8dSJoseph Chen 
initcall_run_list(const init_fnc_t init_sequence[])232f43f854SSimon Glass int initcall_run_list(const init_fnc_t init_sequence[])
24c8a311d9SSimon Glass {
252f43f854SSimon Glass 	const init_fnc_t *init_fnc_ptr;
260a53d515SJoseph Chen 	ulong start = 0, end = 0, sum = 0;
270a53d515SJoseph Chen 
280a53d515SJoseph Chen 	if (!gd->sys_start_tick)
290a53d515SJoseph Chen 		gd->sys_start_tick = get_ticks();
30c8a311d9SSimon Glass 
31c8a311d9SSimon Glass 	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
322f43f854SSimon Glass 		unsigned long reloc_ofs = 0;
33aacc6c5dSSimon Glass 		int ret;
342f43f854SSimon Glass 
352f43f854SSimon Glass 		if (gd->flags & GD_FLG_RELOC)
362f43f854SSimon Glass 			reloc_ofs = gd->reloc_off;
37f134ed7dSSimon Glass #ifdef CONFIG_EFI_APP
38f134ed7dSSimon Glass 		reloc_ofs = (unsigned long)image_base;
39f134ed7dSSimon Glass #endif
40e38d1cb2SAlexey Brodkin 		debug("initcall: %p", (char *)*init_fnc_ptr - reloc_ofs);
41e38d1cb2SAlexey Brodkin 		if (gd->flags & GD_FLG_RELOC)
42e38d1cb2SAlexey Brodkin 			debug(" (relocated to %p)\n", (char *)*init_fnc_ptr);
43e38d1cb2SAlexey Brodkin 		else
44e38d1cb2SAlexey Brodkin 			debug("\n");
4536ba3f8dSJoseph Chen 		call_get_ticks(&start);
46aacc6c5dSSimon Glass 		ret = (*init_fnc_ptr)();
4736ba3f8dSJoseph Chen 		call_get_ticks(&end);
480a53d515SJoseph Chen 
490a53d515SJoseph Chen 		if (start != end) {
500a53d515SJoseph Chen 			sum = TICKS_TO_US(end - gd->sys_start_tick);
510a53d515SJoseph Chen 			debug("\t\t\t\t\t\t\t\t#%8ld us #%4ld.%3ld ms\n",
520a53d515SJoseph Chen 			      TICKS_TO_US(end - start), US_TO_MS(sum), US_TO_US(sum));
530a53d515SJoseph Chen 		}
54aacc6c5dSSimon Glass 		if (ret) {
55aacc6c5dSSimon Glass 			printf("initcall sequence %p failed at call %p (err=%d)\n",
562f43f854SSimon Glass 			       init_sequence,
57aacc6c5dSSimon Glass 			       (char *)*init_fnc_ptr - reloc_ofs, ret);
58c8a311d9SSimon Glass 			return -1;
59c8a311d9SSimon Glass 		}
60c8a311d9SSimon Glass 	}
61c8a311d9SSimon Glass 	return 0;
62c8a311d9SSimon Glass }
63