Add sentries

This commit is contained in:
Peter Rugg
2020-06-29 23:29:08 +01:00
parent 70185dabac
commit c8e4a64128
7 changed files with 37 additions and 16 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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")

View File

@@ -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;

View File

@@ -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

View File

@@ -277,6 +277,7 @@ typedef union tagged {
SpecialRWFunc SpecialRW;
AddrSource SetAddr;
void Seal;
void SealEntry;
SrcSelector Unseal;
void AndPerm;
void SetFlags;

View File

@@ -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));