diff --git a/src_Core/RISCY_OOO/procs/lib/CapChecks.bsvi b/src_Core/RISCY_OOO/procs/lib/CapChecks.bsvi index 981bbad..977beb4 100644 --- a/src_Core/RISCY_OOO/procs/lib/CapChecks.bsvi +++ b/src_Core/RISCY_OOO/procs/lib/CapChecks.bsvi @@ -20,3 +20,4 @@ `CAP_CHECK_FIELD(src1_derivable,"src1_derivable") `CAP_CHECK_FIELD(scr_read_only,"scr_read_only") `CAP_CHECK_FIELD(cfromptr_bypass,"cfromptr_bypass") +`CAP_CHECK_FIELD(ccseal_bypass,"ccseal_bypass") diff --git a/src_Core/RISCY_OOO/procs/lib/Decode.bsv b/src_Core/RISCY_OOO/procs/lib/Decode.bsv index a157460..321ff67 100755 --- a/src_Core/RISCY_OOO/procs/lib/Decode.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Decode.bsv @@ -1052,8 +1052,26 @@ function DecodeResult decode(Instruction inst, Bool cap_mode); dInst.capFunc = CapModify (Seal); end f7_cap_CCSeal: begin - illegalInst = True; - // TODO problematic because checks depend on register value + dInst.capChecks.src1_tag = True; + + dInst.capChecks.src1_unsealed = True; + dInst.capChecks.src2_unsealed = True; + dInst.capChecks.src2_addr_valid_type = True; + dInst.capChecks.src2_permit_seal = True; + dInst.capChecks.ccseal_bypass = 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 = Cap; + regs.dst = Valid(tagged Gpr rd); + regs.src1 = Valid(tagged Gpr rs1); + regs.src2 = Valid(tagged Gpr rs2); + dInst.imm = Invalid; + dInst.capFunc = CapModify (Seal); end f7_cap_TwoSrc: begin case (rd) diff --git a/src_Core/RISCY_OOO/procs/lib/Exec.bsv b/src_Core/RISCY_OOO/procs/lib/Exec.bsv index ed042a4..d40cae8 100755 --- a/src_Core/RISCY_OOO/procs/lib/Exec.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Exec.bsv @@ -205,7 +205,9 @@ function CapPipe capModify(CapPipe a, CapPipe b, CapModifyFunc func); if (addrSource == Src1Type && (getKind(a) == UNSEALED)) return nullWithAddr(-1); // TODO correct behaviour around reserved types else return setAddr(b, (addrSource == Src1Type) ? zeroExtend(getKind(a).SEALED_WITH_TYPE) : getAddr(a) ).value; // TODO check for unrepresentability tagged Seal : - setKind(a, SEALED_WITH_TYPE (truncate(getAddr(b)))); + ((validAsType(b, getAddr(b)) && isValidCap(b)) ? + setKind(a, SEALED_WITH_TYPE (truncate(getAddr(b)))) + : a); tagged Unseal .src : setKind(((src == Src1) ? a:b), UNSEALED); tagged AndPerm : @@ -354,6 +356,10 @@ 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 + capException = Invalid; + boundsCheck = Invalid; + end cf.nextPc = setKind(cf.nextPc, UNSEALED); cf.mispredict = cf.nextPc != ppc;