Board implementations of spl_start_uboot() are not required to be
idempotent - the documented examples sample a GPIO or read a character
from the SPL console - so calling it more than once can yield different
answers.

Add spl_falcon_boot(), which calls spl_start_uboot() at most once and
caches the result.

Signed-off-by: Alexey Charkov <[email protected]>
---
 common/spl/spl.c | 18 ++++++++++++++++++
 include/spl.h    | 11 +++++++++++
 2 files changed, 29 insertions(+)

diff --git a/common/spl/spl.c b/common/spl/spl.c
index 722b18c98edc..abbd56ca2fa7 100644
--- a/common/spl/spl.c
+++ b/common/spl/spl.c
@@ -105,6 +105,24 @@ __weak int spl_start_uboot(void)
        return 1;
 }
 
+/*
+ * Decide about Falcon mode boot exactly once per SPL run. Board
+ * implementations of spl_start_uboot() are not required to be idempotent -
+ * they may sample a button or read a character from the console - so asking
+ * twice can yield two different answers. That matters because both the loader
+ * and the code which finally enters the OS (e.g. spl_invoke_atf()) need the
+ * decision, and they must not disagree about it.
+ */
+bool spl_falcon_boot(void)
+{
+       static int falcon = -1;
+
+       if (falcon < 0)
+               falcon = !spl_start_uboot();
+
+       return falcon;
+}
+
 /*
  * Weak default function for arch specific zImage check. Return zero
  * and fill start and end address if image is recognized.
diff --git a/include/spl.h b/include/spl.h
index 5078d7525abb..8da82e87aa3d 100644
--- a/include/spl.h
+++ b/include/spl.h
@@ -757,6 +757,17 @@ void __noreturn jump_to_image_optee(struct spl_image_info 
*spl_image);
  */
 int spl_start_uboot(void);
 
+/**
+ * spl_falcon_boot() - Check whether Falcon mode boot was requested
+ *
+ * Wrapper around spl_start_uboot() which calls it at most once and caches the
+ * answer, so that everything taking part in a single SPL run agrees on it.
+ * Prefer this over calling spl_start_uboot() directly.
+ *
+ * Return: true if SPL should start the OS, false if U-Boot must be started
+ */
+bool spl_falcon_boot(void);
+
 /**
  * spl_display_print() - Display a board-specific message in SPL
  *

-- 
2.54.0

Reply via email to