From c45dc4a55da7bb1ddcd0a9d4a55ed6b4d5afe086 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Mon, 12 May 2025 12:21:14 +0100 Subject: [PATCH] [riscv] Allow apply_relocs() to use non-inline relocation records The address of the compressed relocation records is currently calculated implicitly relative to the program counter. This requires the relocation records to be copied as part of relocation to a new physical address, so that they can be reapplied (if needed) after copying iPXE to the new physical address. Since the relocation destination will never overlap the original iPXE image, and since the relocation records will not be needed further after completing relocation, we can avoid the need to copy the records by passing in a pointer to the relocation records present in the original iPXE image. Pass the compressed relocation record address as an explicit parameter to apply_relocs(), rather than being implicit in the program counter. Signed-off-by: Michael Brown --- src/arch/riscv/prefix/libprefix.S | 21 +++++++++++---------- src/arch/riscv/prefix/sbiprefix.S | 1 + 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/arch/riscv/prefix/libprefix.S b/src/arch/riscv/prefix/libprefix.S index 42e301e10..9a706af50 100644 --- a/src/arch/riscv/prefix/libprefix.S +++ b/src/arch/riscv/prefix/libprefix.S @@ -227,7 +227,9 @@ print_hex_value_alt: * records are overlaid with .bss). It does not require a valid stack * pointer. * - * Parameters: none (address is implicit in the program counter) + * Parameters: none + * + * a0 - Relocation records * * Returns: none * @@ -241,27 +243,26 @@ print_hex_value_alt: apply_relocs: /* Register usage: * - * a0 - relocation addend + * a0 - current relocation record pointer * a1 - current relocation target address - * a2 - current relocation record pointer + * a2 - relocation addend * a3 - current relocation record value * a4 - number of bits remaining in current relocation record */ la a1, _prefix - la a2, _edata /* Calculate relocation addend */ - LOADN a0, prefix_virt - sub a0, a1, a0 + LOADN a2, prefix_virt + sub a2, a1, a2 /* Skip applying relocations if addend is zero */ - beqz a0, apply_relocs_done + beqz a2, apply_relocs_done progress " reloc" apply_relocs_loop: /* Read new relocation record */ - LOADN a3, (a2) - addi a2, a2, ( __riscv_xlen / 8 ) + LOADN a3, (a0) + addi a0, a0, ( __riscv_xlen / 8 ) li a4, ( __riscv_xlen - 1 ) /* Consume and apply skip, if present (i.e. if MSB=0) */ @@ -275,7 +276,7 @@ apply_relocs_loop: 1: andi t0, a3, 1 beqz t0, 2f LOADN t1, (a1) - add t1, t1, a0 + add t1, t1, a2 STOREN t1, (a1) 2: addi a1, a1, ( __riscv_xlen / 8 ) srli a3, a3, 1 diff --git a/src/arch/riscv/prefix/sbiprefix.S b/src/arch/riscv/prefix/sbiprefix.S index 3885c77be..e83167602 100644 --- a/src/arch/riscv/prefix/sbiprefix.S +++ b/src/arch/riscv/prefix/sbiprefix.S @@ -66,6 +66,7 @@ _sbi_start: progress "\nSBI->iPXE" /* Apply dynamic relocations */ + la a0, _edata call apply_relocs progress " .reloc"