summaryrefslogtreecommitdiffstats
path: root/pbl
diff options
context:
space:
mode:
authorAhmad Fatoum <a.fatoum@pengutronix.de>2023-09-07 10:21:26 +0200
committerSascha Hauer <s.hauer@pengutronix.de>2023-09-08 08:58:29 +0200
commit34b36519d7535d9de34ad09facd82ddc2140b3fc (patch)
tree1565d22876d412cfd10743cc2ae579a60f4fa714 /pbl
parent44080977545a2cf75844ee4701121688db688173 (diff)
downloadbarebox-34b36519d7535d9de34ad09facd82ddc2140b3fc.tar.gz
barebox-34b36519d7535d9de34ad09facd82ddc2140b3fc.tar.xz
console: pbl: correctly handle relocate_to_adr after pbl_set_putc
pbl_set_putc may be called by a PBL entry point to store the absolute address of a routine to be used for printing out a character. If barebox happens to be located outside of the initially known RAM, it will be relocated into it by means of relocate_to_adr(), but nothing will take care to update the function pointer stored by pbl_set_putc. This will usually continue to work until barebox sets up the MMU and everything not known to be RAM is marked as eXecute Never. After that, the next PBL console print will trigger an instruction abort. Fix this by not storing the putc function pointer, but instead an offset relative to _text. This is the second part of fixing barebox hanging on i.MX8M when located at an address greater than 4G. This change has been tested on both i.MX8M (AArch64) and i.MX6 (Thumb2). Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de> Link: https://lore.barebox.org/20230907082126.2326381-3-a.fatoum@pengutronix.de Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'pbl')
-rw-r--r--pbl/console.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/pbl/console.c b/pbl/console.c
index 1a6e839c15..d81bf580d5 100644
--- a/pbl/console.c
+++ b/pbl/console.c
@@ -2,13 +2,14 @@
#include <common.h>
#include <debug_ll.h>
+#include <asm/sections.h>
#include <linux/err.h>
/*
* Put these in the data section so that they survive the clearing of the
* BSS segment.
*/
-static __attribute__ ((section(".data"))) void (*__putc)(void *ctx, int c);
+static __attribute__ ((section(".data"))) ulong putc_offset;
static __attribute__ ((section(".data"))) void *putc_ctx;
/**
@@ -21,13 +22,19 @@ static __attribute__ ((section(".data"))) void *putc_ctx;
*/
void pbl_set_putc(void (*putcf)(void *ctx, int c), void *ctx)
{
- __putc = putcf;
+ putc_offset = (ulong)putcf - (ulong)_text;
putc_ctx = ctx;
}
+static void __putc(void *ctx, int c)
+{
+ void (*putc)(void *, int) = (void *)_text + putc_offset;
+ putc(ctx, c);
+}
+
void console_putc(unsigned int ch, char c)
{
- if (__putc)
+ if (putc_offset)
__putc(putc_ctx, c);
else
putc_ll(c);