Consolidate reset API, add generic reset_prepare mechanism
There are many good reasons why we may want to run some sort of generic
callback before we're executing a reset. Unfortunateley, that is really
hard right now: code that wants to reset simply calls the hard_reset()
function (or one of its ill-differentiated cousins) which is directly
implemented by a myriad of different mainboards, northbridges, SoCs,
etc. More recent x86 SoCs have tried to solve the problem in their own
little corner of soc/intel/common, but it's really something that would
benefit all of coreboot.
This patch expands the concept onto all boards: hard_reset() and friends
get implemented in a generic location where they can run hooks before
calling the platform-specific implementation that is now called
do_hard_reset(). The existing Intel reset_prepare() gets generalized as
soc_reset_prepare() (and other hooks for arch, mainboard, etc. can now
easily be added later if necessary). We will also use this central point
to ensure all platforms flush their cache before reset, which is
generally useful for all cases where we're trying to persist information
in RAM across reboots (like the new persistent CBMEM console does).
Also remove cpu_reset() completely since it's not used anywhere and
doesn't seem very useful compared to the others.
Change-Id: I41b89ce4a923102f0748922496e1dd9bce8a610f
Signed-off-by: Julius Werner <jwerner@chromium.org>
Reviewed-on: https://review.coreboot.org/19789
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Furquan Shaikh <furquan@google.com>
diff --git a/src/lib/Makefile.inc b/src/lib/Makefile.inc
index c4d4f6a..5079bbf 100644
--- a/src/lib/Makefile.inc
+++ b/src/lib/Makefile.inc
@@ -223,6 +223,13 @@
ramstage-y += halt.c
smm-y += halt.c
+bootblock-y += reset.c
+verstage-y += reset.c
+romstage-y += reset.c
+postcar-y += reset.c
+ramstage-y += reset.c
+smm-y += reset.c
+
postcar-y += bootmode.c
postcar-y += boot_device.c
postcar-y += cbfs.c
diff --git a/src/lib/reset.c b/src/lib/reset.c
new file mode 100644
index 0000000..703118a
--- /dev/null
+++ b/src/lib/reset.c
@@ -0,0 +1,59 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright 2017 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <arch/cache.h>
+#include <console/console.h>
+#include <halt.h>
+#include <reset.h>
+
+__attribute__((noreturn)) static void __hard_reset(void) {
+ if (IS_ENABLED(CONFIG_HAVE_HARD_RESET))
+ do_hard_reset();
+ else
+ printk(BIOS_CRIT, "No hard_reset implementation, hanging...\n");
+ halt();
+}
+
+/* Not all platforms implement all reset types. Fall back to hard_reset. */
+__attribute__((weak)) void do_global_reset(void) { __hard_reset(); }
+__attribute__((weak)) void do_soft_reset(void) { __hard_reset(); }
+
+__attribute__((weak)) void soc_reset_prepare(enum reset_type rt) { /* no-op */ }
+
+void global_reset(void)
+{
+ printk(BIOS_INFO, "%s() called!\n", __func__);
+ soc_reset_prepare(GLOBAL_RESET);
+ dcache_clean_all();
+ do_global_reset();
+ halt();
+}
+
+void hard_reset(void)
+{
+ printk(BIOS_INFO, "%s() called!\n", __func__);
+ soc_reset_prepare(HARD_RESET);
+ dcache_clean_all();
+ __hard_reset();
+}
+
+void soft_reset(void)
+{
+ printk(BIOS_INFO, "%s() called!\n", __func__);
+ soc_reset_prepare(SOFT_RESET);
+ dcache_clean_all();
+ do_soft_reset();
+ halt();
+}