From db151e1302e4a1ae249bbcb622e6548b88762d7e Mon Sep 17 00:00:00 2001 From: William Vinnicombe Date: Mon, 1 Sep 2025 11:06:33 +0100 Subject: [PATCH] Add Risc-V crt0 data_cpy skip Also shrink Arm one, and standardise PICO_NO_FLASH skipped code between them --- src/rp2_common/pico_crt0/crt0.S | 33 +++++++--------- src/rp2_common/pico_crt0/crt0_riscv.S | 54 +++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 19 deletions(-) diff --git a/src/rp2_common/pico_crt0/crt0.S b/src/rp2_common/pico_crt0/crt0.S index 2193d5fa..4a78a8fb 100644 --- a/src/rp2_common/pico_crt0/crt0.S +++ b/src/rp2_common/pico_crt0/crt0.S @@ -554,29 +554,24 @@ data_cpy_check: // First check start of copy (r2) mov r7, r2 check_r7: - ldr r5, =(SRAM_BASE >> 16) - cmp r5, r7, lsr #16 + ldr r5, =SRAM_BASE + cmp r5, r7 bgt check_xip_sram - ldr r5, =(SRAM4_BASE >> 16) - cmp r5, r7, lsr #16 + ldr r5, =SRAM4_BASE + cmp r5, r7 bgt check_sram0 - b check_sram1 -check_xip_sram: - mov r5, #(1 << 2) // POWMAN_POWER_DOMAIN_XIP_CACHE - and r5, r6 - cmp r5, #(1 << 2) - beq skip - b noskip -check_sram0: - mov r5, #(1 << 1) // POWMAN_POWER_DOMAIN_SRAM_BANK0 - and r5, r6 - cmp r5, #(1 << 1) - beq skip - b noskip check_sram1: mov r5, #(1 << 0) // POWMAN_POWER_DOMAIN_SRAM_BANK1 - and r5, r6 - cmp r5, #(1 << 0) + b do_check +check_xip_sram: + mov r5, #(1 << 2) // POWMAN_POWER_DOMAIN_XIP_CACHE + b do_check +check_sram0: + mov r5, #(1 << 1) // POWMAN_POWER_DOMAIN_SRAM_BANK0 + b do_check +do_check: + and r7, r5, r6 + cmp r5, r7 beq skip b noskip skip: diff --git a/src/rp2_common/pico_crt0/crt0_riscv.S b/src/rp2_common/pico_crt0/crt0_riscv.S index e9fc7d94..6d87fb5f 100644 --- a/src/rp2_common/pico_crt0/crt0_riscv.S +++ b/src/rp2_common/pico_crt0/crt0_riscv.S @@ -12,6 +12,10 @@ #include "boot/picobin.h" #include "pico/bootrom_constants.h" +#if !PICO_RP2040 +#include "hardware/regs/powman.h" +#endif + #ifdef NDEBUG #ifndef COLLAPSE_IRQS #define COLLAPSE_IRQS @@ -341,6 +345,11 @@ _call_xip_setup: // In a NO_FLASH binary, don't perform .data etc copy, since it's loaded // in-place by the SRAM load. Still need to clear .bss #if !PICO_NO_FLASH +#if LIB_PICO_LOW_POWER && !PICO_RP2040 + // Load previous power state into r6 + li a6, POWMAN_BASE+POWMAN_SCRATCH6_OFFSET + lw a6, 0(a6) +#endif la a4, data_cpy_table // assume there is at least one entry @@ -350,6 +359,10 @@ _call_xip_setup: lw a2, 4(a4) lw a3, 8(a4) addi a4, a4, 12 +#if LIB_PICO_LOW_POWER && !PICO_RP2040 + jal data_cpy_check + bnez a0, 1b +#endif jal data_cpy j 1b 2: @@ -379,6 +392,8 @@ platform_entry: // symbol for stack traces ebreak j 1b + +#if !PICO_NO_FLASH data_cpy_loop: lw a0, (a1) sw a0, (a2) @@ -388,6 +403,45 @@ data_cpy: bltu a2, a3, data_cpy_loop ret +#if LIB_PICO_LOW_POWER && !PICO_RP2040 +data_cpy_check: + // uses a5 and a7 as scratch + // uses the powman_power_state in a6 + // returns in a0 + li a0, 0 + // First check start of copy (a2) + mv a7, a2 +check_a7: + li a5, SRAM_BASE + bgt a5, a7, check_xip_sram + li a5, SRAM4_BASE + bgt a5, a7, check_sram0 +check_sram1: + li a5, 1 << 0 // POWMAN_POWER_DOMAIN_SRAM_BANK1 + j do_check +check_xip_sram: + li a5, 1 << 2 // POWMAN_POWER_DOMAIN_XIP_CACHE + j do_check +check_sram0: + li a5, 1 << 1 // POWMAN_POWER_DOMAIN_SRAM_BANK0 + j do_check +do_check: + and a7, a5, a6 + beq a5, a7, skip + j noskip +skip: + beqz a0, check_end + ret +check_end: + addi a0, a0, 1 + mv a7, a3 + j check_a7 +noskip: + li a0, 0 + ret +#endif +#endif + .align 2 data_cpy_table: #if PICO_RP2350 && PICO_EMBED_XIP_SETUP && !PICO_NO_FLASH