Skip to content

Commit

Permalink
Fix incorrect stack flow during nested irq
Browse files Browse the repository at this point in the history
Signed-off-by: dd-baoshan <[email protected]>
  • Loading branch information
dd-baoshan committed May 27, 2024
1 parent 3a50f5e commit 313976c
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 14 deletions.
20 changes: 10 additions & 10 deletions cv32e40p/env/corev-dv/cv32e40p_asm_program_gen.sv
Original file line number Diff line number Diff line change
Expand Up @@ -289,13 +289,13 @@ class cv32e40p_asm_program_gen extends corev_asm_program_gen;

// Push MIE, MEPC and MSTATUS to stack
interrupt_handler_instr.push_back($sformatf("csrr x%0d, mie", cfg.gpr[0]));
interrupt_handler_instr.push_back($sformatf("%0s x%0d, %0d(x%0d)", store_instr, cfg.gpr[0], 1 * (XLEN/8), cfg.sp));
interrupt_handler_instr.push_back($sformatf("%0s x%0d, %0d(x%0d)", store_instr, cfg.gpr[0], 0 * (XLEN/8), cfg.sp));
interrupt_handler_instr.push_back($sformatf("csrr x%0d, mepc", cfg.gpr[0]));
interrupt_handler_instr.push_back($sformatf("%0s x%0d, %0d(x%0d)", store_instr, cfg.gpr[0], 2 * (XLEN/8), cfg.sp));
interrupt_handler_instr.push_back($sformatf("%0s x%0d, %0d(x%0d)", store_instr, cfg.gpr[0], 1 * (XLEN/8), cfg.sp));
interrupt_handler_instr.push_back($sformatf("csrr x%0d, mstatus", cfg.gpr[0]));
interrupt_handler_instr.push_back($sformatf("%0s x%0d, %0d(x%0d)", store_instr, cfg.gpr[0], 3 * (XLEN/8), cfg.sp));
interrupt_handler_instr.push_back($sformatf("%0s x%0d, %0d(x%0d)", store_instr, cfg.gpr[0], 2 * (XLEN/8), cfg.sp));
interrupt_handler_instr.push_back($sformatf("csrr x%0d, mscratch", cfg.gpr[0]));
interrupt_handler_instr.push_back($sformatf("%0s x%0d, %0d(x%0d)", store_instr, cfg.gpr[0], 4 * (XLEN/8), cfg.sp));
interrupt_handler_instr.push_back($sformatf("%0s x%0d, %0d(x%0d)", store_instr, cfg.gpr[0], 3 * (XLEN/8), cfg.sp));

// Move SP to TP and restore TP
interrupt_handler_instr.push_back($sformatf("add x%0d, x%0d, zero", cfg.tp, cfg.sp));
Expand All @@ -314,7 +314,7 @@ class cv32e40p_asm_program_gen extends corev_asm_program_gen;
end
default: `uvm_fatal(`gfn, $sformatf("Unsupported status %0s", status))
endcase
end
end // enable_nested_interrupt

// Read back interrupt related privileged CSR
// The value of these CSR are checked by comparing with spike simulation result.
Expand Down Expand Up @@ -352,17 +352,17 @@ class cv32e40p_asm_program_gen extends corev_asm_program_gen;
interrupt_handler_instr.push_back($sformatf("csrrw x%0d, mscratch, x%0d", cfg.sp, cfg.sp));
interrupt_handler_instr.push_back($sformatf("add x%0d, x%0d, zero", cfg.sp, cfg.tp));

interrupt_handler_instr.push_back($sformatf("%0s x%0d, %0d(x%0d)", load_instr, cfg.gpr[0], 1 * (XLEN/8), cfg.sp));
interrupt_handler_instr.push_back($sformatf("%0s x%0d, %0d(x%0d)", load_instr, cfg.gpr[0], 0 * (XLEN/8), cfg.sp));
interrupt_handler_instr.push_back($sformatf("csrw mie, x%0d", cfg.gpr[0]));
interrupt_handler_instr.push_back($sformatf("%0s x%0d, %0d(x%0d)", load_instr, cfg.gpr[0], 2 * (XLEN/8), cfg.sp));
interrupt_handler_instr.push_back($sformatf("%0s x%0d, %0d(x%0d)", load_instr, cfg.gpr[0], 1 * (XLEN/8), cfg.sp));
interrupt_handler_instr.push_back($sformatf("csrw mepc, x%0d", cfg.gpr[0]));
interrupt_handler_instr.push_back($sformatf("%0s x%0d, %0d(x%0d)", load_instr, cfg.gpr[0], 3 * (XLEN/8), cfg.sp));
interrupt_handler_instr.push_back($sformatf("%0s x%0d, %0d(x%0d)", load_instr, cfg.gpr[0], 2 * (XLEN/8), cfg.sp));
interrupt_handler_instr.push_back($sformatf("csrw mstatus, x%0d", cfg.gpr[0]));
interrupt_handler_instr.push_back($sformatf("%0s x%0d, %0d(x%0d)", load_instr, cfg.gpr[0], 4 * (XLEN/8), cfg.sp));
interrupt_handler_instr.push_back($sformatf("%0s x%0d, %0d(x%0d)", load_instr, cfg.gpr[0], 3 * (XLEN/8), cfg.sp));
interrupt_handler_instr.push_back($sformatf("csrw mscratch, x%0d", cfg.gpr[0]));

interrupt_handler_instr.push_back($sformatf("addi x%0d, x%0d, %0d", cfg.sp, cfg.sp, 4 * (XLEN/8)));
end
end // enable_nested_interrupt

// Restore user mode GPR value from kernel stack before return

Expand Down
8 changes: 4 additions & 4 deletions cv32e40p/env/corev-dv/cv32e40p_instr_test_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ package cv32e40p_instr_test_pkg;
instr.push_back($sformatf("%0s x%0d, %0d(x%0d)", store_instr, i, (i-1) * (XLEN/8), sp));
end

if(cfg_corev.enable_floating_point && !cfg_corev.enable_fp_in_x_regs) begin
if(cfg_corev.enable_floating_point && !cfg_corev.enable_fp_in_x_regs) begin : PUSH_FREG
randcase
1: store_instr = (FLEN == 32) ? "fsw" : "fsd";
(sp == 2): store_instr = (FLEN == 32) ? "c.fswsp" : "fsd";
Expand Down Expand Up @@ -429,7 +429,7 @@ package cv32e40p_instr_test_pkg;

instr.push_back($sformatf("4: nop")); //BNE 4f Target

end
end // PUSH_FREG

endfunction

Expand All @@ -445,7 +445,7 @@ package cv32e40p_instr_test_pkg;

string load_instr;

if(cfg_corev.enable_floating_point && !cfg_corev.enable_fp_in_x_regs) begin
if(cfg_corev.enable_floating_point && !cfg_corev.enable_fp_in_x_regs) begin : POP_FREG
load_instr = (XLEN == 32) ? "lw" : "ld";

// Pop MSTATUS.FS from kernel stack
Expand Down Expand Up @@ -497,7 +497,7 @@ package cv32e40p_instr_test_pkg;

instr.push_back($sformatf("2: nop")); //BNE 2f Target

end
end // POP_FREG

// fixme: the irq handling logic flow need to be rework to consider nested irq scenario for fpu csr such as FS.
// workaround_1 for MSTATUS.FS during nested irq by assuming FS always DIRTY prior irq handling.
Expand Down

0 comments on commit 313976c

Please sign in to comment.