diff --git a/src_Core/ISA/ISA_Decls_CHERI.bsv b/src_Core/ISA/ISA_Decls_CHERI.bsv old mode 100644 new mode 100755 index df5a8be..684fd70 --- a/src_Core/ISA/ISA_Decls_CHERI.bsv +++ b/src_Core/ISA/ISA_Decls_CHERI.bsv @@ -65,7 +65,7 @@ typedef enum { typedef struct { Bit #(6) cheri_exc_reg; CHERIException cheri_exc_code; -} CSR_XCapCause deriving(Bits); +} CSR_XCapCause deriving(Bits, FShow); 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}); diff --git a/src_Core/RISCY_OOO/procs/RV64G_OOO/AluExePipeline.bsv b/src_Core/RISCY_OOO/procs/RV64G_OOO/AluExePipeline.bsv old mode 100644 new mode 100755 index 3304cc1..d8e1228 --- a/src_Core/RISCY_OOO/procs/RV64G_OOO/AluExePipeline.bsv +++ b/src_Core/RISCY_OOO/procs/RV64G_OOO/AluExePipeline.bsv @@ -87,8 +87,9 @@ typedef struct { // result CapPipe data; // alu compute result Maybe#(Data) csrData; // data to write CSR file + Maybe#(CapPipe) scrData; // datat to write to special capability register file. ControlFlow controlFlow; - Maybe#(CapException) capException; + Maybe#(CHERIException) capException; // speculation Maybe#(SpecTag) spec_tag; `ifdef RVFI @@ -154,8 +155,9 @@ interface AluExeInput; InstTag t, CapPipe dst_data, Maybe#(Data) csrData, + Maybe#(CapPipe) scrData, ControlFlow cf, - Maybe#(CapException) capCause, + Maybe#(CHERIException) capCause, CapPipe pcc `ifdef RVFI , ExtraTraceBundle tb @@ -317,6 +319,11 @@ module mkAluExePipeline#(AluExeInput inIfc)(AluExePipeline); isCompressed: x.orig_inst[1:0] != 2'b11, data: exec_result.data, csrData: isValid(x.dInst.csr) ? Valid (exec_result.csrData) : tagged Invalid, + // The above case will never be valid due to assertions above, but the below one will be in the case of CJALR. + // 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, `ifdef RVFI traceBundle: ExtraTraceBundle{ regWriteData: getAddr(exec_result.data), @@ -347,6 +354,7 @@ module mkAluExePipeline#(AluExeInput inIfc)(AluExePipeline); x.tag, x.data, x.csrData, + x.scrData, x.controlFlow, x.capException, cast(inIfc.scaprf_rd(SCR_PCC)) diff --git a/src_Core/RISCY_OOO/procs/RV64G_OOO/CommitStage.bsv b/src_Core/RISCY_OOO/procs/RV64G_OOO/CommitStage.bsv index e5ad2f5..610db3e 100644 --- a/src_Core/RISCY_OOO/procs/RV64G_OOO/CommitStage.bsv +++ b/src_Core/RISCY_OOO/procs/RV64G_OOO/CommitStage.bsv @@ -621,15 +621,15 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage); // record trap info Addr vaddr = ?; - if ( (trap == tagged Exception InstAccessFault) - || (trap == tagged Exception InstPageFault)) begin + if ( (trap.trap == tagged Exception InstAccessFault) + || (trap.trap == tagged Exception InstPageFault)) begin vaddr = x.tval; end else if(x.ppc_vaddr_csrData matches tagged VAddr .va) begin vaddr = getAddr(va); end let commitTrap_val = Valid (CommitTrap { - trap: trap, + trap: trap.trap, pc: x.pc, addr: vaddr, orig_inst: x.orig_inst diff --git a/src_Core/RISCY_OOO/procs/RV64G_OOO/RFileSynth.bsv b/src_Core/RISCY_OOO/procs/RV64G_OOO/RFileSynth.bsv index bf213e6..63c4b17 100644 --- a/src_Core/RISCY_OOO/procs/RV64G_OOO/RFileSynth.bsv +++ b/src_Core/RISCY_OOO/procs/RV64G_OOO/RFileSynth.bsv @@ -35,7 +35,7 @@ module mkRFileSynth(RFileSynth); CapReg default_register_value = nullCap; //Data default_register_value = 0; `ifdef RVFI_DII - // default_register_value = almightyCap; + default_register_value = almightyCap; `endif let m <- mkRFile(default_register_value, `LAZY_RS_RF); return m; diff --git a/src_Core/RISCY_OOO/procs/RV64G_OOO/RenameStage.bsv b/src_Core/RISCY_OOO/procs/RV64G_OOO/RenameStage.bsv index 510174d..8a147cb 100644 --- a/src_Core/RISCY_OOO/procs/RV64G_OOO/RenameStage.bsv +++ b/src_Core/RISCY_OOO/procs/RV64G_OOO/RenameStage.bsv @@ -357,6 +357,8 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage); // Flip epoch without redirecting // This avoids doing incorrect work incrEpochStallFetch; + Maybe#(TrapWithCap) trapWithCap = Invalid; + if (firstTrap matches tagged Valid .trap) trapWithCap = tagged Valid TrapWithCap{trap: trap, capExp: None}; // just place it in the reorder buffer let y = ToReorderBuffer{pc: setAddr(almightyCap, pc).value, orig_inst: orig_inst, @@ -369,7 +371,7 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage); `endif csr: dInst.csr, claimed_phy_reg: False, // no renaming is done - trap: firstTrap, + trap: trapWithCap, tval: tval, // default values of FullResult ppc_vaddr_csrData: PPC (setAddr(almightyCap, pc).value), // default use PPC diff --git a/src_Core/RISCY_OOO/procs/lib/Decode.bsv b/src_Core/RISCY_OOO/procs/lib/Decode.bsv index 6f8adb4..e314974 100755 --- a/src_Core/RISCY_OOO/procs/lib/Decode.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Decode.bsv @@ -151,6 +151,7 @@ function DecodeResult decode(Instruction inst); iType: Unsupported, execFunc: tagged Other, csr: tagged Invalid, + scr: tagged Invalid, imm: tagged Invalid, capChecks: unpack(0) }; @@ -1039,8 +1040,11 @@ function DecodeResult decode(Instruction inst); regs.src1 = Valid(tagged Gpr rs1); regs.src2 = Invalid; dInst.imm = Invalid; - dInst.csr = tagged Invalid; + //dInst.scr = tagged Valid SCR_PCC; dInst.execFunc = tagged Br AT; + dInst.capChecks.src1_tag = True; + dInst.capChecks.src1_permit_x = True; + dInst.capChecks.src1_unsealed = True; end f5rs2_cap_CGetType: begin dInst.iType = CapInspect; diff --git a/src_Core/RISCY_OOO/procs/lib/Exec.bsv b/src_Core/RISCY_OOO/procs/lib/Exec.bsv index 6bffeb0..4f94b92 100755 --- a/src_Core/RISCY_OOO/procs/lib/Exec.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Exec.bsv @@ -35,39 +35,39 @@ function Maybe#(CapException) capChecks(CapPipe a, CapPipe b, CapChecks toCheck) // TODO plumb register indices here Maybe#(CapException) result = Invalid; if (toCheck.src1_tag && !isValidCap(a)) - result = Valid (CapException {excCode: TagViolation}); + result = Valid (CapException {cheri_exc_code: TagViolation}); else if (toCheck.src2_tag && !isValidCap(b)) - result = Valid (CapException {excCode: TagViolation}); + result = Valid (CapException {cheri_exc_code: TagViolation}); else if (toCheck.src1_sealed_with_type && getKind(a) != SEALED_WITH_TYPE) - result = Valid (CapException {excCode: SealViolation}); + result = Valid (CapException {cheri_exc_code: SealViolation}); else if (toCheck.src1_unsealed && isValidCap(a) && isSealed(a)) - result = Valid (CapException {excCode: SealViolation}); + result = Valid (CapException {cheri_exc_code: SealViolation}); else if (toCheck.src2_unsealed && isValidCap(b) && isSealed(b)) - result = Valid (CapException {excCode: SealViolation}); + result = Valid (CapException {cheri_exc_code: SealViolation}); else if (toCheck.src1_sealed && isValidCap(a) && !isSealed(a)) - result = Valid (CapException {excCode: SealViolation}); + result = Valid (CapException {cheri_exc_code: SealViolation}); else if (toCheck.src2_sealed && isValidCap(b) && !isSealed(b)) - result = Valid (CapException {excCode: SealViolation}); + result = Valid (CapException {cheri_exc_code: SealViolation}); else if (toCheck.src1_src2_types_match && getType(a) != getType(b)) - result = Valid (CapException {excCode: TypeViolation}); + result = Valid (CapException {cheri_exc_code: TypeViolation}); else if (toCheck.src1_permit_ccall && !getHardPerms(a).permitCCall) - result = Valid (CapException {excCode: PermitCCallViolation}); + result = Valid (CapException {cheri_exc_code: PermitCCallViolation}); else if (toCheck.src2_permit_ccall && !getHardPerms(b).permitCCall) - result = Valid (CapException {excCode: PermitCCallViolation}); + result = Valid (CapException {cheri_exc_code: PermitCCallViolation}); else if (toCheck.src1_permit_x && !getHardPerms(a).permitExecute) - result = Valid (CapException {excCode: PermitXViolation}); + result = Valid (CapException {cheri_exc_code: PermitXViolation}); else if (toCheck.src2_no_permit_x && getHardPerms(b).permitExecute) - result = Valid (CapException {excCode: PermitXViolation}); + result = Valid (CapException {cheri_exc_code: PermitXViolation}); else if (toCheck.src2_permit_unseal && !getHardPerms(b).permitUnseal) - result = Valid (CapException {excCode: PermitUnsealViolation}); + result = Valid (CapException {cheri_exc_code: PermitUnsealViolation}); else if (toCheck.src2_permit_seal && !getHardPerms(b).permitSeal) - result = Valid (CapException {excCode: PermitSealViolation}); + result = Valid (CapException {cheri_exc_code: PermitSealViolation}); else if (toCheck.src2_points_to_src1_type && getAddr(b) != zeroExtend(getType(a))) - result = Valid (CapException {excCode: TypeViolation}); + result = Valid (CapException {cheri_exc_code: TypeViolation}); else if (toCheck.src2_addr_valid_type && !validAsType(b, truncate(getAddr(b)))) - result = Valid (CapException {excCode: LengthViolation}); + result = Valid (CapException {cheri_exc_code: LengthViolation}); else if (toCheck.src2_perm_subset_src1 && (getPerms(a) & getPerms(b)) != getPerms(b)) - result = Valid (CapException {excCode: SoftwarePermViolation}); + result = Valid (CapException {cheri_exc_code: SoftwarePermViolation}); return result; endfunction @@ -212,7 +212,7 @@ function ExecResult basicExec(DecodedInst dInst, CapPipe rVal1, CapPipe rVal2, A CapPipe data = nullCap; Data csr_data = 0; CapPipe addr = nullCap; - ControlFlow cf = ControlFlow{pc: pc, nextPc: 0, taken: False, mispredict: False}; + ControlFlow cf = ControlFlow{pc: pc, nextPc: 0, taken: False, newPcc: dInst.capChecks.src1_tag, mispredict: False}; CapPipe aluVal2 = rVal2; if (getDInstImm(dInst) matches tagged Valid .imm) aluVal2 = nullWithAddr(imm); //isValid(dInst.imm) ? fromMaybe(?, dInst.imm) : rVal2; @@ -246,8 +246,9 @@ function ExecResult basicExec(DecodedInst dInst, CapPipe rVal1, CapPipe rVal2, A Ld, St, Lr, Sc, Amo : nullWithAddr(alu_result); default : nullWithAddr(cf.nextPc); endcase); + CapPipe scr_data = rVal1; - return ExecResult{data: data, csrData: csr_data, addr: addr, controlFlow: cf, capException: capException}; + return ExecResult{data: data, csrData: csr_data, scrData: scr_data, addr: addr, controlFlow: cf, capException: capException}; endfunction (* noinline *) diff --git a/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv b/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv index f0ee5f1..c38876b 100755 --- a/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv +++ b/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv @@ -30,6 +30,7 @@ import DefaultValue::*; import MemoryTypes::*; import CHERICap::*; import CHERICC_Fat::*; +import ISA_Decls_CHERI::*; `ifdef RVFI_DII import RVFI_DII_Types::*; `endif @@ -555,6 +556,11 @@ typedef union tagged { Interrupt Interrupt; } Trap deriving(Bits, Eq, FShow); +typedef struct { + Trap trap; + CHERIException capExp; +} TrapWithCap deriving(Bits, Eq, FShow); + // privilege modes Bit#(2) prvU = 0; Bit#(2) prvS = 1; @@ -646,6 +652,7 @@ typedef struct { Addr pc; Addr nextPc; Bool taken; + Bool newPcc; Bool mispredict; } ControlFlow deriving (Bits, Eq, FShow); @@ -678,16 +685,14 @@ typedef struct { Bool src2_derivable; } CapChecks deriving(Bits, Eq, FShow); -typedef struct { - CHERIException excCode; -// TODO GPR or SCR index of cause; -} CapException deriving(Bits, FShow); +typedef CSR_XCapCause CapException; typedef struct { IType iType; ExecFunc execFunc; CapChecks capChecks; Maybe#(CSR) csr; + Maybe#(SCR) scr; // Special Capability Register. Maybe#(ImmData) imm; } DecodedInst deriving(Bits, Eq, FShow); @@ -698,6 +703,7 @@ endfunction typedef struct { CapPipe data; Data csrData; + CapPipe scrData; CapPipe addr; ControlFlow controlFlow; Maybe#(CapException) capException; diff --git a/src_Core/RISCY_OOO/procs/lib/ReorderBuffer.bsv b/src_Core/RISCY_OOO/procs/lib/ReorderBuffer.bsv old mode 100644 new mode 100755 index c429727..7932aae --- a/src_Core/RISCY_OOO/procs/lib/ReorderBuffer.bsv +++ b/src_Core/RISCY_OOO/procs/lib/ReorderBuffer.bsv @@ -35,6 +35,7 @@ import RVFI_DII_Types::*; `endif import CHERICap::*; import CHERICC_Fat::*; +import ISA_Decls_CHERI::*; import Cur_Cycle :: *; @@ -49,6 +50,7 @@ typedef union tagged { CapPipe PPC; // at default store ppc CapPipe VAddr; // for mem inst, store vaddr Data CSRData; // for Csr inst, store csr_data + CapPipe SCRData; // for special capability register store } PPCVAddrCSRData deriving(Bits, FShow); `ifdef RVFI @@ -71,7 +73,7 @@ typedef struct { `endif Maybe#(CSR) csr; Bool claimed_phy_reg; // whether we need to commmit renaming - Maybe#(Trap) trap; + Maybe#(TrapWithCap)trap; Addr tval; // in case of trap PPCVAddrCSRData ppc_vaddr_csrData; Bit#(5) fflags; @@ -113,8 +115,9 @@ interface Row_setExecuted_doFinishAlu; method Action set( CapPipe dst_data, Maybe#(Data) csrData, + Maybe#(CapPipe) scrData, ControlFlow cf, - Maybe#(CapException) cause, + Maybe#(CHERIException) cause, CapPipe pcc `ifdef RVFI , ExtraTraceBundle tb @@ -250,8 +253,8 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p `endif Reg#(Maybe#(CSR)) csr <- mkRegU; Reg#(Bool) claimed_phy_reg <- mkRegU; - Ehr#(TAdd#(TAdd#(2, TDiv#(aluExeNum,2)), aluExeNum), Maybe#(Trap)) trap <- mkEhr(?); - Ehr#(3, Maybe#(Trap)) mem_early_trap <- mkEhr(?); + Ehr#(TAdd#(TAdd#(2, TDiv#(aluExeNum,2)), aluExeNum), Maybe#(TrapWithCap)) trap <- mkEhr(?); + Ehr#(3, Maybe#(TrapWithCap)) mem_early_trap <- mkEhr(?); Ehr#(TAdd#(TAdd#(2, TDiv#(aluExeNum,2)), aluExeNum), Addr) tval <- mkEhr(?); Ehr#(TAdd#(2, aluExeNum), PPCVAddrCSRData) ppc_vaddr_csrData <- mkEhr(?); Ehr#(TAdd#(1, fpuMulDivExeNum), Bit#(5)) fflags <- mkEhr(?); @@ -284,8 +287,9 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p method Action set( CapPipe dst_data, Maybe#(Data) csrData, + Maybe#(CapPipe) scrData, ControlFlow cf, - Maybe#(CapException) cause, + Maybe#(CHERIException) cause, CapPipe pcc `ifdef RVFI , ExtraTraceBundle tb @@ -300,16 +304,19 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p if(csrData matches tagged Valid .d) begin ppc_vaddr_csrData[pvc_finishAlu_port(i)] <= CSRData (d); end + else if(scrData matches tagged Valid .d) begin + ppc_vaddr_csrData[pvc_finishAlu_port(i)] <= SCRData (d); + end else begin - ppc_vaddr_csrData[pvc_finishAlu_port(i)] <= PPC (setAddr(almightyCap, cf.nextPc).value); + ppc_vaddr_csrData[pvc_finishAlu_port(i)] <= PPC (setAddr(pcc, cf.nextPc).value); end 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 (tagged Exception CHERIFault); + trap[trap_finishAlu_port(i)] <= Valid (TrapWithCap{trap: tagged Exception CHERIFault, capExp: LengthViolation}); 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 (tagged Exception CHERIFault); // TODO propagate CHERI cause + trap[trap_finishAlu_port(i)] <= Valid (TrapWithCap{trap: tagged Exception CHERIFault, capExp: fromMaybe(None, cause)}); tval[trap_finishAlu_port(i)] <= tval[trap_finishAlu_port(i)]; end `ifdef RVFI @@ -339,10 +346,10 @@ 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 (tagged Exception CHERIFault); + trap[trap_finishFpuMulDiv_port(i)] <= Valid (TrapWithCap{trap: tagged Exception CHERIFault, capExp: LengthViolation}); 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 (tagged Exception exp); + trap[trap_finishFpuMulDiv_port(i)] <= Valid (TrapWithCap{trap: tagged Exception exp, capExp: None}); tval[trap_finishFpuMulDiv_port(i)] <= tval[trap_finishAlu_port(i)]; end //pc[pc_finishFpuMulDiv_port(i)] <= newPcc; //XXX add pcc checks on FPU instructions @@ -396,10 +403,10 @@ 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 (tagged Exception CHERIFault); + mem_early_trap[0] <= Valid (TrapWithCap{trap: tagged Exception CHERIFault, capExp: LengthViolation}); tval[trap_finishMem_port] <= tval[trap_finishMem_port]; end else if (cause matches tagged Valid .exp) begin - mem_early_trap[0] <= Valid (tagged Exception exp); + mem_early_trap[0] <= Valid (TrapWithCap{trap: tagged Exception exp, capExp: None}); tval[trap_finishMem_port] <= tval[trap_finishMem_port]; end endmethod @@ -526,7 +533,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 (Exception (e)); + else if(cause matches tagged Valid .e) trap[trap_deqLSQ_port] <= Valid (TrapWithCap{trap: tagged Exception e, capExp: None}); // TODO: shouldn't we record tval here as well? // record ld misspeculation ldKilled[ldKill_deqLSQ_port] <= ld_killed; @@ -586,8 +593,9 @@ interface ROB_setExecuted_doFinishAlu; method Action set(InstTag x, CapPipe dst_data, Maybe#(Data) csrData, + Maybe#(CapPipe) scrData, ControlFlow cf, - Maybe#(CapException) cause, + Maybe#(CHERIException) cause, CapPipe pcc `ifdef RVFI , ExtraTraceBundle tb @@ -1134,8 +1142,9 @@ module mkSupReorderBuffer#( InstTag x, CapPipe dst_data, Maybe#(Data) csrData, + Maybe#(CapPipe) scrData, ControlFlow cf, - Maybe#(CapException) cause, + Maybe#(CHERIException) cause, CapPipe pcc `ifdef RVFI , ExtraTraceBundle tb @@ -1146,6 +1155,7 @@ module mkSupReorderBuffer#( row[x.way][x.ptr].setExecuted_doFinishAlu[i].set( dst_data, csrData, + scrData, cf, cause, pcc