blob: db5057fe2966cef2d47bbe28276eeff00c076ca8 [file] [log] [blame]
#include "riscv_macros.h"
#include "sc_test.h"
.altmacro
// global interrupt bit
#define MSIE (1 << IRQ_M_SOFT) //machine software interrupt enable
#define MTIE (1 << IRQ_M_TIMER) //machine timer interrupt enable
#define MEIE (1 << IRQ_M_EXT) //machine external interrupt enable
#define MCAUSE_EXT_IRQ (1 << 31 | IRQ_M_EXT)
#define MCAUSE_SOFT_IRQ (1 << 31 | IRQ_M_SOFT)
#define MCAUSE_TMR_IRQ (1 << 31 | IRQ_M_TIMER)
// IPIC
#define IRQ_LINES_MASK 0x1002000C // Interrupt Mask
#define IRQ_LINES_ADDR 0x10020010 // simulation
#define TRIG_EXT_IRQ_ADDR 0x10020010 // external irq is triggered when tb memory is set to non-zero // Bit [15:0]
#define TRIG_SW_IRQ_ADDR 0x10020010 // software irq is triggered when tb memory is set to non-zero // Bit [16]
#define IPIC_EOI 0xBF4 // end of interrupt
#define IPIC_SOI 0xBF5 // start of interrupt
#define IPIC_IDX 0xBF6 // index register
#define IPIC_ICSR 0xBF7 // interrupt control status register
// IPIC Interrupt Constrol Status Register
#define IPIC_ICSR_IP (1 << 0) // interrupt pending
#define IPIC_ICSR_IE (1 << 1) // interrupt enable
#define IPIC_ICSR_IM (1 << 2) // interrupt mode (0/1: level/edge)
#define IPIC_ICSR_INV (1 << 3) // line inversion
#define IPIC_ICSR_IS (1 << 4) // in service
// Interrupt lines in use
#define IPIC_IRQ_LINE7 7
#define EXT_IRQ_LINE_COMMON 0
#include "timer.h"
#include "reloc.h"
.macro jmp_sc_exit
la t0, sc_exit
jr t0
.endm
.section .text.init
.option norvc
.globl _start
// -----------------------------------------------------------------
// Trap handlers
// 0xXXXXXX00
.option norvc
.org (64*3)
//0xXXXXXXC0
.balign 64
machine_trap_entry:
vec_usr_soft:
#ifdef VECT_IRQ_ENABLED
trap_entry:
j _trap_fail
vec_supervisor_soft:
j _trap_fail
vec_reserved1:
j _trap_fail
vec_machine_soft:
j vec_machine_soft_handler
vec_usr_tmr:
j _trap_fail
vec_supervisor_tmr:
j _trap_fail
vec_reserved2:
j _trap_fail
vec_machine_tmr:
j vec_machine_tmr_handler
vec_usr_ext:
j _trap_fail
vec_supervisor_ext:
j _trap_fail
vec_reserved3:
j _trap_fail
vec_machine_ext:
j vec_machine_ext_handler
vec_reserved4:
j _trap_fail
j _trap_fail
j _trap_fail
j _trap_fail
#else
trap_entry:
j direct_irq_handler
vec_supervisor_soft:
j _trap_fail
vec_reserved1:
j _trap_fail
vec_machine_soft:
j _trap_fail
vec_usr_tmr:
j _trap_fail
vec_supervisor_tmr:
j _trap_fail
vec_reserved2:
j _trap_fail
vec_machine_tmr:
j _trap_fail
vec_usr_ext:
j _trap_fail
vec_supervisor_ext:
j _trap_fail
vec_reserved3:
j _trap_fail
vec_machine_ext:
j _trap_fail
vec_reserved4:
j _trap_fail
j _trap_fail
j _trap_fail
j _trap_fail
#endif // ifdef VECT_IRQ_ENABLED
.balign 64
_start:
la t0, machine_trap_entry
csrw mtvec, t0
la t0, test_start
jr (t0)
// -----------------------------------------------------------------
.option norvc
.balign 64
test_start:
la t0, trap_entry
csrw mtvec, t0 // set mtvec to trap_entry
#ifdef VECT_IRQ_ENABLED
csrsi mtvec, 1 // set vectored mode
#else
csrsi mtvec, 0 // set direct mode
#endif
/// configuring timer interrupt ///
_reset_mtimecmp; // reset timer
_run_timer; // run timer
csrs mstatus, MSTATUS_MIE // enable global interrupt
li a0, MTIE
csrs mie, a0 // enable timer interrupt
li t2, 0 // reset timer counter = 0 (updated in isr)
_read_mtime s1 // read timer value
addi s1, s1, 256
_write_mtimecmp_32 s1
wfi
/// configuring external interrupt ///
csrw mie, zero // disable all interrupts
li t0, IRQ_LINES_ADDR
sh zero, (t0) // set all exterinal interrupt lines low
li t0, IRQ_LINES_MASK
li t1, 0xFFFFF
sw t1, (t0) // Enable Interrupt Mask
#ifdef IPIC_ENABLED
li t0, IPIC_IRQ_LINE7
csrw IPIC_IDX, t0 // set IPIC to expect interupt on line 9...
li t0, (IPIC_ICSR_IE | IPIC_ICSR_IM)
csrw IPIC_ICSR, t0 // ....enable interrupt,set edge interrupt mode
#endif
li t0, MEIE
csrs mie, t0 // enable external interrupt
li t0, TRIG_EXT_IRQ_ADDR
#ifdef IPIC_ENABLED
li t1, (1 << IPIC_IRQ_LINE7)
#else
li t1, (1 << EXT_IRQ_LINE_COMMON)
#endif
sh t1, (t0) //send command to generate external interrupt on line 9 to testbench
nop
nop
nop
nop //wait for external interrupt
/// configuring software interrupt ///
csrw mie, zero // disable all interrupts
li t0, TRIG_SW_IRQ_ADDR
li t1, 0x00010000 // Soft ireq bit [16]
sw t1, (t0) //send command to generate software interrupt
li t0, MSIE
csrs mie, t0 // enable software interrupt
nop
nop
nop
nop //wait for software interrupt
li s1, 3
li a0, 0
beq t2, s1, 1f
li a0, -1
1:
jmp_sc_exit
#ifndef VECT_IRQ_ENABLED
direct_irq_handler:
csrr a1, mcause
li a5, MCAUSE_TMR_IRQ //0x80000007 -- mcause = tmr.irq
beq a1, a5, vec_machine_tmr_handler
li a5, MCAUSE_SOFT_IRQ //0x80000003 -- mcause = soft.irq
beq a1, a5, vec_machine_soft_handler
li a5, MCAUSE_EXT_IRQ //0x8000000B -- mcause = ext.irq
beq a1, a5, vec_machine_ext_handler
mret
#endif
vec_machine_tmr_handler:
csrr a1, mcause
li a5, MCAUSE_TMR_IRQ //0x80000007 -- mcause = tmr.irq
li a0, -1
bne a1, a5, check_fail
csrr t1, mip
li t0, MIP_MTIP
and t0, t1, t0
beqz t0, check_fail
#ifdef IPIC_ENABLED
csrw IPIC_SOI, zero
csrw IPIC_EOI, zero
#endif
_reset_mtimecmp
csrr t1, mip
andi t1, t1, MIP_MTIP
bne t1, zero, check_fail
addi t2, t2, 1 // tmr irq counter update
mret
vec_machine_ext_handler:
csrr a1, mcause
li a5, MCAUSE_EXT_IRQ //0x8000000B -- mcause = ext.irq
li a0, -1
bne a1, a5, check_fail
csrr t1, mip
li t0, MIP_MEIP
and t0, t1, t0
beqz t0, check_fail
#ifdef IPIC_ENABLED
csrw IPIC_SOI, zero
csrw IPIC_EOI, zero
#endif
li t0, MEIE
csrc mie, t0 // disable software interrupt
li t0, TRIG_EXT_IRQ_ADDR
li t1, EXT_IRQ_LINE_COMMON
sh t1, (t0) // send command to disable external interrupt
csrr t1, mip
li t0, MIP_MEIP
bne t1, zero, check_fail
addi t2, t2, 1 // ext irq counter update
mret
vec_machine_soft_handler:
csrr a1, mcause
li a5, MCAUSE_SOFT_IRQ //0x80000003 -- mcause = soft.irq
li a0, -1
bne a1, a5, check_fail
csrr t1, mip
li t0, MIP_MSIP
and t0, t1, t0
beqz t0, check_fail
#ifdef IPIC_ENABLED
csrw IPIC_SOI, zero
csrw IPIC_EOI, zero
#endif
li t0, MSIE
csrc mie, t0 // disable software interrupt
li t0, TRIG_SW_IRQ_ADDR
li t1, 0x00000000
sw t1, (t0) // send command to stop generating software interrupt
li t0, MIP_MSIP
csrc mip, t0
csrr t1, mip
li t0, MIP_MSIP
and t1, t1, t0
bne t1, zero, check_fail
addi t2, t2, 1 // ext irq counter update
mret
check_fail:
la t0, sc_exit
jr t0
_trap_fail:
li a0, -1
j check_fail