Merge pull request #1355 from davidharrishmc/dev

Fixed mstatus bits that should be read-only 0 in certain configurations
This commit is contained in:
Jordan Carlin 2025-04-12 18:52:22 -07:00 committed by GitHub
commit 23607134c4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 40 additions and 39 deletions

View file

@ -82,16 +82,16 @@ module csrsr import cvw::*; #(parameter cvw_t P) (
// extract values to write to upper status register on 64/32-bit access
if (P.XLEN==64) begin:upperstatus
assign nextMBE = CSRWriteValM[37] & P.BIGENDIAN_SUPPORTED;
assign nextSBE = CSRWriteValM[36] & P.S_SUPPORTED & P.BIGENDIAN_SUPPORTED;
assign nextMBE = P.BIGENDIAN_SUPPORTED & CSRWriteValM[37];
assign nextSBE = P.S_SUPPORTED & P.BIGENDIAN_SUPPORTED & CSRWriteValM[36];
end else begin:upperstatus
assign nextMBE = STATUS_MBE;
assign nextSBE = STATUS_SBE;
assign nextMBE = P.BIGENDIAN_SUPPORTED & STATUS_MBE;
assign nextSBE = P.S_SUPPORTED & P.BIGENDIAN_SUPPORTED & STATUS_SBE;
end
// hardwired STATUS bits
assign STATUS_TSR = P.S_SUPPORTED & STATUS_TSR_INT; // override reigster with 0 if supervisor mode not supported
assign STATUS_TW = (P.S_SUPPORTED | P.U_SUPPORTED) & STATUS_TW_INT; // override register with 0 if only machine mode supported
assign STATUS_TW = P.U_SUPPORTED & STATUS_TW_INT; // override register with 0 if only machine mode supported
assign STATUS_TVM = P.S_SUPPORTED & STATUS_TVM_INT; // override reigster with 0 if supervisor mode not supported
assign STATUS_MXR = P.S_SUPPORTED & STATUS_MXR_INT; // override reigster with 0 if supervisor mode not supported
// SXL and UXL bits only matter for RV64. Set to 10 for RV64 if mode is supported, or 0 if not
@ -151,7 +151,7 @@ module csrsr import cvw::*; #(parameter cvw_t P) (
STATUS_SPIE <= 1'b0;
STATUS_MIE <= 1'b0;
STATUS_SIE <= 1'b0;
STATUS_MBE <=1'b 0;
STATUS_MBE <= 1'b0;
STATUS_SBE <= 1'b0;
STATUS_UBE <= 1'b0;
end else if (~StallW) begin
@ -164,7 +164,7 @@ module csrsr import cvw::*; #(parameter cvw_t P) (
STATUS_MPIE <= STATUS_MIE;
STATUS_MIE <= 1'b0;
STATUS_MPP <= PrivilegeModeW;
end else begin // supervisor mode
end else if (P.S_SUPPORTED) begin // supervisor mode
STATUS_SPIE <= STATUS_SIE;
STATUS_SIE <= 1'b0;
STATUS_SPP <= PrivilegeModeW[0];
@ -174,18 +174,18 @@ module csrsr import cvw::*; #(parameter cvw_t P) (
STATUS_MPIE <= 1'b1; //
STATUS_MPP <= P.U_SUPPORTED ? P.U_MODE : P.M_MODE; // set MPP to lowest supported privilege level
STATUS_MPRV_INT <= STATUS_MPRV_INT & (STATUS_MPP == P.M_MODE); // page 21 of privileged spec.
end else if (sretM) begin
end else if (sretM & P.S_SUPPORTED) begin
STATUS_SIE <= STATUS_SPIE; // restore global interrupt enable
STATUS_SPIE <= P.S_SUPPORTED;
STATUS_SPP <= 1'b0; // set SPP to lowest supported privilege level to catch bugs
STATUS_MPRV_INT <= 1'b0; // always clear MPRV
end else if (WriteMSTATUSM) begin
STATUS_TSR_INT <= CSRWriteValM[22];
STATUS_TW_INT <= CSRWriteValM[21];
STATUS_TVM_INT <= CSRWriteValM[20];
STATUS_MXR_INT <= CSRWriteValM[19];
STATUS_SUM_INT <= CSRWriteValM[18];
STATUS_MPRV_INT <= CSRWriteValM[17];
STATUS_TSR_INT <= P.S_SUPPORTED & CSRWriteValM[22];
STATUS_TW_INT <= P.U_SUPPORTED & CSRWriteValM[21];
STATUS_TVM_INT <= P.S_SUPPORTED & CSRWriteValM[20];
STATUS_MXR_INT <= P.S_SUPPORTED & CSRWriteValM[19];
STATUS_SUM_INT <= P.VIRTMEM_SUPPORTED & CSRWriteValM[18];
STATUS_MPRV_INT <= P.U_SUPPORTED & CSRWriteValM[17];
STATUS_FS_INT <= CSRWriteValM[14:13];
STATUS_MPP <= STATUS_MPP_NEXT;
STATUS_SPP <= P.S_SUPPORTED & CSRWriteValM[8];
@ -193,23 +193,23 @@ module csrsr import cvw::*; #(parameter cvw_t P) (
STATUS_SPIE <= P.S_SUPPORTED & CSRWriteValM[5];
STATUS_MIE <= CSRWriteValM[3];
STATUS_SIE <= P.S_SUPPORTED & CSRWriteValM[1];
STATUS_UBE <= CSRWriteValM[6] & P.U_SUPPORTED & P.BIGENDIAN_SUPPORTED;
STATUS_UBE <= P.U_SUPPORTED & P.BIGENDIAN_SUPPORTED & CSRWriteValM[6];
STATUS_MBE <= nextMBE;
STATUS_SBE <= nextSBE;
// coverage off
// MSTATUSH only exists in 32-bit configurations, will not be hit on rv64gc
end else if (WriteMSTATUSHM) begin
STATUS_MBE <= CSRWriteValM[5] & P.BIGENDIAN_SUPPORTED;
STATUS_SBE <= CSRWriteValM[4] & P.S_SUPPORTED & P.BIGENDIAN_SUPPORTED;
end else if ((P.XLEN == 32) & WriteMSTATUSHM) begin
STATUS_MBE <= P.BIGENDIAN_SUPPORTED & CSRWriteValM[5];
STATUS_SBE <= P.S_SUPPORTED & P.BIGENDIAN_SUPPORTED & CSRWriteValM[4];
// coverage on
end else if (WriteSSTATUSM) begin // write a subset of the STATUS bits
STATUS_MXR_INT <= CSRWriteValM[19];
STATUS_SUM_INT <= CSRWriteValM[18];
end else if (P.S_SUPPORTED & WriteSSTATUSM) begin // write a subset of the STATUS bits
STATUS_MXR_INT <= P.S_SUPPORTED & CSRWriteValM[19];
STATUS_SUM_INT <= P.VIRTMEM_SUPPORTED & CSRWriteValM[18];
STATUS_FS_INT <= CSRWriteValM[14:13];
STATUS_SPP <= P.S_SUPPORTED & CSRWriteValM[8];
STATUS_SPIE <= P.S_SUPPORTED & CSRWriteValM[5];
STATUS_SIE <= P.S_SUPPORTED & CSRWriteValM[1];
STATUS_UBE <= CSRWriteValM[6] & P.U_SUPPORTED & P.BIGENDIAN_SUPPORTED;
STATUS_UBE <= P.U_SUPPORTED & P.BIGENDIAN_SUPPORTED & CSRWriteValM[6];
end else if (FRegWriteM | WriteFRMM | SetOrWriteFFLAGSM) STATUS_FS_INT <= 2'b11;
end
endmodule

View file

@ -72,7 +72,7 @@ module privdec import cvw::*; #(parameter cvw_t P) (
assign ebreakM = PrivilegedM & (InstrM[31:20] == 12'b000000000001) & rs1zeroM;
assign wfiM = PrivilegedM & (InstrM[31:20] == 12'b000100000101) & rs1zeroM;
assign sfencevmaM = PrivilegedM & (InstrM[31:25] == 7'b0001001 | invalM) &
(PrivilegeModeW == P.M_MODE | (PrivilegeModeW == P.S_MODE & ~STATUS_TVM));
(PrivilegeModeW == P.M_MODE | (PrivilegeModeW == P.S_MODE & ~STATUS_TVM)) & P.VIRTMEM_SUPPORTED;
///////////////////////////////////////////
// WFI timeout Privileged Spec 3.1.6.5

View file

@ -62,6 +62,7 @@ module riscvassertions import cvw::*; #(parameter cvw_t P);
assert ((P.ZICBOZ_SUPPORTED == 0) | (P.DTIM_SUPPORTED == 0)) else $fatal(1, "ZICBOZ incompatible with DTIM");
assert ((P.SVPBMT_SUPPORTED == 0) | (P.VIRTMEM_SUPPORTED == 1 & P.XLEN==64)) else $fatal(1, "SVPBMT requires VIRTMEM_SUPPORTED and RV64");
assert ((P.SVNAPOT_SUPPORTED == 0) | (P.VIRTMEM_SUPPORTED == 1 & P.XLEN==64)) else $fatal(1, "SVNAPOT requires VIRTMEM_SUPPORTED and RV64");
assert ((P.SVINVAL_SUPPORTED == 0) | (P.VIRTMEM_SUPPORTED == 1)) else $fatal(1, "SVINVAL requires VIRTMEM_SUPPORTED");
assert ((P.ZCA_SUPPORTED == 1) | (P.ZCD_SUPPORTED == 0 & P.ZCF_SUPPORTED == 0 & P.ZCB_SUPPORTED == 0)) else $fatal(1, "ZCB, ZCF, or ZCD requires ZCA");
assert ((P.ZCF_SUPPORTED == 0) | ((P.F_SUPPORTED == 1) & (P.XLEN == 32))) else $fatal(1, "ZCF requires F and XLEN == 32");
assert ((P.ZCD_SUPPORTED == 0) | (P.D_SUPPORTED == 1)) else $fatal(1, "ZCD requires D");

View file

@ -5,7 +5,7 @@ FFFFFFFF # stimecmp readback
00000000 # mtval of faulting instruction address (0x0)
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
00000002 # mcause from an Illegal instruction
00000000 # mtval of faulting instruction (0x0)
FFFFFFFF # mtval of faulting instruction (0x11111111)
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
00000003 # mcause from Breakpoint
80000168 # mtval of breakpoint instruction adress
@ -61,7 +61,7 @@ FFFFFFFF # stimecmp readback
00000000 # mtval of faulting instruction address (0x0)
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
00000002 # mcause from an Illegal instruction
00000000 # mtval of faulting instruction (0x0)
FFFFFFFF # stval of faulting instruction (0xFFFFFFFF)
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
00000003 # mcause from Breakpoint
80000168 # mtval of breakpoint instruction adress

View file

@ -6,7 +6,7 @@
00000000 # stval of faulting instruction address (0x0)
00000800 # masked out mstatus.mpp = 1, mstatus.MPIE = 0, and mstatus.MIE = 0
00000002 # scause from an Illegal instruction
00000000 # stval of faulting instruction (0x0)
FFFFFFFF # stval of faulting instruction (0xFFFFFFFF)
00000800 # masked out mstatus.mpp = 1, mstatus.MPIE = 0, and mstatus.MIE = 0
00000003 # scause from Breakpoint
80000168 # stval of breakpoint instruction adress
@ -57,7 +57,7 @@
00000000 # stval of faulting instruction address (0x0)
00000120 # masked out sstatus.SPP = 1, sstatus.SPIE = 1, and sstatus.SIE = 0
00000002 # scause from an Illegal instruction
00000000 # stval of faulting instruction (0x0)
FFFFFFFF # stval of faulting instruction (0xFFFFFFFF)
00000120 # masked out sstatus.SPP = 1, sstatus.SPIE = 1, and sstatus.SIE = 0
00000003 # scause from Breakpoint
80000168 # stval of breakpoint instruction adress

View file

@ -6,7 +6,7 @@
00000000 # stval of faulting instruction address (0x0)
00000000 # masked out mstatus.mpp = 0, mstatus.MPIE = 0, and mstatus.MIE = 0
00000002 # scause from an Illegal instruction
00000000 # stval of faulting instruction (0x0)
FFFFFFFF # stval of faulting instruction (0xFFFFFFFF)
00000000 # masked out mstatus.mpp = 0, mstatus.MPIE = 0, and mstatus.MIE = 0
00000003 # scause from Breakpoint
80000168 # stval of breakpoint instruction adress
@ -54,7 +54,7 @@
00000000 # stval of faulting instruction address (0x0)
00000020 # masked out sstatus.SPP = 0, sstatus.SPIE = 1, and sstatus.SIE = 0
00000002 # scause from an Illegal instruction
00000000 # stval of faulting instruction (0x0)
FFFFFFFF # stval of faulting instruction (0xFFFFFFFF)
00000020 # masked out sstatus.SPP = 0, sstatus.SPIE = 1, and sstatus.SIE = 0
00000003 # scause from Breakpoint
80000168 # stval of breakpoint instruction adress

View file

@ -89,7 +89,7 @@ cause_instr_access:
ret
cause_illegal_instr:
.insn 0x00000000 // 32 bit zero is an illegal instruction
.word 0xFFFFFFFF // 32 bit ones is an illegal instruction
ret
cause_breakpnt:

View file

@ -13,7 +13,7 @@ FFFFFFFF # stimecmp low bits
00000000
00000002 # mcause from an Illegal instruction
00000000
00000000 # mtval of faulting instruction (0x0)
FFFFFFFF # mtval of faulting instruction (0xFFFFFFFF)
00000000
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
00000000
@ -125,7 +125,7 @@ FFFFFFFF # stimecmp low bits
00000000
00000002 # mcause from an Illegal instruction
00000000
00000000 # mtval of faulting instruction (0x0)
FFFFFFFF # mtval of faulting instruction (0xFFFFFFFF)
00000000
00001880 # masked out mstatus.MPP = 11, mstatus.MPIE = 1, and mstatus.MIE = 0
00000000

View file

@ -8,13 +8,13 @@
00000000 # skipping instruction address fault since they're impossible with compressed instrs enabled
00000001 # scause from an instruction access fault
00000000
00000000 # stval of faulting instruction address (0x0)
00000000 # stval of faulting instruction address (0x00000000)
00000000
00000800 # masked out mstatus.mpp = 1, mstatus.MPIE = 0, and mstatus.MIE = 0
00000000
00000002 # scause from an Illegal instruction
00000000
00000000 # stval of faulting instruction (0x0)
FFFFFFFF # stval of faulting instruction (0xFFFFFFFF)
00000000
00000800 # masked out mstatus.mpp = 1, mstatus.MPIE = 0, and mstatus.MIE = 0
00000000
@ -116,7 +116,7 @@
00000000
00000002 # scause from an Illegal instruction
00000000
00000000 # stval of faulting instruction (0x0)
FFFFFFFF # stval of faulting instruction (0xFFFFFFFF)
00000000
00000120 # masked out sstatus.SPP = 1, sstatus.SPIE = 1, and sstatus.SIE = 0
00000000

View file

@ -8,13 +8,13 @@
00000000 # skipping instruction address fault since they're impossible with compressed instrs enabled
00000001 # scause from an instruction access fault
00000000
00000000 # stval of faulting instruction address (0x0)
00000000 # stval of faulting instruction address (0x00000000)
00000000
00000000 # masked out mstatus.mpp = 0, mstatus.MPIE = 0, and mstatus.MIE = 0
00000000
00000002 # scause from an Illegal instruction
00000000
00000000 # stval of faulting instruction (0x0)
FFFFFFFF # stval of faulting instruction (0xFFFFFFFF)
00000000
00000000 # masked out mstatus.mpp = 0, mstatus.MPIE = 0, and mstatus.MIE = 0
00000000
@ -110,7 +110,7 @@
00000000
00000002 # scause from an Illegal instruction
00000000
00000000 # stval of faulting instruction (0x0)
FFFFFFFF # stval of faulting instruction (0xFFFFFFFF)
00000000
00000020 # masked out sstatus.SPP = 0, sstatus.SPIE = 1, and sstatus.SIE = 0
00000000

View file

@ -90,7 +90,7 @@ cause_instr_access:
ret
cause_illegal_instr:
.insn 0x00000000 // 32 bit zero is an illegal instruction
.word 0xFFFFFFFF // 32 bit 1s is an illegal instruction
ret
cause_breakpnt: