diff --git a/src_Core/CPU/CsrFile.bsv b/src_Core/CPU/CsrFile.bsv index 566743b..42c5a7c 100644 --- a/src_Core/CPU/CsrFile.bsv +++ b/src_Core/CPU/CsrFile.bsv @@ -982,6 +982,10 @@ module mkCsrFile #(Data hartid)(CsrFile); default: return 0; endcase); end + tagged CapException .ce: begin + cause_code = pack(CHERIFault); + // populate CHERI cause register. + end tagged Interrupt .i: begin cause_code = zeroExtend(pack(i)); cause_interrupt = 1; diff --git a/src_Core/ISA/ISA_Decls_CHERI.bsv b/src_Core/ISA/ISA_Decls_CHERI.bsv index ce3e87c..63450e9 100755 --- 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, FShow); +} CSR_XCapCause deriving(Bits, Eq, FShow); CSR_XCapCause noCapCause = CSR_XCapCause {cheri_exc_code: None, cheri_exc_reg: unpack(0)}; diff --git a/src_Core/RISCY_OOO/procs/RV64G_OOO/CommitStage.bsv b/src_Core/RISCY_OOO/procs/RV64G_OOO/CommitStage.bsv index cba92eb..db9d44b 100644 --- a/src_Core/RISCY_OOO/procs/RV64G_OOO/CommitStage.bsv +++ b/src_Core/RISCY_OOO/procs/RV64G_OOO/CommitStage.bsv @@ -624,15 +624,15 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage); // record trap info Addr vaddr = ?; - if ( (trap.trap == tagged Exception InstAccessFault) - || (trap.trap == tagged Exception InstPageFault)) begin + if ( (trap == tagged Exception InstAccessFault) + || (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/RenameStage.bsv b/src_Core/RISCY_OOO/procs/RV64G_OOO/RenameStage.bsv index 6f97e31..faeb6d2 100644 --- a/src_Core/RISCY_OOO/procs/RV64G_OOO/RenameStage.bsv +++ b/src_Core/RISCY_OOO/procs/RV64G_OOO/RenameStage.bsv @@ -231,7 +231,7 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage); Maybe#(Trap) trap = tagged Invalid; let csr_state = csrf.decodeInfo; let pending_interrupt = csrf.pending_interrupt; - let new_exception = checkForException(x.dInst, x.regs, csr_state); + let new_exception = checkForException(x.dInst, x.regs, csr_state, x.pc); // If Fpu regs are accessed, trap if mstatus_fs is "Off" (2'b00) Bool fpr_access = ( fn_ArchReg_is_FpuReg (x.regs.src1) @@ -292,7 +292,7 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage); trap = tagged Valid (tagged Interrupt fromMaybe(?, pending_interrupt)); end else if (isValid(new_exception)) begin // newly found exception - trap = tagged Valid (tagged Exception fromMaybe(?, new_exception)); + trap = new_exception; end else if (fs_trap || csr_access_trap || wfi_trap) begin trap = tagged Valid (tagged Exception IllegalInst); @@ -357,8 +357,6 @@ 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: noCapCause}; // just place it in the reorder buffer let y = ToReorderBuffer{pc: cast(pc), orig_inst: orig_inst, @@ -371,7 +369,7 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage); `endif csr: dInst.csr, claimed_phy_reg: False, // no renaming is done - trap: trapWithCap, + trap: firstTrap, tval: tval, // default values of FullResult ppc_vaddr_csrData: PPC (cast(pc)), // default use PPC diff --git a/src_Core/RISCY_OOO/procs/lib/Exec.bsv b/src_Core/RISCY_OOO/procs/lib/Exec.bsv index fd137a2..b1e0055 100755 --- a/src_Core/RISCY_OOO/procs/lib/Exec.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Exec.bsv @@ -30,13 +30,11 @@ import CHERICC_Fat::*; import ISA_Decls_CHERI::*; (* noinline *) -function Maybe#(CapException) capChecks(CapPipe a, CapPipe b, CapChecks toCheck, CapPipe pcc_end); - function Maybe#(CapException) e1(CHERIException e) = Valid(CapException{cheri_exc_reg: toCheck.rn1, cheri_exc_code: e}); - function Maybe#(CapException) e2(CHERIException e) = Valid(CapException{cheri_exc_reg: toCheck.rn2, cheri_exc_code: e}); - Maybe#(CapException) result = Invalid; - if (!isInBounds(pcc_end, True)) - result = Valid(CapException{cheri_exc_reg: {1'b1,pack(SCR_PCC)}, cheri_exc_code: LengthViolation}); - else if (toCheck.src1_tag && !isValidCap(a)) +function Maybe#(CSR_XCapCause) capChecks(CapPipe a, CapPipe b, CapChecks toCheck); + function Maybe#(CSR_XCapCause) e1(CHERIException e) = Valid(CSR_XCapCause{cheri_exc_reg: toCheck.rn1, cheri_exc_code: e}); + function Maybe#(CSR_XCapCause) e2(CHERIException e) = Valid(CSR_XCapCause{cheri_exc_reg: toCheck.rn2, cheri_exc_code: e}); + Maybe#(CSR_XCapCause) result = Invalid; + if (toCheck.src1_tag && !isValidCap(a)) result = e1(TagViolation); else if (toCheck.src2_tag && !isValidCap(b)) result = e2(TagViolation); @@ -288,14 +286,14 @@ function ExecResult basicExec(DecodedInst dInst, CapPipe rVal1, CapPipe rVal2, C BrFunc br_f = dInst.execFunc matches tagged Br .br_f ? br_f : NT; cf.taken = aluBr(getAddr(rVal1), getAddr(rVal2), br_f); cf.nextPc = brAddrCalc(pcc, rVal1, dInst.iType, fromMaybe(0,getDInstImm(dInst)), cf.taken, orig_inst, (ccall || cjalr)); - if (dInst.execFunc matches tagged Br .br_f) rVal1 = cf.nextPc; + if (dInst.execFunc matches tagged Br .unused) rVal1 = cf.nextPc; cf.mispredict = cf.nextPc != ppc; Data inspect_result = capInspect(rVal1, aluVal2, dInst.execFunc.CapInspect); CapModifyFunc modFunc = ccall ? (Unseal (Src2)):dInst.execFunc.CapModify; CapPipe modify_result = capModify(rVal1, aluVal2, modFunc); CapPipe link_pcc = addPc(pcc, ((orig_inst [1:0] == 2'b11) ? 4 : 2)); - Maybe#(CapException) capException = capChecks(rVal1, aluVal2, dInst.capChecks, link_pcc); + Maybe#(CSR_XCapCause) 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); @@ -327,10 +325,11 @@ function ExecResult basicExec(DecodedInst dInst, CapPipe rVal1, CapPipe rVal2, C endfunction (* noinline *) -function Maybe#(Exception) checkForException( +function Maybe#(Trap) checkForException( DecodedInst dInst, ArchRegs regs, - CsrDecodeInfo csrState + CsrDecodeInfo csrState, + CapMem pcc ); // regs needed to check if x0 is a src Maybe#(Exception) exception = Invalid; let prv = csrState.prv; @@ -392,7 +391,16 @@ function Maybe#(Exception) checkForException( end end - return exception; + // Check that the end of the instruction is in bounds of PCC. + CapPipe pcc_end = cast(addPc(pcc, 2)); + Maybe#(CSR_XCapCause) capException = Invalid; + if (!isInBounds(pcc_end, True)) capException = Valid(CSR_XCapCause{cheri_exc_reg: {1'b1,pack(SCR_PCC)}, cheri_exc_code: LengthViolation}); + + Maybe#(Trap) retval = Invalid; + if (capException matches tagged Valid .ce) retval = Valid(CapException(ce)); + else if (exception matches tagged Valid .e) retval = Valid(Exception(e)); + + return retval; endfunction // check mem access misaligned: byteEn is unshifted (just from Decode) diff --git a/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv b/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv index b197633..6f92077 100755 --- a/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv +++ b/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv @@ -391,15 +391,11 @@ typedef 12 InterruptNum; // Without debugger // Traps are either an exception or an interrupt typedef union tagged { + CapException CapException; Exception Exception; Interrupt Interrupt; } Trap deriving(Bits, Eq, FShow); -typedef struct { - Trap trap; - CSR_XCapCause capExp; -} TrapWithCap deriving(Bits, FShow); - // privilege modes Bit#(2) prvU = 0; Bit#(2) prvS = 1; diff --git a/src_Core/RISCY_OOO/procs/lib/ReorderBuffer.bsv b/src_Core/RISCY_OOO/procs/lib/ReorderBuffer.bsv index b0f0cf4..7245667 100755 --- a/src_Core/RISCY_OOO/procs/lib/ReorderBuffer.bsv +++ b/src_Core/RISCY_OOO/procs/lib/ReorderBuffer.bsv @@ -73,7 +73,7 @@ typedef struct { `endif Maybe#(CSR) csr; Bool claimed_phy_reg; // whether we need to commmit renaming - Maybe#(TrapWithCap)trap; + Maybe#(Trap) trap; Addr tval; // in case of trap PPCVAddrCSRData ppc_vaddr_csrData; Bit#(5) fflags; @@ -239,7 +239,7 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p Integer sb_enq_port = 1; // write spec_bits Integer sb_correctSpec_port = 2; // write spec_bits - Ehr#(TAdd#(2, aluExeNum), CapMem) pc <- mkEhr(?); + Ehr#(TAdd#(2, aluExeNum), CapMem) pc <- mkEhr(?); Reg #(Bit #(32)) orig_inst <- mkRegU; Reg#(IType) iType <- mkRegU; Reg #(Maybe #(ArchRIndx)) rg_dst_reg <- mkRegU; @@ -250,8 +250,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#(TrapWithCap)) trap <- mkEhr(?); - Ehr#(3, Maybe#(TrapWithCap)) mem_early_trap <- mkEhr(?); + 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), Addr) tval <- mkEhr(?); Ehr#(TAdd#(2, aluExeNum), PPCVAddrCSRData) ppc_vaddr_csrData <- mkEhr(?); Ehr#(TAdd#(1, fpuMulDivExeNum), Bit#(5)) fflags <- mkEhr(?); @@ -307,7 +307,7 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p ppc_vaddr_csrData[pvc_finishAlu_port(i)] <= PPC (cast(cf.nextPc)); end if (cause matches tagged Valid .exp) begin - trap[trap_finishAlu_port(i)] <= Valid (TrapWithCap{trap: tagged Exception CHERIFault, capExp: exp}); + trap[trap_finishAlu_port(i)] <= Valid (CapException (exp)); tval[trap_finishAlu_port(i)] <= tval[trap_finishAlu_port(i)]; end `ifdef RVFI @@ -335,7 +335,7 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p // update fflags fflags[fflags_finishFpuMulDiv_port(i)] <= new_fflags; if (cause matches tagged Valid .exp) begin - trap[trap_finishFpuMulDiv_port(i)] <= Valid (TrapWithCap{trap: tagged Exception exp, capExp: noCapCause}); + trap[trap_finishFpuMulDiv_port(i)] <= Valid (Exception (exp)); tval[trap_finishFpuMulDiv_port(i)] <= tval[trap_finishAlu_port(i)]; end `ifdef RVFI @@ -385,7 +385,7 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p // udpate non mmio st nonMMIOStDone[nonMMIOSt_finishMem_port] <= non_mmio_st_done; if (cause matches tagged Valid .exp) begin - mem_early_trap[0] <= Valid (TrapWithCap{trap: tagged Exception exp, capExp: noCapCause}); + mem_early_trap[0] <= Valid ( Exception (exp)); tval[trap_finishMem_port] <= tval[trap_finishMem_port]; end endmethod @@ -512,7 +512,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: noCapCause}); + else if(cause matches tagged Valid .e) trap[trap_deqLSQ_port] <= Valid(Exception(e)); // TODO: shouldn't we record tval here as well? // record ld misspeculation ldKilled[ldKill_deqLSQ_port] <= ld_killed;