mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Ahmad Fatoum <a.fatoum@barebox.org>
To: barebox@lists.infradead.org
Cc: mfe@pengutronix.de, mtr@pengutronix.de,
	Ahmad Fatoum <a.fatoum@barebox.org>
Subject: [RFC PATCH 06/17] PBL: describe the console in the board info and report the stage
Date: Tue, 27 Oct 2026 08:24:39 +0100	[thread overview]
Message-ID: <20261027074014.3280396-7-a.fatoum@barebox.org> (raw)
In-Reply-To: <20261027074014.3280396-1-a.fatoum@barebox.org>

Board entry points usually set up the console UART first thing and
print a '>' with putc_ll() to show that they have been reached.

Let's make the console part of the board info instead and have the stage
dispatch print the stage number followed by '>', e.g. "2>", once it's
up. As the UART may need clocks enabled by SoC init or a description
only filled in by board init, the console is tried before SoC init and
again after each of the two.

Without PBL console support or a console description, the stage number
goes to DEBUG_LL. With DEBUG, each callback run is reported as well.

Assisted-by: Claude:opus-5
Signed-off-by: Ahmad Fatoum <a.fatoum@barebox.org>
---
 Documentation/devel/troubleshooting.rst |  6 +++
 include/pbl.h                           |  6 +++
 include/pbl/entry.h                     | 19 ++++++-
 pbl/entry.c                             | 67 ++++++++++++++++++++++++-
 4 files changed, 96 insertions(+), 2 deletions(-)

diff --git a/Documentation/devel/troubleshooting.rst b/Documentation/devel/troubleshooting.rst
index 2aef57c3c1e2..39cc88a9a7dd 100644
--- a/Documentation/devel/troubleshooting.rst
+++ b/Documentation/devel/troubleshooting.rst
@@ -62,6 +62,12 @@ options:
   the serial console needs to be done in software in some situations before
   the UART is accessible from the outside.
 
+  Boards using the board info entry point (``ENTRY_POINT()``) will
+  also indicate the boot stage before the ``>`` character, e.g. ``1>2>``
+  means the prebootloader entered its 1st stage followed by entering the
+  2nd stage. ``CONFIG_DEBUG_PBL`` would provide more information on what
+  callback is being executed.
+
   .. note::
      Make sure the correct UART index or address is selected under
      **Kernel low-level debugging port** in ``menuconfig``.
diff --git a/include/pbl.h b/include/pbl.h
index 45640c26e32e..9efc520d6a69 100644
--- a/include/pbl.h
+++ b/include/pbl.h
@@ -57,4 +57,10 @@ void __noreturn barebox_pbl_entry(ulong, ulong, void *);
 #define pbl_puts	puts_ll
 #endif
 
+#ifdef DEBUG
+#define pbl_debug	pbl_puts
+#else
+#define pbl_debug	(void)
+#endif
+
 #endif /* __PBL_H__ */
