aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorStewart Smith <stewart@flamingspork.com>2021-12-20 22:22:44 +1000
committerCédric Le Goater <clg@kaod.org>2022-01-03 16:12:45 +0100
commitbd497ddbfc845f55c2de0e65c67e7a8c20687a22 (patch)
tree4d69db4c1363bf426ba412ea8545c4c8aa559bde /core
parent7e1397f23f15be0fa916ab921477d0d0c5a8d4aa (diff)
downloadskiboot-bd497ddbfc845f55c2de0e65c67e7a8c20687a22.zip
skiboot-bd497ddbfc845f55c2de0e65c67e7a8c20687a22.tar.gz
skiboot-bd497ddbfc845f55c2de0e65c67e7a8c20687a22.tar.bz2
Introduce hwprobe facility to avoid hard-coding probe functions
hwprobe is a little system to have different hardware probing modules run in the dependency order they choose rather than hard coding that order in core/init.c. Reviewed-by: Dan Horák <dan@danny.cz> Signed-off-by: Stewart Smith <stewart@flamingspork.com> Signed-off-by: Cédric Le Goater <clg@kaod.org>
Diffstat (limited to 'core')
-rw-r--r--core/Makefile.inc1
-rw-r--r--core/hwprobe.c70
-rw-r--r--core/init.c3
3 files changed, 74 insertions, 0 deletions
diff --git a/core/Makefile.inc b/core/Makefile.inc
index 829800e..f80019b 100644
--- a/core/Makefile.inc
+++ b/core/Makefile.inc
@@ -13,6 +13,7 @@ CORE_OBJS += timer.o i2c.o rtc.o flash.o sensor.o ipmi-opal.o
CORE_OBJS += flash-subpartition.o bitmap.o buddy.o pci-quirk.o powercap.o psr.o
CORE_OBJS += pci-dt-slot.o direct-controls.o cpufeatures.o
CORE_OBJS += flash-firmware-versions.o opal-dump.o
+CORE_OBJS += hwprobe.o
ifeq ($(SKIBOOT_GCOV),1)
CORE_OBJS += gcov-profiling.o
diff --git a/core/hwprobe.c b/core/hwprobe.c
new file mode 100644
index 0000000..0a641ad
--- /dev/null
+++ b/core/hwprobe.c
@@ -0,0 +1,70 @@
+// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
+/* Copyright 2021 Stewart Smith */
+
+#define pr_fmt(fmt) "HWPROBE: " fmt
+#include <skiboot.h>
+#include <string.h>
+
+static bool hwprobe_deps_satisfied(const struct hwprobe *hwp)
+{
+ struct hwprobe *hwprobe;
+ const char **dep;
+ unsigned int i;
+
+ dep = hwp->deps;
+ if (dep == NULL)
+ return true;
+
+
+ prlog(PR_TRACE, "Checking deps for %s\n", hwp->name);
+
+ while (*dep != NULL) {
+ prlog(PR_TRACE, "Checking %s dep %s\n", hwp->name, *dep);
+ hwprobe = &__hwprobes_start;
+ for (i = 0; &hwprobe[i] < &__hwprobes_end; i++) {
+ if(strcmp(hwprobe[i].name, *dep) == 0 &&
+ !hwprobe[i].probed)
+ return false;
+ }
+ dep++;
+ }
+
+ prlog(PR_TRACE, "deps for %s are satisfied!\n", hwp->name);
+ return true;
+
+}
+
+void probe_hardware(void)
+{
+ struct hwprobe *hwprobe;
+ unsigned int i;
+ bool work_todo = true;
+ bool did_something = true;
+
+ while (work_todo) {
+ work_todo = false;
+ did_something = false;
+ hwprobe = &__hwprobes_start;
+ prlog(PR_DEBUG, "Begin loop\n");
+ for (i = 0; &hwprobe[i] < &__hwprobes_end; i++) {
+ if (hwprobe[i].probed)
+ continue;
+ if (hwprobe_deps_satisfied(&hwprobe[i])) {
+ prlog(PR_DEBUG, "Probing %s...\n", hwprobe[i].name);
+ if (hwprobe[i].probe)
+ hwprobe[i].probe();
+ did_something = true;
+ hwprobe[i].probed = true;
+ } else {
+ prlog(PR_DEBUG, "Dependencies for %s not yet satisfied, skipping\n",
+ hwprobe[i].name);
+ work_todo = true;
+ }
+ }
+
+ if (work_todo && !did_something) {
+ prlog(PR_ERR, "Cannot satisfy dependencies! Bailing out\n");
+ break;
+ }
+ }
+}
diff --git a/core/init.c b/core/init.c
index aab0e90..5c2bd7f 100644
--- a/core/init.c
+++ b/core/init.c
@@ -1374,6 +1374,9 @@ void __noreturn __nomcount main_cpu_entry(const void *fdt)
/* Probe PAUs */
probe_pau();
+ /* Probe all HWPROBE hardware we have code linked for*/
+ probe_hardware();
+
/* Initialize PCI */
pci_init_slots();