diff options
Diffstat (limited to 'riscv/riscv/boothdr.S')
-rw-r--r-- | riscv/riscv/boothdr.S | 222 |
1 files changed, 222 insertions, 0 deletions
diff --git a/riscv/riscv/boothdr.S b/riscv/riscv/boothdr.S new file mode 100644 index 0000000..7c24c47 --- /dev/null +++ b/riscv/riscv/boothdr.S @@ -0,0 +1,222 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2012 Regents of the University of California + */ + + +#include <asm/asm-offsets.h> +#include <asm/asm.h> +#include <asm/thread_info.h> +#include <asm/page.h> +#include <asm/pgtable.h> +#include <asm/csr.h> +#include <asm/cpu_ops_sbi.h> +#include <asm/hwcap.h> +#include <asm/image.h> +#include <asm/scs.h> +#include <asm/xip_fixup.h> +#include "const.h" + +.section .startup, "ax" +.global _start + +_start: + j _start_kernel + /* reserved */ + .word 0 + +_start_kernel: + /* Mask all interrupts */ + csrw CSR_IE, zero + csrw CSR_IP, zero + + /* flush the instruction cache */ + fence.i + + /* Reset all registers except ra, a0, a1 */ + call reset_regs + + // testing + .cfi_startproc + .cfi_undefined ra + .option push + .option norelax + la gp, __global_pointer$ + .option pop + la sp, __stack_top + jal zero, c_boot_entry + .cfi_endproc + // testing + + /* + * Setup a PMP to permit access to all of memory. Some machines may + * not implement PMPs, so we set up a quick trap handler to just skip + * touching the PMPs on any trap. + */ + la a0, .Lpmp_done + csrw CSR_TVEC, a0 + + li a0, -1 + csrw CSR_PMPADDR0, a0 + li a0, (PMP_A_NAPOT | PMP_R | PMP_W | PMP_X) + csrw CSR_PMPCFG0, a0 + + +.align 2 + +.Lpmp_done: + /* + * The hartid in a0 is expected later on, and we have no firmware + * to hand it to us. + */ + csrr a0, CSR_MHARTID + + /* Load the global pointer */ + load_global_pointer + + /* + * Disable FPU & VECTOR to detect illegal usage of + * floating point or vector in kernel space + */ + li t0, SR_FS_VS + csrc CSR_STATUS, t0 + +#ifdef CONFIG_RISCV_BOOT_SPINWAIT + li t0, CONFIG_NR_CPUS + blt a0, t0, .Lgood_cores + tail .Lsecondary_park +.Lgood_cores: + /* hart_lottery in flash contains a magic number */ + la a3, hart_lottery + mv a2, a3 + XIP_FIXUP_OFFSET a2 + XIP_FIXUP_FLASH_OFFSET a3 + lw t1, (a3) + amoswap.w t0, t1, (a2) + /* first time here if hart_lottery in RAM is not set */ + beq t0, t1, .Lsecondary_start +#endif /* CONFIG_RISCV_BOOT_SPINWAIT */ + + /* Clear BSS for flat non-ELF images */ + /* __bss_start */ + la a3, _start + /* __bss_stop */ + la a4, _end + ble a4, a3, .Lclear_bss_done +.Lclear_bss: + REG_S zero, (a3) + add a3, a3, RISCV_SZPTR + blt a3, a4, .Lclear_bss +.Lclear_bss_done: + la a2, boot_cpu_hartid + XIP_FIXUP_OFFSET a2 + REG_S a0, (a2) + + /* Initialize page tables and relocate to virtual addresses */ + //la tp, init_task + //la sp, init_thread_union + THREAD_SIZE + //XIP_FIXUP_OFFSET sp + //addi sp, sp, -PT_SIZE_ON_STACK + //scs_load_init_stack + + +reset_regs: + li sp, 0 + li gp, 0 + li tp, 0 + li t0, 0 + li t1, 0 + li t2, 0 + li s0, 0 + li s1, 0 + li a2, 0 + li a3, 0 + li a4, 0 + li a5, 0 + li a6, 0 + li a7, 0 + li s2, 0 + li s3, 0 + li s4, 0 + li s5, 0 + li s6, 0 + li s7, 0 + li s8, 0 + li s9, 0 + li s10, 0 + li s11, 0 + li t3, 0 + li t4, 0 + li t5, 0 + li t6, 0 + csrw CSR_SCRATCH, 0 + +#ifdef CONFIG_FPU + csrr t0, CSR_MISA + andi t0, t0, (COMPAT_HWCAP_ISA_F | COMPAT_HWCAP_ISA_D) + beqz t0, .Lreset_regs_done_fpu + + li t1, SR_FS + csrs CSR_STATUS, t1 + fmv.s.x f0, zero + fmv.s.x f1, zero + fmv.s.x f2, zero + fmv.s.x f3, zero + fmv.s.x f4, zero + fmv.s.x f5, zero + fmv.s.x f6, zero + fmv.s.x f7, zero + fmv.s.x f8, zero + fmv.s.x f9, zero + fmv.s.x f10, zero + fmv.s.x f11, zero + fmv.s.x f12, zero + fmv.s.x f13, zero + fmv.s.x f14, zero + fmv.s.x f15, zero + fmv.s.x f16, zero + fmv.s.x f17, zero + fmv.s.x f18, zero + fmv.s.x f19, zero + fmv.s.x f20, zero + fmv.s.x f21, zero + fmv.s.x f22, zero + fmv.s.x f23, zero + fmv.s.x f24, zero + fmv.s.x f25, zero + fmv.s.x f26, zero + fmv.s.x f27, zero + fmv.s.x f28, zero + fmv.s.x f29, zero + fmv.s.x f30, zero + fmv.s.x f31, zero + csrw fcsr, 0 + /* note that the caller must clear SR_FS */ +.Lreset_regs_done_fpu: +#endif /* CONFIG_FPU */ + +#ifdef CONFIG_RISCV_ISA_V + csrr t0, CSR_MISA + li t1, COMPAT_HWCAP_ISA_V + and t0, t0, t1 + beqz t0, .Lreset_regs_done_vector + + /* + * Clear vector registers and reset vcsr + * VLMAX has a defined value, VLEN is a constant, + * and this form of vsetvli is defined to set vl to VLMAX. + */ + li t1, SR_VS + csrs CSR_STATUS, t1 + csrs CSR_VCSR, x0 + vsetvli t1, x0, e8, m8, ta, ma + vmv.v.i v0, 0 + vmv.v.i v8, 0 + vmv.v.i v16, 0 + vmv.v.i v24, 0 + /* note that the caller must clear SR_VS */ + .Lreset_regs_done_vector: +#endif /* CONFIG_RISCV_ISA_V */ + ret + +.end |