Skip to content
This repository has been archived by the owner on Apr 27, 2023. It is now read-only.

Commit

Permalink
Add timer/watchdog interrupt test.
Browse files Browse the repository at this point in the history
- Repeatedly trigger several timer interrupts and make sure that
  control flow and results are correct.

 On branch master
 Your branch is up-to-date with 'origin/master'.

 Changes to be committed:
	modified:   verif/unit/Makefile.in
	modified:   verif/unit/share/unit_test.h
	modified:   verif/unit/share/util.S
	new file:   verif/unit/timer/Makefile.in
	new file:   verif/unit/timer/test_timer.S
	new file:   verif/unit/timer/test_timer.c
	new file:   verif/unit/timer/test_timer.h

 Changes not staged for commit:
	modified:   rtl/core/frv_csrs.v
	modified:   rtl/core/frv_interrupts.v
	modified:   rtl/core/frv_pipeline_writeback.v
  • Loading branch information
ben-marshall committed Mar 20, 2020
1 parent ac0de7e commit aae0b58
Show file tree
Hide file tree
Showing 7 changed files with 244 additions and 1 deletion.
8 changes: 7 additions & 1 deletion verif/unit/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ run-unit-${1} : $(call unit_test_srec,${1}) $(VL_OUT) ;
$(VL_OUT) +IMEM=$(call unit_test_srec,${1}) \
+WAVES=$(call unit_test_waves,${1}) \
+TIMEOUT=$(UNIT_TIMEOUT) \
+PASS_ADDR=$(UNIT_PASS) +FAIL_ADDR=$(UNIT_FAIL)
+PASS_ADDR=$(UNIT_PASS) +FAIL_ADDR=$(UNIT_FAIL)

$(call unit_test_waves,${1}) : run-unit-${1}
$(call unit_test_log,${1}) : run-unit-${1}
Expand All @@ -75,6 +75,11 @@ UNIT_TESTS += $(call unit_test_srec,${1}) \
$(call unit_test_elf,${1}) \
$(call unit_test_gtkwave,${1})

build-unit-${1} : $(call unit_test_srec,${1}) \
$(call unit_test_objdump,${1}) \
$(call unit_test_elf,${1}) \
$(call unit_test_gtkwave,${1})

UNIT_TESTS_RUN += $(call unit_test_waves,${1}) \
$(call unit_test_objdump,${1}) \
$(call unit_test_log,${1}) \
Expand All @@ -96,6 +101,7 @@ include $(FRV_HOME)/verif/unit/mtime-write/Makefile.in
include $(FRV_HOME)/verif/unit/counters/Makefile.in
include $(FRV_HOME)/verif/unit/instructions/Makefile.in
include $(FRV_HOME)/verif/unit/interrupts/Makefile.in
include $(FRV_HOME)/verif/unit/timer/Makefile.in

.PHONY: unit-tests-build
unit-tests-build: $(UNIT_TESTS)
Expand Down
3 changes: 3 additions & 0 deletions verif/unit/share/unit_test.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ volatile uint64_t __rd_mtime();
//! Read the memory mapped mtimecmp register
volatile uint64_t __rd_mtimecmp();

//! Read the memory mapped mtimecmp register
volatile void __wr_mtimecmp(uint64_t mtc);

//! Intrisic for the `rdcycle` assembly instruction
volatile uint64_t __rdcycle();

Expand Down
11 changes: 11 additions & 0 deletions verif/unit/share/util.S
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,17 @@ __rd_mtimecmp:
ret
.endfunc

.func __wr_mtimecmp
.global __wr_mtimecmp
__wr_mtimecmp:
li a3, 0x00001000 // Base address of MMIO region
li a2, -1
sw a2, 8(a3) // a1 = high word of mtime cmp
sw a1, 12(a3) // a1 = high word of mtime cmp
sw a0, 8(a3) // a0 = low word of mtime
ret
.endfunc

.func __rdcycle
.global __rdcycle
__rdcycle:
Expand Down
7 changes: 7 additions & 0 deletions verif/unit/timer/Makefile.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

TEST_NAME = timer
TEST_SRC = $(UNIT_ROOT)/timer/test_timer.c \
$(UNIT_ROOT)/timer/test_timer.S

$(eval $(call add_unit_test,$(TEST_NAME),$(TEST_SRC)))

109 changes: 109 additions & 0 deletions verif/unit/timer/test_timer.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@

.data

.text

.extern handler_machine_timer

.balign 64
.func __handler_machine_timer
.global __handler_machine_timer
__handler_machine_timer:

addi sp,sp,-(32*4)
sw x1 ,4*1 (sp)
sw x2 ,4*2 (sp)
sw x3 ,4*3 (sp)
sw x4 ,4*4 (sp)
sw x5 ,4*5 (sp)
sw x6 ,4*6 (sp)
sw x7 ,4*7 (sp)
sw x8 ,4*8 (sp)
sw x9 ,4*9 (sp)
sw x10,4*10(sp)
sw x11,4*11(sp)
sw x12,4*12(sp)
sw x13,4*13(sp)
sw x14,4*14(sp)
sw x15,4*15(sp)
sw x16,4*16(sp)
sw x17,4*17(sp)
sw x18,4*18(sp)
sw x19,4*19(sp)
sw x20,4*20(sp)
sw x21,4*21(sp)
sw x22,4*22(sp)
sw x23,4*23(sp)
sw x24,4*24(sp)
sw x25,4*25(sp)
sw x26,4*26(sp)
sw x27,4*27(sp)
sw x28,4*28(sp)
sw x29,4*29(sp)
sw x30,4*30(sp)
sw x31,4*31(sp)

jal handler_machine_timer

lw x1 ,4*1 (sp)
lw x2 ,4*2 (sp)
lw x3 ,4*3 (sp)
lw x4 ,4*4 (sp)
lw x5 ,4*5 (sp)
lw x6 ,4*6 (sp)
lw x7 ,4*7 (sp)
lw x8 ,4*8 (sp)
lw x9 ,4*9 (sp)
lw x10,4*10(sp)
lw x11,4*11(sp)
lw x12,4*12(sp)
lw x13,4*13(sp)
lw x14,4*14(sp)
lw x15,4*15(sp)
lw x16,4*16(sp)
lw x17,4*17(sp)
lw x18,4*18(sp)
lw x19,4*19(sp)
lw x20,4*20(sp)
lw x21,4*21(sp)
lw x22,4*22(sp)
lw x23,4*23(sp)
lw x24,4*24(sp)
lw x25,4*25(sp)
lw x26,4*26(sp)
lw x27,4*27(sp)
lw x28,4*28(sp)
lw x29,4*29(sp)
lw x30,4*30(sp)
lw x31,4*31(sp)
addi sp,sp,32*4

mret
.endfunc


.extern test_fail
.extern test_pass

.balign 128
.global vector_interrupt_table
vector_interrupt_table:
.balign 4; j test_fail // 00 - User SW interrupt / exception
.balign 4; j test_fail // 01 - Supervisor SW interrupt
.balign 4; j test_fail // 02 - Reserved
.balign 4; j test_fail // 03 - Machine SW interrupt
.balign 4; j test_fail // 04 - User Timer Interrupt
.balign 4; j test_fail // 05 - Supervisor Timer Interrupt
.balign 4; j test_fail // 06 - Reserved
.balign 4; j __handler_machine_timer // 07 - Machine Timer Interrupt
.balign 4; j test_fail // 08 - User External Interrupt
.balign 4; j test_fail // 09 - Supervisor External Interrupt
.balign 4; j test_fail // 10 - Reserved
.balign 4; j test_fail // 11 - Machine External Interrupt
.balign 4; j test_fail // 12 - Reserved
.balign 4; j test_fail // 13 - Reserved
.balign 4; j test_fail // 14 - Reserved
.balign 4; j test_fail // 15 - Reserved
.balign 4; j test_fail // 16 - NMI


73 changes: 73 additions & 0 deletions verif/unit/timer/test_timer.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@


#include "unit_test.h"

#include "test_timer.h"

// Interrupt handler table.
extern void vector_interrupt_table ;

static volatile int interrupt_count = 0;
const int max_interrupt_count = 5;
const int interrupt_period = 400;


//! Called when a machine timer interrupt occurs.
void handler_machine_timer() {

uint64_t mtime = __rd_mtime() ;
uint64_t mtime_cmp = __rd_mtimecmp() ;

interrupt_count ++;

__puthex64(mtime);
__putchar(' '); __puthex64(mtime_cmp); __putchar('\n');

uint64_t mtime_cmpn = __rd_mtime() + interrupt_period;

__wr_mtimecmp(mtime_cmpn);

// Disable the machine timer interrupt.
if(interrupt_count >= max_interrupt_count) {
__clr_mie(MIE_MTIE);
}

return;
}


void start_machine_timer() {

mtvec(&vector_interrupt_table, 1);

uint64_t mtime = __rd_mtime();
uint64_t mtime_cmpn = mtime + interrupt_period;

__wr_mtimecmp(mtime_cmpn);

__set_mie(MIE_MTIE);
__set_mstatus(MSTATUS_MIE);

}


/*!
@brief Test for timer interrupts.
*/
int test_main() {

interrupt_count = 0;

uint64_t counter = 0;

start_machine_timer();

while(interrupt_count < max_interrupt_count) {
counter ++;
if(counter & 0xFFF == 0) {
__putchar("#");
}
}

return 0;
}
34 changes: 34 additions & 0 deletions verif/unit/timer/test_timer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@

#ifndef TEST_INTERRUPTS_H
#define TEST_INTERRUPTS_H

#define MSTATUS_MIE (0x00000001 << 3)
#define MSTATUS_SIE (0x00000001 << 1)
#define MSTATUS_UIE (0x00000001 << 0)

#define MIP_MEIP (0x00000001 << 11)
#define MIP_MTIP (0x00000001 << 7)
#define MIP_MSIP (0x00000001 << 3)

#define MIE_MEIE (0x00000001 << 11)
#define MIE_MTIE (0x00000001 << 7)
#define MIE_MSIE (0x00000001 << 3)

#define MTVEC_DIRECT 0x0
#define MTVEC_VECTORED 0x1

volatile uint32_t mtvec(void *func, uint32_t mode) {
uint32_t rd;
uint32_t base = (uint32_t)func;
uint32_t wr = (base & 0xFFFFFFFC) | mode;
asm volatile("csrrw %0, mtvec, %1" : "=r"(rd) : "r"(wr));
return rd;
}

//! Setup the interrupt handler.
void setup_timer_interrupt_handler(
volatile int * indicator
);

#endif

0 comments on commit aae0b58

Please sign in to comment.