diff --git a/include/pbl/entry.h b/include/pbl/entry.h
index 17056a3ab1ca..acf0ea1e1824 100644
--- a/include/pbl/entry.h
+++ b/include/pbl/entry.h
@@ -26,12 +26,27 @@ enum pbl_stage_idx {
 typedef void (*pbl_board_fn_t)(void);
 typedef enum pbl_stage_idx (*pbl_locate_pc_fn_t)(void);
 
+struct pbl_console_driver {
+	void (*putc)(void *arg, int c);	/* as accepted by pbl_set_putc() */
+};
+
+/*
+ * arg is usually the UART base address. A console without setup callback
+ * is registered before soc_init, else after. Without a console, the PBL
+ * prints through DEBUG_LL.
+ */
+struct pbl_console {
+	void (*setup)(void *arg);
+	void *arg;
+	const struct pbl_console_driver *driver;
+};
+
 /*
  * Only the callbacks of the stage the PBL was entered in are run.
  *
  * prereloc_cpu_init runs on the stage's stack, but unrelocated and before
  * BSS is cleared, so it must be __prereloc and may not use globals.
- * The other callbacks run relocated with BSS cleared.
+ * The console setup and the other callbacks run relocated with BSS cleared.
  */
 struct pbl_stage {
 	unsigned long stacktop;		/* stack top or PBL_STACKTOP_* */
@@ -60,6 +75,8 @@ struct pbl_board_info {
 	/* Called without a stack, so it must not spill */
 	pbl_locate_pc_fn_t assembly_locate_pc;
 
+	struct pbl_console console;
+
 	struct pbl_stage rom_stage;	/* PBL_STAGE_ROM */
 	struct pbl_stage first_stage;	/* PBL_STAGE_OCRAM */
 	struct pbl_stage second_stage;	/* PBL_STAGE_DRAM */
diff --git a/pbl/entry.c b/pbl/entry.c
index 1349e7c56a93..827af905964b 100644
--- a/pbl/entry.c
+++ b/pbl/entry.c
@@ -11,7 +11,11 @@
 #include <asm/reloc.h>
 #include <asm/sections.h>
 #include <asm-generic/registers.h>
+#include <console.h>
+#include <debug_ll.h>
+#include <stdio.h>
 #include <barebox.h>
+#include <pbl.h>
 #include <pbl/entry.h>
 #include <pbl/soc-type.h>
 #include <pbl/handoff-data.h>
@@ -136,6 +140,44 @@ pbl_head_reloc_v1(ulong stage_ul, ulong entry_data)
 	pbl_head_entry_v1(entry_data);
 }
 
+static void pbl_console_report_stage(int stage_idx)
+{
+	static bool stage_reported;
+	char stage_str[2] = "0";
+
+	if (stage_reported)
+		return;
+
+	stage_str[0] += stage_idx;
+
+	pbl_puts(stage_str);
+	pbl_puts(">");
+
+	stage_reported = true;
+}
+
+/* Called until there is a console, board_init may still describe it */
+static void pbl_console_init(const struct pbl_console *console,
+			     int stage_idx)
+{
+	static bool console_initialized;
+
+	if (console_initialized)
+		return;
+
+	if (console->setup)
+		console->setup(console->arg);
+
+	if (console->driver && console->driver->putc) {
+		pbl_set_putc(console->driver->putc, console->arg);
+		console_initialized = true;
+	}
+
+	/* Without PBL_CONSOLE, pbl_puts() is DEBUG_LL's puts_ll() */
+	if (console_initialized || !IS_ENABLED(CONFIG_PBL_CONSOLE))
+		pbl_console_report_stage(stage_idx);
+}
+
 /* noinline, so &__pbl_board_info isn't computed before relocation */
 static void noinline pbl_head_entry_v1(ulong entry_data)
 {
@@ -154,12 +196,35 @@ static void noinline pbl_head_entry_v1(ulong entry_data)
 
 	current_stage = stage;
 
+	/* A console needing no setup is readily usable in soc_init */
+	if (!pbi->console.setup)
+		pbl_console_init(&pbi->console, stage_idx);
+
 	if (stage->soc_init)
 		stage->soc_init();
+
+	/* Initialize console if possible */
+	pbl_console_init(&pbi->console, stage_idx);
+
+	if (stage->soc_init)
+		pbl_debug("soc_init done\n");
+
 	if (stage->board_init)
 		stage->board_init(entry_data);
-	if (stage->soc_chainload)
+
+	/* Initialize console if possible */
+	pbl_console_init(&pbi->console, stage_idx);
+
+	/* Without a console, the stage goes to the DEBUG_LL fallback */
+	pbl_console_report_stage(stage_idx);
+
+	if (stage->board_init)
+		pbl_debug("board_init done\n");
+
+	if (stage->soc_chainload) {
+		pbl_debug("Chainloading..\n");
 		stage->soc_chainload(stage->board_data);
+	}
 
 	hang();
 }
-- 
2.47.3




  parent reply	other threads:[~2026-10-27  7:45 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-27  7:24 [RFC PATCH 00/17] Switch RISC-V to declarative entry points Ahmad Fatoum
2026-10-27  7:24 ` [RFC PATCH 01/17] asm-generic: add registers.h with a pc_inside() helper Ahmad Fatoum
2026-10-27  7:24 ` [RFC PATCH 02/17] RISC-V: add call_with_stack() helper Ahmad Fatoum
2026-10-27  7:24 ` [RFC PATCH 03/17] RISC-V: implement relocate_to_adr_full() Ahmad Fatoum
2026-10-27  7:24 ` [RFC PATCH 04/17] PBL: add SoC type declaration and handoff support Ahmad Fatoum
2026-10-27  7:24 ` [RFC PATCH 05/17] PBL: introduce board info based entry point framework Ahmad Fatoum
2026-10-27  7:24 ` Ahmad Fatoum [this message]
2026-10-27  7:24 ` [RFC PATCH 07/17] RISC-V: make barebox_riscv_entry() non-naked Ahmad Fatoum
2026-10-27  7:24 ` [RFC PATCH 08/17] RISC-V: add PBL heads for the board info stage dispatch Ahmad Fatoum
2026-10-27  7:24 ` [RFC PATCH 09/17] RISC-V: board-dt-2nd: migrate to board info entry point Ahmad Fatoum
2026-10-27  7:24 ` [RFC PATCH 10/17] RISC-V: hifive: " Ahmad Fatoum
2026-10-27  7:24 ` [RFC PATCH 11/17] RISC-V: allow relocating the PBL more than once Ahmad Fatoum
2026-10-27  7:24 ` [RFC PATCH 12/17] RISC-V: nmon: preserve s1-s3 for the caller Ahmad Fatoum
2026-10-27  7:24 ` [RFC PATCH 13/17] RISC-V: beaglev: migrate to board info entry point Ahmad Fatoum
2026-10-27  7:24 ` [RFC PATCH 14/17] RISC-V: allwinner-d1: " Ahmad Fatoum
2026-10-27  7:24 ` [RFC PATCH 15/17] RISC-V: erizo: " Ahmad Fatoum
2026-10-27  7:24 ` [RFC PATCH 16/17] RISC-V: litex-linux: " Ahmad Fatoum
2026-10-27  7:24 ` [RFC PATCH 17/17] Documentation: porting: describe the " Ahmad Fatoum

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261027074014.3280396-7-a.fatoum@barebox.org \
    --to=a.fatoum@barebox.org \
    --cc=barebox@lists.infradead.org \
    --cc=mfe@pengutronix.de \
    --cc=mtr@pengutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox