123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204 |
- // See LICENSE for license details
- #ifndef ENTRY_S
- #define ENTRY_S
- #include "riscv_encoding.h"
- #include "riscv_bits.h"
- #include "n22_eclic.h"
- #include "n22_tmr.h"
- ###############################################
- ###############################################
- # Disable Interrupt
- #
- .macro DISABLE_MIE
- csrc CSR_MSTATUS, MSTATUS_MIE
- .endm
- ###############################################
- ###############################################
- #Save caller registers
- .macro SAVE_CONTEXT
- STORE x1, 0*REGBYTES(sp)
- STORE x5, 1*REGBYTES(sp)
- STORE x6, 2*REGBYTES(sp)
- STORE x7, 3*REGBYTES(sp)
- STORE x10, 4*REGBYTES(sp)
- STORE x11, 5*REGBYTES(sp)
- STORE x12, 6*REGBYTES(sp)
- STORE x13, 7*REGBYTES(sp)
- STORE x14, 8*REGBYTES(sp)
- STORE x15, 9*REGBYTES(sp)
- STORE x16, 10*REGBYTES(sp)
- STORE x17, 11*REGBYTES(sp)
- STORE x28, 12*REGBYTES(sp)
- STORE x29, 13*REGBYTES(sp)
- STORE x30, 14*REGBYTES(sp)
- STORE x31, 15*REGBYTES(sp)
- .endm
- ###############################################
- ###############################################
- #restore caller registers
- .macro RESTORE_CONTEXT
- LOAD x1, 0*REGBYTES(sp)
- LOAD x5, 1*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)
- 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)
- .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)
- 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)
- .endm
- ###############################################
- ###############################################
- #restore caller registers
- .macro RESTORE_CONTEXT_ONLY_X5
- LOAD x5, 1*REGBYTES(sp)
- .endm
- ###############################################
- ###############################################
- # Save the mepc and mstatus
- #
- .macro SAVE_MEPC_MSTATUS
- csrr x5, CSR_MEPC
- STORE x5, 16*REGBYTES(sp)
- csrr x5, CSR_MSTATUS
- STORE x5, 17*REGBYTES(sp)
- csrr x5, CSR_MXSTATUS
- STORE x5, 18*REGBYTES(sp)
- .endm
- ###############################################
- ###############################################
- # Restore the mepc and mstatus
- #
- .macro RESTORE_MEPC_MSTATUS
- 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_MXSTATUS, x5
- .endm
- ###############################################
- ###############################################
- // trap entry point
- //
- .section .text.entry
- .align 6 // In ECLIC 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 reg
- SAVE_MEPC_MSTATUS
- // Set the function argument
- csrr a0, mcause
- mv a1, sp
- // Call the function
- call handle_trap
- // Restore the MEPC/MStatus reg
- RESTORE_MEPC_MSTATUS
- // 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
- addi sp, sp, -19*REGBYTES
- 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, 16
- //------This special CSR read operation, which is actually use mepc as operand to directly store it to memory
- csrrwi x0, CSR_PUSHMEPC, 17
- //------This special CSR read operation, which is actually use mxstatus as operand to directly store it to memory
- csrrwi x0, CSR_PUSHMXSTATUS, 18
- service_loop:
- //------This special CSR read/write operation, which is actually Claim the ECLIC 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_MINTSEL_JAL, ra
- RESTORE_CONTEXT_EXCPT_X5
- #---- Critical section with interrupts disabled -----------------------
- DISABLE_MIE # Disable interrupts
- LOAD x5, 18*REGBYTES(sp)
- csrw CSR_MXSTATUS, x5
- LOAD x5, 17*REGBYTES(sp)
- csrw CSR_MEPC, x5
- LOAD x5, 16*REGBYTES(sp)
- csrw CSR_MCAUSE, x5
- RESTORE_CONTEXT_ONLY_X5
- // De-allocate the stack space
- addi sp, sp, 19*REGBYTES
- // Return to regular code
- mret
- #endif
|