diff --git a/src_Core/RISCY_OOO/procs/RV64G_OOO/AluExePipeline.bsv b/src_Core/RISCY_OOO/procs/RV64G_OOO/AluExePipeline.bsv index c59af20..474778d 100755 --- a/src_Core/RISCY_OOO/procs/RV64G_OOO/AluExePipeline.bsv +++ b/src_Core/RISCY_OOO/procs/RV64G_OOO/AluExePipeline.bsv @@ -192,7 +192,7 @@ endinterface module mkAluExePipeline#(AluExeInput inIfc)(AluExePipeline); Bool verbose = False; - Integer verbosity = 1; + Integer verbosity = 0; // alu reservation station ReservationStationAlu rsAlu <- mkReservationStationAlu; diff --git a/src_Core/RISCY_OOO/procs/RV64G_OOO/MemExePipeline.bsv b/src_Core/RISCY_OOO/procs/RV64G_OOO/MemExePipeline.bsv index a1a5483..b91dc1f 100644 --- a/src_Core/RISCY_OOO/procs/RV64G_OOO/MemExePipeline.bsv +++ b/src_Core/RISCY_OOO/procs/RV64G_OOO/MemExePipeline.bsv @@ -63,6 +63,7 @@ typedef struct { PhyRegs regs; InstTag tag; LdStQTag ldstq_tag; + CapChecks cap_checks; } MemDispatchToRegRead deriving(Bits, Eq, FShow); typedef struct { @@ -74,6 +75,7 @@ typedef struct { // src reg vals CapPipe rVal1; CapPipe rVal2; + CapChecks cap_checks; } MemRegReadToExe deriving(Bits, FShow); typedef struct { @@ -90,6 +92,8 @@ typedef struct { ByteEn store_data_BE; `endif Bool misaligned; + Maybe#(CSR_XCapCause) capException; + Maybe#(BoundsCheck) check; } MemExeToFinish deriving(Bits, FShow); // bookkeeping when waiting for MMIO resp which may cause exception @@ -161,7 +165,7 @@ interface MemExeInput; CapPipe vaddr, Data store_data, ByteEn store_data_BE, Bool access_at_commit, Bool non_mmio_st_done, - Maybe#(Exception) cause + Maybe#(CSR_XCapCause) cause `ifdef RVFI , ExtraTraceBundle tb `endif @@ -207,7 +211,7 @@ interface MemExePipeline; endinterface module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline); - Bool verbose = False; + Bool verbose = True; // we change cache request in case of single core, becaues our MSI protocol // is not good with single core @@ -396,7 +400,8 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline); imm: x.data.imm, regs: x.regs, tag: x.tag, - ldstq_tag: x.data.ldstq_tag + ldstq_tag: x.data.ldstq_tag, + cap_checks: x.data.cap_checks }, spec_bits: x.spec_bits }); @@ -438,7 +443,8 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline); tag: x.tag, ldstq_tag: x.ldstq_tag, rVal1: rVal1, - rVal2: rVal2 + rVal2: rVal2, + cap_checks: x.cap_checks }, spec_bits: dispToReg.spec_bits }); @@ -482,6 +488,8 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline); lsq.updateData(stTag, d); end + CapPipe ddc = cast(inIfc.scaprf_rd(SCR_DDC)); // ToDo: feed DDC into the prepareBoundsCheck function below somehow. + // go to next stage by sending to TLB dTlb.procReq(DTlbReq { inst: MemExeToFinish { @@ -494,7 +502,9 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline); store_data: data, store_data_BE: origBE, `endif - misaligned: memAddrMisaligned(getAddr(vaddr), origBE) + misaligned: memAddrMisaligned(getAddr(vaddr), origBE), + capException: capChecks(x.rVal1, x.rVal2, x.cap_checks), + check: prepareBoundsCheck(x.rVal1, vaddr, almightyCap, x.cap_checks) }, specBits: regToExe.spec_bits }); @@ -564,13 +574,15 @@ module mkMemExePipeline#(MemExeInput inIfc)(MemExePipeline); endcase); Bool access_at_commit = !isValid(cause) && (isMMIO || isLrScAmo); Bool non_mmio_st_done = !isValid(cause) && !isMMIO && x.mem_func == St; - CapPipe pcc = cast(inIfc.rob_getPC(x.tag)); - CapPipe ddc = cast(inIfc.scaprf_rd(SCR_DDC)); - Bool ddc_out_of_bounds = !isInBounds(modifyOffset(ddc,getAddr(x.vaddr),True).value,True); - Bool out_of_bounds = (getFlags(pcc) == 1'b1) ? isInBounds(x.vaddr, False):ddc_out_of_bounds; + 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 inIfc.rob_setExecuted_doFinishMem(x.tag, x.vaddr, store_data, store_data_BE, access_at_commit, non_mmio_st_done, - (out_of_bounds) ? Valid(CHERIFault):Invalid + x.capException `ifdef RVFI , ExtraTraceBundle{ regWriteData: memData[pack(x.ldstq_tag)], diff --git a/src_Core/RISCY_OOO/procs/RV64G_OOO/RenameStage.bsv b/src_Core/RISCY_OOO/procs/RV64G_OOO/RenameStage.bsv index b12b427..6a534ed 100644 --- a/src_Core/RISCY_OOO/procs/RV64G_OOO/RenameStage.bsv +++ b/src_Core/RISCY_OOO/procs/RV64G_OOO/RenameStage.bsv @@ -697,7 +697,8 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage); data: MemRSData { mem_func: mem_inst.mem_func, imm: validValue(dInst.imm), - ldstq_tag: lsqTag + ldstq_tag: lsqTag, + cap_checks: dInst.capChecks }, regs: phy_regs, tag: inst_tag, diff --git a/src_Core/RISCY_OOO/procs/RV64G_OOO/ReservationStationMem.bsv b/src_Core/RISCY_OOO/procs/RV64G_OOO/ReservationStationMem.bsv index 8bbf195..d5f05d0 100644 --- a/src_Core/RISCY_OOO/procs/RV64G_OOO/ReservationStationMem.bsv +++ b/src_Core/RISCY_OOO/procs/RV64G_OOO/ReservationStationMem.bsv @@ -1,6 +1,6 @@ // Copyright (c) 2017 Massachusetts Institute of Technology -// +// // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without @@ -8,10 +8,10 @@ // modify, merge, publish, distribute, sublicense, and/or sell copies // of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: -// +// // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND @@ -31,6 +31,7 @@ typedef struct { MemFunc mem_func; ImmData imm; LdStQTag ldstq_tag; + CapChecks cap_checks; } MemRSData deriving(Bits, Eq, FShow); // MEM pipeline is aggressive, i.e. it recv bypass and early RS wakeup diff --git a/src_Core/RISCY_OOO/procs/lib/Decode.bsv b/src_Core/RISCY_OOO/procs/lib/Decode.bsv index 5a0ae00..019cb84 100755 --- a/src_Core/RISCY_OOO/procs/lib/Decode.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Decode.bsv @@ -34,12 +34,6 @@ Bit#(3) memWU = 3'b110; // Smaller decode functions function Maybe#(MemInst) decodeMemInst(Instruction inst); - MemInst mem_inst = MemInst{ mem_func: ?, - amo_func: None, - unsignedLd: False, - byteEn: replicate(False), - aq: False, - rl: False }; Bool illegalInst = False; Opcode opcode = unpackOpcode(inst[6:0]); let funct5 = inst[31:27]; @@ -152,7 +146,8 @@ function Maybe#(MemInst) decodeMemInst(Instruction inst); unsignedLd: unsignedLd, byteEn: byteEn, aq: aq, - rl: rl } ); + rl: rl, + ddc_bounds: True } ); end endfunction @@ -230,7 +225,8 @@ function Maybe#(MemInst) decodeCapMemInst(Instruction inst); unsignedLd: unsignedLd, byteEn: byteEn, aq: aq, - rl: rl } ); + rl: rl, + ddc_bounds: ddc} ); end endfunction @@ -1133,23 +1129,49 @@ function DecodeResult decode(Instruction inst); end f7_cap_Loads: begin dInst.iType = Ld; - if (cap_mem_inst matches tagged Valid .ci) dInst.execFunc = tagged Mem ci; + MemInst mi = cap_mem_inst.Valid; + if (isValid(cap_mem_inst)) dInst.execFunc = tagged Mem mi; else illegalInst = True; regs.dst = Valid(tagged Gpr rd); regs.src1 = Valid(tagged Gpr rs1); regs.src2 = Invalid; dInst.imm = Valid (0); dInst.csr = tagged Invalid; + + dInst.capChecks.check_enable = True; + dInst.capChecks.check_low_src = Src1Addr; + dInst.capChecks.check_high_src = Src1AddrPlus2; // Should add the access size somehow... + dInst.capChecks.check_inclusive = True; + if (mi.ddc_bounds) begin + dInst.capChecks.check_authority_src = Ddc; + end else begin + dInst.capChecks.check_authority_src = Src1; + dInst.capChecks.src1_tag = True; + dInst.capChecks.src1_unsealed = True; + end end f7_cap_Stores: begin dInst.iType = St; - if (cap_mem_inst matches tagged Valid .ci) dInst.execFunc = tagged Mem ci; + MemInst mi = cap_mem_inst.Valid; + if (isValid(cap_mem_inst)) dInst.execFunc = tagged Mem mi; else illegalInst = True; regs.dst = Invalid; regs.src1 = Valid(tagged Gpr rs1); regs.src2 = Valid(tagged Gpr rs2); dInst.imm = Valid (0); dInst.csr = tagged Invalid; + + dInst.capChecks.check_enable = True; + dInst.capChecks.check_low_src = Src1Addr; + dInst.capChecks.check_high_src = Src1AddrPlus2; // Should add the access size somehow... + dInst.capChecks.check_inclusive = True; + if (mi.ddc_bounds) begin + dInst.capChecks.check_authority_src = Ddc; + end else begin + dInst.capChecks.check_authority_src = Src1; + dInst.capChecks.src1_tag = True; + dInst.capChecks.src1_unsealed = True; + end end f7_cap_TwoOp: begin case (funct5rs2) diff --git a/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv b/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv index 41d9b11..d8ec9a6 100755 --- a/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv +++ b/src_Core/RISCY_OOO/procs/lib/ProcTypes.bsv @@ -500,7 +500,8 @@ typedef struct { typedef enum { Src1, Src2, - Pcc + Pcc, + Ddc } CheckAuthoritySrc deriving(Bits, Eq, FShow); typedef enum { diff --git a/src_Core/RISCY_OOO/procs/lib/ReorderBuffer.bsv b/src_Core/RISCY_OOO/procs/lib/ReorderBuffer.bsv index 7245667..24c929b 100755 --- a/src_Core/RISCY_OOO/procs/lib/ReorderBuffer.bsv +++ b/src_Core/RISCY_OOO/procs/lib/ReorderBuffer.bsv @@ -157,7 +157,7 @@ interface ReorderBufferRowEhr#(numeric type aluExeNum, numeric type fpuMulDivExe method Action setExecuted_doFinishMem(CapPipe vaddr, Data store_data, ByteEn store_data_BE, Bool access_at_commit, Bool non_mmio_st_done, - Maybe#(Exception) cause + Maybe#(CSR_XCapCause) cause `ifdef RVFI , ExtraTraceBundle tb `endif @@ -357,7 +357,7 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p method Action setExecuted_doFinishMem(CapPipe vaddr, Data store_data, ByteEn store_data_BE, Bool access_at_commit, Bool non_mmio_st_done, - Maybe#(Exception) cause + Maybe#(CSR_XCapCause) cause `ifdef RVFI , ExtraTraceBundle tb `endif @@ -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 ( Exception (exp)); + mem_early_trap[0] <= Valid ( CapException (exp)); tval[trap_finishMem_port] <= tval[trap_finishMem_port]; end endmethod @@ -626,7 +626,7 @@ interface SupReorderBuffer#(numeric type aluExeNum, numeric type fpuMulDivExeNum CapPipe vaddr, Data store_data, ByteEn store_data_BE, Bool access_at_commit, Bool non_mmio_st_done, - Maybe#(Exception) cause + Maybe#(CSR_XCapCause) cause `ifdef RVFI , ExtraTraceBundle tb `endif @@ -1239,7 +1239,7 @@ module mkSupReorderBuffer#( method Action setExecuted_doFinishMem( InstTag x, CapPipe vaddr, Data store_data, ByteEn store_data_BE, Bool access_at_commit, - Bool non_mmio_st_done, Maybe#(Exception) cause + Bool non_mmio_st_done, Maybe#(CSR_XCapCause) cause `ifdef RVFI , tb `endif diff --git a/src_Core/RISCY_OOO/procs/lib/Types.bsv b/src_Core/RISCY_OOO/procs/lib/Types.bsv index c5e40af..66c979c 100644 --- a/src_Core/RISCY_OOO/procs/lib/Types.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Types.bsv @@ -124,6 +124,7 @@ typedef struct { MemDataByteEn byteEn; // takes place of double word Bool aq; Bool rl; + Bool ddc_bounds; } MemInst deriving(Bits, Eq, FShow); `ifdef BSIM