]> Git Repo - u-boot.git/blob - lib/initcall.c
Merge branch 'misc' of https://source.denx.de/u-boot/custodians/u-boot-tegra
[u-boot.git] / lib / initcall.c
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
12 DECLARE_GLOBAL_DATA_PTR;
13
14 static 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  */
35 static 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  */
50 int initcall_run_list(const init_fnc_t init_sequence[])
51 {
52         ulong 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                 reloc_ofs = calc_reloc_ofs();
60                 type = initcall_is_event(func);
61
62                 if (type) {
63                         if (!CONFIG_IS_ENABLED(EVENT))
64                                 continue;
65                         debug("initcall: event %d/%s\n", type,
66                               event_type_name(type));
67                 } else if (reloc_ofs) {
68                         debug("initcall: %p (relocated to %p)\n",
69                               (char *)func - reloc_ofs, (char *)func);
70                 } else {
71                         debug("initcall: %p\n", (char *)func - reloc_ofs);
72                 }
73
74                 ret = type ? event_notify_null(type) : func();
75                 if (ret)
76                         break;
77         }
78
79         if (ret) {
80                 if (CONFIG_IS_ENABLED(EVENT)) {
81                         char buf[60];
82
83                         /* don't worry about buf size as we are dying here */
84                         if (type) {
85                                 sprintf(buf, "event %d/%s", type,
86                                         event_type_name(type));
87                         } else {
88                                 sprintf(buf, "call %p",
89                                         (char *)func - reloc_ofs);
90                         }
91
92                         printf("initcall failed at %s (err=%dE)\n", buf, ret);
93                 } else {
94                         printf("initcall failed at call %p (err=%d)\n",
95                                (char *)func - reloc_ofs, ret);
96                 }
97
98                 return ret;
99         }
100
101         return 0;
102 }
This page took 0.026751 seconds and 4 git commands to generate.