* [PATCH 0/2] ARM: Avoid to clear bss multiple times
@ 2026-02-26 12:23 Sascha Hauer
2026-02-26 12:23 ` [PATCH 1/2] ARM: setupc_32: remove relocation code from setup_c Sascha Hauer
2026-02-26 12:23 ` [PATCH 2/2] ARM: setup_c: avoid clearing BSS twice Sascha Hauer
0 siblings, 2 replies; 4+ messages in thread
From: Sascha Hauer @ 2026-02-26 12:23 UTC (permalink / raw)
To: BAREBOX; +Cc: Claude Opus 4.6
Currently we clear the bss everytime we call setup_c(). We can do better
and clear it only once which makes for example alloc_pte() in the PBL
MMU setup preserve its state and we can call mmu_early_enable() multiple
times without harm.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
Sascha Hauer (2):
ARM: setupc_32: remove relocation code from setup_c
ARM: setup_c: avoid clearing BSS twice
arch/arm/cpu/common.c | 2 ++
arch/arm/cpu/setupc_32.S | 35 +++++++++++++----------------------
arch/arm/cpu/setupc_64.S | 10 ++++++++--
3 files changed, 23 insertions(+), 24 deletions(-)
---
base-commit: bd5518cd7e34861706f87c8ca67b640d6257d5b8
change-id: 20260226-arm-setup-c-30f0dccdde71
Best regards,
--
Sascha Hauer <s.hauer@pengutronix.de>
^ permalink raw reply [flat|nested] 4+ messages in thread* [PATCH 1/2] ARM: setupc_32: remove relocation code from setup_c 2026-02-26 12:23 [PATCH 0/2] ARM: Avoid to clear bss multiple times Sascha Hauer @ 2026-02-26 12:23 ` Sascha Hauer 2026-02-26 12:23 ` [PATCH 2/2] ARM: setup_c: avoid clearing BSS twice Sascha Hauer 1 sibling, 0 replies; 4+ messages in thread From: Sascha Hauer @ 2026-02-26 12:23 UTC (permalink / raw) To: BAREBOX; +Cc: Claude Opus 4.6 All callers of setup_c() already call relocate_to_current_adr() or relocate_to_adr() before setup_c(), so the relocation (memcpy) code in setup_c is dead and also the sync_caches_for_execution() is unnecessary Remove it and reduce setup_c to just clearing BSS. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> --- arch/arm/cpu/setupc_32.S | 27 +++++---------------------- 1 file changed, 5 insertions(+), 22 deletions(-) diff --git a/arch/arm/cpu/setupc_32.S b/arch/arm/cpu/setupc_32.S index 0134637f62..c2c3f97528 100644 --- a/arch/arm/cpu/setupc_32.S +++ b/arch/arm/cpu/setupc_32.S @@ -7,33 +7,16 @@ .section .text.setupc /* - * setup_c: copy binary to link address, clear bss and - * continue executing at new address. - * - * This function does not return to the address it is - * called from, but to the same location in the copied - * binary. + * setup_c: clear bss */ ENTRY(setup_c) - push {r4, r5} - mov r5, lr - bl get_runtime_offset - subs r4, r0, #0 - beq 1f /* skip memcpy if already at correct address */ - ldr r0,=_text - ldr r2,=__bss_start - sub r2, r2, r0 - add r1, r0, r4 - bl __memcpy /* memcpy(_text, _text + offset, __bss_start - _text) */ -1: ldr r0, =__bss_start + mov r4, lr + ldr r0, =__bss_start mov r1, #0 ldr r2, =__bss_stop sub r2, r2, r0 - bl __memset /* clear bss */ - bl sync_caches_for_execution - sub lr, r5, r4 /* adjust return address to new location */ - pop {r4, r5} - ret lr + bl __memset /* clear bss */ + ret r4 ENDPROC(setup_c) /* -- 2.47.3 ^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 2/2] ARM: setup_c: avoid clearing BSS twice 2026-02-26 12:23 [PATCH 0/2] ARM: Avoid to clear bss multiple times Sascha Hauer 2026-02-26 12:23 ` [PATCH 1/2] ARM: setupc_32: remove relocation code from setup_c Sascha Hauer @ 2026-02-26 12:23 ` Sascha Hauer 2026-03-02 7:01 ` Ahmad Fatoum 1 sibling, 1 reply; 4+ messages in thread From: Sascha Hauer @ 2026-02-26 12:23 UTC (permalink / raw) To: BAREBOX; +Cc: Claude Opus 4.6 Add a bss_cleared variable that is set after the first call to setup_c(). On subsequent calls, the BSS clear is skipped to avoid wiping already-initialized data. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> --- arch/arm/cpu/common.c | 2 ++ arch/arm/cpu/setupc_32.S | 10 +++++++++- arch/arm/cpu/setupc_64.S | 10 ++++++++-- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/arch/arm/cpu/common.c b/arch/arm/cpu/common.c index e86c89f808..40742894c2 100644 --- a/arch/arm/cpu/common.c +++ b/arch/arm/cpu/common.c @@ -77,6 +77,8 @@ int __pure cpu_architecture(void) } #endif +int bss_cleared; + extern int __boot_cpu_mode; int boot_cpu_mode(void) diff --git a/arch/arm/cpu/setupc_32.S b/arch/arm/cpu/setupc_32.S index c2c3f97528..d923a8f621 100644 --- a/arch/arm/cpu/setupc_32.S +++ b/arch/arm/cpu/setupc_32.S @@ -7,16 +7,24 @@ .section .text.setupc /* - * setup_c: clear bss + * setup_c: clear bss if not yet done */ ENTRY(setup_c) + ldr r0, =bss_cleared + ldr r1, [r0] + cmp r1, #0 + bne 1f /* skip if already done */ mov r4, lr ldr r0, =__bss_start mov r1, #0 ldr r2, =__bss_stop sub r2, r2, r0 bl __memset /* clear bss */ + ldr r0, =bss_cleared + mov r1, #1 + str r1, [r0] /* mark bss cleared */ ret r4 +1: ret lr ENDPROC(setup_c) /* diff --git a/arch/arm/cpu/setupc_64.S b/arch/arm/cpu/setupc_64.S index fd95187a04..8262deb512 100644 --- a/arch/arm/cpu/setupc_64.S +++ b/arch/arm/cpu/setupc_64.S @@ -7,17 +7,23 @@ .section .text.setupc /* - * setup_c: clear bss + * setup_c: clear bss if not yet done */ ENTRY(setup_c) + adr_l x0, bss_cleared + ldr w1, [x0] + cbnz w1, 1f /* skip if already done */ mov x15, x30 adr_l x0, __bss_start mov x1, #0 adr_l x2, __bss_stop sub x2, x2, x0 bl __memset /* clear bss */ + adr_l x0, bss_cleared + mov w1, #1 + str w1, [x0] /* mark bss cleared */ mov x30, x15 - ret +1: ret ENDPROC(setup_c) /* -- 2.47.3 ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH 2/2] ARM: setup_c: avoid clearing BSS twice 2026-02-26 12:23 ` [PATCH 2/2] ARM: setup_c: avoid clearing BSS twice Sascha Hauer @ 2026-03-02 7:01 ` Ahmad Fatoum 0 siblings, 0 replies; 4+ messages in thread From: Ahmad Fatoum @ 2026-03-02 7:01 UTC (permalink / raw) To: Sascha Hauer, BAREBOX; +Cc: Claude Opus 4.6 Hi, On 2/26/26 13:23, Sascha Hauer wrote: > Add a bss_cleared variable that is set after the first call to > setup_c(). On subsequent calls, the BSS clear is skipped to avoid > wiping already-initialized data. > > Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> > Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> > --- > arch/arm/cpu/common.c | 2 ++ > arch/arm/cpu/setupc_32.S | 10 +++++++++- > arch/arm/cpu/setupc_64.S | 10 ++++++++-- > 3 files changed, 19 insertions(+), 3 deletions(-) > > diff --git a/arch/arm/cpu/common.c b/arch/arm/cpu/common.c > index e86c89f808..40742894c2 100644 > --- a/arch/arm/cpu/common.c > +++ b/arch/arm/cpu/common.c > @@ -77,6 +77,8 @@ int __pure cpu_architecture(void) > } > #endif > > +int bss_cleared; This will go into BSS, so you implicitly assume BSS to be already zero as this is accessed first before BSS initialization. I suggest, along with moving it into the .data section, that you also move it into the assembly file, so the consumer is directly next to it: .pushsection .data .align 2 setup_c_done: .word 0 .popsection > + > extern int __boot_cpu_mode; > > int boot_cpu_mode(void) > diff --git a/arch/arm/cpu/setupc_32.S b/arch/arm/cpu/setupc_32.S > index c2c3f97528..d923a8f621 100644 > --- a/arch/arm/cpu/setupc_32.S > +++ b/arch/arm/cpu/setupc_32.S > @@ -7,16 +7,24 @@ > .section .text.setupc > > /* > - * setup_c: clear bss > + * setup_c: clear bss if not yet done > */ > ENTRY(setup_c) > + ldr r0, =bss_cleared > + ldr r1, [r0] > + cmp r1, #0 > + bne 1f /* skip if already done */ > mov r4, lr Move this instruction to the start, so ... > ldr r0, =__bss_start > mov r1, #0 > ldr r2, =__bss_stop > sub r2, r2, r0 > bl __memset /* clear bss */ > + ldr r0, =bss_cleared > + mov r1, #1 > + str r1, [r0] /* mark bss cleared */ > ret r4 > +1: ret lr This instruction can be dropped and 1: just points at the existing ret r4? > ENDPROC(setup_c) > > /* > diff --git a/arch/arm/cpu/setupc_64.S b/arch/arm/cpu/setupc_64.S > index fd95187a04..8262deb512 100644 > --- a/arch/arm/cpu/setupc_64.S > +++ b/arch/arm/cpu/setupc_64.S > @@ -7,17 +7,23 @@ > .section .text.setupc > > /* > - * setup_c: clear bss > + * setup_c: clear bss if not yet done > */ > ENTRY(setup_c) > + adr_l x0, bss_cleared > + ldr w1, [x0] > + cbnz w1, 1f /* skip if already done */ > mov x15, x30 > adr_l x0, __bss_start > mov x1, #0 > adr_l x2, __bss_stop > sub x2, x2, x0 > bl __memset /* clear bss */ > + adr_l x0, bss_cleared > + mov w1, #1 > + str w1, [x0] /* mark bss cleared */ > mov x30, x15 > - ret > +1: ret > ENDPROC(setup_c) > > /* > -- Pengutronix e.K. | | Steuerwalder Str. 21 | http://www.pengutronix.de/ | 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-03-02 7:02 UTC | newest] Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2026-02-26 12:23 [PATCH 0/2] ARM: Avoid to clear bss multiple times Sascha Hauer 2026-02-26 12:23 ` [PATCH 1/2] ARM: setupc_32: remove relocation code from setup_c Sascha Hauer 2026-02-26 12:23 ` [PATCH 2/2] ARM: setup_c: avoid clearing BSS twice Sascha Hauer 2026-03-02 7:01 ` Ahmad Fatoum
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox