Commit c6cd4046 authored by Roberto Hexsel's avatar Roberto Hexsel

interrupt on a J/BR delay slot, with JR stalled, loaded the wrong EPC (thnx Vanessa)

parent f449ae9a
......@@ -117,7 +117,8 @@ dat=data.bin
mips-objcopy -S -j .data -j .rodata -O binary $elf $dat &&\
chmod a-x $bin $dat &&\
if [ $verbose = true ] ; then
mips-objdump -z -D -EL -M reg-names=numeric --show-raw-insn \
mips-objdump -z -D -EL -M reg-names=numeric -M cp0-names=mips2r2 \
--show-raw-insn \
--section .text --section .data --section .rodata --section .bss $elf
fi &&\
if [ $miffile = true ] ; then
......@@ -125,5 +126,6 @@ dat=data.bin
fi
# -M reg-names=mips2r2 -M cp0-names=mips2r2 \
# --section .reginfo
......@@ -150,7 +150,8 @@ mips-objcopy -S -j .text -O binary $elf $bin && \
-O binary $elf $dat || exit 1
if [ $? == 0 -a $verbose = true ]; then
mips-objdump -z -D -EL -M reg-names=numeric --show-raw-insn \
mips-objdump -z -D -EL -M reg-names=mips2r2 -M cp0-names=mips2r2 \
--show-raw-insn \
--section .text --section .data \
--section .rodata --section .sdata --section .sbss \
--section .bss $elf
......
......@@ -5,7 +5,7 @@ MEMORY
{
rom (rx) : ORIGIN = 0x00000000, /* x_INST_BASE_ADDR */
LENGTH = 0x00004000, /* x_INST_MEM_SZ */
ram (!rx) : ORIGIN = 0x00020000, /* x_DATA_BASE_ADDR */
ram (!rx) : ORIGIN = 0x00010000, /* x_DATA_BASE_ADDR */
LENGTH = 0x00008000, /* x_DATA_MEM_SZ */
io (!rx) : ORIGIN = 0x0f000000, /* not used, do not remove */
LENGTH = 0x00020000 /* edMemory.sh needs thess lines */
......
......@@ -98,7 +98,7 @@ void readStats(sStats *s) {
//=======================================================================
// memcpy -- need this to fool GCC into believing this is libc
// memcpy -- need this to fool GCC into believing we have libc
//=======================================================================
char *memcpy(char *dst, const char *src, int n) {
int cnt;
......@@ -133,7 +133,7 @@ char *memcpy(char *dst, const char *src, int n) {
//=======================================================================
// memset -- need this to fool GCC into believing this is libc
// memset -- need this to fool GCC into believing we have libc
//=======================================================================
char *memset(char *dst, const int val, int len) {
unsigned char *ptr = (unsigned char*)dst;
......
......@@ -132,6 +132,7 @@ architecture rtl of core is
WB_cop0_val: out std_logic_vector);
end component reg_excp_MM_WB;
signal nullify_MM_pre, nullify_MM_int :std_logic;
signal annul_1, annul_2, annul_twice : std_logic;
signal interrupt, exception_stall : std_logic;
signal exception_taken, interrupt_taken : std_logic;
......@@ -1596,10 +1597,15 @@ begin
MM_B_data <= i_data;
end process MM_FWD_LWLR;
-- if interrupt is in J/BR delaySlot, and JR was stalled, kill instr in MM
U_NULLIFY_THRICE:
FFD port map (clk, rst, '1', nullify_MM_pre, nullify_MM_int);
MM_wreg_cond <= '1' when ( (ram_stall = '1')
or MM_addrError -- abort regWrite if excptn in MEM
or (MM_move = '1' and MM_alu_move_ok = '0') )
or (MM_move = '1' and MM_alu_move_ok = '0')
or (nullify_MM_int = '1')
)
else MM_wreg;
......@@ -1863,6 +1869,7 @@ begin
interrupt_taken <= '0';
ExcCode <= cop0code_NULL;
is_delayslot <= '0';
nullify_MM_pre <= '0';
newSTATUS := STATUS; -- preserve as needed
newSTATUS(STATUS_BEV) := '0'; -- interrupts at offset 0x200
......@@ -2172,11 +2179,13 @@ begin
i_epc_update := '0';
i_nullify := TRUE; -- nullify instructions in IF,RF,EX
if MM_is_delayslot = '1' then -- instr is in delay slot
i_epc_source := EPC_src_MM; -- re-execute branch/jump
is_delayslot <= MM_is_delayslot;
i_epc_source := EPC_src_MM; -- re-execute branch/jump
is_delayslot <= MM_is_delayslot;
nullify_MM_pre <= '1'; -- if stalled, kill instrn in MM
else
i_epc_source := EPC_src_EX;
is_delayslot <= EX_is_delayslot;
i_epc_source := EPC_src_EX;
is_delayslot <= EX_is_delayslot;
nullify_MM_pre <= '0';
end if;
end if;
......@@ -2195,11 +2204,13 @@ begin
i_epc_update := '0';
i_nullify := TRUE; -- nullify instructions in IF,RF,EX
if MM_is_delayslot = '1' then -- instr is in delay slot
i_epc_source := EPC_src_MM; -- re-execute branch/jump
is_delayslot <= MM_is_delayslot;
i_epc_source := EPC_src_MM; -- re-execute branch/jump
is_delayslot <= MM_is_delayslot;
nullify_MM_pre <= '1'; -- if stalled, kill instrn in MM
else
i_epc_source := EPC_src_EX;
is_delayslot <= EX_is_delayslot;
i_epc_source := EPC_src_EX;
is_delayslot <= EX_is_delayslot;
nullify_MM_pre <= '0';
end if;
when others => null;
......
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