Commit 981cbff7 authored by Roberto Hexsel's avatar Roberto Hexsel

fixed extCounter.c

parent 0fdaf364
00000318 00000318
[
08800010 08800010
00000319 00000319
]
00000319
[
08800010 08800010
0000031a 0000031a
]
0000031a
[
08800010 08800010
0000031b 0000031b
08800010 ]
0000031b
...@@ -13,7 +13,7 @@ _start: nop ...@@ -13,7 +13,7 @@ _start: nop
nop nop
mtc0 $k0, cop0_EPC mtc0 $k0, cop0_EPC
nop nop
eret # go into user mode, all else disabled eret # leave exception level, all else disabled
nop nop
exit: exit:
_exit: nop # flush pipeline _exit: nop # flush pipeline
...@@ -26,40 +26,51 @@ _exit: nop # flush pipeline ...@@ -26,40 +26,51 @@ _exit: nop # flush pipeline
nop nop
.end _start .end _start
.org x_EXCEPTION_0180,0 # exception vector_180 .org x_EXCEPTION_0180,0 # exception vector_180
.global _excp_180
.global excp_180 .global excp_180
.ent _excp_180 .ent excp_180
excp_180: excp_180:
_excp_180: li $k0, '[' # to separate output
sw $k0, x_IO_ADDR_RANGE($14)
li $k0, '\n'
sw $k0, x_IO_ADDR_RANGE($14)
mfc0 $k0, cop0_CAUSE mfc0 $k0, cop0_CAUSE
sw $k0, 0($15) # print CAUSE sw $k0, 0($14) # print CAUSE
mfc0 $k0, cop0_EPC # fix return address mfc0 $k0, cop0_EPC # fix return address
sw $k0, 0($14) # print EPC
addiu $7, $7, -1 addiu $7, $7, -1
srl $k0, $k0, 2
sll $k0, $k0, 2 addiu $k1, $zero, -4 # -4 = 0xffff.fffc
mtc0 $k0, cop0_EPC and $k1, $k1, $k0 # fix the invalid address
nop mtc0 $k1, cop0_EPC
li $k0, ']' # to separate output
sw $k0, x_IO_ADDR_RANGE($14)
li $k0, '\n'
sw $k0, x_IO_ADDR_RANGE($14)
eret eret
.end _excp_180 .end excp_180
.org x_ENTRY_POINT,0 # normal code start .org x_ENTRY_POINT,0 # normal code start
main: la $15,x_IO_BASE_ADDR main: la $14, x_IO_BASE_ADDR # used by handler
li $7,4 la $15, x_IO_BASE_ADDR
la $3,here li $7, 3
nop la $3, here
nop nop
here: sw $3, 0($15)
here: sw $3, 0($15)
nop # 4th jr is to this address nop # 4th jr is to this address
beq $7,$zero, end beq $7, $zero, end
nop nop
addiu $3,$3,1 addiu $3, $3, 1
nop # do not stall on $3
nop nop
jr $3 jr $3
nop nop
nop nop
nop nop
end: j exit end: j exit
nop nop
\ No newline at end of file
00000000 00000000
[
08800014
00000318
0f000001
]
00000001 00000001
00000002 [
08800014 08800014
00000318 00000318
0f000002
]
00000002 00000002
00000003 [
08800014 08800014
00000318 00000318
0f000003
]
00000003 00000003
00000004
08800014
00000318
00000004
00000003 00000003
[
08800010 08800010
00000354 00000358
00400001
]
00000002 00000002
[
08800010 08800010
00000354 00000358
00400002
]
00000001 00000001
[
08800010 08800010
00000354 00000358
00400003
]
00000000 00000000
00000000 00000000
[
08800014
000003a0
0f000001
]
00000001 00000001
00000002 00000002
[
08800014 08800014
00000390 000003b8
00000002 0f000003
]
00000003 00000003
00000004
08800014
00000390
00000004
00000005
00000006
08800014
00000390
00000006
00000003 00000003
[
08800010 08800010
000003c8 000003f0
00400001
]
00000002
00000002 00000002
[
08800010 08800010
000003c8 00000410
00400003
]
00000001 00000001
08800010
000003c8
00000000
...@@ -13,7 +13,7 @@ _start: nop ...@@ -13,7 +13,7 @@ _start: nop
nop nop
mtc0 $k0, cop0_EPC mtc0 $k0, cop0_EPC
nop nop
eret # go into user mode, all else disabled eret # leave exception level, all else disabled
nop nop
nop nop
exit: exit:
...@@ -27,94 +27,149 @@ _exit: nop # flush pipeline ...@@ -27,94 +27,149 @@ _exit: nop # flush pipeline
nop nop
.end _start .end _start
.org x_EXCEPTION_0180,0 # exception vector_180 .org x_EXCEPTION_0180,0 # exception vector_180
.global _excp_180
.global excp_180 .global excp_180
.ent _excp_180 .ent excp_180
excp_180: excp_180:
_excp_180: li $k0, '[' # to separate output
sw $k0, x_IO_ADDR_RANGE($14)
li $k0, '\n' # to separate output
sw $k0, x_IO_ADDR_RANGE($14)
mfc0 $k0, cop0_CAUSE mfc0 $k0, cop0_CAUSE
sw $k0,0($14) # print CAUSE sw $k0, 0($14) # print CAUSE
mfc0 $k0, cop0_EPC # print EPC
sw $k0, 0($14)
mfc0 $k0, cop0_EPC # mfc0 $k0, cop0_BadVAddr # print BadVAddr
sw $k0,0($14) # print EPC sw $k0, 0($14)
addiu $7,$7,-1 # repetiton counter
addiu $k1, $zero, -4 # -4 = 0xffff.fffc addiu $7, $7, -1 # repetiton counter
and $15,$15,$k1 # fix the invalid address
addiu $k1, $zero, -4 # -4 = 0xffff.fffc
and $15, $15, $k1 # fix the invalid address
li $k0, ']' # to separate output
sw $k0, x_IO_ADDR_RANGE($14)
li $k0, '\n' # to separate output
sw $k0, x_IO_ADDR_RANGE($14)
eret eret
.end _excp_180
.end excp_180
.org x_ENTRY_POINT,0 # normal code start .org x_ENTRY_POINT,0 # normal code start
main: la $14, x_IO_BASE_ADDR
la $15, x_IO_BASE_ADDR ##
li $7, 3 # do 3 rounds ## do 4 stores: 1st aligned, 2nd, 3rd, 4th misaligned,
la $3, -1 ## hence 3 exceptions of type AddrError store=x14
##
main: la $14, x_IO_BASE_ADDR # used by exception handler
la $15, x_IO_BASE_ADDR # used to generate misaligned references
li $7, 3 # do 4 rounds for each type of exception
li $3, 0 # exception handler decreases $7
nop nop
here: addiu $3, $3, 1 here: nop
sw $3, 0($15) # exception handler decreases $7 sw $3, 0($15) # causes 3 exceptions: addr&{01,10,11}
beq $7, $zero, next # there should be 3 exceptions: addr&{01,10,11} addiu $3, $3, 1 # 1st is aligned, 2nd,3rd,4th misaligned
nop # of type AddrError store=x14 beq $7, $zero, next
addu $15, $15, $3
j here
nop nop
j here
addu $15, $15, $3
next: li $29, '\n' # to separate output next: li $29, '\n' # to separate output
sw $29, x_IO_ADDR_RANGE($14) sw $29, x_IO_ADDR_RANGE($14)
sw $29, x_IO_ADDR_RANGE($14)
##
## do 4 loads, 1st aligned, 2nd, 3rd, 4th misaligned
## hence 3 exceptions of type AddrError if/ld=x10
##
la $15, x_DATA_BASE_ADDR la $15, x_DATA_BASE_ADDR
la $18, x_IO_BASE_ADDR la $18, x_IO_BASE_ADDR
li $7, 3 li $7, 3 # do 3 rounds
la $3, -1 li $3, 0
sw $7, 0($15) sw $7, 0($15)
nop nop
there: addiu $3,$3,1 there: nop
lw $3, 0($15) # there should be 3 exceptions: addr&{01,10,11} lw $5, 0($15) # causes 3 exceptions: addr&{01,10,11}
sw $7, 0($18) # of type AddrError if/ld=x10 sw $7, 0($18) # print value changed by handler
beq $7, $zero, after # sw $5, 0($18) # print value read from memory
nop addiu $3, $3, 1
addu $15, $15, $3 beq $7, $zero, after
j there nop
nop j there
addu $15, $15, $3
after: li $29, '\n' # to separate output after: li $29, '\n' # to separate output
sw $29, x_IO_ADDR_RANGE($14) sw $29, x_IO_ADDR_RANGE($14)
la $14, x_IO_BASE_ADDR sw $29, x_IO_ADDR_RANGE($14)
##
## do 4 half-word stores: 1st,3rd aligned, 2nd,4th misaligned,
## hence 3 exceptions of type AddrError store=x14
##
la $14, x_IO_BASE_ADDR # used by exception handler
la $15, x_IO_BASE_ADDR la $15, x_IO_BASE_ADDR
li $7, 3 li $7, 3
la $3, -1 li $3, 0
nop nop
here2: addiu $3, $3, 1 # there should be 3 exceptions: addr&{01,11} here2: sh $3, 0($15) # causes no exception: addr & 00
sh $3, 0($15) # of type AddrError store=x14 addiu $15, $15, 1 # of type AddrError store=x14
beq $7, $zero, next2 addiu $3 , $3, 1
nop sh $3, 0($15) # causes exception: addr & 01
addu $15, $15, $3 addiu $15, $15, 2 # handler fixes $15 to addr & 00
j here2 addiu $3 , $3, 1
nop sh $3, 0($15) # causes no exception: addr & 10
addiu $15, $15, 1
addiu $3 , $3, 1
sh $3, 0($15) # causes exception: addr & 10
next2: li $29, '\n' # to separate output next2: li $29, '\n' # to separate output
sw $29, x_IO_ADDR_RANGE($14)
sw $29, x_IO_ADDR_RANGE($14) sw $29, x_IO_ADDR_RANGE($14)
la $15, x_DATA_BASE_ADDR la $15, x_DATA_BASE_ADDR
la $18, x_IO_BASE_ADDR la $18, x_IO_BASE_ADDR
li $7, 3 li $7, 3
la $3, -1 la $3, 0
sw $7, 0($15) sw $7, 0($15)
nop nop
there2: lh $3, 0($15) # there should be 3 exceptions: addr&{01,11}
sw $7, 0($18) # of type AddrError if/ld=x10 ##
beq $7, $zero, end ## do 4 half-word loads: 1st,3rd aligned, 2nd,4th misaligned,
nop ## hence 3 exceptions of type AddrError if/ld=x10
addu $15, $15, $3 ##
nop
j there2 there2: lh $3, 0($15) # causes no exception: addr & 00
nop sw $7, 0($18)
addiu $15, $15, 1
addiu $3 , $3, 1
lh $3, 0($15) # causes exception: addr & 01
sw $7, 0($18)
addiu $15, $15, 2 # handler fixes $15 to addr & 00
addiu $3 , $3, 1
lh $3, 0($15) # causes no exception: addr & 10
sw $7, 0($18)
addiu $15, $15, 1
addiu $3 , $3, 1
lh $3, 0($15) # causes exception: addr & 10
sw $7, 0($18)
end: j exit end: j exit
nop nop
...@@ -30,7 +30,7 @@ void main(void) { ...@@ -30,7 +30,7 @@ void main(void) {
if ( (new=readCounter()) > old) { if ( (new=readCounter()) > old) {
increased = increased & TRUE; increased = increased & TRUE;
old = new; old = new;
// print(new); // print current count // print(new); // print current count, not for automated tests
} else { } else {
increased = FALSE; increased = FALSE;
} }
......
This diff is collapsed.
...@@ -32,6 +32,8 @@ entity reg_excp_IF_RF is ...@@ -32,6 +32,8 @@ entity reg_excp_IF_RF is
port(clk, rst, ld: in std_logic; port(clk, rst, ld: in std_logic;
IF_excp_type: in exception_type; IF_excp_type: in exception_type;
RF_excp_type: out exception_type; RF_excp_type: out exception_type;
PC_abort: in boolean;
RF_PC_abort: out boolean;
IF_PC: in reg32; IF_PC: in reg32;
RF_PC: out reg32); RF_PC: out reg32);
end reg_excp_IF_RF; end reg_excp_IF_RF;
...@@ -43,6 +45,7 @@ begin ...@@ -43,6 +45,7 @@ begin
if rising_edge(clk) then if rising_edge(clk) then
if ld = '0' then if ld = '0' then
RF_excp_type <= IF_excp_type ; RF_excp_type <= IF_excp_type ;
RF_PC_abort <= PC_abort ;
RF_PC <= IF_PC ; RF_PC <= IF_PC ;
end if; end if;
end if; end if;
...@@ -72,6 +75,8 @@ entity reg_excp_RF_EX is ...@@ -72,6 +75,8 @@ entity reg_excp_RF_EX is
EX_cop0_sel: out reg3; EX_cop0_sel: out reg3;
RF_is_delayslot: in std_logic; RF_is_delayslot: in std_logic;
EX_is_delayslot: out std_logic; EX_is_delayslot: out std_logic;
RF_PC_abort: in boolean;
EX_PC_abort: out boolean;
RF_PC: in reg32; RF_PC: in reg32;
EX_PC: out reg32; EX_PC: out reg32;
RF_nmi: in std_logic; RF_nmi: in std_logic;
...@@ -101,6 +106,7 @@ begin ...@@ -101,6 +106,7 @@ begin
EX_cop0_reg <= RF_cop0_reg ; EX_cop0_reg <= RF_cop0_reg ;
EX_cop0_sel <= RF_cop0_sel ; EX_cop0_sel <= RF_cop0_sel ;
EX_is_delayslot <= RF_is_delayslot ; EX_is_delayslot <= RF_is_delayslot ;
EX_PC_abort <= RF_PC_abort ;
EX_PC <= RF_PC ; EX_PC <= RF_PC ;
EX_nmi <= RF_nmi ; EX_nmi <= RF_nmi ;
EX_interrupt <= RF_interrupt ; EX_interrupt <= RF_interrupt ;
...@@ -131,6 +137,8 @@ entity reg_excp_EX_MM is ...@@ -131,6 +137,8 @@ entity reg_excp_EX_MM is
MM_PC: out reg32; MM_PC: out reg32;
EX_cop0_LLbit: in std_logic; EX_cop0_LLbit: in std_logic;
MM_cop0_LLbit: out std_logic; MM_cop0_LLbit: out std_logic;
addrError: in boolean;
MM_abort: out boolean;
EX_cop0_a_c: in reg5; EX_cop0_a_c: in reg5;
MM_cop0_a_c: out reg5; MM_cop0_a_c: out reg5;
EX_cop0_val: in reg32; EX_cop0_val: in reg32;
...@@ -155,6 +163,7 @@ begin ...@@ -155,6 +163,7 @@ begin
MM_can_trap <= EX_can_trap ; MM_can_trap <= EX_can_trap ;
MM_PC <= EX_PC ; MM_PC <= EX_PC ;
MM_cop0_LLbit <= EX_cop0_LLbit ; MM_cop0_LLbit <= EX_cop0_LLbit ;
MM_abort <= addrError ;
MM_cop0_a_c <= EX_cop0_a_c ; MM_cop0_a_c <= EX_cop0_a_c ;
MM_cop0_val <= EX_cop0_val ; MM_cop0_val <= EX_cop0_val ;
MM_ex_trapped <= EX_trapped ; MM_ex_trapped <= EX_trapped ;
...@@ -183,8 +192,8 @@ entity reg_excp_MM_WB is ...@@ -183,8 +192,8 @@ entity reg_excp_MM_WB is
WB_PC: out reg32; WB_PC: out reg32;
MM_cop0_LLbit: in std_logic; MM_cop0_LLbit: in std_logic;
WB_cop0_LLbit: out std_logic; WB_cop0_LLbit: out std_logic;
MM_abort: in std_logic; MM_abort: in boolean;
WB_abort: out std_logic; WB_abort: out boolean;
MM_cop0_a_c: in reg5; MM_cop0_a_c: in reg5;
WB_cop0_a_c: out reg5; WB_cop0_a_c: out reg5;
MM_cop0_val: in reg32; MM_cop0_val: in reg32;
...@@ -198,7 +207,7 @@ begin ...@@ -198,7 +207,7 @@ begin
if rst = '0' then if rst = '0' then
WB_can_trap <= b"00"; WB_can_trap <= b"00";
WB_cop0_LLbit <= '0'; WB_cop0_LLbit <= '0';
WB_abort <= '0'; WB_abort <= FALSE;
elsif rising_edge(clk) then elsif rising_edge(clk) then
if ld = '0' then if ld = '0' then
WB_excp_type <= MM_excp_type ; WB_excp_type <= MM_excp_type ;
......
...@@ -29,18 +29,19 @@ package p_EXCEPTION is ...@@ -29,18 +29,19 @@ package p_EXCEPTION is
exBREAK, exTRAP, exSYSCALL, -- 8 exBREAK, exTRAP, exSYSCALL, -- 8
exRESV_INSTR, exWAIT, -- 10 exRESV_INSTR, exWAIT, -- 10
IFaddressError, MMaddressErrorLD, MMaddressErrorST, --13 IFaddressError, MMaddressErrorLD, MMaddressErrorST, --13
exTLBrefill, exTLBdblFault, exTLBinval, exTLBmod, -- 17 exTLBrefill, exTLBrefillWR, -- 15
exOvfl, -- 18 exTLBdblFault, exTLBinval, exTLBmod, -- 18
exLL,exSC, -- 19,20 these are handled by COP0 exOvfl, -- 19
exEHB, -- 21 exLL,exSC, -- 20,21 these are handled by COP0
exTLBP, exTLBR, exTLBWI, exTLBWR, -- 25 exEHB, -- 22
exDERET, -- 26