[PATCH v3 2/8] ARM/ARM64/RISC-V: pbl: add constructor support

Stefan Kerkmann <[email protected]>
Newsgroups org.infradead.lists.barebox
Message-ID <20260817-feature-pbl-get-time-ns-v3-2-9874c1438855@pengutronix.de>
This commit allows running functions marked with
__attribute__((constructor))[1] automatically after the C environment is
setup in setup_c, which most likely will be early setup code shared
across SoCs/Arches in the PBL.

[1]: https://gcc.gnu.org/onlinedocs/gcc-16.2.0/gcc/Common-Attributes.html#index-constructor

Signed-off-by: Stefan Kerkmann <[email protected]>
---
 arch/arm/cpu/setupc_32.S       |  3 +++
 arch/arm/cpu/setupc_64.S       |  3 +++
 arch/arm/lib/pbl.lds.S         |  8 ++++++++
 arch/riscv/lib/pbl.lds.S       |  9 +++++++++
 arch/riscv/lib/setupc.S        |  3 +++
 include/asm-generic/sections.h |  2 ++
 pbl/Makefile                   |  1 +
 pbl/ctors.c                    | 13 +++++++++++++
 8 files changed, 42 insertions(+)

diff --git a/arch/arm/cpu/setupc_32.S b/arch/arm/cpu/setupc_32.S
index fadfc28ae1..f34b144556 100644
--- a/arch/arm/cpu/setupc_32.S
+++ b/arch/arm/cpu/setupc_32.S
@@ -23,6 +23,9 @@ ENTRY(setup_c)
 	ldr	r0, =bss_cleared
 	mov	r1, #1
 	str	r1, [r0]		/* mark bss cleared */
+#ifdef __PBL__
+	bl	pbl_do_ctors
+#endif
 1:	pop	{r4, pc}
 ENDPROC(setup_c)
 
diff --git a/arch/arm/cpu/setupc_64.S b/arch/arm/cpu/setupc_64.S
index a0767c5136..e3c6149e27 100644
--- a/arch/arm/cpu/setupc_64.S
+++ b/arch/arm/cpu/setupc_64.S
@@ -22,6 +22,9 @@ ENTRY(setup_c)
 	adr_l	x0, bss_cleared
 	mov	w1, #1
 	str	w1, [x0]		/* mark bss cleared */
+#ifdef __PBL__
+	bl	pbl_do_ctors
+#endif
 	mov	x30, x15
 1:	ret
 ENDPROC(setup_c)
diff --git a/arch/arm/lib/pbl.lds.S b/arch/arm/lib/pbl.lds.S
index 9c51f5eb3a..72aca83495 100644
--- a/arch/arm/lib/pbl.lds.S
+++ b/arch/arm/lib/pbl.lds.S
@@ -78,6 +78,14 @@ SECTIONS
 	. = ALIGN(4);
 	.rodata : { *(.rodata*) }
 
+	. = ALIGN(ASM_SZPTR);
+	__ctors_start = .;
+	.init_array : {
+		KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*)))
+		KEEP(*(.init_array))
+	}
+	__ctors_end = .;
+
 	.barebox_imd : { BAREBOX_IMD }
 
 	. = ALIGN(PBL_SEGMENT_ALIGN);
diff --git a/arch/riscv/lib/pbl.lds.S b/arch/riscv/lib/pbl.lds.S
index 3a37d01475..17cd61ff75 100644
--- a/arch/riscv/lib/pbl.lds.S
+++ b/arch/riscv/lib/pbl.lds.S
@@ -4,6 +4,7 @@
 #include <linux/sizes.h>
 #include <asm/barebox.lds.h>
 #include <asm-generic/memory_layout.h>
+#include <asm-generic/pointer.h>
 
 OUTPUT_ARCH(BAREBOX_OUTPUT_ARCH)
 OUTPUT_FORMAT(BAREBOX_OUTPUT_FORMAT)
@@ -32,6 +33,14 @@ SECTIONS
 	__start_rodata = .;
 	.rodata : { *(.rodata*) }
 
+	. = ALIGN(ASM_SZPTR);
+	__ctors_start = .;
+	.init_array : {
+		KEEP(*(SORT_BY_INIT_PRIORITY(.init_array.*)))
+		KEEP(*(.init_array))
+	}
+	__ctors_end = .;
+
 	.barebox_imd : { BAREBOX_IMD }
 
 	__end_rodata = .;
diff --git a/arch/riscv/lib/setupc.S b/arch/riscv/lib/setupc.S
index 5370e8a48e..938c78350c 100644
--- a/arch/riscv/lib/setupc.S
+++ b/arch/riscv/lib/setupc.S
@@ -23,6 +23,9 @@ ENTRY(setup_c)
 	lla	a0, bss_cleared
 	li	a1, 1
 	sw	a1, 0(a0)
+#ifdef __PBL__
+	jal	pbl_do_ctors
+#endif
 zeroed:
 	REG_L	ra, SZREG(sp)
 	addi	sp, sp, SZREG * 2
diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
index 816e30341d..c7c576970a 100644
--- a/include/asm-generic/sections.h
+++ b/include/asm-generic/sections.h
@@ -49,4 +49,6 @@ static inline bool in_barebox_efi_runtime(unsigned long addr)
 	       addr < (unsigned long)__efi_runtime_stop;
 }
 
+void pbl_do_ctors(void);
+
 #endif /* _ASM_GENERIC_SECTIONS_H_ */
diff --git a/pbl/Makefile b/pbl/Makefile
index 4506f192fe..7ce8cee077 100644
--- a/pbl/Makefile
+++ b/pbl/Makefile
@@ -3,6 +3,7 @@
 #
 # only unsed by the pbl
 #
+pbl-y += ctors.o
 pbl-y += misc.o
 pbl-y += string.o
 pbl-y += malloc.o
diff --git a/pbl/ctors.c b/pbl/ctors.c
new file mode 100644
index 0000000000..fcab599877
--- /dev/null
+++ b/pbl/ctors.c
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <asm-generic/sections.h>
+
+typedef void (*ctor_fn_t)(void);
+
+void pbl_do_ctors(void)
+{
+	ctor_fn_t *fn = (ctor_fn_t *)__ctors_start;
+
+	for (; fn < (ctor_fn_t *)__ctors_end; fn++)
+		(*fn)();
+}

-- 
2.47.3
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.