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*0a53d515SJoseph Chen #define TICKS_TO_US(ticks) ((ticks) / (COUNTER_FREQUENCY / 1000000)) 14*0a53d515SJoseph Chen #define US_TO_MS(ticks) ((ticks) / 1000) 15*0a53d515SJoseph Chen #define US_TO_US(ticks) ((ticks) % 1000) 1636ba3f8dSJoseph Chen 1736ba3f8dSJoseph Chen #ifdef DEBUG 1836ba3f8dSJoseph Chen static inline void call_get_ticks(ulong *ticks) { *ticks = get_ticks(); } 1936ba3f8dSJoseph Chen #else 2036ba3f8dSJoseph Chen static inline void call_get_ticks(ulong *ticks) { } 2136ba3f8dSJoseph Chen #endif 2236ba3f8dSJoseph Chen 232f43f854SSimon Glass int initcall_run_list(const init_fnc_t init_sequence[]) 24c8a311d9SSimon Glass { 252f43f854SSimon Glass const init_fnc_t *init_fnc_ptr; 26*0a53d515SJoseph Chen ulong start = 0, end = 0, sum = 0; 27*0a53d515SJoseph Chen 28*0a53d515SJoseph Chen if (!gd->sys_start_tick) 29*0a53d515SJoseph 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); 48*0a53d515SJoseph Chen 49*0a53d515SJoseph Chen if (start != end) { 50*0a53d515SJoseph Chen sum = TICKS_TO_US(end - gd->sys_start_tick); 51*0a53d515SJoseph Chen debug("\t\t\t\t\t\t\t\t#%8ld us #%4ld.%3ld ms\n", 52*0a53d515SJoseph Chen TICKS_TO_US(end - start), US_TO_MS(sum), US_TO_US(sum)); 53*0a53d515SJoseph 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