Merge branch 'pdr32-wip' into HEAD
This commit is contained in:
Submodule libs/cheri-cap-lib updated: 4b08d61aa2...80ba19db9f
@@ -140,10 +140,10 @@ module mkScrFile (ScrFile);
|
||||
Reg#(CapReg) ddc_reg <- mkCsrReg(defaultValue);
|
||||
|
||||
// User level SCRs with accessSysRegs
|
||||
Reg#(CapReg) utcc_reg <- mkCsrReg(defaultValue);
|
||||
Reg#(CapReg) utdc_reg <- mkCsrReg(nullCap);
|
||||
Reg#(CapReg) uScratchC_reg <- mkCsrReg(nullCap);
|
||||
Reg#(CapReg) uepcc_reg <- mkCsrReg(defaultValue);
|
||||
// Reg#(CapReg) utcc_reg <- mkCsrReg(defaultValue);
|
||||
// Reg#(CapReg) utdc_reg <- mkCsrReg(nullCap);
|
||||
// Reg#(CapReg) uScratchC_reg <- mkCsrReg(nullCap);
|
||||
// Reg#(CapReg) uepcc_reg <- mkCsrReg(defaultValue);
|
||||
|
||||
// System level SCRs with accessSysRegs
|
||||
Reg#(CapReg) stcc_reg <- mkCsrReg(defaultValue);
|
||||
@@ -164,10 +164,10 @@ module mkScrFile (ScrFile);
|
||||
SCR_PCC: pcc_reg[0];
|
||||
SCR_DDC: ddc_reg;
|
||||
// User CSRs with accessSysRegs
|
||||
SCR_UTCC: utcc_reg;
|
||||
SCR_UTDC: utdc_reg;
|
||||
SCR_UScratchC: uScratchC_reg;
|
||||
SCR_UEPCC: uepcc_reg;
|
||||
// SCR_UTCC: utcc_reg;
|
||||
// SCR_UTDC: utdc_reg;
|
||||
// SCR_UScratchC: uScratchC_reg;
|
||||
// SCR_UEPCC: uepcc_reg;
|
||||
// System CSRs with accessSysRegs
|
||||
SCR_STCC: stcc_reg;
|
||||
SCR_STDC: stdc_reg;
|
||||
|
||||
@@ -67,6 +67,9 @@ typedef struct {
|
||||
CHERIException cheri_exc_code;
|
||||
} CSR_XCapCause deriving(Bits, FShow);
|
||||
|
||||
CSR_XCapCause noCapCause = CSR_XCapCause {cheri_exc_code: None,
|
||||
cheri_exc_reg: unpack(0)};
|
||||
|
||||
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});
|
||||
endfunction
|
||||
@@ -85,10 +88,10 @@ typedef enum {
|
||||
SCR_PCC = 5'd00,
|
||||
SCR_DDC = 5'd01,
|
||||
|
||||
SCR_UTCC = 5'd04,
|
||||
SCR_UTDC = 5'd05,
|
||||
SCR_UScratchC = 5'd06,
|
||||
SCR_UEPCC = 5'd07,
|
||||
// SCR_UTCC = 5'd04,
|
||||
// SCR_UTDC = 5'd05,
|
||||
// SCR_UScratchC = 5'd06,
|
||||
// SCR_UEPCC = 5'd07,
|
||||
|
||||
SCR_STCC = 5'd12,
|
||||
SCR_STDC = 5'd13,
|
||||
@@ -98,8 +101,32 @@ typedef enum {
|
||||
SCR_MTCC = 5'd28,
|
||||
SCR_MTDC = 5'd29,
|
||||
SCR_MScratchC = 5'd30,
|
||||
SCR_MEPCC = 5'd31
|
||||
} SCR deriving(Bits, Eq, FShow);
|
||||
SCR_MEPCC = 5'd31,
|
||||
|
||||
// As with CSRs, SCR that catches all unimplemented SCRs
|
||||
SCR_None = 5'd10
|
||||
} SCR deriving(Bits, Eq, FShow, Bounded);
|
||||
|
||||
function SCR unpackSCR(Bit#(5) x);
|
||||
return (case(x)
|
||||
pack(SCR'(SCR_PCC )): (SCR_PCC );
|
||||
pack(SCR'(SCR_DDC )): (SCR_DDC );
|
||||
// pack(SCR'(SCR_UTCC )): (SCR_UTCC );
|
||||
// pack(SCR'(SCR_UTDC )): (SCR_UTDC );
|
||||
// pack(SCR'(SCR_UScratchC)): (SCR_UScratchC);
|
||||
// pack(SCR'(SCR_UEPCC )): (SCR_UEPCC );
|
||||
pack(SCR'(SCR_STCC )): (SCR_STCC );
|
||||
pack(SCR'(SCR_STDC )): (SCR_STDC );
|
||||
pack(SCR'(SCR_SScratchC)): (SCR_SScratchC);
|
||||
pack(SCR'(SCR_SEPCC )): (SCR_SEPCC );
|
||||
pack(SCR'(SCR_MTCC )): (SCR_MTCC );
|
||||
pack(SCR'(SCR_MTDC )): (SCR_MTDC );
|
||||
pack(SCR'(SCR_MScratchC)): (SCR_MScratchC);
|
||||
pack(SCR'(SCR_MEPCC )): (SCR_MEPCC );
|
||||
|
||||
default : (SCR_None );
|
||||
endcase);
|
||||
endfunction
|
||||
|
||||
function CapPipe update_scr_via_csr (CapPipe old_scr, WordXL new_csr);
|
||||
let new_scr = setOffset(old_scr, new_csr);
|
||||
|
||||
@@ -89,7 +89,8 @@ typedef struct {
|
||||
Maybe#(Data) csrData; // data to write CSR file
|
||||
Maybe#(CapPipe) scrData; // datat to write to special capability register file.
|
||||
ControlFlow controlFlow;
|
||||
Maybe#(CHERIException) capException;
|
||||
Maybe#(CSR_XCapCause) capException;
|
||||
Maybe#(BoundsCheck) check;
|
||||
// speculation
|
||||
Maybe#(SpecTag) spec_tag;
|
||||
`ifdef RVFI
|
||||
@@ -157,7 +158,7 @@ interface AluExeInput;
|
||||
Maybe#(Data) csrData,
|
||||
Maybe#(CapPipe) scrData,
|
||||
ControlFlow cf,
|
||||
Maybe#(CHERIException) capCause,
|
||||
Maybe#(CSR_XCapCause) capCause,
|
||||
CapPipe pcc
|
||||
`ifdef RVFI
|
||||
, ExtraTraceBundle tb
|
||||
@@ -256,6 +257,9 @@ module mkAluExePipeline#(AluExeInput inIfc)(AluExePipeline);
|
||||
|
||||
// get rVal2 (check bypass)
|
||||
CapPipe rVal2 = nullCap;
|
||||
if(x.dInst.scr matches tagged Valid .scr) begin
|
||||
rVal2 = cast(inIfc.scaprf_rd(scr));
|
||||
end
|
||||
if(x.regs.src2 matches tagged Valid .src2 &&& src2 != 0) begin
|
||||
rVal2 <- readRFBypass(src2, regsReady.src2, inIfc.rf_rd2(src2), bypassWire);
|
||||
end
|
||||
@@ -323,7 +327,8 @@ module mkAluExePipeline#(AluExeInput inIfc)(AluExePipeline);
|
||||
// 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,
|
||||
capException: exec_result.capException,
|
||||
check: exec_result.boundsCheck,
|
||||
`ifdef RVFI
|
||||
traceBundle: ExtraTraceBundle{
|
||||
regWriteData: getAddr(exec_result.data),
|
||||
@@ -349,6 +354,13 @@ module mkAluExePipeline#(AluExeInput inIfc)(AluExePipeline);
|
||||
inIfc.writeRegFile(dst.indx, x.data);
|
||||
end
|
||||
|
||||
if (x.check matches tagged Valid .check &&& x.capException matches tagged Invalid) begin
|
||||
if (!( (check.check_low >= check.authority_base) &&
|
||||
(check.check_inclusive ? (check.check_high <= check.authority_top )
|
||||
: (check.check_high < check.authority_top ))))
|
||||
x.capException = Valid(CSR_XCapCause{cheri_exc_reg: check.authority_idx, cheri_exc_code: LengthViolation});
|
||||
end
|
||||
|
||||
// update the instruction in the reorder buffer.
|
||||
inIfc.rob_setExecuted(
|
||||
x.tag,
|
||||
|
||||
@@ -358,7 +358,7 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
|
||||
// This avoids doing incorrect work
|
||||
incrEpochStallFetch;
|
||||
Maybe#(TrapWithCap) trapWithCap = Invalid;
|
||||
if (firstTrap matches tagged Valid .trap) trapWithCap = tagged Valid TrapWithCap{trap: trap, capExp: None};
|
||||
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: setAddr(almightyCap, pc).value,
|
||||
orig_inst: orig_inst,
|
||||
|
||||
72
src_Core/RISCY_OOO/procs/lib/CSRs.bsvi
Normal file
72
src_Core/RISCY_OOO/procs/lib/CSRs.bsvi
Normal file
@@ -0,0 +1,72 @@
|
||||
// user standard CSRs
|
||||
`CSR(CSRfflags , 12'h001)
|
||||
`CSR(CSRfrm , 12'h002)
|
||||
`CSR(CSRfcsr , 12'h003)
|
||||
`CSR(CSRcycle , 12'hc00)
|
||||
`CSR(CSRtime , 12'hc01)
|
||||
`CSR(CSRinstret , 12'hc02)
|
||||
// user non-standard CSRs (TODO)
|
||||
`CSR(CSRterminate , 12'h800) // terminate (used to exit Linux)
|
||||
`CSR(CSRstats , 12'h801) // turn on/off perf counters
|
||||
// `CSR(CSRuccsr , 12'h8c0)
|
||||
// supervisor standard `CSR(CSRs
|
||||
`CSR(CSRsstatus , 12'h100)
|
||||
// no user trap handler, so no se/ideleg
|
||||
`CSR(CSRsie , 12'h104)
|
||||
`CSR(CSRstvec , 12'h105)
|
||||
`CSR(CSRscounteren , 12'h106)
|
||||
`CSR(CSRsscratch , 12'h140)
|
||||
`CSR(CSRsepc , 12'h141)
|
||||
`CSR(CSRscause , 12'h142)
|
||||
`CSR(CSRstval , 12'h143) // it's still called sbadaddr in spike
|
||||
`CSR(CSRsip , 12'h144)
|
||||
`CSR(CSRsatp , 12'h180) // it's still called sptbr in spike
|
||||
`CSR(CSRsccsr , 12'h9c0)
|
||||
// machine standard CSRs
|
||||
`CSR(CSRmstatus , 12'h300)
|
||||
`CSR(CSRmisa , 12'h301)
|
||||
`CSR(CSRmedeleg , 12'h302)
|
||||
`CSR(CSRmideleg , 12'h303)
|
||||
`CSR(CSRmie , 12'h304)
|
||||
`CSR(CSRmtvec , 12'h305)
|
||||
`CSR(CSRmcounteren , 12'h306)
|
||||
`CSR(CSRmscratch , 12'h340)
|
||||
`CSR(CSRmepc , 12'h341)
|
||||
`CSR(CSRmcause , 12'h342)
|
||||
`CSR(CSRmtval , 12'h343) // it's still called mbadaddr in spike
|
||||
`CSR(CSRmip , 12'h344)
|
||||
`CSR(CSRmcycle , 12'hb00)
|
||||
`CSR(CSRminstret , 12'hb02)
|
||||
`CSR(CSRmvendorid , 12'hf11)
|
||||
`CSR(CSRmarchid , 12'hf12)
|
||||
`CSR(CSRmimpid , 12'hf13)
|
||||
`CSR(CSRmhartid , 12'hf14)
|
||||
`CSR(CSRmccsr , 12'hbc0)
|
||||
`ifdef SECURITY
|
||||
// sanctum machine CSR
|
||||
`CSR(CSRmevbase , 12'h7c0)
|
||||
`CSR(CSRmevmask , 12'h7c1)
|
||||
`CSR(CSRmeatp , 12'h7c2)
|
||||
`CSR(CSRmmrbm , 12'h7c3)
|
||||
`CSR(CSRmemrbm , 12'h7c4)
|
||||
`CSR(CSRmparbase , 12'h7c5)
|
||||
`CSR(CSRmparmask , 12'h7c6)
|
||||
`CSR(CSRmeparbase , 12'h7c7)
|
||||
`CSR(CSRmeparmask , 12'h7c8)
|
||||
`CSR(CSRmflush , 12'h7c9) // flush pipeline + cache
|
||||
`CSR(CSRmspec , 12'h7ca) // control speculation
|
||||
// sanctum user CSR
|
||||
`CSR(CSRtrng , 12'hcc0) // random number for secure boot
|
||||
`endif
|
||||
|
||||
`CSR(CSRtselect , 12'h7A0) // Debug/trace tselect
|
||||
`CSR(CSRtdata1 , 12'h7A1) // Debug/trace tdata1
|
||||
`CSR(CSRtdata2 , 12'h7A2) // Debug/trace tdata2
|
||||
`CSR(CSRtdata3 , 12'h7A3) // Debug/trace tdata3
|
||||
|
||||
`ifdef INCLUDE_GDB_CONTROL
|
||||
`CSR(CSRdcsr , 12'h7B0) // Debug control and status
|
||||
`CSR(CSRdpc , 12'h7B1) // Debug PC
|
||||
`CSR(CSRdscratch0 , 12'h7B2) // Debug scratch0
|
||||
`CSR(CSRdscratch1 , 12'h7B3) // Debug scratch1
|
||||
`endif
|
||||
18
src_Core/RISCY_OOO/procs/lib/CapChecks.bsvi
Normal file
18
src_Core/RISCY_OOO/procs/lib/CapChecks.bsvi
Normal file
@@ -0,0 +1,18 @@
|
||||
`CAP_CHECK_FIELD(src1_tag,"src1_tag")
|
||||
`CAP_CHECK_FIELD(src2_tag,"src2_tag")
|
||||
`CAP_CHECK_FIELD(src1_sealed_with_type,"src1_sealed_with_type")
|
||||
`CAP_CHECK_FIELD(src1_unsealed,"src1_unsealed")
|
||||
`CAP_CHECK_FIELD(src2_unsealed,"src2_unsealed")
|
||||
`CAP_CHECK_FIELD(src1_sealed,"src1_sealed")
|
||||
`CAP_CHECK_FIELD(src2_sealed,"src2_sealed")
|
||||
`CAP_CHECK_FIELD(src1_src2_types_match,"src1_src2_types_match")
|
||||
`CAP_CHECK_FIELD(src1_permit_ccall,"src1_permit_ccall")
|
||||
`CAP_CHECK_FIELD(src2_permit_ccall,"src2_permit_ccall")
|
||||
`CAP_CHECK_FIELD(src1_permit_x,"src1_permit_x")
|
||||
`CAP_CHECK_FIELD(src2_no_permit_x,"src2_no_permit_x")
|
||||
`CAP_CHECK_FIELD(src2_permit_unseal,"src2_permit_unseal")
|
||||
`CAP_CHECK_FIELD(src2_permit_seal,"src2_permit_seal")
|
||||
`CAP_CHECK_FIELD(src2_points_to_src1_type,"src2_points_to_src1_type")
|
||||
`CAP_CHECK_FIELD(src2_addr_valid_type,"src2_addr_valid_type")
|
||||
`CAP_CHECK_FIELD(src1_perm_subset_src2,"src1_perm_subset_src2")
|
||||
`CAP_CHECK_FIELD(src1_derivable,"src1_derivable")
|
||||
@@ -185,6 +185,7 @@ function DecodeResult decode(Instruction inst);
|
||||
ImmData immB = signExtend({ inst[31], inst[7], inst[30:25], inst[11:8], 1'b0});
|
||||
ImmData immU = signExtend({ inst[31:12], 12'b0 });
|
||||
ImmData immJ = signExtend({ inst[31], inst[19:12], inst[20], inst[30:21], 1'b0});
|
||||
ImmData immIunsigned = zeroExtend(inst[31:20]);
|
||||
|
||||
// Results of mini-decoders
|
||||
Maybe#(MemInst) mem_inst = decodeMemInst(inst);
|
||||
@@ -738,42 +739,76 @@ function DecodeResult decode(Instruction inst);
|
||||
dInst.execFunc = CapModify (ModifyOffset (IncOffset));
|
||||
end
|
||||
f3_cap_CSetBoundsImmediate: begin
|
||||
illegalInst = True;
|
||||
// TODO
|
||||
// dInst.capChecks.src1_tag = True;
|
||||
// dInst.capChecks.src1_unsealed = True;
|
||||
dInst.capChecks.src1_tag = True;
|
||||
dInst.capChecks.src1_unsealed = True;
|
||||
|
||||
// regs.dst = Valid(tagged Gpr rd);
|
||||
// regs.src1 = Valid(tagged Gpr rs1);
|
||||
// regs.src1 = Invalid;
|
||||
// dInst.imm = Valid (immI);
|
||||
dInst.capChecks.check_enable = True;
|
||||
dInst.capChecks.check_authority_src = Src1;
|
||||
dInst.capChecks.check_low_src = Src1Addr;
|
||||
dInst.capChecks.check_high_src = ResultTop;
|
||||
dInst.capChecks.check_inclusive = True;
|
||||
|
||||
dInst.iType = Alu;
|
||||
regs.dst = Valid(tagged Gpr rd);
|
||||
regs.src1 = Valid(tagged Gpr rs1);
|
||||
regs.src2 = Invalid;
|
||||
dInst.imm = Valid (immIunsigned);
|
||||
dInst.execFunc = CapModify (SetBounds (SetBounds));
|
||||
end
|
||||
f3_cap_ThreeOp: begin
|
||||
case (funct7)
|
||||
f7_cap_CSpecialRW: begin
|
||||
// TODO
|
||||
// TODO capChecks
|
||||
|
||||
dInst.iType = Alu;
|
||||
regs.dst = Valid(tagged Gpr rd);
|
||||
regs.src1 = Valid(tagged Gpr rs1);
|
||||
regs.src2 = Invalid;
|
||||
dInst.scr = Valid (unpackSCR(rs2));
|
||||
|
||||
let scrType = case (rs2[1:0])
|
||||
0: TCC;
|
||||
3: EPCC;
|
||||
default: Normal;
|
||||
endcase;
|
||||
|
||||
dInst.execFunc = CapModify (SpecialRW (scrType));
|
||||
end
|
||||
f7_cap_CSetBounds: begin
|
||||
illegalInst = True;
|
||||
// TODO
|
||||
// dInst.capChecks.src1_tag = True;
|
||||
// dInst.capChecks.src1_unsealed = True;
|
||||
dInst.capChecks.src1_tag = True;
|
||||
dInst.capChecks.src1_unsealed = True;
|
||||
|
||||
// regs.dst = Valid(tagged Gpr rd);
|
||||
// regs.src1 = Valid(tagged Gpr rs1);
|
||||
// regs.src2 = Valid(tagged Gpr rs2);
|
||||
// dInst.imm = Invalid;
|
||||
dInst.capChecks.check_enable = True;
|
||||
dInst.capChecks.check_authority_src = Src1;
|
||||
dInst.capChecks.check_low_src = Src1Addr;
|
||||
dInst.capChecks.check_high_src = ResultTop;
|
||||
dInst.capChecks.check_inclusive = True;
|
||||
|
||||
dInst.iType = Alu;
|
||||
regs.dst = Valid(tagged Gpr rd);
|
||||
regs.src1 = Valid(tagged Gpr rs1);
|
||||
regs.src2 = Valid(tagged Gpr rs2);
|
||||
dInst.imm = Invalid;
|
||||
dInst.execFunc = CapModify (SetBounds (SetBounds));
|
||||
end
|
||||
f7_cap_CSetBoundsExact: begin
|
||||
illegalInst = True;
|
||||
// TODO
|
||||
// dInst.capChecks.src1_tag = True;
|
||||
// dInst.capChecks.src1_unsealed = True;
|
||||
dInst.capChecks.src1_tag = True;
|
||||
dInst.capChecks.src1_unsealed = True;
|
||||
// TODO assert exact
|
||||
|
||||
// regs.dst = Valid(tagged Gpr rd);
|
||||
// regs.src1 = Valid(tagged Gpr rs1);
|
||||
// regs.src2 = Valid(tagged Gpr rs2);
|
||||
// dInst.imm = Invalid;
|
||||
dInst.capChecks.check_enable = True;
|
||||
dInst.capChecks.check_authority_src = Src1;
|
||||
dInst.capChecks.check_low_src = Src1Addr;
|
||||
dInst.capChecks.check_high_src = ResultTop;
|
||||
dInst.capChecks.check_inclusive = True;
|
||||
|
||||
dInst.iType = Alu;
|
||||
regs.dst = Valid(tagged Gpr rd);
|
||||
regs.src1 = Valid(tagged Gpr rs1);
|
||||
regs.src2 = Valid(tagged Gpr rs2);
|
||||
dInst.imm = Invalid;
|
||||
dInst.execFunc = CapModify (SetBounds (SetBounds));
|
||||
end
|
||||
f7_cap_CSetOffset: begin
|
||||
dInst.capChecks.src1_unsealed = True;
|
||||
@@ -813,6 +848,12 @@ function DecodeResult decode(Instruction inst);
|
||||
dInst.capChecks.src2_permit_seal = True;
|
||||
dInst.capChecks.src2_addr_valid_type = 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 = Alu;
|
||||
regs.dst = Valid(tagged Gpr rd);
|
||||
regs.src1 = Valid(tagged Gpr rs1);
|
||||
@@ -857,6 +898,12 @@ function DecodeResult decode(Instruction inst);
|
||||
dInst.capChecks.src2_points_to_src1_type = True;
|
||||
dInst.capChecks.src2_permit_unseal = 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 = Alu;
|
||||
regs.dst = Valid(tagged Gpr rd);
|
||||
regs.src1 = Valid(tagged Gpr rs1);
|
||||
@@ -878,6 +925,12 @@ function DecodeResult decode(Instruction inst);
|
||||
dInst.capChecks.src1_tag = True;
|
||||
dInst.capChecks.src1_unsealed = True;
|
||||
|
||||
dInst.capChecks.check_enable = True;
|
||||
dInst.capChecks.check_authority_src = Src1;
|
||||
dInst.capChecks.check_low_src = Src2Type;
|
||||
dInst.capChecks.check_high_src = Src2Type;
|
||||
dInst.capChecks.check_inclusive = False;
|
||||
|
||||
dInst.iType = Alu;
|
||||
regs.dst = Valid(tagged Gpr rd);
|
||||
regs.src1 = Valid(tagged Gpr rs1);
|
||||
@@ -913,7 +966,13 @@ function DecodeResult decode(Instruction inst);
|
||||
dInst.iType = Alu;
|
||||
regs.dst = Valid(tagged Gpr rd);
|
||||
regs.src1 = Valid(tagged Gpr rs1);
|
||||
regs.src2 = Valid(tagged Gpr rs2);
|
||||
if (rs2 == 0) begin
|
||||
regs.src2 = Invalid;
|
||||
dInst.scr = Valid (SCR_DDC);
|
||||
end else begin
|
||||
regs.src2 = Valid (tagged Gpr rs2);
|
||||
dInst.scr = Invalid;
|
||||
end
|
||||
dInst.imm = Invalid;
|
||||
dInst.execFunc = CapInspect (ToPtr);
|
||||
end
|
||||
@@ -941,17 +1000,26 @@ function DecodeResult decode(Instruction inst);
|
||||
dInst.execFunc = Alu (Sub);
|
||||
end
|
||||
f7_cap_CBuildCap: begin
|
||||
illegalInst = True;
|
||||
// TODO
|
||||
dInst.capChecks.src1_tag = True;
|
||||
dInst.capChecks.src1_unsealed = True;
|
||||
dInst.capChecks.src2_perm_subset_src1 = True;
|
||||
dInst.capChecks.src2_derivable = True;
|
||||
dInst.capChecks.src2_tag = True;
|
||||
dInst.capChecks.src2_unsealed = True;
|
||||
dInst.capChecks.src1_perm_subset_src2 = True;
|
||||
dInst.capChecks.src1_derivable = True;
|
||||
|
||||
dInst.capChecks.check_enable = True;
|
||||
dInst.capChecks.check_authority_src = Src2;
|
||||
dInst.capChecks.check_low_src = Src1Base;
|
||||
dInst.capChecks.check_high_src = Src1Top;
|
||||
dInst.capChecks.check_inclusive = True;
|
||||
|
||||
// Swap arguments so SCR possibly goes in RS2
|
||||
dInst.iType = Alu;
|
||||
regs.dst = Valid(tagged Gpr rd);
|
||||
regs.src1 = Valid(tagged Gpr rs1);
|
||||
regs.src2 = Valid(tagged Gpr rs2);
|
||||
regs.src1 = Valid(tagged Gpr rs2);
|
||||
if (rs1 == 0) begin
|
||||
dInst.scr = Valid(SCR_DDC);
|
||||
end else begin
|
||||
regs.src2 = Valid(tagged Gpr rs1);
|
||||
end
|
||||
dInst.imm = Invalid;
|
||||
dInst.execFunc = CapModify (BuildCap);
|
||||
end
|
||||
@@ -994,18 +1062,20 @@ function DecodeResult decode(Instruction inst);
|
||||
dInst.execFunc = CapInspect (GetSealed);
|
||||
end
|
||||
f5rs2_cap_CRRL: begin
|
||||
illegalInst = True;
|
||||
// TODO
|
||||
// regs.dst = Valid(tagged Gpr rd);
|
||||
// regs.src1 = Valid(tagged Gpr rs1);
|
||||
// dInst.imm = Invalid;
|
||||
dInst.iType = Alu;
|
||||
regs.dst = Valid(tagged Gpr rd);
|
||||
regs.src1 = Valid(tagged Gpr 0); // Operate on nullcap
|
||||
regs.src2 = Valid(tagged Gpr rs1);
|
||||
dInst.imm = Invalid;
|
||||
dInst.execFunc = CapModify (SetBounds (CRRL));
|
||||
end
|
||||
f5rs2_cap_CRAM: begin
|
||||
illegalInst = True;
|
||||
// TODO
|
||||
// regs.dst = Valid(tagged Gpr rd);
|
||||
// regs.src1 = Valid(tagged Gpr rs1);
|
||||
// dInst.imm = Invalid;
|
||||
dInst.iType = Alu;
|
||||
regs.dst = Valid(tagged Gpr rd);
|
||||
regs.src1 = Valid(tagged Gpr 0); // Operate on nullcap
|
||||
regs.src2 = Valid(tagged Gpr rs1);
|
||||
dInst.imm = Invalid;
|
||||
dInst.execFunc = CapModify (SetBounds (CRAM));
|
||||
end
|
||||
f5rs2_cap_CMove: begin
|
||||
dInst.iType = Alu;
|
||||
|
||||
@@ -66,11 +66,49 @@ function Maybe#(CapException) capChecks(CapPipe a, CapPipe b, CapChecks toCheck)
|
||||
result = e2(TypeViolation);
|
||||
else if (toCheck.src2_addr_valid_type && !validAsType(b, truncate(getAddr(b))))
|
||||
result = e2(LengthViolation);
|
||||
else if (toCheck.src2_perm_subset_src1 && (getPerms(a) & getPerms(b)) != getPerms(b))
|
||||
else if (toCheck.src1_perm_subset_src2 && (getPerms(a) & getPerms(b)) != getPerms(a))
|
||||
result = e2(SoftwarePermViolation);
|
||||
else if (toCheck.src1_derivable && !isDerivable(a))
|
||||
result = e1(LengthViolation);
|
||||
return result;
|
||||
endfunction
|
||||
|
||||
(* noinline *)
|
||||
function Maybe#(BoundsCheck) prepareBoundsCheck(CapPipe a, CapPipe b, CapChecks toCheck);
|
||||
BoundsCheck ret = ?;
|
||||
CapPipe authority = ?;
|
||||
case(toCheck.check_authority_src)
|
||||
Src1: begin
|
||||
authority = a;
|
||||
ret.authority_idx = toCheck.rn1;
|
||||
end
|
||||
Src2: begin
|
||||
authority = b;
|
||||
ret.authority_idx = toCheck.rn2;
|
||||
end
|
||||
endcase
|
||||
ret.authority_base = getBase(authority);
|
||||
ret.authority_top = getTop(authority);
|
||||
|
||||
case(toCheck.check_low_src)
|
||||
Src1Addr: ret.check_low = getAddr(a);
|
||||
Src1Base: ret.check_low = getBase(a);
|
||||
Src2Addr: ret.check_low = getAddr(b);
|
||||
Src2Type: ret.check_low = zeroExtend(getType(b));
|
||||
endcase
|
||||
|
||||
case(toCheck.check_high_src)
|
||||
Src1Top: ret.check_high = getTop(a);
|
||||
Src2Addr: ret.check_high = {1'b0,getAddr(b)};
|
||||
Src2Type: ret.check_high = zeroExtend(getType(b));
|
||||
ResultTop: ret.check_high = {1'b0,getAddr(a)} + {1'b0,getAddr(b)};
|
||||
endcase
|
||||
|
||||
ret.check_inclusive = toCheck.check_inclusive;
|
||||
if (toCheck.check_enable) return Valid(ret);
|
||||
else return Invalid;
|
||||
endfunction
|
||||
|
||||
(* noinline *)
|
||||
function Data alu(Data a, Data b, AluFunc func);
|
||||
Data res = (case(func)
|
||||
@@ -97,15 +135,27 @@ function Data alu(Data a, Data b, AluFunc func);
|
||||
return res;
|
||||
endfunction
|
||||
|
||||
(* noinline *)
|
||||
function CapPipe setBoundsALU(CapPipe cap, Data len, SetBoundsFunc boundsOp);
|
||||
let combinedResult = setBoundsCombined(cap, len);
|
||||
CapPipe res = (case (boundsOp) matches
|
||||
SetBounds: combinedResult.cap;
|
||||
CRRL: nullWithAddr(combinedResult.length);
|
||||
CRAM: nullWithAddr(combinedResult.mask);
|
||||
endcase);
|
||||
// TODO exfiltrate exact somehow...
|
||||
return res;
|
||||
endfunction
|
||||
|
||||
(* noinline *)
|
||||
function CapPipe capModify(CapPipe a, CapPipe b, CapModifyFunc func);
|
||||
CapPipe res = (case(func) matches
|
||||
tagged ModifyOffset .offsetOp :
|
||||
modifyOffset(a, getAddr(b), offsetOp == IncOffset).value;
|
||||
tagged SetBounds .exact :
|
||||
setBounds(a, getAddr(b)).value;
|
||||
//tagged SpecialRW :
|
||||
// error("SpecialRW not yet implemented");
|
||||
tagged SetBounds .boundsOp :
|
||||
setBoundsALU(a, getAddr(b), boundsOp);
|
||||
tagged SpecialRW .scrType :
|
||||
a; //TODO masking of various bits
|
||||
tagged SetAddr .addrSource :
|
||||
if (addrSource == Src2Type && !isSealed(b)) return nullWithAddr(-1);
|
||||
else return setAddr(a, (addrSource == Src2Type) ? zeroExtend(getType(b)) : getAddr(b) ).value;
|
||||
@@ -120,7 +170,7 @@ function CapPipe capModify(CapPipe a, CapPipe b, CapModifyFunc func);
|
||||
//tagged FromPtr :
|
||||
// error("FromPtr not yet implemented");
|
||||
tagged BuildCap :
|
||||
setValidCap(a, True);
|
||||
setType(setValidCap(a, True),-1);
|
||||
tagged Move :
|
||||
a;
|
||||
tagged ClearTag :
|
||||
@@ -156,7 +206,7 @@ function Data capInspect(CapPipe a, CapPipe b, CapInspectFunc func);
|
||||
tagged GetType :
|
||||
signExtend(getType(a));
|
||||
tagged ToPtr :
|
||||
(getAddr(a) - getBase(b));
|
||||
(isValidCap(a) ? (getAddr(a) - getBase(b)) : 0);
|
||||
default: ?;
|
||||
endcase);
|
||||
return res;
|
||||
@@ -233,7 +283,8 @@ function ExecResult basicExec(DecodedInst dInst, CapPipe rVal1, CapPipe rVal2, C
|
||||
Data inspect_result = capInspect(rVal1, aluVal2, dInst.execFunc.CapInspect);
|
||||
CapModifyFunc modFunc = ccall ? (Unseal (Src2)):dInst.execFunc.CapModify;
|
||||
CapPipe modify_result = capModify(rVal1, aluVal2, modFunc);
|
||||
Maybe#(CapException) capException = capChecks(rVal1, aluVal2, dInst.capChecks); // TODO use this to throw exceptions
|
||||
Maybe#(CapException) 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);
|
||||
tagged CapModify .x: modify_result;
|
||||
@@ -258,7 +309,7 @@ function ExecResult basicExec(DecodedInst dInst, CapPipe rVal1, CapPipe rVal2, C
|
||||
Jr &&& (ccall): cap_alu_result; // Depending on defaults falling through!
|
||||
Jr &&& (cjalr): link_pcc;
|
||||
Jr : nullWithAddr(getOffset(link_pcc));
|
||||
Auipc : nullWithAddr(pc + fromMaybe(?, getDInstImm(dInst))); // could be computed with alu
|
||||
Auipc : (getFlags(pcc)[0] == 1'b0 ? nullWithAddr(pc + fromMaybe(?, getDInstImm(dInst))) : modifyOffset(pcc, fromMaybe(?, getDInstImm(dInst)), True).value); // could be computed with alu
|
||||
Csr : rVal1;
|
||||
default : cap_alu_result;
|
||||
endcase);
|
||||
@@ -267,9 +318,9 @@ function ExecResult basicExec(DecodedInst dInst, CapPipe rVal1, CapPipe rVal2, C
|
||||
Ld, St, Lr, Sc, Amo : nullWithAddr(alu_result);
|
||||
default : nullWithAddr(cf.nextPc);
|
||||
endcase);
|
||||
CapPipe scr_data = rVal1;
|
||||
CapPipe scr_data = modify_result;
|
||||
|
||||
return ExecResult{data: data, csrData: csr_data, scrData: scr_data, addr: addr, controlFlow: cf, capException: capException};
|
||||
return ExecResult{data: data, csrData: csr_data, scrData: scr_data, addr: addr, controlFlow: cf, capException: capException, boundsCheck: boundsCheck};
|
||||
endfunction
|
||||
|
||||
(* noinline *)
|
||||
|
||||
22
src_Core/RISCY_OOO/procs/lib/Opcodes.bsvi
Normal file
22
src_Core/RISCY_OOO/procs/lib/Opcodes.bsvi
Normal file
@@ -0,0 +1,22 @@
|
||||
`OPCODE(Load , 7'b0000011)
|
||||
`OPCODE(LoadFp , 7'b0000111)
|
||||
`OPCODE(MiscMem, 7'b0001111)
|
||||
`OPCODE(OpImm , 7'b0010011)
|
||||
`OPCODE(Auipc , 7'b0010111)
|
||||
`OPCODE(OpImm32, 7'b0011011)
|
||||
`OPCODE(Store , 7'b0100011)
|
||||
`OPCODE(StoreFp, 7'b0100111)
|
||||
`OPCODE(Amo , 7'b0101111)
|
||||
`OPCODE(Op , 7'b0110011)
|
||||
`OPCODE(Lui , 7'b0110111)
|
||||
`OPCODE(Op32 , 7'b0111011)
|
||||
`OPCODE(Fmadd , 7'b1000011)
|
||||
`OPCODE(Fmsub , 7'b1000111)
|
||||
`OPCODE(Fnmsub , 7'b1001011)
|
||||
`OPCODE(Fnmadd , 7'b1001111)
|
||||
`OPCODE(OpFp , 7'b1010011)
|
||||
`OPCODE(OpCHERI, 7'b1011011)
|
||||
`OPCODE(Branch , 7'b1100011)
|
||||
`OPCODE(Jalr , 7'b1100111)
|
||||
`OPCODE(Jal , 7'b1101111)
|
||||
`OPCODE(System , 7'b1110011)
|
||||
@@ -171,212 +171,37 @@ function Bool allRegsReady(RegsReady x);
|
||||
endfunction
|
||||
|
||||
typedef enum {
|
||||
Invalid = 7'b0,
|
||||
Load = 7'b0000011,
|
||||
LoadFp = 7'b0000111,
|
||||
MiscMem = 7'b0001111,
|
||||
OpImm = 7'b0010011,
|
||||
Auipc = 7'b0010111,
|
||||
OpImm32 = 7'b0011011,
|
||||
Store = 7'b0100011,
|
||||
StoreFp = 7'b0100111,
|
||||
Amo = 7'b0101111,
|
||||
Op = 7'b0110011,
|
||||
Lui = 7'b0110111,
|
||||
Op32 = 7'b0111011,
|
||||
Fmadd = 7'b1000011,
|
||||
Fmsub = 7'b1000111,
|
||||
Fnmsub = 7'b1001011,
|
||||
Fnmadd = 7'b1001111,
|
||||
OpFp = 7'b1010011,
|
||||
OpCHERI = 7'b1011011,
|
||||
Branch = 7'b1100011,
|
||||
Jalr = 7'b1100111,
|
||||
Jal = 7'b1101111,
|
||||
System = 7'b1110011
|
||||
`define OPCODE(o,v) o = v,
|
||||
`include "Opcodes.bsvi"
|
||||
`undef OPCODE
|
||||
Invalid = 7'b0
|
||||
} Opcode deriving(Bits, Eq, FShow);
|
||||
|
||||
function Opcode unpackOpcode(Bit#(7) x);
|
||||
return (case(x)
|
||||
pack(Opcode'(Load )): (Load );
|
||||
pack(Opcode'(LoadFp )): (LoadFp );
|
||||
pack(Opcode'(MiscMem)): (MiscMem);
|
||||
pack(Opcode'(OpImm )): (OpImm );
|
||||
pack(Opcode'(Auipc )): (Auipc );
|
||||
pack(Opcode'(OpImm32)): (OpImm32);
|
||||
pack(Opcode'(Store )): (Store );
|
||||
pack(Opcode'(StoreFp)): (StoreFp);
|
||||
pack(Opcode'(Amo )): (Amo );
|
||||
pack(Opcode'(Op )): (Op );
|
||||
pack(Opcode'(Lui )): (Lui );
|
||||
pack(Opcode'(Op32 )): (Op32 );
|
||||
pack(Opcode'(Fmadd )): (Fmadd );
|
||||
pack(Opcode'(Fmsub )): (Fmsub );
|
||||
pack(Opcode'(Fnmsub )): (Fnmsub );
|
||||
pack(Opcode'(Fnmadd )): (Fnmadd );
|
||||
pack(Opcode'(OpFp )): (OpFp );
|
||||
pack(Opcode'(OpCHERI)): (OpCHERI);
|
||||
pack(Opcode'(Branch )): (Branch );
|
||||
pack(Opcode'(Jalr )): (Jalr );
|
||||
pack(Opcode'(Jal )): (Jal );
|
||||
pack(Opcode'(System )): (System );
|
||||
default : (Invalid);
|
||||
`define OPCODE(o,v) pack(Opcode'(o)): (o);
|
||||
`include "Opcodes.bsvi"
|
||||
`undef OPCODE
|
||||
default : Invalid;
|
||||
endcase);
|
||||
endfunction
|
||||
|
||||
/* If Bluespec never allows illegal values of sparse enumerated types, this function should replace the one above:
|
||||
function Opcode unpackOpcode(Bit#(7) x);
|
||||
Opcode test = unpack(x);
|
||||
if (pack(test) != x) return Invalid;
|
||||
else return test;
|
||||
endfunction
|
||||
*/
|
||||
typedef enum {
|
||||
// user standard CSRs
|
||||
CSRfflags = 12'h001,
|
||||
CSRfrm = 12'h002,
|
||||
CSRfcsr = 12'h003,
|
||||
CSRcycle = 12'hc00,
|
||||
CSRtime = 12'hc01,
|
||||
CSRinstret = 12'hc02,
|
||||
// user non-standard CSRs (TODO)
|
||||
CSRterminate = 12'h800, // terminate (used to exit Linux)
|
||||
CSRstats = 12'h801, // turn on/off perf counters
|
||||
CSRuccsr = 12'h8c0,
|
||||
// supervisor standard CSRs
|
||||
CSRsstatus = 12'h100,
|
||||
// no user trap handler, so no se/ideleg
|
||||
CSRsie = 12'h104,
|
||||
CSRstvec = 12'h105,
|
||||
CSRscounteren = 12'h106,
|
||||
CSRsscratch = 12'h140,
|
||||
CSRsepc = 12'h141,
|
||||
CSRscause = 12'h142,
|
||||
CSRstval = 12'h143, // it's still called sbadaddr in spike
|
||||
CSRsip = 12'h144,
|
||||
CSRsatp = 12'h180, // it's still called sptbr in spike
|
||||
CSRsccsr = 12'h9c0,
|
||||
// machine standard CSRs
|
||||
CSRmstatus = 12'h300,
|
||||
CSRmisa = 12'h301,
|
||||
CSRmedeleg = 12'h302,
|
||||
CSRmideleg = 12'h303,
|
||||
CSRmie = 12'h304,
|
||||
CSRmtvec = 12'h305,
|
||||
CSRmcounteren = 12'h306,
|
||||
CSRmscratch = 12'h340,
|
||||
CSRmepc = 12'h341,
|
||||
CSRmcause = 12'h342,
|
||||
CSRmtval = 12'h343, // it's still called mbadaddr in spike
|
||||
CSRmip = 12'h344,
|
||||
CSRmcycle = 12'hb00,
|
||||
CSRminstret = 12'hb02,
|
||||
CSRmvendorid = 12'hf11,
|
||||
CSRmarchid = 12'hf12,
|
||||
CSRmimpid = 12'hf13,
|
||||
CSRmhartid = 12'hf14,
|
||||
CSRmccsr = 12'hbc0,
|
||||
`ifdef SECURITY
|
||||
// sanctum machine CSR
|
||||
CSRmevbase = 12'h7c0,
|
||||
CSRmevmask = 12'h7c1,
|
||||
CSRmeatp = 12'h7c2,
|
||||
CSRmmrbm = 12'h7c3,
|
||||
CSRmemrbm = 12'h7c4,
|
||||
CSRmparbase = 12'h7c5,
|
||||
CSRmparmask = 12'h7c6,
|
||||
CSRmeparbase = 12'h7c7,
|
||||
CSRmeparmask = 12'h7c8,
|
||||
CSRmflush = 12'h7c9, // flush pipeline + cache
|
||||
CSRmspec = 12'h7ca, // control speculation
|
||||
// sanctum user CSR
|
||||
CSRtrng = 12'hcc0, // random number for secure boot
|
||||
`endif
|
||||
|
||||
CSRtselect = 12'h7A0, // Debug/trace tselect
|
||||
CSRtdata1 = 12'h7A1, // Debug/trace tdata1
|
||||
CSRtdata2 = 12'h7A2, // Debug/trace tdata2
|
||||
CSRtdata3 = 12'h7A3, // Debug/trace tdata3
|
||||
|
||||
`ifdef INCLUDE_GDB_CONTROL
|
||||
CSRdcsr = 12'h7B0, // Debug control and status
|
||||
CSRdpc = 12'h7B1, // Debug PC
|
||||
CSRdscratch0 = 12'h7B2, // Debug scratch0
|
||||
CSRdscratch1 = 12'h7B3, // Debug scratch1
|
||||
`endif
|
||||
|
||||
`define CSR(c,v) c = v,
|
||||
`include "CSRs.bsvi"
|
||||
`undef CSR
|
||||
// CSR that catches all the unimplemented CSRs. To avoid exception on this,
|
||||
// make it a user non-standard read/write CSR.
|
||||
// Bluespec: in RenameStage.getTrap(), we force this to be a csr_access_trap
|
||||
CSRnone = 12'h8ff
|
||||
CSRnone = 12'h8ff
|
||||
} CSR deriving(Bits, Eq, FShow);
|
||||
|
||||
function CSR unpackCSR(Bit#(12) x);
|
||||
return (case(x)
|
||||
pack(CSR'(CSRfflags )): (CSRfflags );
|
||||
pack(CSR'(CSRfrm )): (CSRfrm );
|
||||
pack(CSR'(CSRfcsr )): (CSRfcsr );
|
||||
pack(CSR'(CSRcycle )): (CSRcycle );
|
||||
pack(CSR'(CSRtime )): (CSRtime );
|
||||
pack(CSR'(CSRinstret )): (CSRinstret );
|
||||
pack(CSR'(CSRterminate )): (CSRterminate );
|
||||
pack(CSR'(CSRstats )): (CSRstats );
|
||||
pack(CSR'(CSRsstatus )): (CSRsstatus );
|
||||
pack(CSR'(CSRsie )): (CSRsie );
|
||||
pack(CSR'(CSRstvec )): (CSRstvec );
|
||||
pack(CSR'(CSRscounteren)): (CSRscounteren);
|
||||
pack(CSR'(CSRsscratch )): (CSRsscratch );
|
||||
pack(CSR'(CSRsepc )): (CSRsepc );
|
||||
pack(CSR'(CSRscause )): (CSRscause );
|
||||
pack(CSR'(CSRstval )): (CSRstval );
|
||||
pack(CSR'(CSRsip )): (CSRsip );
|
||||
pack(CSR'(CSRsatp )): (CSRsatp );
|
||||
pack(CSR'(CSRmstatus )): (CSRmstatus );
|
||||
pack(CSR'(CSRmisa )): (CSRmisa );
|
||||
pack(CSR'(CSRmedeleg )): (CSRmedeleg );
|
||||
pack(CSR'(CSRmideleg )): (CSRmideleg );
|
||||
pack(CSR'(CSRmie )): (CSRmie );
|
||||
pack(CSR'(CSRmtvec )): (CSRmtvec );
|
||||
pack(CSR'(CSRmcounteren)): (CSRmcounteren);
|
||||
pack(CSR'(CSRmscratch )): (CSRmscratch );
|
||||
pack(CSR'(CSRmepc )): (CSRmepc );
|
||||
pack(CSR'(CSRmcause )): (CSRmcause );
|
||||
pack(CSR'(CSRmtval )): (CSRmtval );
|
||||
pack(CSR'(CSRmip )): (CSRmip );
|
||||
pack(CSR'(CSRmcycle )): (CSRmcycle );
|
||||
pack(CSR'(CSRminstret )): (CSRminstret );
|
||||
pack(CSR'(CSRmvendorid )): (CSRmvendorid );
|
||||
pack(CSR'(CSRmarchid )): (CSRmarchid );
|
||||
pack(CSR'(CSRmimpid )): (CSRmimpid );
|
||||
pack(CSR'(CSRmhartid )): (CSRmhartid );
|
||||
`ifdef SECURITY
|
||||
pack(CSR'(CSRmevbase )): (CSRmevbase );
|
||||
pack(CSR'(CSRmevmask )): (CSRmevmask );
|
||||
pack(CSR'(CSRmeatp )): (CSRmeatp );
|
||||
pack(CSR'(CSRmmrbm )): (CSRmmrbm );
|
||||
pack(CSR'(CSRmemrbm )): (CSRmemrbm );
|
||||
pack(CSR'(CSRmparbase )): (CSRmparbase );
|
||||
pack(CSR'(CSRmparmask )): (CSRmparmask );
|
||||
pack(CSR'(CSRmeparbase )): (CSRmeparbase );
|
||||
pack(CSR'(CSRmeparmask )): (CSRmeparmask );
|
||||
pack(CSR'(CSRmflush )): (CSRmflush );
|
||||
pack(CSR'(CSRmspec )): (CSRmspec );
|
||||
pack(CSR'(CSRtrng )): (CSRtrng );
|
||||
`endif
|
||||
|
||||
pack(CSR'(CSRtselect )): (CSRtselect );
|
||||
pack(CSR'(CSRtdata1 )): (CSRtdata1 );
|
||||
pack(CSR'(CSRtdata2 )): (CSRtdata2 );
|
||||
pack(CSR'(CSRtdata3 )): (CSRtdata3 );
|
||||
|
||||
`ifdef INCLUDE_GDB_CONTROL
|
||||
pack(CSR'(CSRdcsr )): (CSRdcsr );
|
||||
pack(CSR'(CSRdpc )): (CSRdpc );
|
||||
pack(CSR'(CSRdscratch0 )): (CSRdscratch0 );
|
||||
pack(CSR'(CSRdscratch1 )): (CSRdscratch1 );
|
||||
`endif
|
||||
|
||||
default : (CSRnone );
|
||||
`define CSR(c,v) pack(CSR'(c)): (c);
|
||||
`include "CSRs.bsvi"
|
||||
`undef CSR
|
||||
default : (CSRnone );
|
||||
endcase);
|
||||
endfunction
|
||||
|
||||
@@ -420,9 +245,13 @@ typedef enum {
|
||||
} ModifyOffsetFunc deriving(Bits, Eq, FShow);
|
||||
|
||||
typedef enum {
|
||||
SetBounds, SetBoundsExact, CRRL, CRAM
|
||||
SetBounds, CRRL, CRAM
|
||||
} SetBoundsFunc deriving(Bits, Eq, FShow);
|
||||
|
||||
typedef enum {
|
||||
TCC, EPCC, Normal
|
||||
} SpecialRWFunc deriving(Bits, Eq, FShow);
|
||||
|
||||
typedef enum {
|
||||
Src2Type, Src2Addr
|
||||
} AddrSource deriving(Bits, Eq, FShow);
|
||||
@@ -433,8 +262,8 @@ typedef enum {
|
||||
|
||||
typedef union tagged {
|
||||
ModifyOffsetFunc ModifyOffset;
|
||||
Bool SetBounds;
|
||||
void SpecialRW;
|
||||
SetBoundsFunc SetBounds;
|
||||
SpecialRWFunc SpecialRW;
|
||||
AddrSource SetAddr;
|
||||
void Seal;
|
||||
SrcSelector Unseal;
|
||||
@@ -568,8 +397,8 @@ typedef union tagged {
|
||||
|
||||
typedef struct {
|
||||
Trap trap;
|
||||
CHERIException capExp;
|
||||
} TrapWithCap deriving(Bits, Eq, FShow);
|
||||
CSR_XCapCause capExp;
|
||||
} TrapWithCap deriving(Bits, FShow);
|
||||
|
||||
// privilege modes
|
||||
Bit#(2) prvU = 0;
|
||||
@@ -672,30 +501,72 @@ typedef struct {
|
||||
Bool illegalInst;
|
||||
} DecodeResult deriving(Bits, Eq, FShow);
|
||||
|
||||
typedef enum {
|
||||
Src1,
|
||||
Src2
|
||||
} CheckAuthoritySrc deriving(Bits, Eq, FShow);
|
||||
|
||||
typedef enum {
|
||||
Src1Addr,
|
||||
Src2Addr,
|
||||
Src2Type,
|
||||
Src1Base
|
||||
} CheckLowSrc deriving(Bits, Eq, FShow);
|
||||
|
||||
typedef enum {
|
||||
Src1Top,
|
||||
Src2Addr,
|
||||
Src2Type,
|
||||
ResultTop
|
||||
} CheckHighSrc deriving(Bits, Eq, FShow);
|
||||
|
||||
typedef struct {
|
||||
Data authority_base;
|
||||
CapTop authority_top;
|
||||
Bit#(6) authority_idx;
|
||||
Data check_low;
|
||||
CapTop check_high;
|
||||
Bool check_inclusive;
|
||||
} BoundsCheck deriving(Bits, Eq, FShow);
|
||||
|
||||
typedef Bit#(65) CapTop;
|
||||
|
||||
typedef Bit#(32) ImmData; // 32-bit decoded immediate data
|
||||
|
||||
typedef struct {
|
||||
Bool src1_tag;
|
||||
Bool src2_tag;
|
||||
Bool src1_sealed_with_type;
|
||||
Bool src1_unsealed;
|
||||
Bool src2_unsealed;
|
||||
Bool src1_sealed;
|
||||
Bool src2_sealed;
|
||||
Bool src1_src2_types_match;
|
||||
Bool src1_permit_ccall;
|
||||
Bool src2_permit_ccall;
|
||||
Bool src1_permit_x;
|
||||
Bool src2_no_permit_x;
|
||||
Bool src2_permit_unseal;
|
||||
Bool src2_permit_seal;
|
||||
Bool src2_points_to_src1_type;
|
||||
Bool src2_addr_valid_type;
|
||||
Bool src2_perm_subset_src1;
|
||||
Bool src2_derivable;
|
||||
`define CAP_CHECK_FIELD(x,s) Bool x;
|
||||
`include "CapChecks.bsvi"
|
||||
`undef CAP_CHECK_FIELD
|
||||
|
||||
Bool check_enable;
|
||||
CheckAuthoritySrc check_authority_src;
|
||||
CheckLowSrc check_low_src;
|
||||
CheckHighSrc check_high_src;
|
||||
Bool check_inclusive;
|
||||
|
||||
Bit#(6) rn1;
|
||||
Bit#(6) rn2;
|
||||
} CapChecks deriving(Bits, Eq, FShow);
|
||||
} CapChecks deriving(Bits, Eq);
|
||||
|
||||
instance FShow#(CapChecks);
|
||||
function Fmt fshow(CapChecks x);
|
||||
let ret = $format("CapChecks {",
|
||||
"rn1 ", fshow(x.rn1), ", rn2 ", fshow(x.rn2));
|
||||
|
||||
`define CAP_CHECK_FIELD(f,s) if (x.f) ret = ret + $format(", ", s);
|
||||
`include "CapChecks.bsvi"
|
||||
`undef CAP_CHECK_FIELD
|
||||
|
||||
if (x.check_enable)
|
||||
ret = $format(ret, ", bounds check: ",
|
||||
"auth ", fshow(x.check_authority_src), ", ",
|
||||
"low ", fshow(x.check_low_src), ", ",
|
||||
"high ", fshow(x.check_high_src), ", ",
|
||||
"inclusive ", fshow(x.check_inclusive));
|
||||
|
||||
return $format(ret, "}");
|
||||
endfunction
|
||||
endinstance
|
||||
|
||||
typedef CSR_XCapCause CapException;
|
||||
|
||||
@@ -719,6 +590,7 @@ typedef struct {
|
||||
CapPipe addr;
|
||||
ControlFlow controlFlow;
|
||||
Maybe#(CapException) capException;
|
||||
Maybe#(BoundsCheck) boundsCheck;
|
||||
} ExecResult deriving(Bits, FShow);
|
||||
|
||||
// MMIO
|
||||
|
||||
@@ -117,7 +117,7 @@ interface Row_setExecuted_doFinishAlu;
|
||||
Maybe#(Data) csrData,
|
||||
Maybe#(CapPipe) scrData,
|
||||
ControlFlow cf,
|
||||
Maybe#(CHERIException) cause,
|
||||
Maybe#(CSR_XCapCause) cause,
|
||||
CapPipe pcc
|
||||
`ifdef RVFI
|
||||
, ExtraTraceBundle tb
|
||||
@@ -289,7 +289,7 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
|
||||
Maybe#(Data) csrData,
|
||||
Maybe#(CapPipe) scrData,
|
||||
ControlFlow cf,
|
||||
Maybe#(CHERIException) cause,
|
||||
Maybe#(CSR_XCapCause) cause,
|
||||
CapPipe pcc
|
||||
`ifdef RVFI
|
||||
, ExtraTraceBundle tb
|
||||
@@ -313,10 +313,12 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
|
||||
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 (TrapWithCap{trap: tagged Exception CHERIFault, capExp: LengthViolation});
|
||||
trap[trap_finishAlu_port(i)] <= Valid (TrapWithCap{trap: tagged Exception CHERIFault,
|
||||
capExp: CSR_XCapCause {cheri_exc_code: LengthViolation,
|
||||
cheri_exc_reg: {1,pack(SCR_PCC)}}});
|
||||
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 (TrapWithCap{trap: tagged Exception CHERIFault, capExp: fromMaybe(None, cause)});
|
||||
trap[trap_finishAlu_port(i)] <= Valid (TrapWithCap{trap: tagged Exception CHERIFault, capExp: exp});
|
||||
tval[trap_finishAlu_port(i)] <= tval[trap_finishAlu_port(i)];
|
||||
end
|
||||
`ifdef RVFI
|
||||
@@ -346,10 +348,12 @@ 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 (TrapWithCap{trap: tagged Exception CHERIFault, capExp: LengthViolation});
|
||||
trap[trap_finishFpuMulDiv_port(i)] <= Valid (TrapWithCap{trap: tagged Exception CHERIFault,
|
||||
capExp: CSR_XCapCause {cheri_exc_code: LengthViolation,
|
||||
cheri_exc_reg: {1,pack(SCR_PCC)}}});
|
||||
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 (TrapWithCap{trap: tagged Exception exp, capExp: None});
|
||||
trap[trap_finishFpuMulDiv_port(i)] <= Valid (TrapWithCap{trap: tagged Exception exp, capExp: noCapCause});
|
||||
tval[trap_finishFpuMulDiv_port(i)] <= tval[trap_finishAlu_port(i)];
|
||||
end
|
||||
//pc[pc_finishFpuMulDiv_port(i)] <= newPcc; //XXX add pcc checks on FPU instructions
|
||||
@@ -403,10 +407,12 @@ 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 (TrapWithCap{trap: tagged Exception CHERIFault, capExp: LengthViolation});
|
||||
mem_early_trap[0] <= Valid (TrapWithCap{trap: tagged Exception CHERIFault,
|
||||
capExp: CSR_XCapCause {cheri_exc_code: LengthViolation,
|
||||
cheri_exc_reg: {1,pack(SCR_PCC)}}});
|
||||
tval[trap_finishMem_port] <= tval[trap_finishMem_port];
|
||||
end else if (cause matches tagged Valid .exp) begin
|
||||
mem_early_trap[0] <= Valid (TrapWithCap{trap: tagged Exception exp, capExp: None});
|
||||
mem_early_trap[0] <= Valid (TrapWithCap{trap: tagged Exception exp, capExp: noCapCause});
|
||||
tval[trap_finishMem_port] <= tval[trap_finishMem_port];
|
||||
end
|
||||
endmethod
|
||||
@@ -533,7 +539,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: None});
|
||||
else if(cause matches tagged Valid .e) trap[trap_deqLSQ_port] <= Valid (TrapWithCap{trap: tagged Exception e, capExp: noCapCause});
|
||||
// TODO: shouldn't we record tval here as well?
|
||||
// record ld misspeculation
|
||||
ldKilled[ldKill_deqLSQ_port] <= ld_killed;
|
||||
@@ -595,7 +601,7 @@ interface ROB_setExecuted_doFinishAlu;
|
||||
Maybe#(Data) csrData,
|
||||
Maybe#(CapPipe) scrData,
|
||||
ControlFlow cf,
|
||||
Maybe#(CHERIException) cause,
|
||||
Maybe#(CSR_XCapCause) cause,
|
||||
CapPipe pcc
|
||||
`ifdef RVFI
|
||||
, ExtraTraceBundle tb
|
||||
@@ -1144,7 +1150,7 @@ module mkSupReorderBuffer#(
|
||||
Maybe#(Data) csrData,
|
||||
Maybe#(CapPipe) scrData,
|
||||
ControlFlow cf,
|
||||
Maybe#(CHERIException) cause,
|
||||
Maybe#(CSR_XCapCause) cause,
|
||||
CapPipe pcc
|
||||
`ifdef RVFI
|
||||
, ExtraTraceBundle tb
|
||||
|
||||
Reference in New Issue
Block a user