diff --git a/src_Core/CPU/CsrFile.bsv b/src_Core/CPU/CsrFile.bsv index be5986c..ad8e81f 100644 --- a/src_Core/CPU/CsrFile.bsv +++ b/src_Core/CPU/CsrFile.bsv @@ -1154,7 +1154,7 @@ module mkCsrFile #(Data hartid)(CsrFile); /* ie_vec [prvM] */ prev_ie_vec[prvM], ie_vec [prvS], ie_vec [prvU]); - return RET_Updates {new_pcc: cast(mepcc_reg[0]) + return RET_Updates {new_pcc: cast(setKind(mepcc_reg[0], getKind(mepcc_reg[0]) == SENTRY ? UNSEALED : getKind(mepcc_reg[0]))) `ifdef INCLUDE_TANDEM_VERIF , prv: prev_prv_vec[prvM], status: mstatus_val @@ -1183,7 +1183,7 @@ module mkCsrFile #(Data hartid)(CsrFile); ie_vec [prvM], /* ie_vec [prvS] */ prev_ie_vec[prvS], ie_vec [prvU]); - return RET_Updates {new_pcc: cast(sepcc_reg[0]) + return RET_Updates {new_pcc: cast(setKind(sepcc_reg[0], getKind(sepcc_reg[0]) == SENTRY ? UNSEALED : getKind(sepcc_reg[0]))) `ifdef INCLUDE_TANDEM_VERIF , prv: prev_prv_vec[prvS], status: mstatus_val diff --git a/src_Core/ISA/ISA_Decls_CHERI.bsv b/src_Core/ISA/ISA_Decls_CHERI.bsv index 3336057..56fb917 100755 --- a/src_Core/ISA/ISA_Decls_CHERI.bsv +++ b/src_Core/ISA/ISA_Decls_CHERI.bsv @@ -101,10 +101,10 @@ function SCR unpackSCR(Bit#(5) x); endcase); endfunction -function CapPipe update_scr_via_csr (CapPipe old_scr, WordXL new_csr); +function CapPipe update_scr_via_csr (CapPipe old_scr, WordXL new_csr, Bool allow_sealed); let new_scr = setOffset(old_scr, new_csr); let ret = new_scr.value; - if (!new_scr.exact || (getKind(old_scr) != UNSEALED)) begin + if (!new_scr.exact || (getKind(old_scr) != UNSEALED && !allow_sealed)) begin ret = setValidCap(ret, False); end return ret; @@ -191,7 +191,8 @@ Bit #(5) f5rs2_cap_CClearReg = 5'h0d; // 5'h0e unused Bit #(5) f5rs2_cap_CGetAddr = 5'h0f; Bit #(5) f5rs2_cap_CClearFPReg = 5'h10; -// 5'h11-5'h1f unused (5'h1f reserved for 1-reg instructions +Bit #(5) f5rs2_cap_CSealEntry = 5'h11; +// 5'h12-5'h1f unused (5'h1f reserved for 1-reg instructions // ================================================================ // f7_cap_{Load, Store} opcode subdivision diff --git a/src_Core/RISCY_OOO/procs/lib/CapChecks.bsvi b/src_Core/RISCY_OOO/procs/lib/CapChecks.bsvi index 648df40..3e8d8ad 100644 --- a/src_Core/RISCY_OOO/procs/lib/CapChecks.bsvi +++ b/src_Core/RISCY_OOO/procs/lib/CapChecks.bsvi @@ -5,6 +5,7 @@ `CAP_CHECK_FIELD(src2_sealed_with_type,"src2_sealed_with_type") `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(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 9efb1e1..0877c0a 100755 --- a/src_Core/RISCY_OOO/procs/lib/Decode.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Decode.bsv @@ -1295,6 +1295,16 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); regs.src1 = Valid(tagged Gpr rs1); dInst.capFunc = CapInspect (GetAddr); end + f5rs2_cap_CSealEntry: begin + dInst.capChecks.src1_tag = True; + dInst.capChecks.src1_unsealed = True; + dInst.capChecks.src1_permit_x = True; + + dInst.iType = Cap; + regs.dst = Valid(tagged Gpr rd); + regs.src1 = Valid(tagged Gpr rs1); + dInst.capFunc = CapModify (SealEntry); + end f5rs2_cap_CGetOffset: begin dInst.iType = Cap; regs.dst = Valid(tagged Gpr rd); @@ -1316,7 +1326,7 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); f5rs2_cap_CJALR: begin dInst.capChecks.src1_tag = True; dInst.capChecks.src1_permit_x = True; - dInst.capChecks.src1_unsealed = True; + dInst.capChecks.src1_unsealed_or_sentry = True; dInst.capChecks.check_enable = True; dInst.capChecks.check_authority_src = Src1; diff --git a/src_Core/RISCY_OOO/procs/lib/Exec.bsv b/src_Core/RISCY_OOO/procs/lib/Exec.bsv index e336a17..adfc6a7 100755 --- a/src_Core/RISCY_OOO/procs/lib/Exec.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Exec.bsv @@ -45,6 +45,8 @@ function Maybe#(CSR_XCapCause) capChecks(CapPipe a, CapPipe b, CapPipe ddc, CapC result = eDDC(SealViolation); else if (toCheck.src1_unsealed && isValidCap(a) && (getKind(a) != UNSEALED)) result = e1(SealViolation); + else if (toCheck.src1_unsealed_or_sentry && isValidCap(a) && (getKind(a) != UNSEALED) && (getKind(a) != SENTRY)) + result = e1(SealViolation); else if (toCheck.src2_unsealed && isValidCap(b) && (getKind(b) != UNSEALED)) result = e2(SealViolation); else if (toCheck.src1_sealed_with_type && (getKind (a) matches tagged SEALED_WITH_TYPE .t ? False : True)) @@ -179,10 +181,10 @@ function CapPipe specialRWALU(CapPipe cap, CapPipe oldCap, SpecialRWFunc scrType let offset = getOffset(cap); let oldOffset = getOffset(oldCap); CapPipe res = (case (scrType) matches - tagged TVEC .csrf: update_scr_via_csr(oldCap, csrOp(oldOffset, getAddr(cap), csrf) & ~64'h2); - tagged EPC .csrf: update_scr_via_csr(oldCap, csrOp(oldOffset, getAddr(cap), csrf) & ~64'h1); - tagged TCC: update_scr_via_csr(cap, offset & ~64'h2); // Mask out bit 1 - tagged EPCC: update_scr_via_csr(cap, offset & ~64'h1); // Mask out bit 0 TODO factor out update_scr_via_csr + tagged TVEC .csrf: update_scr_via_csr(oldCap, csrOp(oldOffset, getAddr(cap), csrf) & ~64'h2, False); + tagged EPC .csrf: update_scr_via_csr(oldCap, csrOp(oldOffset, getAddr(cap), csrf) & ~64'h1, False); + tagged TCC: update_scr_via_csr(cap, offset & ~64'h2, False); // Mask out bit 1 + tagged EPCC: update_scr_via_csr(cap, offset & ~64'h1, offset[0] == 1'b0); // Mask out bit 0 tagged Normal: cap; endcase); return res; @@ -205,8 +207,13 @@ function Tuple2#(CapPipe,Bool) capModify(CapPipe a, CapPipe b, CapModifyFunc fun tagged EPC ._: nullWithAddr(getOffset(b)); endcase); tagged SetAddr .addrSource : - if (addrSource == Src1Type && (getKind(a) == UNSEALED)) return t(nullWithAddr(-1)); // TODO correct behaviour around reserved types + if (addrSource == Src1Type && (getKind(a) == UNSEALED)) return t(nullWithAddr(otype_unsealed_ext)); + else if (addrSource == Src1Type && (getKind(a) == SENTRY )) return t(nullWithAddr(otype_sentry_ext)); + else if (addrSource == Src1Type && (getKind(a) == RES0 )) return t(nullWithAddr(otype_res0_ext)); + else if (addrSource == Src1Type && (getKind(a) == RES1 )) return t(nullWithAddr(otype_res1_ext)); else return t(setAddr(b, (addrSource == Src1Type) ? zeroExtend(getKind(a).SEALED_WITH_TYPE) : getAddr(a) ).value); + tagged SealEntry : + t(setKind(a, SENTRY)); tagged Seal : t((validAsType(b, getAddr(b)) && isValidCap(b)) ? setKind(a, SEALED_WITH_TYPE (truncate(getAddr(b)))) @@ -220,7 +227,7 @@ function Tuple2#(CapPipe,Bool) capModify(CapPipe a, CapPipe b, CapModifyFunc fun tagged FromPtr : t(getAddr(a) == 0 ? nullCap : setOffset(b, getAddr(a)).value); tagged BuildCap : - t(setKind(setValidCap(a, True),UNSEALED)); // TODO preserve sentries + t(setKind(setValidCap(a, True), getKind(a)==SENTRY ? SENTRY : UNSEALED)); tagged Move : t(a); tagged ClearTag : @@ -303,6 +310,7 @@ function CapPipe brAddrCalc(CapPipe pc, CapPipe val, IType iType, Data imm, Bool CapPipe branchTarget = incOffset(pc, imm).value; CapPipe jumpTarget = incOffset(val, imm).value; 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; Jr,CCall,CJALR : jumpTarget; @@ -365,7 +373,7 @@ function ExecResult basicExec(DecodedInst dInst, CapPipe rVal1, CapPipe rVal2, C if (dInst.capChecks.cfromptr_bypass && getAddr(rVal1) == 0) begin capException = Invalid; end - if (dInst.capChecks.ccseal_bypass && (!isValidCap(rVal2) || getAddr(rVal2) == -1) && isValidCap(rVal1)) begin + if (dInst.capChecks.ccseal_bypass && (!isValidCap(rVal2) || getAddr(rVal2) == -1 || getKind(rVal1) != UNSEALED) && isValidCap(rVal1)) begin capException = Invalid; boundsCheck = Invalid; end @@ -379,7 +387,7 @@ function ExecResult basicExec(DecodedInst dInst, CapPipe rVal1, CapPipe rVal2, C Amo : rVal2; J : nullWithAddr(getOffset(link_pcc)); CCall : cap_alu_result; - CJALR : link_pcc; + CJALR : setKind(link_pcc, SENTRY); Jr : nullWithAddr(getOffset(link_pcc)); Auipc : nullWithAddr(getOffset(pcc) + getDInstImm(dInst).Valid); Auipcc : incOffset(pcc, getDInstImm(dInst).Valid).value; // could be computed with alu diff --git a/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv b/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv index 96bbf19..d192e1e 100755 --- a/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv +++ b/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv @@ -277,6 +277,7 @@ typedef union tagged { SpecialRWFunc SpecialRW; AddrSource SetAddr; void Seal; + void SealEntry; SrcSelector Unseal; void AndPerm; void SetFlags; diff --git a/src_Testbench/SoC/SoC_Map.bsv b/src_Testbench/SoC/SoC_Map.bsv index 2ce4e70..5b85527 100644 --- a/src_Testbench/SoC/SoC_Map.bsv +++ b/src_Testbench/SoC/SoC_Map.bsv @@ -172,8 +172,7 @@ module mkSoC_Map (SoC_Map_IFC); // (Caches need this information to cache these addresses.) function Bool fn_is_mem_addr (Fabric_Addr addr); - return ( inRange(mem0_controller_addr_range, addr) - || inRange(tcm_addr_range, addr)); + return (inRange(tcm_addr_range, addr)); endfunction // ---------------------------------------------------------------- @@ -183,6 +182,7 @@ module mkSoC_Map (SoC_Map_IFC); function Bool fn_is_IO_addr (Fabric_Addr addr); return ( inRange(boot_rom_addr_range, addr) + || inRange(mem0_controller_addr_range, addr) || inRange(near_mem_io_addr_range, addr) || inRange(plic_addr_range, addr) || inRange(uart0_addr_range, addr));