Changes for CJALR to work in a basic case, as well as piping CHERI exceptions through to commit, though the register isn't piped and I've undone some useful work for that piping. Oh well.

This commit is contained in:
jon
2020-04-06 18:18:05 +01:00
parent 4ce8f54903
commit 850e632140
9 changed files with 78 additions and 47 deletions

2
src_Core/ISA/ISA_Decls_CHERI.bsv Normal file → Executable file
View File

@@ -65,7 +65,7 @@ typedef enum {
typedef struct {
Bit #(6) cheri_exc_reg;
CHERIException cheri_exc_code;
} CSR_XCapCause deriving(Bits);
} CSR_XCapCause deriving(Bits, FShow);
function Bit#(64) xccsr_to_word(CSR_XCapCause xccsr);
return zeroExtend({xccsr.cheri_exc_reg, pack(xccsr.cheri_exc_code), 3'b0, 1'b1, 1'b1});

12
src_Core/RISCY_OOO/procs/RV64G_OOO/AluExePipeline.bsv Normal file → Executable file
View File

@@ -87,8 +87,9 @@ typedef struct {
// result
CapPipe data; // alu compute result
Maybe#(Data) csrData; // data to write CSR file
Maybe#(CapPipe) scrData; // datat to write to special capability register file.
ControlFlow controlFlow;
Maybe#(CapException) capException;
Maybe#(CHERIException) capException;
// speculation
Maybe#(SpecTag) spec_tag;
`ifdef RVFI
@@ -154,8 +155,9 @@ interface AluExeInput;
InstTag t,
CapPipe dst_data,
Maybe#(Data) csrData,
Maybe#(CapPipe) scrData,
ControlFlow cf,
Maybe#(CapException) capCause,
Maybe#(CHERIException) capCause,
CapPipe pcc
`ifdef RVFI
, ExtraTraceBundle tb
@@ -317,6 +319,11 @@ module mkAluExePipeline#(AluExeInput inIfc)(AluExePipeline);
isCompressed: x.orig_inst[1:0] != 2'b11,
data: exec_result.data,
csrData: isValid(x.dInst.csr) ? Valid (exec_result.csrData) : tagged Invalid,
// The above case will never be valid due to assertions above, but the below one will be in the case of CJALR.
// This means that we will have instructions that both write SCR registers and also get mispredictions, unlike
// the CSR file. Given the assertions above, this seems dangerous...
scrData: isValid(x.dInst.scr) ? Valid (exec_result.scrData) : tagged Invalid,
capException: isValid(exec_result.capException) ? (Valid (exec_result.capException.Valid.cheri_exc_code)) : Invalid,
`ifdef RVFI
traceBundle: ExtraTraceBundle{
regWriteData: getAddr(exec_result.data),
@@ -347,6 +354,7 @@ module mkAluExePipeline#(AluExeInput inIfc)(AluExePipeline);
x.tag,
x.data,
x.csrData,
x.scrData,
x.controlFlow,
x.capException,
cast(inIfc.scaprf_rd(SCR_PCC))

View File

@@ -621,15 +621,15 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
// record trap info
Addr vaddr = ?;
if ( (trap == tagged Exception InstAccessFault)
|| (trap == tagged Exception InstPageFault)) begin
if ( (trap.trap == tagged Exception InstAccessFault)
|| (trap.trap == tagged Exception InstPageFault)) begin
vaddr = x.tval;
end
else if(x.ppc_vaddr_csrData matches tagged VAddr .va) begin
vaddr = getAddr(va);
end
let commitTrap_val = Valid (CommitTrap {
trap: trap,
trap: trap.trap,
pc: x.pc,
addr: vaddr,
orig_inst: x.orig_inst

View File

@@ -35,7 +35,7 @@ module mkRFileSynth(RFileSynth);
CapReg default_register_value = nullCap;
//Data default_register_value = 0;
`ifdef RVFI_DII
// default_register_value = almightyCap;
default_register_value = almightyCap;
`endif
let m <- mkRFile(default_register_value, `LAZY_RS_RF);
return m;

View File

@@ -357,6 +357,8 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
// Flip epoch without redirecting
// This avoids doing incorrect work
incrEpochStallFetch;
Maybe#(TrapWithCap) trapWithCap = Invalid;
if (firstTrap matches tagged Valid .trap) trapWithCap = tagged Valid TrapWithCap{trap: trap, capExp: None};
// just place it in the reorder buffer
let y = ToReorderBuffer{pc: setAddr(almightyCap, pc).value,
orig_inst: orig_inst,
@@ -369,7 +371,7 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
`endif
csr: dInst.csr,
claimed_phy_reg: False, // no renaming is done
trap: firstTrap,
trap: trapWithCap,
tval: tval,
// default values of FullResult
ppc_vaddr_csrData: PPC (setAddr(almightyCap, pc).value), // default use PPC

View File

@@ -151,6 +151,7 @@ function DecodeResult decode(Instruction inst);
iType: Unsupported,
execFunc: tagged Other,
csr: tagged Invalid,
scr: tagged Invalid,
imm: tagged Invalid,
capChecks: unpack(0)
};
@@ -1039,8 +1040,11 @@ function DecodeResult decode(Instruction inst);
regs.src1 = Valid(tagged Gpr rs1);
regs.src2 = Invalid;
dInst.imm = Invalid;
dInst.csr = tagged Invalid;
//dInst.scr = tagged Valid SCR_PCC;
dInst.execFunc = tagged Br AT;
dInst.capChecks.src1_tag = True;
dInst.capChecks.src1_permit_x = True;
dInst.capChecks.src1_unsealed = True;
end
f5rs2_cap_CGetType: begin
dInst.iType = CapInspect;

View File

@@ -35,39 +35,39 @@ 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});
result = Valid (CapException {cheri_exc_code: TagViolation});
else if (toCheck.src2_tag && !isValidCap(b))
result = Valid (CapException {excCode: TagViolation});
result = Valid (CapException {cheri_exc_code: TagViolation});
else if (toCheck.src1_sealed_with_type && getKind(a) != SEALED_WITH_TYPE)
result = Valid (CapException {excCode: SealViolation});
result = Valid (CapException {cheri_exc_code: SealViolation});
else if (toCheck.src1_unsealed && isValidCap(a) && isSealed(a))
result = Valid (CapException {excCode: SealViolation});
result = Valid (CapException {cheri_exc_code: SealViolation});
else if (toCheck.src2_unsealed && isValidCap(b) && isSealed(b))
result = Valid (CapException {excCode: SealViolation});
result = Valid (CapException {cheri_exc_code: SealViolation});
else if (toCheck.src1_sealed && isValidCap(a) && !isSealed(a))
result = Valid (CapException {excCode: SealViolation});
result = Valid (CapException {cheri_exc_code: SealViolation});
else if (toCheck.src2_sealed && isValidCap(b) && !isSealed(b))
result = Valid (CapException {excCode: SealViolation});
result = Valid (CapException {cheri_exc_code: SealViolation});
else if (toCheck.src1_src2_types_match && getType(a) != getType(b))
result = Valid (CapException {excCode: TypeViolation});
result = Valid (CapException {cheri_exc_code: TypeViolation});
else if (toCheck.src1_permit_ccall && !getHardPerms(a).permitCCall)
result = Valid (CapException {excCode: PermitCCallViolation});
result = Valid (CapException {cheri_exc_code: PermitCCallViolation});
else if (toCheck.src2_permit_ccall && !getHardPerms(b).permitCCall)
result = Valid (CapException {excCode: PermitCCallViolation});
result = Valid (CapException {cheri_exc_code: PermitCCallViolation});
else if (toCheck.src1_permit_x && !getHardPerms(a).permitExecute)
result = Valid (CapException {excCode: PermitXViolation});
result = Valid (CapException {cheri_exc_code: PermitXViolation});
else if (toCheck.src2_no_permit_x && getHardPerms(b).permitExecute)
result = Valid (CapException {excCode: PermitXViolation});
result = Valid (CapException {cheri_exc_code: PermitXViolation});
else if (toCheck.src2_permit_unseal && !getHardPerms(b).permitUnseal)
result = Valid (CapException {excCode: PermitUnsealViolation});
result = Valid (CapException {cheri_exc_code: PermitUnsealViolation});
else if (toCheck.src2_permit_seal && !getHardPerms(b).permitSeal)
result = Valid (CapException {excCode: PermitSealViolation});
result = Valid (CapException {cheri_exc_code: PermitSealViolation});
else if (toCheck.src2_points_to_src1_type && getAddr(b) != zeroExtend(getType(a)))
result = Valid (CapException {excCode: TypeViolation});
result = Valid (CapException {cheri_exc_code: TypeViolation});
else if (toCheck.src2_addr_valid_type && !validAsType(b, truncate(getAddr(b))))
result = Valid (CapException {excCode: LengthViolation});
result = Valid (CapException {cheri_exc_code: LengthViolation});
else if (toCheck.src2_perm_subset_src1 && (getPerms(a) & getPerms(b)) != getPerms(b))
result = Valid (CapException {excCode: SoftwarePermViolation});
result = Valid (CapException {cheri_exc_code: SoftwarePermViolation});
return result;
endfunction
@@ -212,7 +212,7 @@ function ExecResult basicExec(DecodedInst dInst, CapPipe rVal1, CapPipe rVal2, A
CapPipe data = nullCap;
Data csr_data = 0;
CapPipe addr = nullCap;
ControlFlow cf = ControlFlow{pc: pc, nextPc: 0, taken: False, mispredict: False};
ControlFlow cf = ControlFlow{pc: pc, nextPc: 0, taken: False, newPcc: dInst.capChecks.src1_tag, mispredict: False};
CapPipe aluVal2 = rVal2;
if (getDInstImm(dInst) matches tagged Valid .imm) aluVal2 = nullWithAddr(imm); //isValid(dInst.imm) ? fromMaybe(?, dInst.imm) : rVal2;
@@ -246,8 +246,9 @@ function ExecResult basicExec(DecodedInst dInst, CapPipe rVal1, CapPipe rVal2, A
Ld, St, Lr, Sc, Amo : nullWithAddr(alu_result);
default : nullWithAddr(cf.nextPc);
endcase);
CapPipe scr_data = rVal1;
return ExecResult{data: data, csrData: csr_data, addr: addr, controlFlow: cf, capException: capException};
return ExecResult{data: data, csrData: csr_data, scrData: scr_data, addr: addr, controlFlow: cf, capException: capException};
endfunction
(* noinline *)

View File

@@ -30,6 +30,7 @@ import DefaultValue::*;
import MemoryTypes::*;
import CHERICap::*;
import CHERICC_Fat::*;
import ISA_Decls_CHERI::*;
`ifdef RVFI_DII
import RVFI_DII_Types::*;
`endif
@@ -555,6 +556,11 @@ typedef union tagged {
Interrupt Interrupt;
} Trap deriving(Bits, Eq, FShow);
typedef struct {
Trap trap;
CHERIException capExp;
} TrapWithCap deriving(Bits, Eq, FShow);
// privilege modes
Bit#(2) prvU = 0;
Bit#(2) prvS = 1;
@@ -646,6 +652,7 @@ typedef struct {
Addr pc;
Addr nextPc;
Bool taken;
Bool newPcc;
Bool mispredict;
} ControlFlow deriving (Bits, Eq, FShow);
@@ -678,16 +685,14 @@ 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 CSR_XCapCause CapException;
typedef struct {
IType iType;
ExecFunc execFunc;
CapChecks capChecks;
Maybe#(CSR) csr;
Maybe#(SCR) scr; // Special Capability Register.
Maybe#(ImmData) imm;
} DecodedInst deriving(Bits, Eq, FShow);
@@ -698,6 +703,7 @@ endfunction
typedef struct {
CapPipe data;
Data csrData;
CapPipe scrData;
CapPipe addr;
ControlFlow controlFlow;
Maybe#(CapException) capException;

40
src_Core/RISCY_OOO/procs/lib/ReorderBuffer.bsv Normal file → Executable file
View File

@@ -35,6 +35,7 @@ import RVFI_DII_Types::*;
`endif
import CHERICap::*;
import CHERICC_Fat::*;
import ISA_Decls_CHERI::*;
import Cur_Cycle :: *;
@@ -49,6 +50,7 @@ typedef union tagged {
CapPipe PPC; // at default store ppc
CapPipe VAddr; // for mem inst, store vaddr
Data CSRData; // for Csr inst, store csr_data
CapPipe SCRData; // for special capability register store
} PPCVAddrCSRData deriving(Bits, FShow);
`ifdef RVFI
@@ -71,7 +73,7 @@ typedef struct {
`endif
Maybe#(CSR) csr;
Bool claimed_phy_reg; // whether we need to commmit renaming
Maybe#(Trap) trap;
Maybe#(TrapWithCap)trap;
Addr tval; // in case of trap
PPCVAddrCSRData ppc_vaddr_csrData;
Bit#(5) fflags;
@@ -113,8 +115,9 @@ interface Row_setExecuted_doFinishAlu;
method Action set(
CapPipe dst_data,
Maybe#(Data) csrData,
Maybe#(CapPipe) scrData,
ControlFlow cf,
Maybe#(CapException) cause,
Maybe#(CHERIException) cause,
CapPipe pcc
`ifdef RVFI
, ExtraTraceBundle tb
@@ -250,8 +253,8 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
`endif
Reg#(Maybe#(CSR)) csr <- mkRegU;
Reg#(Bool) claimed_phy_reg <- mkRegU;
Ehr#(TAdd#(TAdd#(2, TDiv#(aluExeNum,2)), aluExeNum), Maybe#(Trap)) trap <- mkEhr(?);
Ehr#(3, Maybe#(Trap)) mem_early_trap <- mkEhr(?);
Ehr#(TAdd#(TAdd#(2, TDiv#(aluExeNum,2)), aluExeNum), Maybe#(TrapWithCap)) trap <- mkEhr(?);
Ehr#(3, Maybe#(TrapWithCap)) mem_early_trap <- mkEhr(?);
Ehr#(TAdd#(TAdd#(2, TDiv#(aluExeNum,2)), aluExeNum), Addr) tval <- mkEhr(?);
Ehr#(TAdd#(2, aluExeNum), PPCVAddrCSRData) ppc_vaddr_csrData <- mkEhr(?);
Ehr#(TAdd#(1, fpuMulDivExeNum), Bit#(5)) fflags <- mkEhr(?);
@@ -284,8 +287,9 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
method Action set(
CapPipe dst_data,
Maybe#(Data) csrData,
Maybe#(CapPipe) scrData,
ControlFlow cf,
Maybe#(CapException) cause,
Maybe#(CHERIException) cause,
CapPipe pcc
`ifdef RVFI
, ExtraTraceBundle tb
@@ -300,16 +304,19 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
if(csrData matches tagged Valid .d) begin
ppc_vaddr_csrData[pvc_finishAlu_port(i)] <= CSRData (d);
end
else if(scrData matches tagged Valid .d) begin
ppc_vaddr_csrData[pvc_finishAlu_port(i)] <= SCRData (d);
end
else begin
ppc_vaddr_csrData[pvc_finishAlu_port(i)] <= PPC (setAddr(almightyCap, cf.nextPc).value);
ppc_vaddr_csrData[pvc_finishAlu_port(i)] <= PPC (setAddr(pcc, cf.nextPc).value);
end
CapPipe new_pcc = setAddrUnsafe(pcc, getAddr(pc[pc_finishAlu_port(i)]));
pc[pc_finishAlu_port(i)] <= new_pcc;
if (!isInBounds(new_pcc, False)) begin
trap[trap_finishAlu_port(i)] <= Valid (tagged Exception CHERIFault);
trap[trap_finishAlu_port(i)] <= Valid (TrapWithCap{trap: tagged Exception CHERIFault, capExp: LengthViolation});
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 CHERIFault); // TODO propagate CHERI cause
trap[trap_finishAlu_port(i)] <= Valid (TrapWithCap{trap: tagged Exception CHERIFault, capExp: fromMaybe(None, cause)});
tval[trap_finishAlu_port(i)] <= tval[trap_finishAlu_port(i)];
end
`ifdef RVFI
@@ -339,10 +346,10 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
fflags[fflags_finishFpuMulDiv_port(i)] <= new_fflags;
CapPipe new_pcc = setAddrUnsafe(pcc, getAddr(pc[pc_finishAlu_port(i)]));
if (!isInBounds(new_pcc, False)) begin
trap[trap_finishFpuMulDiv_port(i)] <= Valid (tagged Exception CHERIFault);
trap[trap_finishFpuMulDiv_port(i)] <= Valid (TrapWithCap{trap: tagged Exception CHERIFault, capExp: LengthViolation});
tval[trap_finishFpuMulDiv_port(i)] <= tval[trap_finishAlu_port(i)];
end else if (cause matches tagged Valid .exp) begin
trap[trap_finishFpuMulDiv_port(i)] <= Valid (tagged Exception exp);
trap[trap_finishFpuMulDiv_port(i)] <= Valid (TrapWithCap{trap: tagged Exception exp, capExp: None});
tval[trap_finishFpuMulDiv_port(i)] <= tval[trap_finishAlu_port(i)];
end
//pc[pc_finishFpuMulDiv_port(i)] <= newPcc; //XXX add pcc checks on FPU instructions
@@ -396,10 +403,10 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
CapPipe new_pcc = setAddrUnsafe(pcc, getAddr(pc[pc_finishMem_port]));
pc[pc_finishMem_port] <= new_pcc;
if (!isInBounds(new_pcc, False)) begin
mem_early_trap[0] <= Valid (tagged Exception CHERIFault);
mem_early_trap[0] <= Valid (TrapWithCap{trap: tagged Exception CHERIFault, capExp: LengthViolation});
tval[trap_finishMem_port] <= tval[trap_finishMem_port];
end else if (cause matches tagged Valid .exp) begin
mem_early_trap[0] <= Valid (tagged Exception exp);
mem_early_trap[0] <= Valid (TrapWithCap{trap: tagged Exception exp, capExp: None});
tval[trap_finishMem_port] <= tval[trap_finishMem_port];
end
endmethod
@@ -526,7 +533,7 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
// record trap
//doAssert(!isValid(trap[trap_deqLSQ_port]), "cannot have trap");
if (isValid(mem_early_trap[0])) trap[trap_deqLSQ_port] <= mem_early_trap[0];
else if(cause matches tagged Valid .e) trap[trap_deqLSQ_port] <= Valid (Exception (e));
else if(cause matches tagged Valid .e) trap[trap_deqLSQ_port] <= Valid (TrapWithCap{trap: tagged Exception e, capExp: None});
// TODO: shouldn't we record tval here as well?
// record ld misspeculation
ldKilled[ldKill_deqLSQ_port] <= ld_killed;
@@ -586,8 +593,9 @@ interface ROB_setExecuted_doFinishAlu;
method Action set(InstTag x,
CapPipe dst_data,
Maybe#(Data) csrData,
Maybe#(CapPipe) scrData,
ControlFlow cf,
Maybe#(CapException) cause,
Maybe#(CHERIException) cause,
CapPipe pcc
`ifdef RVFI
, ExtraTraceBundle tb
@@ -1134,8 +1142,9 @@ module mkSupReorderBuffer#(
InstTag x,
CapPipe dst_data,
Maybe#(Data) csrData,
Maybe#(CapPipe) scrData,
ControlFlow cf,
Maybe#(CapException) cause,
Maybe#(CHERIException) cause,
CapPipe pcc
`ifdef RVFI
, ExtraTraceBundle tb
@@ -1146,6 +1155,7 @@ module mkSupReorderBuffer#(
row[x.way][x.ptr].setExecuted_doFinishAlu[i].set(
dst_data,
csrData,
scrData,
cf,
cause,
pcc