Add initial exception checks
This commit is contained in:
@@ -42,10 +42,11 @@ typedef enum {
|
||||
CallTrap = 5'd5,
|
||||
ReturnTrap = 5'd6,
|
||||
StackUnderflow = 5'd7,
|
||||
MMUStoreCapProhibit = 5'd8,
|
||||
RepresentViolation = 5'd9,
|
||||
UnalignedBase = 5'd10,
|
||||
// 5'd11 - 5'd15 reserved
|
||||
SoftwarePermViolation = 5'd8,
|
||||
MMUStoreCapProhibit = 5'd9,
|
||||
RepresentViolation = 5'd10,
|
||||
UnalignedBase = 5'd11,
|
||||
// 5'd12 - 5'd15 reserved
|
||||
GlobalViolation = 5'd16,
|
||||
PermitXViolation = 5'd17,
|
||||
PermitRViolation = 5'd18,
|
||||
|
||||
@@ -88,6 +88,7 @@ typedef struct {
|
||||
CapPipe data; // alu compute result
|
||||
Maybe#(Data) csrData; // data to write CSR file
|
||||
ControlFlow controlFlow;
|
||||
Maybe#(CapException) capException;
|
||||
// speculation
|
||||
Maybe#(SpecTag) spec_tag;
|
||||
`ifdef RVFI
|
||||
@@ -154,7 +155,7 @@ interface AluExeInput;
|
||||
CapPipe dst_data,
|
||||
Maybe#(Data) csrData,
|
||||
ControlFlow cf,
|
||||
Maybe#(Exception) cause,
|
||||
Maybe#(CapException) capCause,
|
||||
CapPipe pcc
|
||||
`ifdef RVFI
|
||||
, ExtraTraceBundle tb
|
||||
@@ -347,7 +348,7 @@ module mkAluExePipeline#(AluExeInput inIfc)(AluExePipeline);
|
||||
x.data,
|
||||
x.csrData,
|
||||
x.controlFlow,
|
||||
tagged Invalid,
|
||||
x.capException,
|
||||
cast(inIfc.scaprf_rd(SCR_PCC))
|
||||
`ifdef RVFI
|
||||
, x.traceBundle
|
||||
@@ -355,6 +356,7 @@ module mkAluExePipeline#(AluExeInput inIfc)(AluExePipeline);
|
||||
);
|
||||
|
||||
// handle spec tags for branch predictions
|
||||
// TODO what happens here if we trap?
|
||||
(* split *)
|
||||
if (x.controlFlow.mispredict) (* nosplit *) begin
|
||||
// wrong branch predictin, we must have spec tag
|
||||
|
||||
@@ -28,6 +28,48 @@ import ProcTypes::*;
|
||||
import Vector::*;
|
||||
import CHERICap::*;
|
||||
import CHERICC_Fat::*;
|
||||
import ISA_Decls_CHERI::*;
|
||||
|
||||
(* noinline *)
|
||||
function Maybe#(CapException) capChecks(CapPipe a, CapPipe b, CapChecks toCheck);
|
||||
// TODO plumb register indices here
|
||||
Maybe#(CapException) result = Invalid;
|
||||
if (toCheck.src1_tag && !isValidCap(a))
|
||||
result = Valid (CapException {excCode: TagViolation});
|
||||
else if (toCheck.src2_tag && !isValidCap(b))
|
||||
result = Valid (CapException {excCode: TagViolation});
|
||||
else if (toCheck.src1_sealed_with_type && getKind(a) != SEALED_WITH_TYPE)
|
||||
result = Valid (CapException {excCode: SealViolation});
|
||||
else if (toCheck.src1_unsealed && isValidCap(a) && isSealed(a))
|
||||
result = Valid (CapException {excCode: SealViolation});
|
||||
else if (toCheck.src2_unsealed && isValidCap(b) && isSealed(b))
|
||||
result = Valid (CapException {excCode: SealViolation});
|
||||
else if (toCheck.src1_sealed && isValidCap(a) && !isSealed(a))
|
||||
result = Valid (CapException {excCode: SealViolation});
|
||||
else if (toCheck.src2_sealed && isValidCap(b) && !isSealed(b))
|
||||
result = Valid (CapException {excCode: SealViolation});
|
||||
else if (toCheck.src1_src2_types_match && getType(a) != getType(b))
|
||||
result = Valid (CapException {excCode: TypeViolation});
|
||||
else if (toCheck.src1_permit_ccall && !getHardPerms(a).permitCCall)
|
||||
result = Valid (CapException {excCode: PermitCCallViolation});
|
||||
else if (toCheck.src2_permit_ccall && !getHardPerms(b).permitCCall)
|
||||
result = Valid (CapException {excCode: PermitCCallViolation});
|
||||
else if (toCheck.src1_permit_x && !getHardPerms(a).permitExecute)
|
||||
result = Valid (CapException {excCode: PermitXViolation});
|
||||
else if (toCheck.src2_no_permit_x && getHardPerms(b).permitExecute)
|
||||
result = Valid (CapException {excCode: PermitXViolation});
|
||||
else if (toCheck.src2_permit_unseal && !getHardPerms(b).permitUnseal)
|
||||
result = Valid (CapException {excCode: PermitUnsealViolation});
|
||||
else if (toCheck.src2_permit_seal && !getHardPerms(b).permitSeal)
|
||||
result = Valid (CapException {excCode: PermitSealViolation});
|
||||
else if (toCheck.src2_points_to_src1_type && getAddr(b) != zeroExtend(getType(a)))
|
||||
result = Valid (CapException {excCode: TypeViolation});
|
||||
else if (toCheck.src2_addr_valid_type && !validAsType(b, truncate(getAddr(b))))
|
||||
result = Valid (CapException {excCode: LengthViolation});
|
||||
else if (toCheck.src2_perm_subset_src1 && (getPerms(a) & getPerms(b)) != getPerms(b))
|
||||
result = Valid (CapException {excCode: SoftwarePermViolation});
|
||||
return result;
|
||||
endfunction
|
||||
|
||||
(* noinline *)
|
||||
function Data alu(Data a, Data b, AluFunc func);
|
||||
@@ -58,7 +100,7 @@ endfunction
|
||||
(* noinline *)
|
||||
function CapPipe capModify(CapPipe a, CapPipe b, CapModifyFunc func);
|
||||
CapPipe res = (case(func) matches
|
||||
tagged ModifyOffset .offsetOp:
|
||||
tagged ModifyOffset .offsetOp :
|
||||
modifyOffset(a, getAddr(b), offsetOp == IncOffset).value;
|
||||
tagged SetBounds .exact :
|
||||
setBounds(a, getAddr(b)).value;
|
||||
@@ -178,9 +220,9 @@ function ExecResult basicExec(DecodedInst dInst, CapPipe rVal1, CapPipe rVal2, A
|
||||
AluFunc alu_f = dInst.execFunc matches tagged Alu .alu_f ? alu_f : Add;
|
||||
Data alu_result = alu(getAddr(rVal1), getAddr(aluVal2), alu_f);
|
||||
|
||||
// Pass capabilities into these functions when they are passed in.
|
||||
Data inspect_result = capInspect(rVal1, aluVal2, dInst.execFunc.CapInspect);
|
||||
CapPipe modify_result = capModify(rVal1, aluVal2, dInst.execFunc.CapModify);
|
||||
Maybe#(CapException) capException = capChecks(rVal1, aluVal2, dInst.capChecks); // TODO use this to throw exceptions
|
||||
|
||||
// Default branch function is not taken
|
||||
BrFunc br_f = dInst.execFunc matches tagged Br .br_f ? br_f : NT;
|
||||
@@ -205,7 +247,7 @@ function ExecResult basicExec(DecodedInst dInst, CapPipe rVal1, CapPipe rVal2, A
|
||||
default : nullWithAddr(cf.nextPc);
|
||||
endcase);
|
||||
|
||||
return ExecResult{data: data, csrData: csr_data, addr: addr, controlFlow: cf};
|
||||
return ExecResult{data: data, csrData: csr_data, addr: addr, controlFlow: cf, capException: capException};
|
||||
endfunction
|
||||
|
||||
(* noinline *)
|
||||
|
||||
@@ -33,6 +33,7 @@ import CHERICC_Fat::*;
|
||||
`ifdef RVFI_DII
|
||||
import RVFI_DII_Types::*;
|
||||
`endif
|
||||
import ISA_Decls_CHERI::*;
|
||||
|
||||
typedef `NUM_CORES CoreNum;
|
||||
typedef Bit#(TLog#(CoreNum)) CoreId;
|
||||
@@ -677,6 +678,11 @@ typedef struct {
|
||||
Bool src2_derivable;
|
||||
} CapChecks deriving(Bits, Eq, FShow);
|
||||
|
||||
typedef struct {
|
||||
CHERIException excCode;
|
||||
// TODO GPR or SCR index of cause;
|
||||
} CapException deriving(Bits, FShow);
|
||||
|
||||
typedef struct {
|
||||
IType iType;
|
||||
ExecFunc execFunc;
|
||||
@@ -694,6 +700,7 @@ typedef struct {
|
||||
Data csrData;
|
||||
CapPipe addr;
|
||||
ControlFlow controlFlow;
|
||||
Maybe#(CapException) capException;
|
||||
} ExecResult deriving(Bits, FShow);
|
||||
|
||||
// MMIO
|
||||
|
||||
@@ -114,7 +114,7 @@ interface Row_setExecuted_doFinishAlu;
|
||||
CapPipe dst_data,
|
||||
Maybe#(Data) csrData,
|
||||
ControlFlow cf,
|
||||
Maybe#(Exception) cause,
|
||||
Maybe#(CapException) cause,
|
||||
CapPipe pcc
|
||||
`ifdef RVFI
|
||||
, ExtraTraceBundle tb
|
||||
@@ -285,7 +285,7 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
|
||||
CapPipe dst_data,
|
||||
Maybe#(Data) csrData,
|
||||
ControlFlow cf,
|
||||
Maybe#(Exception) cause,
|
||||
Maybe#(CapException) cause,
|
||||
CapPipe pcc
|
||||
`ifdef RVFI
|
||||
, ExtraTraceBundle tb
|
||||
@@ -309,7 +309,7 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
|
||||
trap[trap_finishAlu_port(i)] <= Valid (tagged Exception CHERIFault);
|
||||
tval[trap_finishAlu_port(i)] <= tval[trap_finishAlu_port(i)];
|
||||
end else if (cause matches tagged Valid .exp) begin
|
||||
trap[trap_finishAlu_port(i)] <= Valid (tagged Exception exp);
|
||||
trap[trap_finishAlu_port(i)] <= Valid (tagged Exception CHERIFault); // TODO propagate CHERI cause
|
||||
tval[trap_finishAlu_port(i)] <= tval[trap_finishAlu_port(i)];
|
||||
end
|
||||
`ifdef RVFI
|
||||
@@ -587,7 +587,7 @@ interface ROB_setExecuted_doFinishAlu;
|
||||
CapPipe dst_data,
|
||||
Maybe#(Data) csrData,
|
||||
ControlFlow cf,
|
||||
Maybe#(Exception) cause,
|
||||
Maybe#(CapException) cause,
|
||||
CapPipe pcc
|
||||
`ifdef RVFI
|
||||
, ExtraTraceBundle tb
|
||||
@@ -1135,7 +1135,7 @@ module mkSupReorderBuffer#(
|
||||
CapPipe dst_data,
|
||||
Maybe#(Data) csrData,
|
||||
ControlFlow cf,
|
||||
Maybe#(Exception) cause,
|
||||
Maybe#(CapException) cause,
|
||||
CapPipe pcc
|
||||
`ifdef RVFI
|
||||
, ExtraTraceBundle tb
|
||||
|
||||
Reference in New Issue
Block a user