From 6450d9c33cf5a72eaf9af85fc5e6552ff37469d7 Mon Sep 17 00:00:00 2001 From: Peter Rugg Date: Wed, 14 Apr 2021 14:53:49 +0100 Subject: [PATCH] Make JAL and JALR mode-dependent --- .../RISCY_OOO/procs/RV64G_OOO/CommitStage.bsv | 1 + .../RISCY_OOO/procs/RV64G_OOO/FetchStage.bsv | 6 +-- src_Core/RISCY_OOO/procs/lib/BrPred.bsv | 2 +- src_Core/RISCY_OOO/procs/lib/CapChecks.bsvi | 1 + src_Core/RISCY_OOO/procs/lib/Decode.bsv | 26 +++++++-- src_Core/RISCY_OOO/procs/lib/Exec.bsv | 53 ++++++++++--------- src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv | 2 +- .../RISCY_OOO/procs/lib/ReorderBuffer.bsv | 2 +- 8 files changed, 59 insertions(+), 34 deletions(-) diff --git a/src_Core/RISCY_OOO/procs/RV64G_OOO/CommitStage.bsv b/src_Core/RISCY_OOO/procs/RV64G_OOO/CommitStage.bsv index 5c58751..8f1185c 100644 --- a/src_Core/RISCY_OOO/procs/RV64G_OOO/CommitStage.bsv +++ b/src_Core/RISCY_OOO/procs/RV64G_OOO/CommitStage.bsv @@ -1184,6 +1184,7 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage); Auipc, Auipcc: auipcCnt = auipcCnt + 1; Br: brCnt = brCnt + 1; J : jmpCnt = jmpCnt + 1; + CJAL: jmpCnt = jmpCnt + 1; Jr: jrCnt = jrCnt + 1; CJALR: jrCnt = jrCnt + 1; Ld: begin diff --git a/src_Core/RISCY_OOO/procs/RV64G_OOO/FetchStage.bsv b/src_Core/RISCY_OOO/procs/RV64G_OOO/FetchStage.bsv index 1e57e09..c819973 100644 --- a/src_Core/RISCY_OOO/procs/RV64G_OOO/FetchStage.bsv +++ b/src_Core/RISCY_OOO/procs/RV64G_OOO/FetchStage.bsv @@ -717,7 +717,7 @@ module mkFetchStage(FetchStage); CapMem push_addr = addPc(pc, ((in.inst_kind == Inst_32b) ? 4 : 2)); CapMem pop_addr = ras.ras[i].first; - if (dInst.iType == J && dst_link) begin + if ((dInst.iType == J || dInst.iType == CJAL) && dst_link) begin // rs1 is invalid, i.e., not link: push ras.ras[i].popPush(False, Valid (push_addr)); end @@ -821,7 +821,7 @@ module mkFetchStage(FetchStage); if(redirectInst matches tagged Valid .iType &&& doStats) begin case(iType) Br: decRedirectBrCnt.incr(1); - J : decRedirectJmpCnt.incr(1); + J, CJAL: decRedirectJmpCnt.incr(1); Jr: decRedirectJrCnt.incr(1); default: decRedirectOtherCnt.incr(1); endcase @@ -930,7 +930,7 @@ module mkFetchStage(FetchStage); CapMem pc, CapMem next_pc, IType iType, Bool taken, DirPredTrainInfo dpTrain, Bool mispred, Bool isCompressed ); - //if (iType == J || (iType == Br && next_pc < pc)) begin + //if (iType == J || iType == CJAL || (iType == Br && next_pc < pc)) begin // // Only train the next address predictor for jumps and backward branches // // next_pc != pc + 4 is a substitute for taken // nextAddrPred.update(pc, next_pc, taken); diff --git a/src_Core/RISCY_OOO/procs/lib/BrPred.bsv b/src_Core/RISCY_OOO/procs/lib/BrPred.bsv index 5943f36..1ac9456 100644 --- a/src_Core/RISCY_OOO/procs/lib/BrPred.bsv +++ b/src_Core/RISCY_OOO/procs/lib/BrPred.bsv @@ -48,7 +48,7 @@ function Maybe#(CapMem) decodeBrPred( CapMem pc, DecodedInst dInst, Bool histTak Maybe#(CapMem) nextPc = tagged Invalid; CapPipe pcPipe = cast(pc); CapMem jTarget = cast(incOffset(pcPipe, imm_val).value); - if( dInst.iType == J ) begin + if( dInst.iType == J || dInst.iType == CJAL ) begin nextPc = tagged Valid jTarget; end else if( dInst.iType == Br ) begin if( histTaken ) begin diff --git a/src_Core/RISCY_OOO/procs/lib/CapChecks.bsvi b/src_Core/RISCY_OOO/procs/lib/CapChecks.bsvi index 722ce39..018b513 100644 --- a/src_Core/RISCY_OOO/procs/lib/CapChecks.bsvi +++ b/src_Core/RISCY_OOO/procs/lib/CapChecks.bsvi @@ -6,6 +6,7 @@ `CAP_CHECK_FIELD(ddc_unsealed,"ddc_unsealed") `CAP_CHECK_FIELD(src1_unsealed,"src1_unsealed") `CAP_CHECK_FIELD(src1_unsealed_or_sentry,"src1_unsealed_or_sentry") +`CAP_CHECK_FIELD(src1_unsealed_or_imm_zero,"src1_unsealed_or_imm_zero") `CAP_CHECK_FIELD(src2_unsealed,"src2_unsealed") `CAP_CHECK_FIELD(src1_src2_types_match,"src1_src2_types_match") `CAP_CHECK_FIELD(src1_permit_ccall,"src1_permit_ccall") diff --git a/src_Core/RISCY_OOO/procs/lib/Decode.bsv b/src_Core/RISCY_OOO/procs/lib/Decode.bsv index f415631..28510fc 100755 --- a/src_Core/RISCY_OOO/procs/lib/Decode.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Decode.bsv @@ -491,7 +491,13 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); end opcJal: begin - dInst.iType = J; + if (cap_mode) begin + dInst.iType = CJAL; + end + else begin + dInst.iType = J; + end + regs.dst = Valid(tagged Gpr rd); regs.src1 = Invalid; regs.src2 = Invalid; @@ -506,18 +512,32 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); end opcJalr: begin - dInst.iType = Jr; regs.dst = Valid(tagged Gpr rd); regs.src1 = Valid(tagged Gpr rs1); regs.src2 = Invalid; dInst.imm = Valid(immI); dInst.csr = tagged Invalid; dInst.execFunc = tagged Br AT; + dInst.capChecks.check_enable = True; - dInst.capChecks.check_authority_src = Pcc; dInst.capChecks.check_low_src = Src1Addr; dInst.capChecks.check_high_src = Src1AddrPlus2; dInst.capChecks.check_inclusive = True; + if (cap_mode) begin + dInst.iType = CJALR; + + dInst.capChecks.src1_tag = True; + dInst.capChecks.src1_permit_x = True; + dInst.capChecks.src1_unsealed_or_sentry = True; + dInst.capChecks.src1_unsealed_or_imm_zero = True; + + dInst.capChecks.check_authority_src = Src1; + end + else begin + dInst.iType = Jr; + + dInst.capChecks.check_authority_src = Pcc; + end end opcBranch: begin diff --git a/src_Core/RISCY_OOO/procs/lib/Exec.bsv b/src_Core/RISCY_OOO/procs/lib/Exec.bsv index e629b29..cfbfa2b 100755 --- a/src_Core/RISCY_OOO/procs/lib/Exec.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Exec.bsv @@ -46,54 +46,56 @@ import ISA_Decls_CHERI::*; import CacheUtils::*; // For CLoadTags alignment (* noinline *) -function Maybe#(CSR_XCapCause) capChecksExec(CapPipe a, CapPipe b, CapPipe ddc, CapChecks toCheck, Bool cap_exact); +function Maybe#(CSR_XCapCause) capChecksExec(CapPipe a, CapPipe b, CapPipe ddc, CapChecks toCheck, Bool cap_exact, ImmData imm); 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}); function Maybe#(CSR_XCapCause) eDDC(CHERIException e) = Valid(CSR_XCapCause{cheri_exc_reg: {1'b1, pack(scrAddrDDC)}, cheri_exc_code: e}); Maybe#(CSR_XCapCause) result = Invalid; - if (toCheck.ddc_tag && !isValidCap(ddc)) + if (toCheck.ddc_tag && !isValidCap(ddc)) result = eDDC(cheriExcTagViolation); - else if (toCheck.src1_tag && !isValidCap(a)) + else if (toCheck.src1_tag && !isValidCap(a)) result = e1(cheriExcTagViolation); - else if (toCheck.src2_tag && !isValidCap(b)) + else if (toCheck.src2_tag && !isValidCap(b)) result = e2(cheriExcTagViolation); - else if (toCheck.ddc_unsealed && isValidCap(ddc) && (getKind(ddc) != UNSEALED)) + else if (toCheck.ddc_unsealed && isValidCap(ddc) && (getKind(ddc) != UNSEALED)) result = eDDC(cheriExcSealViolation); - else if (toCheck.src1_unsealed && isValidCap(a) && (getKind(a) != UNSEALED)) + else if (toCheck.src1_unsealed && isValidCap(a) && (getKind(a) != UNSEALED)) result = e1(cheriExcSealViolation); - else if (toCheck.src1_unsealed_or_sentry && isValidCap(a) && (getKind(a) != UNSEALED) && (getKind(a) != SENTRY)) + else if (toCheck.src1_unsealed_or_sentry && isValidCap(a) && (getKind(a) != UNSEALED) && (getKind(a) != SENTRY)) result = e1(cheriExcSealViolation); - else if (toCheck.src2_unsealed && isValidCap(b) && (getKind(b) != UNSEALED)) + else if (toCheck.src1_unsealed_or_imm_zero && isValidCap(a) && (getKind(a) != UNSEALED) && (imm != 0)) + result = e1(cheriExcSealViolation); + else if (toCheck.src2_unsealed && isValidCap(b) && (getKind(b) != UNSEALED)) result = e2(cheriExcSealViolation); - else if (toCheck.src1_sealed_with_type && (getKind (a) matches tagged SEALED_WITH_TYPE .t ? False : True)) + else if (toCheck.src1_sealed_with_type && (getKind (a) matches tagged SEALED_WITH_TYPE .t ? False : True)) result = e1(cheriExcSealViolation); - else if (toCheck.src2_sealed_with_type && (getKind (b) matches tagged SEALED_WITH_TYPE .t ? False : True)) + else if (toCheck.src2_sealed_with_type && (getKind (b) matches tagged SEALED_WITH_TYPE .t ? False : True)) result = e2(cheriExcSealViolation); - else if (toCheck.src1_type_not_reserved && !validAsType(a, zeroExtend(getKind(a).SEALED_WITH_TYPE))) + else if (toCheck.src1_type_not_reserved && !validAsType(a, zeroExtend(getKind(a).SEALED_WITH_TYPE))) result = e1(cheriExcTypeViolation); - else if (toCheck.src1_src2_types_match && getKind(a).SEALED_WITH_TYPE != getKind(b).SEALED_WITH_TYPE) + else if (toCheck.src1_src2_types_match && getKind(a).SEALED_WITH_TYPE != getKind(b).SEALED_WITH_TYPE) result = e1(cheriExcTypeViolation); - else if (toCheck.src1_permit_ccall && !getHardPerms(a).permitCCall) + else if (toCheck.src1_permit_ccall && !getHardPerms(a).permitCCall) result = e1(cheriExcPermitCCallViolation); - else if (toCheck.src2_permit_ccall && !getHardPerms(b).permitCCall) + else if (toCheck.src2_permit_ccall && !getHardPerms(b).permitCCall) result = e2(cheriExcPermitCCallViolation); - else if (toCheck.src1_permit_x && !getHardPerms(a).permitExecute) + else if (toCheck.src1_permit_x && !getHardPerms(a).permitExecute) result = e1(cheriExcPermitXViolation); - else if (toCheck.src2_no_permit_x && getHardPerms(b).permitExecute) + else if (toCheck.src2_no_permit_x && getHardPerms(b).permitExecute) result = e2(cheriExcPermitXViolation); - else if (toCheck.src2_permit_unseal && !getHardPerms(b).permitUnseal) + else if (toCheck.src2_permit_unseal && !getHardPerms(b).permitUnseal) result = e2(cheriExcPermitUnsealViolation); - else if (toCheck.src2_permit_seal && !getHardPerms(b).permitSeal) + else if (toCheck.src2_permit_seal && !getHardPerms(b).permitSeal) result = e2(cheriExcPermitSealViolation); - else if (toCheck.src2_points_to_src1_type && getAddr(b) != zeroExtend(getKind(a).SEALED_WITH_TYPE)) + else if (toCheck.src2_points_to_src1_type && getAddr(b) != zeroExtend(getKind(a).SEALED_WITH_TYPE)) result = e2(cheriExcTypeViolation); - else if (toCheck.src2_addr_valid_type && !validAsType(b, truncate(getAddr(b)))) + else if (toCheck.src2_addr_valid_type && !validAsType(b, truncate(getAddr(b)))) result = e2(cheriExcLengthViolation); - else if (toCheck.src1_perm_subset_src2 && (getPerms(a) & getPerms(b)) != getPerms(a)) + else if (toCheck.src1_perm_subset_src2 && (getPerms(a) & getPerms(b)) != getPerms(a)) result = e2(cheriExcSoftwarePermViolation); - else if (toCheck.src1_derivable && !isDerivable(a)) + else if (toCheck.src1_derivable && !isDerivable(a)) result = e1(cheriExcLengthViolation); - else if (toCheck.cap_exact && !cap_exact) + else if (toCheck.cap_exact && !cap_exact) result = e1(cheriExcRepresentViolation); return result; endfunction @@ -358,7 +360,7 @@ function CapPipe brAddrCalc(CapPipe pc, CapPipe val, IType iType, Data imm, Bool jumpTarget = setAddrUnsafe(jumpTarget, {truncateLSB(getAddr(jumpTarget)), 1'b0}); jumpTarget = setKind(jumpTarget, UNSEALED); // It is checked elsewhere that we have an unsealed cap already, or sentry if permitted CapPipe targetAddr = (case (iType) - J : branchTarget; + J, CJAL : branchTarget; Jr,CCall,CJALR : jumpTarget; Br : (taken? branchTarget : pcPlusN); default : pcPlusN; @@ -407,7 +409,7 @@ function ExecResult basicExec(DecodedInst dInst, CapPipe rVal1, CapPipe rVal2, C cf.taken = aluBr(getAddr(rVal1), getAddr(rVal2), br_f); cf.nextPc = brAddrCalc(pcc, rVal1, dInst.iType, fromMaybe(0,getDInstImm(dInst)), cf.taken, orig_inst, newPcc); - Maybe#(CSR_XCapCause) capException = capChecksExec(rVal1, aluVal2, nullCap, dInst.capChecks, cap_exact); + Maybe#(CSR_XCapCause) capException = capChecksExec(rVal1, aluVal2, nullCap, dInst.capChecks, cap_exact, dInst.imm.Valid); if (dInst.execFunc matches tagged Br .unused) begin rVal1 = cf.nextPc; if (!cf.taken) dInst.capChecks.check_enable = False; @@ -431,6 +433,7 @@ function ExecResult basicExec(DecodedInst dInst, CapPipe rVal1, CapPipe rVal2, C Sc : rVal2; Amo : rVal2; J : nullWithAddr(getOffset(link_pcc)); + CJAL : setKind(link_pcc, SENTRY); CCall : cap_alu_result; CJALR : setKind(link_pcc, SENTRY); Jr : nullWithAddr(getOffset(link_pcc)); diff --git a/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv b/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv index 21830b0..8708ad7 100755 --- a/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv +++ b/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv @@ -268,7 +268,7 @@ typedef enum { Alu, Ld, St, Lr, Sc, J, Jr, Br, - CCall, CJALR, Cap, + CCall, CJAL, CJALR, Cap, Auipc, Auipcc, Fpu, diff --git a/src_Core/RISCY_OOO/procs/lib/ReorderBuffer.bsv b/src_Core/RISCY_OOO/procs/lib/ReorderBuffer.bsv index 0fde3d8..ffbf123 100755 --- a/src_Core/RISCY_OOO/procs/lib/ReorderBuffer.bsv +++ b/src_Core/RISCY_OOO/procs/lib/ReorderBuffer.bsv @@ -57,7 +57,7 @@ import Cur_Cycle :: *; // some parts of full_result are for verification // but some are truly used for execution -// ppc is only used by iType = BR/J/JR +// ppc is only used by iType = BR/J/CJAL/JR // csrData is only used by iType = Csr // vaddr is only used by mem inst in page fault typedef union tagged {