diff --git a/libs/cheri-cap-lib b/libs/cheri-cap-lib index 4b08d61..80ba19d 160000 --- a/libs/cheri-cap-lib +++ b/libs/cheri-cap-lib @@ -1 +1 @@ -Subproject commit 4b08d61aa228a1170876a89f738e21eae953739c +Subproject commit 80ba19db9fdef5a59b4fa1d1f33f3b02d27a7d91 diff --git a/src_Core/CHERI/ScrFile.bsv b/src_Core/CHERI/ScrFile.bsv index 54e3580..36a3c74 100644 --- a/src_Core/CHERI/ScrFile.bsv +++ b/src_Core/CHERI/ScrFile.bsv @@ -140,10 +140,10 @@ module mkScrFile (ScrFile); Reg#(CapReg) ddc_reg <- mkCsrReg(defaultValue); // User level SCRs with accessSysRegs - Reg#(CapReg) utcc_reg <- mkCsrReg(defaultValue); - Reg#(CapReg) utdc_reg <- mkCsrReg(nullCap); - Reg#(CapReg) uScratchC_reg <- mkCsrReg(nullCap); - Reg#(CapReg) uepcc_reg <- mkCsrReg(defaultValue); + // Reg#(CapReg) utcc_reg <- mkCsrReg(defaultValue); + // Reg#(CapReg) utdc_reg <- mkCsrReg(nullCap); + // Reg#(CapReg) uScratchC_reg <- mkCsrReg(nullCap); + // Reg#(CapReg) uepcc_reg <- mkCsrReg(defaultValue); // System level SCRs with accessSysRegs Reg#(CapReg) stcc_reg <- mkCsrReg(defaultValue); @@ -164,10 +164,10 @@ module mkScrFile (ScrFile); SCR_PCC: pcc_reg[0]; SCR_DDC: ddc_reg; // User CSRs with accessSysRegs - SCR_UTCC: utcc_reg; - SCR_UTDC: utdc_reg; - SCR_UScratchC: uScratchC_reg; - SCR_UEPCC: uepcc_reg; + // SCR_UTCC: utcc_reg; + // SCR_UTDC: utdc_reg; + // SCR_UScratchC: uScratchC_reg; + // SCR_UEPCC: uepcc_reg; // System CSRs with accessSysRegs SCR_STCC: stcc_reg; SCR_STDC: stdc_reg; diff --git a/src_Core/ISA/ISA_Decls_CHERI.bsv b/src_Core/ISA/ISA_Decls_CHERI.bsv index 684fd70..4d45b26 100755 --- a/src_Core/ISA/ISA_Decls_CHERI.bsv +++ b/src_Core/ISA/ISA_Decls_CHERI.bsv @@ -67,6 +67,9 @@ typedef struct { CHERIException cheri_exc_code; } CSR_XCapCause deriving(Bits, FShow); +CSR_XCapCause noCapCause = CSR_XCapCause {cheri_exc_code: None, + cheri_exc_reg: unpack(0)}; + function Bit#(64) xccsr_to_word(CSR_XCapCause xccsr); return zeroExtend({xccsr.cheri_exc_reg, pack(xccsr.cheri_exc_code), 3'b0, 1'b1, 1'b1}); endfunction @@ -85,10 +88,10 @@ typedef enum { SCR_PCC = 5'd00, SCR_DDC = 5'd01, - SCR_UTCC = 5'd04, - SCR_UTDC = 5'd05, - SCR_UScratchC = 5'd06, - SCR_UEPCC = 5'd07, +// SCR_UTCC = 5'd04, +// SCR_UTDC = 5'd05, +// SCR_UScratchC = 5'd06, +// SCR_UEPCC = 5'd07, SCR_STCC = 5'd12, SCR_STDC = 5'd13, @@ -98,8 +101,32 @@ typedef enum { SCR_MTCC = 5'd28, SCR_MTDC = 5'd29, SCR_MScratchC = 5'd30, - SCR_MEPCC = 5'd31 -} SCR deriving(Bits, Eq, FShow); + SCR_MEPCC = 5'd31, + + // As with CSRs, SCR that catches all unimplemented SCRs + SCR_None = 5'd10 +} SCR deriving(Bits, Eq, FShow, Bounded); + +function SCR unpackSCR(Bit#(5) x); + return (case(x) + pack(SCR'(SCR_PCC )): (SCR_PCC ); + pack(SCR'(SCR_DDC )): (SCR_DDC ); +// pack(SCR'(SCR_UTCC )): (SCR_UTCC ); +// pack(SCR'(SCR_UTDC )): (SCR_UTDC ); +// pack(SCR'(SCR_UScratchC)): (SCR_UScratchC); +// pack(SCR'(SCR_UEPCC )): (SCR_UEPCC ); + pack(SCR'(SCR_STCC )): (SCR_STCC ); + pack(SCR'(SCR_STDC )): (SCR_STDC ); + pack(SCR'(SCR_SScratchC)): (SCR_SScratchC); + pack(SCR'(SCR_SEPCC )): (SCR_SEPCC ); + pack(SCR'(SCR_MTCC )): (SCR_MTCC ); + pack(SCR'(SCR_MTDC )): (SCR_MTDC ); + pack(SCR'(SCR_MScratchC)): (SCR_MScratchC); + pack(SCR'(SCR_MEPCC )): (SCR_MEPCC ); + + default : (SCR_None ); + endcase); +endfunction function CapPipe update_scr_via_csr (CapPipe old_scr, WordXL new_csr); let new_scr = setOffset(old_scr, new_csr); diff --git a/src_Core/RISCY_OOO/procs/RV64G_OOO/AluExePipeline.bsv b/src_Core/RISCY_OOO/procs/RV64G_OOO/AluExePipeline.bsv index 671b719..816c70c 100755 --- a/src_Core/RISCY_OOO/procs/RV64G_OOO/AluExePipeline.bsv +++ b/src_Core/RISCY_OOO/procs/RV64G_OOO/AluExePipeline.bsv @@ -89,7 +89,8 @@ typedef struct { Maybe#(Data) csrData; // data to write CSR file Maybe#(CapPipe) scrData; // datat to write to special capability register file. ControlFlow controlFlow; - Maybe#(CHERIException) capException; + Maybe#(CSR_XCapCause) capException; + Maybe#(BoundsCheck) check; // speculation Maybe#(SpecTag) spec_tag; `ifdef RVFI @@ -157,7 +158,7 @@ interface AluExeInput; Maybe#(Data) csrData, Maybe#(CapPipe) scrData, ControlFlow cf, - Maybe#(CHERIException) capCause, + Maybe#(CSR_XCapCause) capCause, CapPipe pcc `ifdef RVFI , ExtraTraceBundle tb @@ -256,6 +257,9 @@ module mkAluExePipeline#(AluExeInput inIfc)(AluExePipeline); // get rVal2 (check bypass) CapPipe rVal2 = nullCap; + if(x.dInst.scr matches tagged Valid .scr) begin + rVal2 = cast(inIfc.scaprf_rd(scr)); + end if(x.regs.src2 matches tagged Valid .src2 &&& src2 != 0) begin rVal2 <- readRFBypass(src2, regsReady.src2, inIfc.rf_rd2(src2), bypassWire); end @@ -323,7 +327,8 @@ module mkAluExePipeline#(AluExeInput inIfc)(AluExePipeline); // This means that we will have instructions that both write SCR registers and also get mispredictions, unlike // the CSR file. Given the assertions above, this seems dangerous... scrData: isValid(x.dInst.scr) ? Valid (exec_result.scrData) : tagged Invalid, - capException: isValid(exec_result.capException) ? (Valid (exec_result.capException.Valid.cheri_exc_code)) : Invalid, + capException: exec_result.capException, + check: exec_result.boundsCheck, `ifdef RVFI traceBundle: ExtraTraceBundle{ regWriteData: getAddr(exec_result.data), @@ -349,6 +354,13 @@ module mkAluExePipeline#(AluExeInput inIfc)(AluExePipeline); inIfc.writeRegFile(dst.indx, x.data); end + if (x.check matches tagged Valid .check &&& x.capException matches tagged Invalid) begin + if (!( (check.check_low >= check.authority_base) && + (check.check_inclusive ? (check.check_high <= check.authority_top ) + : (check.check_high < check.authority_top )))) + x.capException = Valid(CSR_XCapCause{cheri_exc_reg: check.authority_idx, cheri_exc_code: LengthViolation}); + end + // update the instruction in the reorder buffer. inIfc.rob_setExecuted( x.tag, diff --git a/src_Core/RISCY_OOO/procs/RV64G_OOO/RenameStage.bsv b/src_Core/RISCY_OOO/procs/RV64G_OOO/RenameStage.bsv index df28f75..92bee4b 100644 --- a/src_Core/RISCY_OOO/procs/RV64G_OOO/RenameStage.bsv +++ b/src_Core/RISCY_OOO/procs/RV64G_OOO/RenameStage.bsv @@ -358,7 +358,7 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage); // This avoids doing incorrect work incrEpochStallFetch; Maybe#(TrapWithCap) trapWithCap = Invalid; - if (firstTrap matches tagged Valid .trap) trapWithCap = tagged Valid TrapWithCap{trap: trap, capExp: None}; + if (firstTrap matches tagged Valid .trap) trapWithCap = tagged Valid TrapWithCap{trap: trap, capExp: noCapCause}; // just place it in the reorder buffer let y = ToReorderBuffer{pc: setAddr(almightyCap, pc).value, orig_inst: orig_inst, diff --git a/src_Core/RISCY_OOO/procs/lib/CSRs.bsvi b/src_Core/RISCY_OOO/procs/lib/CSRs.bsvi new file mode 100644 index 0000000..60987aa --- /dev/null +++ b/src_Core/RISCY_OOO/procs/lib/CSRs.bsvi @@ -0,0 +1,72 @@ + // user standard CSRs + `CSR(CSRfflags , 12'h001) + `CSR(CSRfrm , 12'h002) + `CSR(CSRfcsr , 12'h003) + `CSR(CSRcycle , 12'hc00) + `CSR(CSRtime , 12'hc01) + `CSR(CSRinstret , 12'hc02) + // user non-standard CSRs (TODO) + `CSR(CSRterminate , 12'h800) // terminate (used to exit Linux) + `CSR(CSRstats , 12'h801) // turn on/off perf counters + // `CSR(CSRuccsr , 12'h8c0) + // supervisor standard `CSR(CSRs + `CSR(CSRsstatus , 12'h100) + // no user trap handler, so no se/ideleg + `CSR(CSRsie , 12'h104) + `CSR(CSRstvec , 12'h105) + `CSR(CSRscounteren , 12'h106) + `CSR(CSRsscratch , 12'h140) + `CSR(CSRsepc , 12'h141) + `CSR(CSRscause , 12'h142) + `CSR(CSRstval , 12'h143) // it's still called sbadaddr in spike + `CSR(CSRsip , 12'h144) + `CSR(CSRsatp , 12'h180) // it's still called sptbr in spike + `CSR(CSRsccsr , 12'h9c0) + // machine standard CSRs + `CSR(CSRmstatus , 12'h300) + `CSR(CSRmisa , 12'h301) + `CSR(CSRmedeleg , 12'h302) + `CSR(CSRmideleg , 12'h303) + `CSR(CSRmie , 12'h304) + `CSR(CSRmtvec , 12'h305) + `CSR(CSRmcounteren , 12'h306) + `CSR(CSRmscratch , 12'h340) + `CSR(CSRmepc , 12'h341) + `CSR(CSRmcause , 12'h342) + `CSR(CSRmtval , 12'h343) // it's still called mbadaddr in spike + `CSR(CSRmip , 12'h344) + `CSR(CSRmcycle , 12'hb00) + `CSR(CSRminstret , 12'hb02) + `CSR(CSRmvendorid , 12'hf11) + `CSR(CSRmarchid , 12'hf12) + `CSR(CSRmimpid , 12'hf13) + `CSR(CSRmhartid , 12'hf14) + `CSR(CSRmccsr , 12'hbc0) +`ifdef SECURITY + // sanctum machine CSR + `CSR(CSRmevbase , 12'h7c0) + `CSR(CSRmevmask , 12'h7c1) + `CSR(CSRmeatp , 12'h7c2) + `CSR(CSRmmrbm , 12'h7c3) + `CSR(CSRmemrbm , 12'h7c4) + `CSR(CSRmparbase , 12'h7c5) + `CSR(CSRmparmask , 12'h7c6) + `CSR(CSRmeparbase , 12'h7c7) + `CSR(CSRmeparmask , 12'h7c8) + `CSR(CSRmflush , 12'h7c9) // flush pipeline + cache + `CSR(CSRmspec , 12'h7ca) // control speculation + // sanctum user CSR + `CSR(CSRtrng , 12'hcc0) // random number for secure boot +`endif + + `CSR(CSRtselect , 12'h7A0) // Debug/trace tselect + `CSR(CSRtdata1 , 12'h7A1) // Debug/trace tdata1 + `CSR(CSRtdata2 , 12'h7A2) // Debug/trace tdata2 + `CSR(CSRtdata3 , 12'h7A3) // Debug/trace tdata3 + +`ifdef INCLUDE_GDB_CONTROL + `CSR(CSRdcsr , 12'h7B0) // Debug control and status + `CSR(CSRdpc , 12'h7B1) // Debug PC + `CSR(CSRdscratch0 , 12'h7B2) // Debug scratch0 + `CSR(CSRdscratch1 , 12'h7B3) // Debug scratch1 +`endif diff --git a/src_Core/RISCY_OOO/procs/lib/CapChecks.bsvi b/src_Core/RISCY_OOO/procs/lib/CapChecks.bsvi new file mode 100644 index 0000000..4fd4435 --- /dev/null +++ b/src_Core/RISCY_OOO/procs/lib/CapChecks.bsvi @@ -0,0 +1,18 @@ +`CAP_CHECK_FIELD(src1_tag,"src1_tag") +`CAP_CHECK_FIELD(src2_tag,"src2_tag") +`CAP_CHECK_FIELD(src1_sealed_with_type,"src1_sealed_with_type") +`CAP_CHECK_FIELD(src1_unsealed,"src1_unsealed") +`CAP_CHECK_FIELD(src2_unsealed,"src2_unsealed") +`CAP_CHECK_FIELD(src1_sealed,"src1_sealed") +`CAP_CHECK_FIELD(src2_sealed,"src2_sealed") +`CAP_CHECK_FIELD(src1_src2_types_match,"src1_src2_types_match") +`CAP_CHECK_FIELD(src1_permit_ccall,"src1_permit_ccall") +`CAP_CHECK_FIELD(src2_permit_ccall,"src2_permit_ccall") +`CAP_CHECK_FIELD(src1_permit_x,"src1_permit_x") +`CAP_CHECK_FIELD(src2_no_permit_x,"src2_no_permit_x") +`CAP_CHECK_FIELD(src2_permit_unseal,"src2_permit_unseal") +`CAP_CHECK_FIELD(src2_permit_seal,"src2_permit_seal") +`CAP_CHECK_FIELD(src2_points_to_src1_type,"src2_points_to_src1_type") +`CAP_CHECK_FIELD(src2_addr_valid_type,"src2_addr_valid_type") +`CAP_CHECK_FIELD(src1_perm_subset_src2,"src1_perm_subset_src2") +`CAP_CHECK_FIELD(src1_derivable,"src1_derivable") diff --git a/src_Core/RISCY_OOO/procs/lib/Decode.bsv b/src_Core/RISCY_OOO/procs/lib/Decode.bsv index 2ddce34..0576f24 100755 --- a/src_Core/RISCY_OOO/procs/lib/Decode.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Decode.bsv @@ -185,6 +185,7 @@ function DecodeResult decode(Instruction inst); ImmData immB = signExtend({ inst[31], inst[7], inst[30:25], inst[11:8], 1'b0}); ImmData immU = signExtend({ inst[31:12], 12'b0 }); ImmData immJ = signExtend({ inst[31], inst[19:12], inst[20], inst[30:21], 1'b0}); + ImmData immIunsigned = zeroExtend(inst[31:20]); // Results of mini-decoders Maybe#(MemInst) mem_inst = decodeMemInst(inst); @@ -738,42 +739,76 @@ function DecodeResult decode(Instruction inst); dInst.execFunc = CapModify (ModifyOffset (IncOffset)); end f3_cap_CSetBoundsImmediate: begin - illegalInst = True; - // TODO - // dInst.capChecks.src1_tag = True; - // dInst.capChecks.src1_unsealed = True; + dInst.capChecks.src1_tag = True; + dInst.capChecks.src1_unsealed = True; - // regs.dst = Valid(tagged Gpr rd); - // regs.src1 = Valid(tagged Gpr rs1); - // regs.src1 = Invalid; - // dInst.imm = Valid (immI); + dInst.capChecks.check_enable = True; + dInst.capChecks.check_authority_src = Src1; + dInst.capChecks.check_low_src = Src1Addr; + dInst.capChecks.check_high_src = ResultTop; + dInst.capChecks.check_inclusive = True; + + dInst.iType = Alu; + regs.dst = Valid(tagged Gpr rd); + regs.src1 = Valid(tagged Gpr rs1); + regs.src2 = Invalid; + dInst.imm = Valid (immIunsigned); + dInst.execFunc = CapModify (SetBounds (SetBounds)); end f3_cap_ThreeOp: begin case (funct7) f7_cap_CSpecialRW: begin - // TODO + // TODO capChecks + + dInst.iType = Alu; + regs.dst = Valid(tagged Gpr rd); + regs.src1 = Valid(tagged Gpr rs1); + regs.src2 = Invalid; + dInst.scr = Valid (unpackSCR(rs2)); + + let scrType = case (rs2[1:0]) + 0: TCC; + 3: EPCC; + default: Normal; + endcase; + + dInst.execFunc = CapModify (SpecialRW (scrType)); end f7_cap_CSetBounds: begin - illegalInst = True; - // TODO - // dInst.capChecks.src1_tag = True; - // dInst.capChecks.src1_unsealed = True; + dInst.capChecks.src1_tag = True; + dInst.capChecks.src1_unsealed = True; - // regs.dst = Valid(tagged Gpr rd); - // regs.src1 = Valid(tagged Gpr rs1); - // regs.src2 = Valid(tagged Gpr rs2); - // dInst.imm = Invalid; + dInst.capChecks.check_enable = True; + dInst.capChecks.check_authority_src = Src1; + dInst.capChecks.check_low_src = Src1Addr; + dInst.capChecks.check_high_src = ResultTop; + dInst.capChecks.check_inclusive = True; + + dInst.iType = Alu; + regs.dst = Valid(tagged Gpr rd); + regs.src1 = Valid(tagged Gpr rs1); + regs.src2 = Valid(tagged Gpr rs2); + dInst.imm = Invalid; + dInst.execFunc = CapModify (SetBounds (SetBounds)); end f7_cap_CSetBoundsExact: begin illegalInst = True; - // TODO - // dInst.capChecks.src1_tag = True; - // dInst.capChecks.src1_unsealed = True; + dInst.capChecks.src1_tag = True; + dInst.capChecks.src1_unsealed = True; + // TODO assert exact - // regs.dst = Valid(tagged Gpr rd); - // regs.src1 = Valid(tagged Gpr rs1); - // regs.src2 = Valid(tagged Gpr rs2); - // dInst.imm = Invalid; + dInst.capChecks.check_enable = True; + dInst.capChecks.check_authority_src = Src1; + dInst.capChecks.check_low_src = Src1Addr; + dInst.capChecks.check_high_src = ResultTop; + dInst.capChecks.check_inclusive = True; + + dInst.iType = Alu; + regs.dst = Valid(tagged Gpr rd); + regs.src1 = Valid(tagged Gpr rs1); + regs.src2 = Valid(tagged Gpr rs2); + dInst.imm = Invalid; + dInst.execFunc = CapModify (SetBounds (SetBounds)); end f7_cap_CSetOffset: begin dInst.capChecks.src1_unsealed = True; @@ -813,6 +848,12 @@ function DecodeResult decode(Instruction inst); dInst.capChecks.src2_permit_seal = True; dInst.capChecks.src2_addr_valid_type = True; + dInst.capChecks.check_enable = True; + dInst.capChecks.check_authority_src = Src2; + dInst.capChecks.check_low_src = Src2Addr; + dInst.capChecks.check_high_src = Src2Addr; + dInst.capChecks.check_inclusive = False; + dInst.iType = Alu; regs.dst = Valid(tagged Gpr rd); regs.src1 = Valid(tagged Gpr rs1); @@ -857,6 +898,12 @@ function DecodeResult decode(Instruction inst); dInst.capChecks.src2_points_to_src1_type = True; dInst.capChecks.src2_permit_unseal = True; + dInst.capChecks.check_enable = True; + dInst.capChecks.check_authority_src = Src2; + dInst.capChecks.check_low_src = Src2Addr; + dInst.capChecks.check_high_src = Src2Addr; + dInst.capChecks.check_inclusive = False; + dInst.iType = Alu; regs.dst = Valid(tagged Gpr rd); regs.src1 = Valid(tagged Gpr rs1); @@ -878,6 +925,12 @@ function DecodeResult decode(Instruction inst); dInst.capChecks.src1_tag = True; dInst.capChecks.src1_unsealed = True; + dInst.capChecks.check_enable = True; + dInst.capChecks.check_authority_src = Src1; + dInst.capChecks.check_low_src = Src2Type; + dInst.capChecks.check_high_src = Src2Type; + dInst.capChecks.check_inclusive = False; + dInst.iType = Alu; regs.dst = Valid(tagged Gpr rd); regs.src1 = Valid(tagged Gpr rs1); @@ -913,7 +966,13 @@ function DecodeResult decode(Instruction inst); dInst.iType = Alu; regs.dst = Valid(tagged Gpr rd); regs.src1 = Valid(tagged Gpr rs1); - regs.src2 = Valid(tagged Gpr rs2); + if (rs2 == 0) begin + regs.src2 = Invalid; + dInst.scr = Valid (SCR_DDC); + end else begin + regs.src2 = Valid (tagged Gpr rs2); + dInst.scr = Invalid; + end dInst.imm = Invalid; dInst.execFunc = CapInspect (ToPtr); end @@ -941,17 +1000,26 @@ function DecodeResult decode(Instruction inst); dInst.execFunc = Alu (Sub); end f7_cap_CBuildCap: begin - illegalInst = True; - // TODO - dInst.capChecks.src1_tag = True; - dInst.capChecks.src1_unsealed = True; - dInst.capChecks.src2_perm_subset_src1 = True; - dInst.capChecks.src2_derivable = True; + dInst.capChecks.src2_tag = True; + dInst.capChecks.src2_unsealed = True; + dInst.capChecks.src1_perm_subset_src2 = True; + dInst.capChecks.src1_derivable = True; + dInst.capChecks.check_enable = True; + dInst.capChecks.check_authority_src = Src2; + dInst.capChecks.check_low_src = Src1Base; + dInst.capChecks.check_high_src = Src1Top; + dInst.capChecks.check_inclusive = True; + + // Swap arguments so SCR possibly goes in RS2 dInst.iType = Alu; regs.dst = Valid(tagged Gpr rd); - regs.src1 = Valid(tagged Gpr rs1); - regs.src2 = Valid(tagged Gpr rs2); + regs.src1 = Valid(tagged Gpr rs2); + if (rs1 == 0) begin + dInst.scr = Valid(SCR_DDC); + end else begin + regs.src2 = Valid(tagged Gpr rs1); + end dInst.imm = Invalid; dInst.execFunc = CapModify (BuildCap); end @@ -994,18 +1062,20 @@ function DecodeResult decode(Instruction inst); dInst.execFunc = CapInspect (GetSealed); end f5rs2_cap_CRRL: begin - illegalInst = True; - // TODO - // regs.dst = Valid(tagged Gpr rd); - // regs.src1 = Valid(tagged Gpr rs1); - // dInst.imm = Invalid; + dInst.iType = Alu; + regs.dst = Valid(tagged Gpr rd); + regs.src1 = Valid(tagged Gpr 0); // Operate on nullcap + regs.src2 = Valid(tagged Gpr rs1); + dInst.imm = Invalid; + dInst.execFunc = CapModify (SetBounds (CRRL)); end f5rs2_cap_CRAM: begin - illegalInst = True; - // TODO - // regs.dst = Valid(tagged Gpr rd); - // regs.src1 = Valid(tagged Gpr rs1); - // dInst.imm = Invalid; + dInst.iType = Alu; + regs.dst = Valid(tagged Gpr rd); + regs.src1 = Valid(tagged Gpr 0); // Operate on nullcap + regs.src2 = Valid(tagged Gpr rs1); + dInst.imm = Invalid; + dInst.execFunc = CapModify (SetBounds (CRAM)); end f5rs2_cap_CMove: begin dInst.iType = Alu; diff --git a/src_Core/RISCY_OOO/procs/lib/Exec.bsv b/src_Core/RISCY_OOO/procs/lib/Exec.bsv index 7fefc6c..61411dd 100755 --- a/src_Core/RISCY_OOO/procs/lib/Exec.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Exec.bsv @@ -66,11 +66,49 @@ function Maybe#(CapException) capChecks(CapPipe a, CapPipe b, CapChecks toCheck) result = e2(TypeViolation); else if (toCheck.src2_addr_valid_type && !validAsType(b, truncate(getAddr(b)))) result = e2(LengthViolation); - else if (toCheck.src2_perm_subset_src1 && (getPerms(a) & getPerms(b)) != getPerms(b)) + else if (toCheck.src1_perm_subset_src2 && (getPerms(a) & getPerms(b)) != getPerms(a)) result = e2(SoftwarePermViolation); + else if (toCheck.src1_derivable && !isDerivable(a)) + result = e1(LengthViolation); return result; endfunction +(* noinline *) +function Maybe#(BoundsCheck) prepareBoundsCheck(CapPipe a, CapPipe b, CapChecks toCheck); + BoundsCheck ret = ?; + CapPipe authority = ?; + case(toCheck.check_authority_src) + Src1: begin + authority = a; + ret.authority_idx = toCheck.rn1; + end + Src2: begin + authority = b; + ret.authority_idx = toCheck.rn2; + end + endcase + ret.authority_base = getBase(authority); + ret.authority_top = getTop(authority); + + case(toCheck.check_low_src) + Src1Addr: ret.check_low = getAddr(a); + Src1Base: ret.check_low = getBase(a); + Src2Addr: ret.check_low = getAddr(b); + Src2Type: ret.check_low = zeroExtend(getType(b)); + endcase + + case(toCheck.check_high_src) + Src1Top: ret.check_high = getTop(a); + Src2Addr: ret.check_high = {1'b0,getAddr(b)}; + Src2Type: ret.check_high = zeroExtend(getType(b)); + ResultTop: ret.check_high = {1'b0,getAddr(a)} + {1'b0,getAddr(b)}; + endcase + + ret.check_inclusive = toCheck.check_inclusive; + if (toCheck.check_enable) return Valid(ret); + else return Invalid; +endfunction + (* noinline *) function Data alu(Data a, Data b, AluFunc func); Data res = (case(func) @@ -97,15 +135,27 @@ function Data alu(Data a, Data b, AluFunc func); return res; endfunction +(* noinline *) +function CapPipe setBoundsALU(CapPipe cap, Data len, SetBoundsFunc boundsOp); + let combinedResult = setBoundsCombined(cap, len); + CapPipe res = (case (boundsOp) matches + SetBounds: combinedResult.cap; + CRRL: nullWithAddr(combinedResult.length); + CRAM: nullWithAddr(combinedResult.mask); + endcase); + // TODO exfiltrate exact somehow... + return res; +endfunction + (* noinline *) function CapPipe capModify(CapPipe a, CapPipe b, CapModifyFunc func); CapPipe res = (case(func) matches tagged ModifyOffset .offsetOp : modifyOffset(a, getAddr(b), offsetOp == IncOffset).value; - tagged SetBounds .exact : - setBounds(a, getAddr(b)).value; - //tagged SpecialRW : - // error("SpecialRW not yet implemented"); + tagged SetBounds .boundsOp : + setBoundsALU(a, getAddr(b), boundsOp); + tagged SpecialRW .scrType : + a; //TODO masking of various bits tagged SetAddr .addrSource : if (addrSource == Src2Type && !isSealed(b)) return nullWithAddr(-1); else return setAddr(a, (addrSource == Src2Type) ? zeroExtend(getType(b)) : getAddr(b) ).value; @@ -120,7 +170,7 @@ function CapPipe capModify(CapPipe a, CapPipe b, CapModifyFunc func); //tagged FromPtr : // error("FromPtr not yet implemented"); tagged BuildCap : - setValidCap(a, True); + setType(setValidCap(a, True),-1); tagged Move : a; tagged ClearTag : @@ -156,7 +206,7 @@ function Data capInspect(CapPipe a, CapPipe b, CapInspectFunc func); tagged GetType : signExtend(getType(a)); tagged ToPtr : - (getAddr(a) - getBase(b)); + (isValidCap(a) ? (getAddr(a) - getBase(b)) : 0); default: ?; endcase); return res; @@ -233,7 +283,8 @@ function ExecResult basicExec(DecodedInst dInst, CapPipe rVal1, CapPipe rVal2, C Data inspect_result = capInspect(rVal1, aluVal2, dInst.execFunc.CapInspect); CapModifyFunc modFunc = ccall ? (Unseal (Src2)):dInst.execFunc.CapModify; CapPipe modify_result = capModify(rVal1, aluVal2, modFunc); - Maybe#(CapException) capException = capChecks(rVal1, aluVal2, dInst.capChecks); // TODO use this to throw exceptions + Maybe#(CapException) capException = capChecks(rVal1, aluVal2, dInst.capChecks); + Maybe#(BoundsCheck) boundsCheck = prepareBoundsCheck(rVal1, aluVal2, dInst.capChecks); CapPipe cap_alu_result = case (dInst.execFunc) matches tagged CapInspect .x: nullWithAddr(inspect_result); tagged CapModify .x: modify_result; @@ -258,7 +309,7 @@ function ExecResult basicExec(DecodedInst dInst, CapPipe rVal1, CapPipe rVal2, C Jr &&& (ccall): cap_alu_result; // Depending on defaults falling through! Jr &&& (cjalr): link_pcc; Jr : nullWithAddr(getOffset(link_pcc)); - Auipc : nullWithAddr(pc + fromMaybe(?, getDInstImm(dInst))); // could be computed with alu + Auipc : (getFlags(pcc)[0] == 1'b0 ? nullWithAddr(pc + fromMaybe(?, getDInstImm(dInst))) : modifyOffset(pcc, fromMaybe(?, getDInstImm(dInst)), True).value); // could be computed with alu Csr : rVal1; default : cap_alu_result; endcase); @@ -267,9 +318,9 @@ function ExecResult basicExec(DecodedInst dInst, CapPipe rVal1, CapPipe rVal2, C Ld, St, Lr, Sc, Amo : nullWithAddr(alu_result); default : nullWithAddr(cf.nextPc); endcase); - CapPipe scr_data = rVal1; + CapPipe scr_data = modify_result; - return ExecResult{data: data, csrData: csr_data, scrData: scr_data, addr: addr, controlFlow: cf, capException: capException}; + return ExecResult{data: data, csrData: csr_data, scrData: scr_data, addr: addr, controlFlow: cf, capException: capException, boundsCheck: boundsCheck}; endfunction (* noinline *) diff --git a/src_Core/RISCY_OOO/procs/lib/Opcodes.bsvi b/src_Core/RISCY_OOO/procs/lib/Opcodes.bsvi new file mode 100644 index 0000000..dd24766 --- /dev/null +++ b/src_Core/RISCY_OOO/procs/lib/Opcodes.bsvi @@ -0,0 +1,22 @@ +`OPCODE(Load , 7'b0000011) +`OPCODE(LoadFp , 7'b0000111) +`OPCODE(MiscMem, 7'b0001111) +`OPCODE(OpImm , 7'b0010011) +`OPCODE(Auipc , 7'b0010111) +`OPCODE(OpImm32, 7'b0011011) +`OPCODE(Store , 7'b0100011) +`OPCODE(StoreFp, 7'b0100111) +`OPCODE(Amo , 7'b0101111) +`OPCODE(Op , 7'b0110011) +`OPCODE(Lui , 7'b0110111) +`OPCODE(Op32 , 7'b0111011) +`OPCODE(Fmadd , 7'b1000011) +`OPCODE(Fmsub , 7'b1000111) +`OPCODE(Fnmsub , 7'b1001011) +`OPCODE(Fnmadd , 7'b1001111) +`OPCODE(OpFp , 7'b1010011) +`OPCODE(OpCHERI, 7'b1011011) +`OPCODE(Branch , 7'b1100011) +`OPCODE(Jalr , 7'b1100111) +`OPCODE(Jal , 7'b1101111) +`OPCODE(System , 7'b1110011) diff --git a/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv b/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv index 677fb16..75fe67b 100755 --- a/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv +++ b/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv @@ -171,212 +171,37 @@ function Bool allRegsReady(RegsReady x); endfunction typedef enum { - Invalid = 7'b0, - Load = 7'b0000011, - LoadFp = 7'b0000111, - MiscMem = 7'b0001111, - OpImm = 7'b0010011, - Auipc = 7'b0010111, - OpImm32 = 7'b0011011, - Store = 7'b0100011, - StoreFp = 7'b0100111, - Amo = 7'b0101111, - Op = 7'b0110011, - Lui = 7'b0110111, - Op32 = 7'b0111011, - Fmadd = 7'b1000011, - Fmsub = 7'b1000111, - Fnmsub = 7'b1001011, - Fnmadd = 7'b1001111, - OpFp = 7'b1010011, - OpCHERI = 7'b1011011, - Branch = 7'b1100011, - Jalr = 7'b1100111, - Jal = 7'b1101111, - System = 7'b1110011 +`define OPCODE(o,v) o = v, +`include "Opcodes.bsvi" +`undef OPCODE + Invalid = 7'b0 } Opcode deriving(Bits, Eq, FShow); function Opcode unpackOpcode(Bit#(7) x); return (case(x) - pack(Opcode'(Load )): (Load ); - pack(Opcode'(LoadFp )): (LoadFp ); - pack(Opcode'(MiscMem)): (MiscMem); - pack(Opcode'(OpImm )): (OpImm ); - pack(Opcode'(Auipc )): (Auipc ); - pack(Opcode'(OpImm32)): (OpImm32); - pack(Opcode'(Store )): (Store ); - pack(Opcode'(StoreFp)): (StoreFp); - pack(Opcode'(Amo )): (Amo ); - pack(Opcode'(Op )): (Op ); - pack(Opcode'(Lui )): (Lui ); - pack(Opcode'(Op32 )): (Op32 ); - pack(Opcode'(Fmadd )): (Fmadd ); - pack(Opcode'(Fmsub )): (Fmsub ); - pack(Opcode'(Fnmsub )): (Fnmsub ); - pack(Opcode'(Fnmadd )): (Fnmadd ); - pack(Opcode'(OpFp )): (OpFp ); - pack(Opcode'(OpCHERI)): (OpCHERI); - pack(Opcode'(Branch )): (Branch ); - pack(Opcode'(Jalr )): (Jalr ); - pack(Opcode'(Jal )): (Jal ); - pack(Opcode'(System )): (System ); - default : (Invalid); +`define OPCODE(o,v) pack(Opcode'(o)): (o); +`include "Opcodes.bsvi" +`undef OPCODE + default : Invalid; endcase); endfunction -/* If Bluespec never allows illegal values of sparse enumerated types, this function should replace the one above: -function Opcode unpackOpcode(Bit#(7) x); - Opcode test = unpack(x); - if (pack(test) != x) return Invalid; - else return test; -endfunction -*/ typedef enum { - // user standard CSRs - CSRfflags = 12'h001, - CSRfrm = 12'h002, - CSRfcsr = 12'h003, - CSRcycle = 12'hc00, - CSRtime = 12'hc01, - CSRinstret = 12'hc02, - // user non-standard CSRs (TODO) - CSRterminate = 12'h800, // terminate (used to exit Linux) - CSRstats = 12'h801, // turn on/off perf counters - CSRuccsr = 12'h8c0, - // supervisor standard CSRs - CSRsstatus = 12'h100, - // no user trap handler, so no se/ideleg - CSRsie = 12'h104, - CSRstvec = 12'h105, - CSRscounteren = 12'h106, - CSRsscratch = 12'h140, - CSRsepc = 12'h141, - CSRscause = 12'h142, - CSRstval = 12'h143, // it's still called sbadaddr in spike - CSRsip = 12'h144, - CSRsatp = 12'h180, // it's still called sptbr in spike - CSRsccsr = 12'h9c0, - // machine standard CSRs - CSRmstatus = 12'h300, - CSRmisa = 12'h301, - CSRmedeleg = 12'h302, - CSRmideleg = 12'h303, - CSRmie = 12'h304, - CSRmtvec = 12'h305, - CSRmcounteren = 12'h306, - CSRmscratch = 12'h340, - CSRmepc = 12'h341, - CSRmcause = 12'h342, - CSRmtval = 12'h343, // it's still called mbadaddr in spike - CSRmip = 12'h344, - CSRmcycle = 12'hb00, - CSRminstret = 12'hb02, - CSRmvendorid = 12'hf11, - CSRmarchid = 12'hf12, - CSRmimpid = 12'hf13, - CSRmhartid = 12'hf14, - CSRmccsr = 12'hbc0, -`ifdef SECURITY - // sanctum machine CSR - CSRmevbase = 12'h7c0, - CSRmevmask = 12'h7c1, - CSRmeatp = 12'h7c2, - CSRmmrbm = 12'h7c3, - CSRmemrbm = 12'h7c4, - CSRmparbase = 12'h7c5, - CSRmparmask = 12'h7c6, - CSRmeparbase = 12'h7c7, - CSRmeparmask = 12'h7c8, - CSRmflush = 12'h7c9, // flush pipeline + cache - CSRmspec = 12'h7ca, // control speculation - // sanctum user CSR - CSRtrng = 12'hcc0, // random number for secure boot -`endif - - CSRtselect = 12'h7A0, // Debug/trace tselect - CSRtdata1 = 12'h7A1, // Debug/trace tdata1 - CSRtdata2 = 12'h7A2, // Debug/trace tdata2 - CSRtdata3 = 12'h7A3, // Debug/trace tdata3 - -`ifdef INCLUDE_GDB_CONTROL - CSRdcsr = 12'h7B0, // Debug control and status - CSRdpc = 12'h7B1, // Debug PC - CSRdscratch0 = 12'h7B2, // Debug scratch0 - CSRdscratch1 = 12'h7B3, // Debug scratch1 -`endif - +`define CSR(c,v) c = v, +`include "CSRs.bsvi" +`undef CSR // CSR that catches all the unimplemented CSRs. To avoid exception on this, // make it a user non-standard read/write CSR. // Bluespec: in RenameStage.getTrap(), we force this to be a csr_access_trap - CSRnone = 12'h8ff + CSRnone = 12'h8ff } CSR deriving(Bits, Eq, FShow); function CSR unpackCSR(Bit#(12) x); return (case(x) - pack(CSR'(CSRfflags )): (CSRfflags ); - pack(CSR'(CSRfrm )): (CSRfrm ); - pack(CSR'(CSRfcsr )): (CSRfcsr ); - pack(CSR'(CSRcycle )): (CSRcycle ); - pack(CSR'(CSRtime )): (CSRtime ); - pack(CSR'(CSRinstret )): (CSRinstret ); - pack(CSR'(CSRterminate )): (CSRterminate ); - pack(CSR'(CSRstats )): (CSRstats ); - pack(CSR'(CSRsstatus )): (CSRsstatus ); - pack(CSR'(CSRsie )): (CSRsie ); - pack(CSR'(CSRstvec )): (CSRstvec ); - pack(CSR'(CSRscounteren)): (CSRscounteren); - pack(CSR'(CSRsscratch )): (CSRsscratch ); - pack(CSR'(CSRsepc )): (CSRsepc ); - pack(CSR'(CSRscause )): (CSRscause ); - pack(CSR'(CSRstval )): (CSRstval ); - pack(CSR'(CSRsip )): (CSRsip ); - pack(CSR'(CSRsatp )): (CSRsatp ); - pack(CSR'(CSRmstatus )): (CSRmstatus ); - pack(CSR'(CSRmisa )): (CSRmisa ); - pack(CSR'(CSRmedeleg )): (CSRmedeleg ); - pack(CSR'(CSRmideleg )): (CSRmideleg ); - pack(CSR'(CSRmie )): (CSRmie ); - pack(CSR'(CSRmtvec )): (CSRmtvec ); - pack(CSR'(CSRmcounteren)): (CSRmcounteren); - pack(CSR'(CSRmscratch )): (CSRmscratch ); - pack(CSR'(CSRmepc )): (CSRmepc ); - pack(CSR'(CSRmcause )): (CSRmcause ); - pack(CSR'(CSRmtval )): (CSRmtval ); - pack(CSR'(CSRmip )): (CSRmip ); - pack(CSR'(CSRmcycle )): (CSRmcycle ); - pack(CSR'(CSRminstret )): (CSRminstret ); - pack(CSR'(CSRmvendorid )): (CSRmvendorid ); - pack(CSR'(CSRmarchid )): (CSRmarchid ); - pack(CSR'(CSRmimpid )): (CSRmimpid ); - pack(CSR'(CSRmhartid )): (CSRmhartid ); -`ifdef SECURITY - pack(CSR'(CSRmevbase )): (CSRmevbase ); - pack(CSR'(CSRmevmask )): (CSRmevmask ); - pack(CSR'(CSRmeatp )): (CSRmeatp ); - pack(CSR'(CSRmmrbm )): (CSRmmrbm ); - pack(CSR'(CSRmemrbm )): (CSRmemrbm ); - pack(CSR'(CSRmparbase )): (CSRmparbase ); - pack(CSR'(CSRmparmask )): (CSRmparmask ); - pack(CSR'(CSRmeparbase )): (CSRmeparbase ); - pack(CSR'(CSRmeparmask )): (CSRmeparmask ); - pack(CSR'(CSRmflush )): (CSRmflush ); - pack(CSR'(CSRmspec )): (CSRmspec ); - pack(CSR'(CSRtrng )): (CSRtrng ); -`endif - - pack(CSR'(CSRtselect )): (CSRtselect ); - pack(CSR'(CSRtdata1 )): (CSRtdata1 ); - pack(CSR'(CSRtdata2 )): (CSRtdata2 ); - pack(CSR'(CSRtdata3 )): (CSRtdata3 ); - -`ifdef INCLUDE_GDB_CONTROL - pack(CSR'(CSRdcsr )): (CSRdcsr ); - pack(CSR'(CSRdpc )): (CSRdpc ); - pack(CSR'(CSRdscratch0 )): (CSRdscratch0 ); - pack(CSR'(CSRdscratch1 )): (CSRdscratch1 ); -`endif - - default : (CSRnone ); +`define CSR(c,v) pack(CSR'(c)): (c); +`include "CSRs.bsvi" +`undef CSR + default : (CSRnone ); endcase); endfunction @@ -420,9 +245,13 @@ typedef enum { } ModifyOffsetFunc deriving(Bits, Eq, FShow); typedef enum { - SetBounds, SetBoundsExact, CRRL, CRAM + SetBounds, CRRL, CRAM } SetBoundsFunc deriving(Bits, Eq, FShow); +typedef enum { + TCC, EPCC, Normal +} SpecialRWFunc deriving(Bits, Eq, FShow); + typedef enum { Src2Type, Src2Addr } AddrSource deriving(Bits, Eq, FShow); @@ -433,8 +262,8 @@ typedef enum { typedef union tagged { ModifyOffsetFunc ModifyOffset; - Bool SetBounds; - void SpecialRW; + SetBoundsFunc SetBounds; + SpecialRWFunc SpecialRW; AddrSource SetAddr; void Seal; SrcSelector Unseal; @@ -568,8 +397,8 @@ typedef union tagged { typedef struct { Trap trap; - CHERIException capExp; -} TrapWithCap deriving(Bits, Eq, FShow); + CSR_XCapCause capExp; +} TrapWithCap deriving(Bits, FShow); // privilege modes Bit#(2) prvU = 0; @@ -672,30 +501,72 @@ typedef struct { Bool illegalInst; } DecodeResult deriving(Bits, Eq, FShow); +typedef enum { + Src1, + Src2 +} CheckAuthoritySrc deriving(Bits, Eq, FShow); + +typedef enum { + Src1Addr, + Src2Addr, + Src2Type, + Src1Base +} CheckLowSrc deriving(Bits, Eq, FShow); + +typedef enum { + Src1Top, + Src2Addr, + Src2Type, + ResultTop +} CheckHighSrc deriving(Bits, Eq, FShow); + +typedef struct { + Data authority_base; + CapTop authority_top; + Bit#(6) authority_idx; + Data check_low; + CapTop check_high; + Bool check_inclusive; +} BoundsCheck deriving(Bits, Eq, FShow); + +typedef Bit#(65) CapTop; + typedef Bit#(32) ImmData; // 32-bit decoded immediate data typedef struct { - Bool src1_tag; - Bool src2_tag; - Bool src1_sealed_with_type; - Bool src1_unsealed; - Bool src2_unsealed; - Bool src1_sealed; - Bool src2_sealed; - Bool src1_src2_types_match; - Bool src1_permit_ccall; - Bool src2_permit_ccall; - Bool src1_permit_x; - Bool src2_no_permit_x; - Bool src2_permit_unseal; - Bool src2_permit_seal; - Bool src2_points_to_src1_type; - Bool src2_addr_valid_type; - Bool src2_perm_subset_src1; - Bool src2_derivable; +`define CAP_CHECK_FIELD(x,s) Bool x; +`include "CapChecks.bsvi" +`undef CAP_CHECK_FIELD + + Bool check_enable; + CheckAuthoritySrc check_authority_src; + CheckLowSrc check_low_src; + CheckHighSrc check_high_src; + Bool check_inclusive; + Bit#(6) rn1; Bit#(6) rn2; -} CapChecks deriving(Bits, Eq, FShow); +} CapChecks deriving(Bits, Eq); + +instance FShow#(CapChecks); + function Fmt fshow(CapChecks x); + let ret = $format("CapChecks {", + "rn1 ", fshow(x.rn1), ", rn2 ", fshow(x.rn2)); + +`define CAP_CHECK_FIELD(f,s) if (x.f) ret = ret + $format(", ", s); +`include "CapChecks.bsvi" +`undef CAP_CHECK_FIELD + + if (x.check_enable) + ret = $format(ret, ", bounds check: ", + "auth ", fshow(x.check_authority_src), ", ", + "low ", fshow(x.check_low_src), ", ", + "high ", fshow(x.check_high_src), ", ", + "inclusive ", fshow(x.check_inclusive)); + + return $format(ret, "}"); + endfunction +endinstance typedef CSR_XCapCause CapException; @@ -719,6 +590,7 @@ typedef struct { CapPipe addr; ControlFlow controlFlow; Maybe#(CapException) capException; + Maybe#(BoundsCheck) boundsCheck; } ExecResult deriving(Bits, FShow); // MMIO diff --git a/src_Core/RISCY_OOO/procs/lib/ReorderBuffer.bsv b/src_Core/RISCY_OOO/procs/lib/ReorderBuffer.bsv index 7932aae..4a9ad86 100755 --- a/src_Core/RISCY_OOO/procs/lib/ReorderBuffer.bsv +++ b/src_Core/RISCY_OOO/procs/lib/ReorderBuffer.bsv @@ -117,7 +117,7 @@ interface Row_setExecuted_doFinishAlu; Maybe#(Data) csrData, Maybe#(CapPipe) scrData, ControlFlow cf, - Maybe#(CHERIException) cause, + Maybe#(CSR_XCapCause) cause, CapPipe pcc `ifdef RVFI , ExtraTraceBundle tb @@ -289,7 +289,7 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p Maybe#(Data) csrData, Maybe#(CapPipe) scrData, ControlFlow cf, - Maybe#(CHERIException) cause, + Maybe#(CSR_XCapCause) cause, CapPipe pcc `ifdef RVFI , ExtraTraceBundle tb @@ -313,10 +313,12 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p CapPipe new_pcc = setAddrUnsafe(pcc, getAddr(pc[pc_finishAlu_port(i)])); pc[pc_finishAlu_port(i)] <= new_pcc; if (!isInBounds(new_pcc, False)) begin - trap[trap_finishAlu_port(i)] <= Valid (TrapWithCap{trap: tagged Exception CHERIFault, capExp: LengthViolation}); + trap[trap_finishAlu_port(i)] <= Valid (TrapWithCap{trap: tagged Exception CHERIFault, + capExp: CSR_XCapCause {cheri_exc_code: LengthViolation, + cheri_exc_reg: {1,pack(SCR_PCC)}}}); tval[trap_finishAlu_port(i)] <= tval[trap_finishAlu_port(i)]; end else if (cause matches tagged Valid .exp) begin - trap[trap_finishAlu_port(i)] <= Valid (TrapWithCap{trap: tagged Exception CHERIFault, capExp: fromMaybe(None, cause)}); + trap[trap_finishAlu_port(i)] <= Valid (TrapWithCap{trap: tagged Exception CHERIFault, capExp: exp}); tval[trap_finishAlu_port(i)] <= tval[trap_finishAlu_port(i)]; end `ifdef RVFI @@ -346,10 +348,12 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p fflags[fflags_finishFpuMulDiv_port(i)] <= new_fflags; CapPipe new_pcc = setAddrUnsafe(pcc, getAddr(pc[pc_finishAlu_port(i)])); if (!isInBounds(new_pcc, False)) begin - trap[trap_finishFpuMulDiv_port(i)] <= Valid (TrapWithCap{trap: tagged Exception CHERIFault, capExp: LengthViolation}); + trap[trap_finishFpuMulDiv_port(i)] <= Valid (TrapWithCap{trap: tagged Exception CHERIFault, + capExp: CSR_XCapCause {cheri_exc_code: LengthViolation, + cheri_exc_reg: {1,pack(SCR_PCC)}}}); tval[trap_finishFpuMulDiv_port(i)] <= tval[trap_finishAlu_port(i)]; end else if (cause matches tagged Valid .exp) begin - trap[trap_finishFpuMulDiv_port(i)] <= Valid (TrapWithCap{trap: tagged Exception exp, capExp: None}); + trap[trap_finishFpuMulDiv_port(i)] <= Valid (TrapWithCap{trap: tagged Exception exp, capExp: noCapCause}); tval[trap_finishFpuMulDiv_port(i)] <= tval[trap_finishAlu_port(i)]; end //pc[pc_finishFpuMulDiv_port(i)] <= newPcc; //XXX add pcc checks on FPU instructions @@ -403,10 +407,12 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p CapPipe new_pcc = setAddrUnsafe(pcc, getAddr(pc[pc_finishMem_port])); pc[pc_finishMem_port] <= new_pcc; if (!isInBounds(new_pcc, False)) begin - mem_early_trap[0] <= Valid (TrapWithCap{trap: tagged Exception CHERIFault, capExp: LengthViolation}); + mem_early_trap[0] <= Valid (TrapWithCap{trap: tagged Exception CHERIFault, + capExp: CSR_XCapCause {cheri_exc_code: LengthViolation, + cheri_exc_reg: {1,pack(SCR_PCC)}}}); tval[trap_finishMem_port] <= tval[trap_finishMem_port]; end else if (cause matches tagged Valid .exp) begin - mem_early_trap[0] <= Valid (TrapWithCap{trap: tagged Exception exp, capExp: None}); + mem_early_trap[0] <= Valid (TrapWithCap{trap: tagged Exception exp, capExp: noCapCause}); tval[trap_finishMem_port] <= tval[trap_finishMem_port]; end endmethod @@ -533,7 +539,7 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p // record trap //doAssert(!isValid(trap[trap_deqLSQ_port]), "cannot have trap"); if (isValid(mem_early_trap[0])) trap[trap_deqLSQ_port] <= mem_early_trap[0]; - else if(cause matches tagged Valid .e) trap[trap_deqLSQ_port] <= Valid (TrapWithCap{trap: tagged Exception e, capExp: None}); + else if(cause matches tagged Valid .e) trap[trap_deqLSQ_port] <= Valid (TrapWithCap{trap: tagged Exception e, capExp: noCapCause}); // TODO: shouldn't we record tval here as well? // record ld misspeculation ldKilled[ldKill_deqLSQ_port] <= ld_killed; @@ -595,7 +601,7 @@ interface ROB_setExecuted_doFinishAlu; Maybe#(Data) csrData, Maybe#(CapPipe) scrData, ControlFlow cf, - Maybe#(CHERIException) cause, + Maybe#(CSR_XCapCause) cause, CapPipe pcc `ifdef RVFI , ExtraTraceBundle tb @@ -1144,7 +1150,7 @@ module mkSupReorderBuffer#( Maybe#(Data) csrData, Maybe#(CapPipe) scrData, ControlFlow cf, - Maybe#(CHERIException) cause, + Maybe#(CSR_XCapCause) cause, CapPipe pcc `ifdef RVFI , ExtraTraceBundle tb