Check PCC bounds in rename.
This commit is contained in:
@@ -982,6 +982,10 @@ module mkCsrFile #(Data hartid)(CsrFile);
|
||||
default: return 0;
|
||||
endcase);
|
||||
end
|
||||
tagged CapException .ce: begin
|
||||
cause_code = pack(CHERIFault);
|
||||
// populate CHERI cause register.
|
||||
end
|
||||
tagged Interrupt .i: begin
|
||||
cause_code = zeroExtend(pack(i));
|
||||
cause_interrupt = 1;
|
||||
|
||||
@@ -65,7 +65,7 @@ typedef enum {
|
||||
typedef struct {
|
||||
Bit #(6) cheri_exc_reg;
|
||||
CHERIException cheri_exc_code;
|
||||
} CSR_XCapCause deriving(Bits, FShow);
|
||||
} CSR_XCapCause deriving(Bits, Eq, FShow);
|
||||
|
||||
CSR_XCapCause noCapCause = CSR_XCapCause {cheri_exc_code: None,
|
||||
cheri_exc_reg: unpack(0)};
|
||||
|
||||
@@ -624,15 +624,15 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
|
||||
|
||||
// record trap info
|
||||
Addr vaddr = ?;
|
||||
if ( (trap.trap == tagged Exception InstAccessFault)
|
||||
|| (trap.trap == tagged Exception InstPageFault)) begin
|
||||
if ( (trap == tagged Exception InstAccessFault)
|
||||
|| (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
|
||||
|
||||
@@ -231,7 +231,7 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
|
||||
Maybe#(Trap) trap = tagged Invalid;
|
||||
let csr_state = csrf.decodeInfo;
|
||||
let pending_interrupt = csrf.pending_interrupt;
|
||||
let new_exception = checkForException(x.dInst, x.regs, csr_state);
|
||||
let new_exception = checkForException(x.dInst, x.regs, csr_state, x.pc);
|
||||
|
||||
// If Fpu regs are accessed, trap if mstatus_fs is "Off" (2'b00)
|
||||
Bool fpr_access = ( fn_ArchReg_is_FpuReg (x.regs.src1)
|
||||
@@ -292,7 +292,7 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
|
||||
trap = tagged Valid (tagged Interrupt fromMaybe(?, pending_interrupt));
|
||||
end else if (isValid(new_exception)) begin
|
||||
// newly found exception
|
||||
trap = tagged Valid (tagged Exception fromMaybe(?, new_exception));
|
||||
trap = new_exception;
|
||||
end
|
||||
else if (fs_trap || csr_access_trap || wfi_trap) begin
|
||||
trap = tagged Valid (tagged Exception IllegalInst);
|
||||
@@ -357,8 +357,6 @@ 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: noCapCause};
|
||||
// just place it in the reorder buffer
|
||||
let y = ToReorderBuffer{pc: cast(pc),
|
||||
orig_inst: orig_inst,
|
||||
@@ -371,7 +369,7 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
|
||||
`endif
|
||||
csr: dInst.csr,
|
||||
claimed_phy_reg: False, // no renaming is done
|
||||
trap: trapWithCap,
|
||||
trap: firstTrap,
|
||||
tval: tval,
|
||||
// default values of FullResult
|
||||
ppc_vaddr_csrData: PPC (cast(pc)), // default use PPC
|
||||
|
||||
@@ -30,13 +30,11 @@ import CHERICC_Fat::*;
|
||||
import ISA_Decls_CHERI::*;
|
||||
|
||||
(* noinline *)
|
||||
function Maybe#(CapException) capChecks(CapPipe a, CapPipe b, CapChecks toCheck, CapPipe pcc_end);
|
||||
function Maybe#(CapException) e1(CHERIException e) = Valid(CapException{cheri_exc_reg: toCheck.rn1, cheri_exc_code: e});
|
||||
function Maybe#(CapException) e2(CHERIException e) = Valid(CapException{cheri_exc_reg: toCheck.rn2, cheri_exc_code: e});
|
||||
Maybe#(CapException) result = Invalid;
|
||||
if (!isInBounds(pcc_end, True))
|
||||
result = Valid(CapException{cheri_exc_reg: {1'b1,pack(SCR_PCC)}, cheri_exc_code: LengthViolation});
|
||||
else if (toCheck.src1_tag && !isValidCap(a))
|
||||
function Maybe#(CSR_XCapCause) capChecks(CapPipe a, CapPipe b, CapChecks toCheck);
|
||||
function Maybe#(CSR_XCapCause) e1(CHERIException e) = Valid(CSR_XCapCause{cheri_exc_reg: toCheck.rn1, cheri_exc_code: e});
|
||||
function Maybe#(CSR_XCapCause) e2(CHERIException e) = Valid(CSR_XCapCause{cheri_exc_reg: toCheck.rn2, cheri_exc_code: e});
|
||||
Maybe#(CSR_XCapCause) result = Invalid;
|
||||
if (toCheck.src1_tag && !isValidCap(a))
|
||||
result = e1(TagViolation);
|
||||
else if (toCheck.src2_tag && !isValidCap(b))
|
||||
result = e2(TagViolation);
|
||||
@@ -288,14 +286,14 @@ function ExecResult basicExec(DecodedInst dInst, CapPipe rVal1, CapPipe rVal2, C
|
||||
BrFunc br_f = dInst.execFunc matches tagged Br .br_f ? br_f : NT;
|
||||
cf.taken = aluBr(getAddr(rVal1), getAddr(rVal2), br_f);
|
||||
cf.nextPc = brAddrCalc(pcc, rVal1, dInst.iType, fromMaybe(0,getDInstImm(dInst)), cf.taken, orig_inst, (ccall || cjalr));
|
||||
if (dInst.execFunc matches tagged Br .br_f) rVal1 = cf.nextPc;
|
||||
if (dInst.execFunc matches tagged Br .unused) rVal1 = cf.nextPc;
|
||||
cf.mispredict = cf.nextPc != ppc;
|
||||
|
||||
Data inspect_result = capInspect(rVal1, aluVal2, dInst.execFunc.CapInspect);
|
||||
CapModifyFunc modFunc = ccall ? (Unseal (Src2)):dInst.execFunc.CapModify;
|
||||
CapPipe modify_result = capModify(rVal1, aluVal2, modFunc);
|
||||
CapPipe link_pcc = addPc(pcc, ((orig_inst [1:0] == 2'b11) ? 4 : 2));
|
||||
Maybe#(CapException) capException = capChecks(rVal1, aluVal2, dInst.capChecks, link_pcc);
|
||||
Maybe#(CSR_XCapCause) capException = capChecks(rVal1, aluVal2, dInst.capChecks);
|
||||
Maybe#(BoundsCheck) boundsCheck = prepareBoundsCheck(rVal1, aluVal2, dInst.capChecks);
|
||||
|
||||
CapPipe cap_alu_result = case (dInst.execFunc) matches tagged CapInspect .x: nullWithAddr(inspect_result);
|
||||
@@ -327,10 +325,11 @@ function ExecResult basicExec(DecodedInst dInst, CapPipe rVal1, CapPipe rVal2, C
|
||||
endfunction
|
||||
|
||||
(* noinline *)
|
||||
function Maybe#(Exception) checkForException(
|
||||
function Maybe#(Trap) checkForException(
|
||||
DecodedInst dInst,
|
||||
ArchRegs regs,
|
||||
CsrDecodeInfo csrState
|
||||
CsrDecodeInfo csrState,
|
||||
CapMem pcc
|
||||
); // regs needed to check if x0 is a src
|
||||
Maybe#(Exception) exception = Invalid;
|
||||
let prv = csrState.prv;
|
||||
@@ -392,7 +391,16 @@ function Maybe#(Exception) checkForException(
|
||||
end
|
||||
end
|
||||
|
||||
return exception;
|
||||
// Check that the end of the instruction is in bounds of PCC.
|
||||
CapPipe pcc_end = cast(addPc(pcc, 2));
|
||||
Maybe#(CSR_XCapCause) capException = Invalid;
|
||||
if (!isInBounds(pcc_end, True)) capException = Valid(CSR_XCapCause{cheri_exc_reg: {1'b1,pack(SCR_PCC)}, cheri_exc_code: LengthViolation});
|
||||
|
||||
Maybe#(Trap) retval = Invalid;
|
||||
if (capException matches tagged Valid .ce) retval = Valid(CapException(ce));
|
||||
else if (exception matches tagged Valid .e) retval = Valid(Exception(e));
|
||||
|
||||
return retval;
|
||||
endfunction
|
||||
|
||||
// check mem access misaligned: byteEn is unshifted (just from Decode)
|
||||
|
||||
@@ -391,15 +391,11 @@ typedef 12 InterruptNum; // Without debugger
|
||||
|
||||
// Traps are either an exception or an interrupt
|
||||
typedef union tagged {
|
||||
CapException CapException;
|
||||
Exception Exception;
|
||||
Interrupt Interrupt;
|
||||
} Trap deriving(Bits, Eq, FShow);
|
||||
|
||||
typedef struct {
|
||||
Trap trap;
|
||||
CSR_XCapCause capExp;
|
||||
} TrapWithCap deriving(Bits, FShow);
|
||||
|
||||
// privilege modes
|
||||
Bit#(2) prvU = 0;
|
||||
Bit#(2) prvS = 1;
|
||||
|
||||
@@ -73,7 +73,7 @@ typedef struct {
|
||||
`endif
|
||||
Maybe#(CSR) csr;
|
||||
Bool claimed_phy_reg; // whether we need to commmit renaming
|
||||
Maybe#(TrapWithCap)trap;
|
||||
Maybe#(Trap) trap;
|
||||
Addr tval; // in case of trap
|
||||
PPCVAddrCSRData ppc_vaddr_csrData;
|
||||
Bit#(5) fflags;
|
||||
@@ -239,7 +239,7 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
|
||||
Integer sb_enq_port = 1; // write spec_bits
|
||||
Integer sb_correctSpec_port = 2; // write spec_bits
|
||||
|
||||
Ehr#(TAdd#(2, aluExeNum), CapMem) pc <- mkEhr(?);
|
||||
Ehr#(TAdd#(2, aluExeNum), CapMem) pc <- mkEhr(?);
|
||||
Reg #(Bit #(32)) orig_inst <- mkRegU;
|
||||
Reg#(IType) iType <- mkRegU;
|
||||
Reg #(Maybe #(ArchRIndx)) rg_dst_reg <- mkRegU;
|
||||
@@ -250,8 +250,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#(TrapWithCap)) trap <- mkEhr(?);
|
||||
Ehr#(3, Maybe#(TrapWithCap)) mem_early_trap <- mkEhr(?);
|
||||
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), Addr) tval <- mkEhr(?);
|
||||
Ehr#(TAdd#(2, aluExeNum), PPCVAddrCSRData) ppc_vaddr_csrData <- mkEhr(?);
|
||||
Ehr#(TAdd#(1, fpuMulDivExeNum), Bit#(5)) fflags <- mkEhr(?);
|
||||
@@ -307,7 +307,7 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
|
||||
ppc_vaddr_csrData[pvc_finishAlu_port(i)] <= PPC (cast(cf.nextPc));
|
||||
end
|
||||
if (cause matches tagged Valid .exp) begin
|
||||
trap[trap_finishAlu_port(i)] <= Valid (TrapWithCap{trap: tagged Exception CHERIFault, capExp: exp});
|
||||
trap[trap_finishAlu_port(i)] <= Valid (CapException (exp));
|
||||
tval[trap_finishAlu_port(i)] <= tval[trap_finishAlu_port(i)];
|
||||
end
|
||||
`ifdef RVFI
|
||||
@@ -335,7 +335,7 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
|
||||
// update fflags
|
||||
fflags[fflags_finishFpuMulDiv_port(i)] <= new_fflags;
|
||||
if (cause matches tagged Valid .exp) begin
|
||||
trap[trap_finishFpuMulDiv_port(i)] <= Valid (TrapWithCap{trap: tagged Exception exp, capExp: noCapCause});
|
||||
trap[trap_finishFpuMulDiv_port(i)] <= Valid (Exception (exp));
|
||||
tval[trap_finishFpuMulDiv_port(i)] <= tval[trap_finishAlu_port(i)];
|
||||
end
|
||||
`ifdef RVFI
|
||||
@@ -385,7 +385,7 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
|
||||
// udpate non mmio st
|
||||
nonMMIOStDone[nonMMIOSt_finishMem_port] <= non_mmio_st_done;
|
||||
if (cause matches tagged Valid .exp) begin
|
||||
mem_early_trap[0] <= Valid (TrapWithCap{trap: tagged Exception exp, capExp: noCapCause});
|
||||
mem_early_trap[0] <= Valid ( Exception (exp));
|
||||
tval[trap_finishMem_port] <= tval[trap_finishMem_port];
|
||||
end
|
||||
endmethod
|
||||
@@ -512,7 +512,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 (TrapWithCap{trap: tagged Exception e, capExp: noCapCause});
|
||||
else if(cause matches tagged Valid .e) trap[trap_deqLSQ_port] <= Valid(Exception(e));
|
||||
// TODO: shouldn't we record tval here as well?
|
||||
// record ld misspeculation
|
||||
ldKilled[ldKill_deqLSQ_port] <= ld_killed;
|
||||
|
||||
Reference in New Issue
Block a user