URL
https://opencores.org/ocsvn/riscv_vhdl/riscv_vhdl/trunk
Subversion Repositories riscv_vhdl
[/] [riscv_vhdl/] [trunk/] [examples/] [boot/] [src/] [crt.S] - Rev 5
Compare with Previous | Blame | View Log
##! Register ABI Name Description Saver
##! x1 ra Return address Caller
##! x2 s0/fp Saved register/frame pointer Callee
##! x14 sp Stack pointer Callee
##! x15 tp Thread pointer Callee
#include "encoding.h"
.text
.align 4
.globl reset_vector
.globl _start
trap_table:
#define BAD_TRAP_VECTOR 0
.word bad_trap
.word bad_trap # pmp_trap
.word bad_trap # illegal_insn_trap
.word bad_trap
.word bad_trap # misaligned_load_trap
.word bad_trap # pmp_trap
.word bad_trap # misaligned_store_trap
.word bad_trap # pmp_trap
.word bad_trap
.word bad_trap # mcall_trap
.word bad_trap
.word bad_trap
.word bad_trap
#define TRAP_FROM_MACHINE_MODE_VECTOR 13
.word bad_trap # __trap_from_machine_mode
.word bad_trap
.word bad_trap
##! Disabling the compressed code
# .option norvc
reset_vector:
j _start
bad_trap:
j bad_trap
_start:
li x1, 0
li x2, 0
li x3, 0
li x4, 0
li x5, 0
li x6, 0
li x7, 0
li x8, 0
li x9, 0
li x10,0
li x11,0
li x12,0
li x13,0
li x14,0
li x15,0
li x16,0
li x17,0
li x18,0
li x19,0
li x20,0
li x21,0
li x22,0
li x23,0
li x24,0
li x25,0
li x26,0
li x27,0
li x28,0
li x29,0
li x30,0
li x31,0
##! csrs (pseudo asm instruction) - set bit
##! csrrs - atomic read and set bit
##! csrc (pseudo asm instruction) - clear bit
##! csrrc - atomic read and clear bit
li t0, 0x00001800 # MPP[12:11] = 0x3 (Previous to machine mode)
csrc mstatus, t0 # run tests in user mode = 0, by clearing bits
li t0, 0x00000008 # Enable irq in machine and user modes after execution of xRET
csrs mstatus, t0 # enable interrupts in user mode
#li t0, MSTATUS_FS;
#csrs mstatus, t0 # enable FPU
#li t0, MSTATUS_XS;
#csrs mstatus, t0 # enable accelerator
##! init mtvec register (see https://github.com/riscv/riscv-test-env/blob/master/p/riscv_test.h)
la t0, trap_entry
csrw mtvec, t0
li t0, 0x00000800
csrs mie, t0 # Enable External irq (ftom PLIC) for M mode
#if 0
##! see https://github.com/riscv/riscv-tests/benchmarks/common
csrr t0, mstatus
li t1, MSTATUS_XS
and t1, t0, t1
sw t1, have_vec, t2
## if that didn't stick, we don't have a FPU, so don't initialize it
li t1, MSTATUS_FS
and t1, t0, t1
beqz t1, 1f
#endif
# intialization when FPU enabled
#ifdef REMOVETHIS__riscv_hard_float
fssr x0
fmv.s.x f0, x0
fmv.s.x f1, x0
fmv.s.x f2, x0
fmv.s.x f3, x0
fmv.s.x f4, x0
fmv.s.x f5, x0
fmv.s.x f6, x0
fmv.s.x f7, x0
fmv.s.x f8, x0
fmv.s.x f9, x0
fmv.s.x f10,x0
fmv.s.x f11,x0
fmv.s.x f12,x0
fmv.s.x f13,x0
fmv.s.x f14,x0
fmv.s.x f15,x0
fmv.s.x f16,x0
fmv.s.x f17,x0
fmv.s.x f18,x0
fmv.s.x f19,x0
fmv.s.x f20,x0
fmv.s.x f21,x0
fmv.s.x f22,x0
fmv.s.x f23,x0
fmv.s.x f24,x0
fmv.s.x f25,x0
fmv.s.x f26,x0
fmv.s.x f27,x0
fmv.s.x f28,x0
fmv.s.x f29,x0
fmv.s.x f30,x0
fmv.s.x f31,x0
#endif
##! initialize global pointer (no need in it)
lui gp, 0x10000
##! get core id
csrr a0, mhartid # for now, assume only 1 core
li a1, 1
1:bgeu a0, a1, 1b
# Task stack pointer (tp) uses the same value as sp.
#define STACK_512KB 19
lui t0, 0x10000 # t0 = SRAM base address = 0x10000000 . lui = load upper immediate 20-bits
add sp, zero, 1 # sp = 1
sll sp, sp, STACK_512KB # sp = sp << 19 = 0x80000
add sp, t0, sp # sp = sp + 0x10000000 = 0x10080000
add tp, zero, sp # tp = sp + 0
## Use tp register to save/restore registers context on task switching
addi tp,tp,-256 # tp = tp - 256 = 0x1007ff00
# 1 KB for the tap stack + TLS. Add signed extended 12-bits to register
addi sp, sp, -1024 # sp = 0x1007fc00
# copy image 64 KB
jal _init
##! jump to entry point in SRAM = 0x10000000
##! 'meps' - Machine Exception Program Coutner
lui t0, 0x10000 # t0 = SRAM base address = 0x10000000 . lui = load upper immediate 20-bits
csrw mepc, t0
##! @see riscv-priv-spec-1.7.pdf. 3.2.1
##! After handling a trap, the ERET instruction is used to return to the privilege level at which the
##! trap occurred. In addition to manipulating the privilege stack as described in Section 3.1.5, ERET
##! sets the pc to the value stored in the Xepc register, where X is the privilege mode (S, H, or M) in
##! which the ERET instruction was executed.
mret
trap_entry:
##! module CSRFile rises io_fatc signal that is cause of the 'ptw.invalidate'.
fence
csrw mscratch, a0;
_save_context(tp)
## @brief Call function :
## long handle_trap(long cause, long epc, long long regs[32])
## a0 = argument 1: cause
## a1 = argument 2: mepc
## a2 = argument 3: pointer on stack
## @return a0 New instruction pointer offset
csrr a0, mcause
csrr a1, mepc
sd a1,COOP_REG_TP(tp)
mv a2, sp
# !!! Cannot reset external pending bits only via IrqController (page 28)
li t0, 0x00000800
csrc mip, t0 #csrc pseudo asm instruction clear CSR bit.
#[11] MEIP: machine pending external interrupt
jal handle_trap
# tp-offset in the context array is used to save mepc value. An it may be
# modified by isr handler during preemtive task switching.
ld a1,COOP_REG_TP(tp)
csrw mepc,a1
_restore_context(tp)
mret
.section ".tdata.begin"
.globl _tdata_begin
_tdata_begin:
.section ".tdata.end"
.globl _tdata_end
_tdata_end:
.section ".tbss.end"
.globl _tbss_end
_tbss_end: