From 313976cf3b7e9db46045146ae936d8af258381b3 Mon Sep 17 00:00:00 2001 From: dd-baoshan Date: Mon, 27 May 2024 17:03:55 +0800 Subject: [PATCH] Fix incorrect stack flow during nested irq Signed-off-by: dd-baoshan --- .../env/corev-dv/cv32e40p_asm_program_gen.sv | 20 +++++++++---------- .../env/corev-dv/cv32e40p_instr_test_pkg.sv | 8 ++++---- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/cv32e40p/env/corev-dv/cv32e40p_asm_program_gen.sv b/cv32e40p/env/corev-dv/cv32e40p_asm_program_gen.sv index b59df77f73..66bd44a981 100644 --- a/cv32e40p/env/corev-dv/cv32e40p_asm_program_gen.sv +++ b/cv32e40p/env/corev-dv/cv32e40p_asm_program_gen.sv @@ -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)); @@ -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. @@ -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 diff --git a/cv32e40p/env/corev-dv/cv32e40p_instr_test_pkg.sv b/cv32e40p/env/corev-dv/cv32e40p_instr_test_pkg.sv index 7b64f28c6c..630548bce4 100644 --- a/cv32e40p/env/corev-dv/cv32e40p_instr_test_pkg.sv +++ b/cv32e40p/env/corev-dv/cv32e40p_instr_test_pkg.sv @@ -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"; @@ -429,7 +429,7 @@ package cv32e40p_instr_test_pkg; instr.push_back($sformatf("4: nop")); //BNE 4f Target - end + end // PUSH_FREG endfunction @@ -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 @@ -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.