You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

286 lines
7.5 KiB

// See LICENSE for license details
#ifndef ENTRY_S
#define ENTRY_S
#include "riscv_encoding.h"
#include "riscv_bits.h"
#include "n200_eclic.h"
#include "n200_timer.h"
###############################################
###############################################
# Disable Interrupt
#
.macro DISABLE_MIE
csrc CSR_MSTATUS, MSTATUS_MIE
.endm
###############################################
###############################################
#Save caller registers
.macro SAVE_CONTEXT
#ifdef __riscv_flen
#if (__riscv_flen==64 )
addi sp, sp, -20*REGBYTES - 20*FPREGBYTES
#else
addi sp, sp, -20*REGBYTES
#endif
#else
addi sp, sp, -20*REGBYTES
#endif
STORE x1, 0*REGBYTES(sp)
STORE x4, 1*REGBYTES(sp)
STORE x5, 2*REGBYTES(sp)
STORE x6, 3*REGBYTES(sp)
STORE x7, 4*REGBYTES(sp)
STORE x10, 5*REGBYTES(sp)
STORE x11, 6*REGBYTES(sp)
STORE x12, 7*REGBYTES(sp)
STORE x13, 8*REGBYTES(sp)
STORE x14, 9*REGBYTES(sp)
STORE x15, 10*REGBYTES(sp)
#ifndef __riscv_32e
STORE x16, 11*REGBYTES(sp)
STORE x17, 12*REGBYTES(sp)
STORE x28, 13*REGBYTES(sp)
STORE x29, 14*REGBYTES(sp)
STORE x30, 15*REGBYTES(sp)
STORE x31, 16*REGBYTES(sp)
#endif
#ifdef __riscv_flen
#if (__riscv_flen == 64)
FPSTORE f0, (20*REGBYTES + 0*FPREGBYTES)(sp)
FPSTORE f1, (20*REGBYTES + 1*FPREGBYTES)(sp)
FPSTORE f2, (20*REGBYTES + 2*FPREGBYTES)(sp)
FPSTORE f3, (20*REGBYTES + 3*FPREGBYTES)(sp)
FPSTORE f4, (20*REGBYTES + 4*FPREGBYTES)(sp)
FPSTORE f5, (20*REGBYTES + 5*FPREGBYTES)(sp)
FPSTORE f6, (20*REGBYTES + 6*FPREGBYTES)(sp)
FPSTORE f7, (20*REGBYTES + 7*FPREGBYTES)(sp)
FPSTORE f10, (20*REGBYTES + 8*FPREGBYTES)(sp)
FPSTORE f11, (20*REGBYTES + 9*FPREGBYTES)(sp)
FPSTORE f12, (20*REGBYTES + 10*FPREGBYTES)(sp)
FPSTORE f13, (20*REGBYTES + 11*FPREGBYTES)(sp)
FPSTORE f14, (20*REGBYTES + 12*FPREGBYTES)(sp)
FPSTORE f15, (20*REGBYTES + 13*FPREGBYTES)(sp)
FPSTORE f16, (20*REGBYTES + 14*FPREGBYTES)(sp)
FPSTORE f17, (20*REGBYTES + 15*FPREGBYTES)(sp)
FPSTORE f28, (20*REGBYTES + 16*FPREGBYTES)(sp)
FPSTORE f29, (20*REGBYTES + 17*FPREGBYTES)(sp)
FPSTORE f30, (20*REGBYTES + 18*FPREGBYTES)(sp)
FPSTORE f31, (20*REGBYTES + 19*FPREGBYTES)(sp)
#endif
#endif
.endm
###############################################
###############################################
#restore caller registers
.macro RESTORE_CONTEXT
LOAD x1, 0*REGBYTES(sp)
LOAD x4, 1*REGBYTES(sp)
LOAD x5, 2*REGBYTES(sp)
LOAD x6, 3*REGBYTES(sp)
LOAD x7, 4*REGBYTES(sp)
LOAD x10, 5*REGBYTES(sp)
LOAD x11, 6*REGBYTES(sp)
LOAD x12, 7*REGBYTES(sp)
LOAD x13, 8*REGBYTES(sp)
LOAD x14, 9*REGBYTES(sp)
LOAD x15, 10*REGBYTES(sp)
#ifndef __riscv_32e
LOAD x16, 11*REGBYTES(sp)
LOAD x17, 12*REGBYTES(sp)
LOAD x28, 13*REGBYTES(sp)
LOAD x29, 14*REGBYTES(sp)
LOAD x30, 15*REGBYTES(sp)
LOAD x31, 16*REGBYTES(sp)
#endif
#ifdef __riscv_flen
#if (__riscv_flen==64)
/* Restore fp caller registers */
FPLOAD f0, (20*REGBYTES + 0*FPREGBYTES)(sp)
FPLOAD f1, (20*REGBYTES + 1*FPREGBYTES)(sp)
FPLOAD f2, (20*REGBYTES + 2*FPREGBYTES)(sp)
FPLOAD f3, (20*REGBYTES + 3*FPREGBYTES)(sp)
FPLOAD f4, (20*REGBYTES + 4*FPREGBYTES)(sp)
FPLOAD f5, (20*REGBYTES + 5*FPREGBYTES)(sp)
FPLOAD f6, (20*REGBYTES + 6*FPREGBYTES)(sp)
FPLOAD f7, (20*REGBYTES + 7*FPREGBYTES)(sp)
FPLOAD f10, (20*REGBYTES + 8*FPREGBYTES)(sp)
FPLOAD f11, (20*REGBYTES + 9*FPREGBYTES)(sp)
FPLOAD f12, (20*REGBYTES + 10*FPREGBYTES)(sp)
FPLOAD f13, (20*REGBYTES + 11*FPREGBYTES)(sp)
FPLOAD f14, (20*REGBYTES + 12*FPREGBYTES)(sp)
FPLOAD f15, (20*REGBYTES + 13*FPREGBYTES)(sp)
FPLOAD f16, (20*REGBYTES + 14*FPREGBYTES)(sp)
FPLOAD f17, (20*REGBYTES + 15*FPREGBYTES)(sp)
FPLOAD f28, (20*REGBYTES + 16*FPREGBYTES)(sp)
FPLOAD f29, (20*REGBYTES + 17*FPREGBYTES)(sp)
FPLOAD f30, (20*REGBYTES + 18*FPREGBYTES)(sp)
FPLOAD f31, (20*REGBYTES + 19*FPREGBYTES)(sp)
#endif
#endif
#ifdef __riscv_flen
#if(__riscv_flen == 64 )
addi sp, sp, 20*REGBYTES + 20*FPREGBYTES
#else
addi sp, sp, 20*REGBYTES
#endif
#else
// De-allocate the stack space
addi sp, sp, 20*REGBYTES
#endif
.endm
###############################################
###############################################
#restore caller registers
.macro RESTORE_CONTEXT_EXCPT_X5
LOAD x1, 0*REGBYTES(sp)
LOAD x6, 2*REGBYTES(sp)
LOAD x7, 3*REGBYTES(sp)
LOAD x10, 4*REGBYTES(sp)
LOAD x11, 5*REGBYTES(sp)
LOAD x12, 6*REGBYTES(sp)
LOAD x13, 7*REGBYTES(sp)
LOAD x14, 8*REGBYTES(sp)
LOAD x15, 9*REGBYTES(sp)
#ifndef __riscv_32e
LOAD x16, 10*REGBYTES(sp)
LOAD x17, 11*REGBYTES(sp)
LOAD x28, 12*REGBYTES(sp)
LOAD x29, 13*REGBYTES(sp)
LOAD x30, 14*REGBYTES(sp)
LOAD x31, 15*REGBYTES(sp)
#endif
.endm
###############################################
###############################################
#restore caller registers
.macro RESTORE_CONTEXT_ONLY_X5
LOAD x5, 1*REGBYTES(sp)
.endm
###############################################
###############################################
# Save the mepc and mstatus
#
.macro SAVE_EPC_STATUS
csrr x5, CSR_MEPC
STORE x5, 16*REGBYTES(sp)
csrr x5, CSR_MSTATUS
STORE x5, 17*REGBYTES(sp)
csrr x5, CSR_MSUBM
STORE x5, 18*REGBYTES(sp)
.endm
###############################################
###############################################
# Restore the mepc and mstatus
#
.macro RESTORE_EPC_STATUS
LOAD x5, 16*REGBYTES(sp)
csrw CSR_MEPC, x5
LOAD x5, 17*REGBYTES(sp)
csrw CSR_MSTATUS, x5
LOAD x5, 18*REGBYTES(sp)
csrw CSR_MSUBM, x5
.endm
###############################################
###############################################
// Trap entry point
//
.section .text.trap
.align 6// In CLIC mode, the trap entry must be 64bytes aligned
.global trap_entry
.weak trap_entry
trap_entry:
// Allocate the stack space
// addi sp, sp, -19*REGBYTES
// Save the caller saving registers (context)
SAVE_CONTEXT
// Save the MEPC/Mstatus/Msubm reg
SAVE_EPC_STATUS
// Set the function argument
csrr a0, mcause
mv a1, sp
// Call the function
call handle_trap
// Restore the MEPC/Mstatus/Msubm reg
RESTORE_EPC_STATUS
// Restore the caller saving registers (context)
RESTORE_CONTEXT
// De-allocate the stack space
// addi sp, sp, 19*REGBYTES
// Return to regular code
mret
###############################################
###############################################
// IRQ entry point
//
.section .text.irq
.align 2
.global irq_entry
.weak irq_entry
irq_entry: // -------------> This label will be set to MTVT2 register
// Allocate the stack space
SAVE_CONTEXT// Save 16 regs
//------This special CSR read operation, which is actually use mcause as operand to directly store it to memory
csrrwi x0, CSR_PUSHMCAUSE, 17
//------This special CSR read operation, which is actually use mepc as operand to directly store it to memory
csrrwi x0, CSR_PUSHMEPC, 18
//------This special CSR read operation, which is actually use Msubm as operand to directly store it to memory
csrrwi x0, CSR_PUSHMSUBM, 19
service_loop:
//------This special CSR read/write operation, which is actually Claim the CLIC to find its pending highest
// ID, if the ID is not 0, then automatically enable the mstatus.MIE, and jump to its vector-entry-label, and
// update the link register
csrrw ra, CSR_JALMNXTI, ra
//RESTORE_CONTEXT_EXCPT_X5
#---- Critical section with interrupts disabled -----------------------
DISABLE_MIE # Disable interrupts
LOAD x5, 19*REGBYTES(sp)
csrw CSR_MSUBM, x5
LOAD x5, 18*REGBYTES(sp)
csrw CSR_MEPC, x5
LOAD x5, 17*REGBYTES(sp)
csrw CSR_MCAUSE, x5
RESTORE_CONTEXT
// Return to regular code
mret
#endif