mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
allowed for vectored and unvectored interrupts in trap handlers
This commit is contained in:
parent
ac03a95aeb
commit
2da39c7052
@ -55,12 +55,15 @@ RVTEST_CODE_BEGIN
|
|||||||
|
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
.macro TRAP_HANDLER MODE // default to vectored tests
|
.macro TRAP_HANDLER MODE, VECTORED=1 // default to vectored tests
|
||||||
// Set up the exception Handler, keeping the original handler in x4.
|
// Set up the exception Handler, keeping the original handler in x4.
|
||||||
|
|
||||||
// trap handler setup
|
// trap handler setup
|
||||||
|
|
||||||
la x1, trap_handler_\MODE\()
|
la x1, trap_handler_\MODE\()
|
||||||
|
.if (\VECTORED == 1)
|
||||||
|
ori x1, x1, 0x1 // set mode field of tvec to 1, forcing vectored interrupts
|
||||||
|
.endif
|
||||||
|
|
||||||
.if (\MODE\() == m)
|
.if (\MODE\() == m)
|
||||||
csrrw x4, \MODE\()tvec, x1 // x4 reserved for "default" trap handler address that needs to be restored before halting this test.
|
csrrw x4, \MODE\()tvec, x1 // x4 reserved for "default" trap handler address that needs to be restored before halting this test.
|
||||||
.else
|
.else
|
||||||
@ -71,7 +74,8 @@ RVTEST_CODE_BEGIN
|
|||||||
li a1, 0
|
li a1, 0
|
||||||
li a2, 0 // reset trap handler inputs to zero
|
li a2, 0 // reset trap handler inputs to zero
|
||||||
|
|
||||||
j trap_handler_end_\MODE\()
|
j trap_handler_end_\MODE\() // skip the trap handler when it is being defined.
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------
|
||||||
// General traps Handler
|
// General traps Handler
|
||||||
//
|
//
|
||||||
@ -106,9 +110,25 @@ RVTEST_CODE_BEGIN
|
|||||||
//
|
//
|
||||||
// --------------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
.align 2
|
||||||
trap_handler_\MODE\():
|
trap_handler_\MODE\():
|
||||||
// The processor is always in machine mode when a trap takes us here
|
j trap_unvectored_\MODE\() // for the unvectored implimentation: jump past this table of addresses into the actual handler
|
||||||
|
// *** ASSUMES that a cause value of 0 for an interrupt is unimplemented
|
||||||
|
// otherwise, a vectored interrupt handler should jump to trap_handler_\MODE\() + 4 * Interrupt cause code
|
||||||
|
.4byte s_soft_interrupt_\MODE\() // 1: instruction access fault // the zero spot is taken up by the instruction to skip this table.
|
||||||
|
.4byte segfault_\MODE\() // 2: reserved
|
||||||
|
.4byte m_soft_interrupt_\MODE\() // 3: breakpoint
|
||||||
|
.4byte segfault_\MODE\() // 4: reserved
|
||||||
|
.4byte s_time_interrupt_\MODE\() // 5: load access fault
|
||||||
|
.4byte segfault_\MODE\() // 6: reserved
|
||||||
|
.4byte m_time_interrupt_\MODE\() // 7: store access fault
|
||||||
|
.4byte segfault_\MODE\() // 8: reserved
|
||||||
|
.4byte s_ext_interrupt_\MODE\() // 9: ecall from S-mode
|
||||||
|
.4byte segfault_\MODE\() // 10: reserved
|
||||||
|
.4byte m_ext_interrupt_\MODE\() // 11: ecall from M-mode
|
||||||
|
// 12 through >=16 are reserved or designated for platform use
|
||||||
|
|
||||||
|
trap_unvectored_\MODE\():
|
||||||
// save registers on stack before using
|
// save registers on stack before using
|
||||||
sd x1, -8(sp)
|
sd x1, -8(sp)
|
||||||
sd x5, -16(sp)
|
sd x5, -16(sp)
|
||||||
@ -126,7 +146,7 @@ trap_handler_\MODE\():
|
|||||||
bnez x5, trapreturn_\MODE\() // return from interrupt
|
bnez x5, trapreturn_\MODE\() // return from interrupt
|
||||||
// Other trap handling is specified in the vector Table
|
// Other trap handling is specified in the vector Table
|
||||||
slli x1, x1, 3 // multiply cause by 8 to get offset in vector Table
|
slli x1, x1, 3 // multiply cause by 8 to get offset in vector Table
|
||||||
la x5, trap_handler_vector_table_\MODE\()
|
la x5, exception_vector_table_\MODE\()
|
||||||
add x5, x5, x1 // compute address of vector in Table
|
add x5, x5, x1 // compute address of vector in Table
|
||||||
ld x5, 0(x5) // fectch address of handler from vector Table
|
ld x5, 0(x5) // fectch address of handler from vector Table
|
||||||
jr x5 // and jump to the handler
|
jr x5 // and jump to the handler
|
||||||
@ -248,13 +268,32 @@ accessfault_\MODE\():
|
|||||||
// *** What do I have to do here?
|
// *** What do I have to do here?
|
||||||
j trapreturn_\MODE\()
|
j trapreturn_\MODE\()
|
||||||
|
|
||||||
|
s_soft_interrupt_\MODE\(): // these labels are here to make sure the code compiles, but don't actually do anything yet
|
||||||
|
j trapreturn_\MODE\()
|
||||||
|
|
||||||
|
m_soft_interrupt_\MODE\():
|
||||||
|
j trapreturn_\MODE\()
|
||||||
|
|
||||||
|
s_time_interrupt_\MODE\():
|
||||||
|
j trapreturn_\MODE\()
|
||||||
|
|
||||||
|
m_time_interrupt_\MODE\():
|
||||||
|
j trapreturn_\MODE\()
|
||||||
|
|
||||||
|
s_ext_interrupt_\MODE\():
|
||||||
|
j trapreturn_\MODE\()
|
||||||
|
|
||||||
|
m_ext_interrupt_\MODE\():
|
||||||
|
j trapreturn_\MODE\()
|
||||||
|
|
||||||
|
|
||||||
// Table of trap behavior
|
// Table of trap behavior
|
||||||
// lists what to do on each exception (not interrupts)
|
// lists what to do on each exception (not interrupts)
|
||||||
// unexpected exceptions should cause segfaults for easy detection
|
// unexpected exceptions should cause segfaults for easy detection
|
||||||
// Expected exceptions should increment the EPC to the next instruction and return
|
// Expected exceptions should increment the EPC to the next instruction and return
|
||||||
|
|
||||||
.align 3 // aligns this data table to an 8 byte boundary
|
.align 3 // aligns this data table to an 8 byte boundary
|
||||||
trap_handler_vector_table_\MODE\():
|
exception_vector_table_\MODE\():
|
||||||
.8byte segfault_\MODE\() // 0: instruction address misaligned
|
.8byte segfault_\MODE\() // 0: instruction address misaligned
|
||||||
.8byte instrfault_\MODE\() // 1: instruction access fault
|
.8byte instrfault_\MODE\() // 1: instruction access fault
|
||||||
.8byte illegalinstr_\MODE\() // 2: illegal instruction
|
.8byte illegalinstr_\MODE\() // 2: illegal instruction
|
||||||
|
Loading…
Reference in New Issue
Block a user