summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorTom Rini <[email protected]>2023-08-31 15:10:42 -0400
committerTom Rini <[email protected]>2023-08-31 15:10:42 -0400
commitb8b512a45358d50bce2e17b5941c5e39b52a0594 (patch)
treef70b4d2452f8ca45025916cd85f0d1af684902bb /lib
parentb81a024e4a37097d3dcffccb225850f8f6dc8277 (diff)
parent91caa3bb89b112a1421ee2ee3661baf67c64bab9 (diff)
Merge branch '2023-08-31-replace-more-init-hooks-with-events' into next
To quote the author: This series replaces some more of the init hooks in board_f.c and board_r.c with events. Notably it converts last_state_init() over. It also provides a 'simple' event spy, which takes no arguments. It turns out that this is quite a common case, so it is worth optimising for this, to reduce code size, before events become too commonly used. Finally, it introduces a way of emitting an event in an initcall, instead of calling a function. This is likely to be used at least as often as the functions, as we convert more of these initcalls. As part of this, the initcall code is brought back into a C file. Somehow the compiler has changed or something else, so that this does not confer any benefits now. For boards with EVENT enabled, this unfortunately results in small growth, e.g. for firefly: aarch64: (for 1/1 boards) all +114.0 data +16.0 rodata +22.0 text +76.0 arm: (for 1/1 boards) all +82.0 rodata +18.0 text +64.0 For boards without EVENT enabled the growth is smaller, e.g. nokia_rx51: arm: (for 1/1 boards) all +32.0 data +8.0 rodata -8.0 text +32.0 I cannot find a good way to avoid the latter, other than macro magic with an embedded comma (to completely remove an event entry), which seems nasty.
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile1
-rw-r--r--lib/fwu_updates/fwu.c4
-rw-r--r--lib/initcall.c109
3 files changed, 112 insertions, 2 deletions
diff --git a/lib/Makefile b/lib/Makefile
index 8d8ccc8bbc3..839872d804b 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -44,6 +44,7 @@ obj-$(CONFIG_GZIP_COMPRESSED) += gzip.o
obj-$(CONFIG_GENERATE_SMBIOS_TABLE) += smbios.o
obj-$(CONFIG_SMBIOS_PARSER) += smbios-parser.o
obj-$(CONFIG_IMAGE_SPARSE) += image-sparse.o
+obj-y += initcall.o
obj-y += ldiv.o
obj-$(CONFIG_XXHASH) += xxhash.o
obj-y += net_utils.o
diff --git a/lib/fwu_updates/fwu.c b/lib/fwu_updates/fwu.c
index 22bdc78df59..b5805740153 100644
--- a/lib/fwu_updates/fwu.c
+++ b/lib/fwu_updates/fwu.c
@@ -618,7 +618,7 @@ int fwu_trial_state_ctr_start(void)
return ret;
}
-static int fwu_boottime_checks(void *ctx, struct event *event)
+static int fwu_boottime_checks(void)
{
int ret;
u32 boot_idx, active_idx;
@@ -682,4 +682,4 @@ static int fwu_boottime_checks(void *ctx, struct event *event)
return 0;
}
-EVENT_SPY(EVT_MAIN_LOOP, fwu_boottime_checks);
+EVENT_SPY_SIMPLE(EVT_MAIN_LOOP, fwu_boottime_checks);
diff --git a/lib/initcall.c b/lib/initcall.c
new file mode 100644
index 00000000000..480490ea239
--- /dev/null
+++ b/lib/initcall.c
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (c) 2013 The Chromium OS Authors.
+ */
+
+#include <common.h>
+#include <efi.h>
+#include <initcall.h>
+#include <log.h>
+#include <relocate.h>
+#include <asm/global_data.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static ulong calc_reloc_ofs(void)
+{
+#ifdef CONFIG_EFI_APP
+ return (ulong)image_base;
+#endif
+ /*
+ * Sandbox is relocated by the OS, so symbols always appear at
+ * the relocated address.
+ */
+ if (IS_ENABLED(CONFIG_SANDBOX) || (gd->flags & GD_FLG_RELOC))
+ return gd->reloc_off;
+
+ return 0;
+}
+
+/**
+ * initcall_is_event() - Get the event number for an initcall
+ *
+ * func: Function pointer to check
+ * Return: Event number, if this is an event, else 0
+ */
+static int initcall_is_event(init_fnc_t func)
+{
+ ulong val = (ulong)func;
+
+ if ((val & INITCALL_IS_EVENT) == INITCALL_IS_EVENT)
+ return val & INITCALL_EVENT_TYPE;
+
+ return 0;
+}
+
+/*
+ * To enable debugging. add #define DEBUG at the top of the including file.
+ *
+ * To find a symbol, use grep on u-boot.map
+ */
+int initcall_run_list(const init_fnc_t init_sequence[])
+{
+ ulong reloc_ofs = calc_reloc_ofs();
+ const init_fnc_t *ptr;
+ enum event_t type;
+ init_fnc_t func;
+ int ret = 0;
+
+ for (ptr = init_sequence; func = *ptr, !ret && func; ptr++) {
+ type = initcall_is_event(func);
+
+ if (type) {
+ if (!CONFIG_IS_ENABLED(EVENT))
+ continue;
+ debug("initcall: event %d/%s\n", type,
+ event_type_name(type));
+ } else if (reloc_ofs) {
+ debug("initcall: %p (relocated to %p)\n",
+ (char *)func - reloc_ofs, (char *)func);
+ } else {
+ debug("initcall: %p\n", (char *)func - reloc_ofs);
+ }
+
+ ret = type ? event_notify_null(type) : func();
+ }
+
+ if (ret) {
+ if (CONFIG_IS_ENABLED(EVENT)) {
+ char buf[60];
+
+ /* don't worry about buf size as we are dying here */
+ if (type) {
+ sprintf(buf, "event %d/%s", type,
+ event_type_name(type));
+ } else {
+ sprintf(buf, "call %p", func);
+ }
+
+ printf("initcall failed at %s (err=%dE)\n", buf, ret);
+ } else {
+ printf("initcall failed at call %p (err=%d)\n",
+ (char *)func - reloc_ofs, ret);
+ }
+
+ return ret;
+ }
+
+ return 0;
+}
+
+void initcall_manual_reloc(init_fnc_t init_sequence[])
+{
+ init_fnc_t *ptr;
+
+ for (ptr = init_sequence; *ptr; ptr++) {
+ if (!initcall_is_event(*ptr))
+ MANUAL_RELOC(*ptr);
+ }
+}