Commit 15af2070 authored by Roberto Hexsel's avatar Roberto Hexsel

handlers turned EXL=0 too early accepting interrupts from within selves

parent 9782bdeb
Pipeline #4434 skipped
......@@ -5,7 +5,8 @@
.set noat # do not use register $1 as $at
.align 2
.set M_StatusIEn,0x0000ff11 # STATUS.intEn=1, user mode
.set M_StatusIEn,0x0000ff13 # STATUS.intEn=1, user mode, EXL=1
# 0xff13 = -237
#================================================================
# interrupt handler for external counter attached to IP5=HW3
......@@ -59,9 +60,7 @@ extCounter:
mfc0 $k0, c0_status # Read STATUS register
ori $k0, $k0, M_StatusIEn # but do not modify its contents
addiu $k1, $zero, -7 # except for re-enabling interrupts
and $k0, $k1, $k0 # -7 = 0xffff.fff9
mtc0 $k0, c0_status
mtc0 $k0, c0_status # except for re-enabling interrupts
eret # Return from interrupt
.end extCounter
#----------------------------------------------------------------
......@@ -71,9 +70,9 @@ extCounter:
# interrupt handler for UART attached to IP6=HW4
# for UART's address see vhdl/packageMemory.vhd
#
.global Ud, _uart_buff
.bss
.align 2
.global Ud, _uart_buff
Ud:
rx_hd: .space 4
rx_tl: .space 4
......@@ -134,8 +133,6 @@ UARTret:
mfc0 $k0, c0_status # Read STATUS register
ori $k0, $k0, M_StatusIEn # but do not modify its contents
addiu $k1, $zero, -7 # except for re-enabling interrupts
and $k0, $k1, $k0 # -7 = 0xffff.fff9 = user mode
mtc0 $k0, c0_status
eret # Return from interrupt
.end UARTinterr
......@@ -150,17 +147,14 @@ UARTret:
.global countCompare
.ent countCompare
countCompare:
mfc0 $k1,c0_count # read COMPARE and clear IRQ
mfc0 $k1,c0_count # read COMPARE and clear IRQ
addiu $k1,$k1,num_cycles # set next interrupt in so many ticks
mtc0 $k1,c0_compare
mfc0 $k0, c0_status # Read STATUS register
ori $k0, $k0, M_StatusIEn # but do not modify its contents
lui $k1, 0xffff # except for re-enabling interrupts
ori $k1, $k1, 0xfff9 # and going into user mode
and $k0, $k1, $k0
mtc0 $k0, c0_status
eret # Return from interrupt
mfc0 $k0, c0_status # Read STATUS register
ori $k0, $k0, M_StatusIEn # but do not modify its contents
mtc0 $k0, c0_status # except for re-enabling interrupts
eret # Return from interrupt
.end countCompare
#----------------------------------------------------------------
......@@ -172,9 +166,9 @@ countCompare:
.global enableInterr,disableInterr
.ent enableInterr
enableInterr:
mfc0 $v0, cop0_STATUS # Read STATUS register
mfc0 $v0, c0_status # Read STATUS register
ori $v0, $v0, 1 # and enable interrupts
mtc0 $v0, cop0_STATUS
mtc0 $v0, c0_status
nop
jr $ra # return updated STATUS
nop
......@@ -182,10 +176,10 @@ enableInterr:
.ent disableInterr
disableInterr:
mfc0 $v0, cop0_STATUS # Read STATUS register
mfc0 $v0, c0_status # Read STATUS register
addiu $v1, $zero, -2 # and disable interrupts
and $v0, $v0, $v1 # -2 = 0xffff.fffe
mtc0 $v0, cop0_STATUS
mtc0 $v0, c0_status
nop
jr $ra # return updated STATUS
nop
......
......@@ -292,10 +292,8 @@ _excp_0180ret:
lw $k0, 1*4($k1)
# mfc0 $k0, c0_status
# and do not modify its contents
addi $k1, $zero, -15 # except for re-enabling interrupts
ori $k0, $k0, M_StatusIEn # and keeping user/kernel mode
and $k0, $k1, $k0 # as it was on exception entry
mtc0 $k0, c0_status # -15 = 0xffff.fff1
mtc0 $k0, c0_status # -239 = 0xffff.ff11
eret # Return from exception
.end _excp_0180
......@@ -317,7 +315,6 @@ _excp_0180ret:
.org x_EXCEPTION_0200,0 # exception vector_200, interrupt handlers
.ent _excp_0200
excp_0200:
_excp_0200:
mfc0 $k0, c0_cause
andi $k0, $k0, M_CauseIM # Keep only IP bits from Cause
......@@ -359,11 +356,9 @@ handlers_tbl:
dismiss: # No pending request, must have been noise
# do nothing and return
excp_0200ret:
_excp_0200ret:
mfc0 $k0, c0_status # Read STATUS register
addi $k1, $zero, -15 # and do not modify its contents -15=fff1
ori $k0, $k0, M_StatusIEn # except for re-enabling interrupts
and $k0, $k1, $k0 # and keeping user/kernel mode
mtc0 $k0, c0_status # as it was on interrupt entry
eret # Return from interrupt
nop
......
......@@ -59,14 +59,14 @@ excp_180:
li $k0, '\n'
sw $k0, x_IO_ADDR_RANGE($14)
mfc0 $k0, cop0_CAUSE
mfc0 $k0, c0_cause
sw $k0, 0($14) # print CAUSE
mfc0 $k0, cop0_EPC # fix return address
mfc0 $k0, c0_epc # fix return address
sw $k0, 0($14) # print EPC
addiu $k1, $zero, -4 # -4 = 0xffff.fffc
and $k1, $k1, $k0 # fix the invalid address
mtc0 $k1, cop0_EPC
mtc0 $k1, c0_epc
li $k0, ']' # to separate output
sw $k0, x_IO_ADDR_RANGE($14)
......@@ -90,7 +90,7 @@ _excp_0200:
.org x_EXCEPTION_BFC0,0
_excp_BFC0:
la $k0, x_IO_BASE_ADDR
mfc0 $k1, cop0_CAUSE
mfc0 $k1, c0_cause
sw $k1, 0($k0) # print CAUSE, flush pipe and stop simulation
nop
nop
......
......@@ -9,8 +9,8 @@ _start: nop
li $sp,(x_DATA_BASE_ADDR+x_DATA_MEM_SZ-8) # initialize SP: ramTop-8
## set STATUS, cop0, no interrupts enabled, user mode
li $k0, 0x10000010
mtc0 $k0, cop0_STATUS
li $k0, cop0_STATUS_normal
mtc0 $k0, c0_status
j main
nop
......@@ -61,13 +61,13 @@ excp_180:
li $k0, '\n' # to separate output
sw $k0, x_IO_ADDR_RANGE($14)
mfc0 $k0, cop0_CAUSE # print CAUSE
mfc0 $k0, c0_cause # print CAUSE
sw $k0, 0($14)
mfc0 $k0, cop0_EPC # print EPC
mfc0 $k0, c0_epc # print EPC
sw $k0, 0($14)
mfc0 $k0, cop0_BadVAddr # print BadVAddr
mfc0 $k0, c0_badvaddr # print BadVAddr
xor $k0, $k0, $30 # mask off top address bits,
sw $k0, 0($14) # show only bits that differ
......@@ -87,7 +87,7 @@ excp_180:
.org x_EXCEPTION_0200,0
_excp_0200:
la $k0, x_IO_BASE_ADDR
mfc0 $k1, cop0_CAUSE
mfc0 $k1, c0_cause
sw $k1, 0($k0) # print CAUSE, flush pipe and stop simulation
nop
nop
......
......@@ -13,12 +13,12 @@
_start: nop
li $k0, cop0_STATUS_reset # RESET, kernel mode, all else disabled
mtc0 $k0, cop0_STATUS
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, cop0_STATUS
mtc0 $k0, c0_status
li $k0, cop0_CAUSE_reset # RESET, disable counter
mtc0 $k0, cop0_CAUSE
mtc0 $k0, c0_cause
la $15,x_IO_BASE_ADDR
nop
......@@ -38,7 +38,7 @@ _exit: nop # flush pipeline
.org x_EXCEPTION_0000,0
_excp_0000:
la $k0, x_IO_BASE_ADDR
mfc0 $k1, cop0_CAUSE
mfc0 $k1, c0_cause
sw $k1, 0($k0) # print CAUSE, flush pipe and stop simulation
nop
nop
......@@ -48,7 +48,7 @@ _excp_0000:
.org x_EXCEPTION_0100,0
_excp_0100:
la $k0, x_IO_BASE_ADDR
mfc0 $k1, cop0_CAUSE
mfc0 $k1, c0_cause
sw $k1, 0($k0) # print CAUSE, flush pipe and stop simulation
nop
nop
......@@ -58,7 +58,7 @@ _excp_0100:
.org x_EXCEPTION_0180,0
_excp_180:
la $k0, x_IO_BASE_ADDR
mfc0 $k1, cop0_CAUSE
mfc0 $k1, c0_cause
sw $k1, 0($k0) # print CAUSE, flush pipe and stop simulation
nop
nop
......@@ -91,14 +91,14 @@ _excp_200:
sw $30, x_IO_ADDR_RANGE($15)
sw $13, x_IO_ADDR_RANGE($15) # blank line
mfc0 $k0, cop0_CAUSE # read CAUSE and
mfc0 $k0, c0_cause # read CAUSE and
lui $k1, 0x7fff # mask-off branch-delay bit
ori $k1, $k1, 0xffff
and $k0, $k0, $k1
sw $k0, 0($15) # print CAUSE
li $k0, 0x1800ff01 # enable interrupts
mtc0 $k0, cop0_STATUS
li $k0, 0x1800ff03 # enable interrupts, EXL=1
mtc0 $k0, c0_status
ehb
eret
......@@ -118,8 +118,8 @@ err3:
sw $13, x_IO_ADDR_RANGE($15) # blank line
sw $22, 0($15)
li $k0, 0x1800ff00 # disable interrupts
mtc0 $k0, cop0_STATUS
li $k0, 0x1800ff02 # disable interrupts, EXL=1
mtc0 $k0, c0_status
ehb
eret
......@@ -128,7 +128,7 @@ err3:
.org x_EXCEPTION_BFC0,0
_excp_BFC0:
la $k0, x_IO_BASE_ADDR
mfc0 $k1, cop0_CAUSE
mfc0 $k1, c0_cause
sw $k1, 0($k0) # print CAUSE, flush pipe and stop simulation
nop
nop
......@@ -151,10 +151,10 @@ main: la $15, x_IO_BASE_ADDR
mtc0 $5,cop0_COMPARE
# enable Counter
mfc0 $5,cop0_CAUSE
mfc0 $5,c0_cause
li $6,0xf7ffffff # CAUSE(DisableCount) <= 0
and $5,$5,$6
mtc0 $5,cop0_CAUSE # enable counter
mtc0 $5,c0_cause # enable counter
li $20, TRUE # counting is monotonic?
li $21, 0 # old value
......@@ -185,10 +185,10 @@ here: addiu $11, $12, 2 # this is a NOP
# check if the counter stops
#
there: sw $13, x_IO_ADDR_RANGE($15) # print a newline
mfc0 $5,cop0_CAUSE
mfc0 $5,c0_cause
lui $6,0x0880 # CAUSE(DisableCount) <= 1
or $5, $5, $6
mtc0 $5, cop0_CAUSE # disable counter
mtc0 $5, c0_cause # disable counter
addiu $11,$12,6 # this is a NOP
mfc0 $18, cop0_COUNT # print current COUNT
#sw $18, 0($15)
......
......@@ -85,7 +85,7 @@ _excp_200:
move $19, $24 # write part of JALR performed?
li $k0, 0x10008001 # CP0active, enable COUNT interrupts
li $k0, 0x10008003 # CP0active, enable COUNT irq, EXL=1
mtc0 $k0, c0_status
eret
#
......
......@@ -139,7 +139,7 @@ lo_pri: lui $k0, %hi(ext_restart)
rf_irq: sw $k1, 0x20($15) # print IRQ source
sw $13, 0x20($15)
li $k0, 0x1000f001 # CP0active, enable COUNT interrupts
li $k0, 0x1000f003 # CP0active, enable COUNT irq, EXL=1
mtc0 $k0, c0_status
eret
#
......
......@@ -8,10 +8,10 @@
.ent _start
_start: nop
li $k0,0x10000002 # RESET_STATUS, kernel mode, all else disabled
mtc0 $k0,cop0_STATUS
mtc0 $k0,c0_status
li $sp,(x_DATA_BASE_ADDR+x_DATA_MEM_SZ-8) # initialize SP: memTop-8
li $k0, 0x1000ff01 # enable interrupts
mtc0 $k0, cop0_STATUS
mtc0 $k0, c0_status
nop
j main
nop
......@@ -32,7 +32,7 @@ _exit: nop # flush pipeline
.org x_EXCEPTION_0000,0
_excp_0000:
la $k0, x_IO_BASE_ADDR
mfc0 $k1, cop0_CAUSE
mfc0 $k1, c0_cause
sw $k1, 0($k0) # print CAUSE, flush pipe and stop simulation
nop
nop
......@@ -42,7 +42,7 @@ _excp_0000:
.org x_EXCEPTION_0100,0
_excp_0100:
la $k0, x_IO_BASE_ADDR
mfc0 $k1, cop0_CAUSE
mfc0 $k1, c0_cause
sw $k1, 0($k0) # print CAUSE, flush pipe and stop simulation
nop
nop
......@@ -56,14 +56,14 @@ _excp_0100:
.global excp_180
.ent excp_180
excp_180:
mfc0 $k0, cop0_CAUSE # show cause
mfc0 $k0, c0_cause # show cause
sw $k0, 0($15)
li $k0, 0x10000000 # disable interrupts, kernel mode
mtc0 $k0, cop0_STATUS
mtc0 $k0, c0_status
li $k1, 0x00000000 # remove SW interrupt request
mtc0 $k1, cop0_CAUSE
li $k0, 0x1000ff01 # enable interrupts, user mode
mtc0 $k0, cop0_STATUS
mtc0 $k1, c0_cause
li $k0, 0x1000ff03 # enable interrupts, user mode, EXL=1
mtc0 $k0, c0_status
eret
nop
.end excp_180
......@@ -71,7 +71,7 @@ excp_180:
_excp_0200:
la $k0, x_IO_BASE_ADDR
mfc0 $k1, cop0_CAUSE
mfc0 $k1, c0_cause
sw $k1, 0($k0) # print CAUSE, flush pipe and stop simulation
nop
nop
......@@ -81,7 +81,7 @@ _excp_0200:
.org x_EXCEPTION_BFC0,0
_excp_BFC0:
la $k0, x_IO_BASE_ADDR
mfc0 $k1, cop0_CAUSE
mfc0 $k1, c0_cause
sw $k1, 0($k0) # print CAUSE, flush pipe and stop simulation
nop
nop
......@@ -113,7 +113,7 @@ L: ll $t1, 0($t0) # load-linked
nop
li $k1, 0x00000100 # cause SW interrupt after 4 rounds
mtc0 $k1, cop0_CAUSE # causes SC to fail and prints 0000.0000=CAUSE
mtc0 $k1, c0_cause # causes SC to fail and prints 0000.0000=CAUSE
nop # must delay SC so that interrupt starts before the SC
nop
......@@ -138,9 +138,9 @@ fwd: addi $t2, $t1, 1 # increment value read by LL
nop
li $k1, 0x00000000 # clear CAUSE
mtc0 $k1, cop0_CAUSE
li $k0,0x10000000 # RESET_STATUS, kernel mode, all else disabled
mtc0 $k0,cop0_STATUS
mtc0 $k1, c0_cause
li $k0, 0x10000000 # RESET_STATUS, kernel mode, all else disabled
mtc0 $k0, c0_status
##
......
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