Commit 254f4bbb authored by Roberto Hexsel's avatar Roberto Hexsel

added tests for interrupt on JR delay slot

parent c6cd4046
......@@ -45,9 +45,31 @@
.set cop0_LLAddr, $17
.set cop0_ErrorPC, $30
.set c0_index, $0
.set c0_random, $1
.set c0_entrylo0,$2
.set c0_entrylo1,$3
.set c0_context ,$4
.set c0_pagemask,$5
.set c0_wired, $6
.set c0_badvaddr,$8
.set c0_count ,$9
.set c0_entryhi ,$10
.set c0_compare ,$11
.set c0_status ,$12
.set c0_cause ,$13
.set c0_epc, $14
.set c0_config, $16
.set c0_config_f0,0
.set c0_config_f1,1
.set c0_lladdr, $17
.set c0_errorpc, $30
# reset: COP0 present, at exception level, all else disabled
.set cop0_STATUS_reset,0x10000002
.set c0_status_reset, cop0_STATUS_reset
# reset: COUNTER stopped, use special interrVector, no interrupts
.set cop0_CAUSE_reset, 0x0880007c
.set c0_cause_reset, cop0_CAUSE_reset
......@@ -275,8 +275,11 @@ _excp_0200:
jr $k1
nop
## the code for each handler must repeat the exception return
## sequence shown below in excp_0200ret.
handlers_tbl:
j Dismiss # no request: 000
j dismiss # no request: 000
nop
j extCounter # lowest priority, IRQ5: 001
......@@ -297,7 +300,7 @@ handlers_tbl:
nop
Dismiss: # No pending request, must have been noise
dismiss: # No pending request, must have been noise
# do nothing and return
excp_0200ret:
......
......@@ -65,7 +65,7 @@ touch input.data serial.inp
a_FWD="fwdAddAddAddSw fwd_SW lwFWDsw lwFWDsw2 slt32 slt_u_32 slt_s_32 reg0"
a_CAC="dCacheTst lhUshUCache lbUsbUCache lbsbCache dCacheTstH dCacheTstB"
a_BEQ="lw-bne bXtz sltbeq beq_dlySlot jr_dlySlot"
a_BEQ="lw-bne bXtz sltbeq beq_dlySlot jr_dlySlot interrJR_dlySlot"
a_FUN="jaljr jr_2 jal_fun_jr jalr_jr jallwjr bltzal_fun_jr"
a_OTH="mult div mul sll slr movz wsbh_seb extract insert"
a_BHW="lbsb lhsh lwsw lwswIncr swlw lwl_lwr"
......
00000013
c0808000
0000003f
00000046
c0808000
# Testing the internal counter is difficult because it counts clock cycles
# rather than instructions -- if the I/O or memory latencies change then
# the simulation output also changes and comparisons are impossible.
.include "cMIPS.s"
.text
.align 2
.set noat
.set noreorder
.set numCy, 64
.global _start
.global _exit
.set c0_cause_rst, 0x0880007c # disable counter, separate IntVector
_start: nop
li $k0, c0_status_reset # RESET, kernel mode, all else disabled
mtc0 $k0, c0_status
li $sp,(x_DATA_BASE_ADDR+x_DATA_MEM_SZ-8) # initialize SP: ramTop-8
li $k0, 0x1800ff01 # RESET_STATUS, kernel mode, interr enabled
mtc0 $k0, c0_status
li $k0, c0_cause_rst # RESET, disable counter
mtc0 $k0, c0_cause
la $15,x_IO_BASE_ADDR
nop
j main
nop
exit:
_exit: nop # flush pipeline
nop
nop
nop
nop
wait # then stop VHDL simulation
nop
nop
#----------------------------------------------------------------
.org x_EXCEPTION_0000,0
_excp_0000:
la $k0, x_IO_BASE_ADDR
mfc0 $k1, c0_cause
sw $k1, 0($k0) # print CAUSE, flush pipe and stop simulation
nop
nop
nop
wait 0x01
nop
#----------------------------------------------------------------
.org x_EXCEPTION_0100,0
_excp_0100:
la $k0, x_IO_BASE_ADDR
mfc0 $k1, c0_cause
sw $k1, 0($k0) # print CAUSE, flush pipe and stop simulation
nop
nop
nop
wait 0x02
nop
#----------------------------------------------------------------
.org x_EXCEPTION_0180,0
_excp_180:
la $k0, x_IO_BASE_ADDR
mfc0 $k1, c0_cause
sw $k1, 0($k0) # print CAUSE, flush pipe and stop simulation
nop
nop
nop
wait 0x03
nop
#
# interrupt handler =============================================
#
.org x_EXCEPTION_0200,0
_excp_200:
mfc0 $k1, c0_count # read current COUNT
sw $k1, 0($15)
mfc0 $k0, c0_cause # read CAUSE and
nop
sw $k0, 0($15) # print CAUSE
li $k0, 0 # remove IRQ
mtc0 $k0, c0_compare
move $19, $24 # write part of JALR performed?
li $k0, 0x10008001 # CP0active, enable COUNT interrupts
mtc0 $k0, c0_status
ehb
eret
#
#================================================================
#
#----------------------------------------------------------------
.org x_EXCEPTION_BFC0,0
_excp_BFC0:
la $k0, x_IO_BASE_ADDR
mfc0 $k1, c0_cause
sw $k1, 0($k0) # print CAUSE, flush pipe and stop simulation
nop
nop
nop
wait 0x04
nop
##
##-----------------------------------------------------------------
##
.set TRUE, 1
.set FALSE, 0
.org x_ENTRY_POINT,0
main: la $15, x_IO_BASE_ADDR
li $13, '\n'
li $11, 0 # used with the identifiable NOPs
#
# let us cause an interrupt on a stalled JALR
#
.set numCy, 12 # magic number: cycles needed to ensure
# interrupt hits the JALR
two_instr:
li $5, numCy # interrupt again in numCy cycles
mtc0 $5, c0_compare
# enable Counter
mfc0 $5, c0_cause
li $6, 0xf7ffffff # CAUSE.DisableCount <= false
and $5, $5, $6
mtc0 $5, c0_cause # enable counter
nop
li $24, 0
la $20, x_DATA_BASE_ADDR
la $21, one_instr
la $12, err0
sw $12, 4($20) # write error message to memory
nop # align COUNT==COMPARE with JR
sw $21, 0($20) # store jump target
li $11, 0 # this is a NOP
li $11, 1 # this is a NOP
lw $23, 0($20) # load target address to cause delay slot
li $11, 2 # this is a NOP in the 2-cycle delay slot
jalr $24, $23 # save ra in $24
li $11, 3 # this is a NOP
two: li $11, 4 # this is a NOP, return address from jalr
li $11, 5 # this is a NOP
one_instr:
li $11, 6 # this is a NOP
# $19 must be zero
# handler copies $24 -> $19
nop # to ensure JALR did not change $24
bne $zero, $19, err2 # check if return addess was changed
nop
#
# let us cause an interrupt on a JR, delayed by a LW
#
.set numCy, 22 # magic number: cycles needed to ensure
# interrupt hits the JALR
mfc0 $6, c0_count
addiu $5, $6, numCy # interrupt again in numCy cycles
mtc0 $5, c0_compare
move $9, $5
# enable Counter
mfc0 $5, c0_cause
li $6, 0xf7ffffff # CAUSE.DisableCount <= false
and $5, $5, $6
mtc0 $5, c0_cause # enable counter
nop
sw $9, 0($15) # show old+numCycles
li $24, 0
la $20, x_DATA_BASE_ADDR
la $21, zero_instr
la $12, err0
sw $12, 4($20) # write error message to memory
sw $21, 0($20) # store jump target
li $11, 10 # this is a NOP
li $11, 11 # this is a NOP
li $11, 12 # this is a NOP
lw $23, 0($20) # load target address to cause delay slot
jalr $24, $23 # save ra in $24
li $11, 13 # this is a NOP
one: li $11, 14 # this is a NOP
li $11, 15 # this is a NOP
zero_instr:
li $11, 16 # this is a NOP
# $19 must be zero
# handler copies $24 -> $19
nop # to ensure JALR did not change $24
bne $zero, $19, err1 # check if return addess was changed
nop
li $11, 16 # this is a NOP
li $11, 17 # this is a NOP
nop
wait 0xff # end of test
nop
err2: li $30, 'E'
sw $30, x_IO_ADDR_RANGE($15)
li $30, 'R'
sw $30, x_IO_ADDR_RANGE($15)
sw $30, x_IO_ADDR_RANGE($15)
li $30, ' '
sw $30, x_IO_ADDR_RANGE($15)
li $30, 't'
sw $30, x_IO_ADDR_RANGE($15)
li $30, 'w'
sw $30, x_IO_ADDR_RANGE($15)
li $30, 'o'
sw $30, x_IO_ADDR_RANGE($15)
li $30, '\n'
j exit
sw $30, x_IO_ADDR_RANGE($15) # print a newline
err1: li $30, 'E'
sw $30, x_IO_ADDR_RANGE($15)
li $30, 'R'
sw $30, x_IO_ADDR_RANGE($15)
sw $30, x_IO_ADDR_RANGE($15)
li $30, ' '
sw $30, x_IO_ADDR_RANGE($15)
li $30, 'o'
sw $30, x_IO_ADDR_RANGE($15)
li $30, 'n'
sw $30, x_IO_ADDR_RANGE($15)
li $30, 'e'
sw $30, x_IO_ADDR_RANGE($15)
li $30, '\n'
j exit
sw $30, x_IO_ADDR_RANGE($15) # print a newline
err0: li $30, 'E'
sw $30, x_IO_ADDR_RANGE($15)
li $30, 'R'
sw $30, x_IO_ADDR_RANGE($15)
sw $30, x_IO_ADDR_RANGE($15)
li $30, ' '
sw $30, x_IO_ADDR_RANGE($15)
li $30, 'o'
sw $30, x_IO_ADDR_RANGE($15)
li $30, 'v'
sw $30, x_IO_ADDR_RANGE($15)
li $30, 'r'
sw $30, x_IO_ADDR_RANGE($15)
li $30, 'w'
sw $30, x_IO_ADDR_RANGE($15)
li $30, '\n'
j exit
sw $30, x_IO_ADDR_RANGE($15) # print a newline
......@@ -2409,7 +2409,7 @@ begin
disable_count <= CAUSE(CAUSE_DC)
when (cause_update='0' and CAUSE(CAUSE_DC) /= count_enable)
else count_enable; -- load new CAUSE(CAUSE_DC)
COP0_DISABLE_COUNT: FFD port map (clk,'1',rst,disable_count, count_enable);
COP0_DISABLE_COUNT: FFD port map (clk,'1',rst, disable_count, count_enable);
-- BadVAddr -- pg 74 ---------------------------
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment