diff options
Diffstat (limited to 'src/arch/riscv/prefix/sbiprefix.S')
-rw-r--r-- | src/arch/riscv/prefix/sbiprefix.S | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/src/arch/riscv/prefix/sbiprefix.S b/src/arch/riscv/prefix/sbiprefix.S new file mode 100644 index 000000000..0de001951 --- /dev/null +++ b/src/arch/riscv/prefix/sbiprefix.S @@ -0,0 +1,156 @@ +/* + * Copyright (C) 2024 Michael Brown <mbrown@fensystems.co.uk>. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + * + * You can also choose to distribute this program under the terms of + * the Unmodified Binary Distribution Licence (as given in the file + * COPYING.UBDL), provided that you have satisfied its requirements. + */ + + FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ) + +/** @file + * + * SBI position-independent executable prefix + * + */ + + .section ".note.GNU-stack", "", @progbits + .text + +/* SBI debug console extension */ +#define SBI_DBCN ( ( 'D' << 24 ) | ( 'B' << 16 ) | ( 'C' << 8 ) | 'N' ) +#define SBI_DBCN_WRITE 0x00 + +/* SBI system reset extension */ +#define SBI_SRST ( ( 'S' << 24 ) | ( 'R' << 16 ) | ( 'S' << 8 ) | 'T' ) +#define SBI_SRST_SYSTEM_RESET 0x00 +#define SBI_RESET_COLD 0x00000001 + +/* Relative relocation type */ +#define R_RISCV_RELATIVE 3 + + /* Layout of a relocation record */ + .struct 0 +rela_offset: .space ( __riscv_xlen / 8 ) +rela_type: .space ( __riscv_xlen / 8 ) +rela_addend: .space ( __riscv_xlen / 8 ) +rela_len: + .previous + + /* + * Display progress message via debug console + */ + .macro progress message +#ifndef NDEBUG + .section ".prefix.data", "aw", @progbits +progress_\@: + .ascii "\message" + .equ progress_\@_len, . - progress_\@ + .size progress_\@, . - progress_\@ + .previous + li a7, SBI_DBCN + li a6, SBI_DBCN_WRITE + li a0, progress_\@_len + la a1, progress_\@ + mv a2, zero + ecall +#endif + .endm + + /* + * SBI entry point + */ + .section ".prefix", "ax", @progbits + .org 0 + .globl _sbi_start +_sbi_start: + /* Preserve arguments */ + mv s0, a0 + mv s1, a1 + progress "\nSBI->iPXE" + + /* Apply dynamic relocations */ + la t0, _reloc + la t1, _ereloc + la t2, _sbi_start +1: /* Read relocation record */ + LOADN t3, rela_offset(t0) + LOADN t4, rela_type(t0) + LOADN t5, rela_addend(t0) + /* Check relocation type */ + addi t4, t4, -R_RISCV_RELATIVE + bnez t4, 2f + /* Apply relocation */ + add t3, t3, t2 + add t5, t5, t2 + STOREN t5, (t3) +2: /* Loop */ + addi t0, t0, rela_len + blt t0, t1, 1b + progress " .reloc" + + /* Zero the bss */ + la t0, _bss + la t1, _ebss +1: STOREN zero, (t0) + addi t0, t0, ( __riscv_xlen / 8 ) + blt t0, t1, 1b + progress " .bss" + + /* Set up stack */ + la sp, _estack + progress " .stack" + + /* Store boot hart */ + la t0, boot_hart + STOREN s0, (t0) + + /* Register device tree */ + mv a0, s1 + call register_fdt + + /* Call main program */ + progress "\n\n" + call main + + /* We have no return path, since the M-mode SBI implementation + * will have jumped to us by setting our start address in MEPC + * and issuing an MRET instruction. + * + * Attempt a system reset, since there is nothing else we can + * viably do at this point. + */ + progress "\niPXE->SBI reset\n" + li a7, SBI_SRST + li a6, SBI_SRST_SYSTEM_RESET + li a0, SBI_RESET_COLD + mv a1, zero + ecall + + /* If reset failed, lock the system */ + progress "(reset failed)\n" +1: wfi + j 1b + .size _sbi_start, . - _sbi_start + + /* File split information for the compressor */ + .section ".zinfo", "a", @progbits + .ascii "COPY" + .word 0 + .word _sbi_filesz + .word 1 |