1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (c) 2013 The Chromium OS Authors. 4 */ 5 6#include <efi.h> 7#include <initcall.h> 8#include <log.h> 9#include <relocate.h> 10#include <asm/global_data.h> 11 12DECLARE_GLOBAL_DATA_PTR; 13 14static ulong calc_reloc_ofs(void) 15{ 16#ifdef CONFIG_EFI_APP 17 return (ulong)image_base; 18#endif 19 /* 20 * Sandbox is relocated by the OS, so symbols always appear at 21 * the relocated address. 22 */ 23 if (IS_ENABLED(CONFIG_SANDBOX) || (gd->flags & GD_FLG_RELOC)) 24 return gd->reloc_off; 25 26 return 0; 27} 28 29/** 30 * initcall_is_event() - Get the event number for an initcall 31 * 32 * func: Function pointer to check 33 * Return: Event number, if this is an event, else 0 34 */ 35static int initcall_is_event(init_fnc_t func) 36{ 37 ulong val = (ulong)func; 38 39 if ((val & INITCALL_IS_EVENT) == INITCALL_IS_EVENT) 40 return val & INITCALL_EVENT_TYPE; 41 42 return 0; 43} 44 45/* 46 * To enable debugging. add #define DEBUG at the top of the including file. 47 * 48 * To find a symbol, use grep on u-boot.map 49 */ 50int initcall_run_list(const init_fnc_t init_sequence[]) 51{ 52 ulong reloc_ofs = calc_reloc_ofs(); 53 const init_fnc_t *ptr; 54 enum event_t type; 55 init_fnc_t func; 56 int ret = 0; 57 58 for (ptr = init_sequence; func = *ptr, func; ptr++) { 59 type = initcall_is_event(func); 60 61 if (type) { 62 if (!CONFIG_IS_ENABLED(EVENT)) 63 continue; 64 debug("initcall: event %d/%s\n", type, 65 event_type_name(type)); 66 } else if (reloc_ofs) { 67 debug("initcall: %p (relocated to %p)\n", 68 (char *)func - reloc_ofs, (char *)func); 69 } else { 70 debug("initcall: %p\n", (char *)func - reloc_ofs); 71 } 72 73 ret = type ? event_notify_null(type) : func(); 74 if (ret) 75 break; 76 } 77 78 if (ret) { 79 if (CONFIG_IS_ENABLED(EVENT)) { 80 char buf[60]; 81 82 /* don't worry about buf size as we are dying here */ 83 if (type) { 84 sprintf(buf, "event %d/%s", type, 85 event_type_name(type)); 86 } else { 87 sprintf(buf, "call %p", func); 88 } 89 90 printf("initcall failed at %s (err=%dE)\n", buf, ret); 91 } else { 92 printf("initcall failed at call %p (err=%d)\n", 93 (char *)func - reloc_ofs, ret); 94 } 95 96 return ret; 97 } 98 99 return 0; 100} 101