Implement writes to PCC and preparation for checking the bounds of PCC.

This commit is contained in:
Jonathan Woodruff
2020-03-23 14:24:44 +00:00
parent a299a763ed
commit 43fa43e2c9
4 changed files with 51 additions and 37 deletions

View File

@@ -37,6 +37,7 @@ import DefaultValue::*;
import ConfigReg::*;
import Ehr::*;
import GetPut::*;
import Vector::*;
import CHERICap::*;
import CHERICC_Fat::*;
import ISA_Decls_CHERI::*;
@@ -81,9 +82,10 @@ deriving (Bits, FShow);
interface ScrFile;
// Read
method CapReg rd(SCR csr);
// normal write by CSRXXX inst to any CSR
// normal write by RWSpecialCap inst to any SCR
method Action scrInstWr(SCR csr, CapReg x);
interface Vector#(SupSize, Put#(CapReg)) pccWr;
// The WARL transform performed during CSRRx writes to a CSR
method CapReg warl_xform (SCR csr, CapReg x);
@@ -93,8 +95,8 @@ interface ScrFile;
method ActionValue#(Scr_RET_Updates) mret;
// Outputs for CSRs that the rest of the processor needs to know about
method ScrVMInfo vmI;
method ScrVMInfo vmD;
method ScrVMInfo pccCheck;
method ScrVMInfo ddcCheck;
method ScrDecodeInfo decodeInfo;
// terminate
@@ -130,12 +132,11 @@ endmodule
module mkScrFile (ScrFile);
RiscVISASubset isa = defaultValue;
// To save from bypassing logic, CSR reads will get stale value
let mkCsrReg = mkConfigReg;
let mkCsrEhr = mkConfigEhr;
// User level SCRs
Reg#(CapReg) pcc_reg <- mkCsrReg(defaultValue);
Ehr#(SupSize, CapReg) pcc_reg <- mkCsrEhr(defaultValue);
Reg#(CapReg) ddc_reg <- mkCsrReg(defaultValue);
// User level SCRs with accessSysRegs
@@ -160,7 +161,7 @@ module mkScrFile (ScrFile);
function Reg#(CapReg) get_scr(SCR scr);
return (case (scr)
// User SCRs
SCR_PCC: pcc_reg;
SCR_PCC: pcc_reg[0];
SCR_DDC: ddc_reg;
// User CSRs with accessSysRegs
SCR_UTCC: utcc_reg;
@@ -191,6 +192,8 @@ module mkScrFile (ScrFile);
get_scr(csr)._write(x);
endmethod
interface pccWr = map(toPut,pcc_reg);
method ActionValue#(Scr_Trap_Updates) trap(Trap t, Addr pc, Addr addr, Bit #(32) orig_inst);
return ?;
endmethod
@@ -203,24 +206,24 @@ module mkScrFile (ScrFile);
return ?;
endmethod
method ScrVMInfo vmI;
method ScrVMInfo pccCheck;
return ScrVMInfo {
top: truncate(getTop(pcc_reg)),
base: truncate(getBase(pcc_reg)),
perms: getHardPerms(pcc_reg)
top: truncate(getTop(pcc_reg[0])),
base: truncate(getBase(pcc_reg[0])),
perms: getHardPerms(pcc_reg[0])
};
endmethod
method ScrVMInfo vmD;
method ScrVMInfo ddcCheck;
// for load/store, need to consider MPRV
return ScrVMInfo {
top: truncate(getTop(pcc_reg)),
base: truncate(getBase(pcc_reg)),
perms: getHardPerms(pcc_reg)
top: truncate(getTop(ddc_reg)),
base: truncate(getBase(ddc_reg)),
perms: getHardPerms(ddc_reg)
};
endmethod
method ScrDecodeInfo decodeInfo =
ScrDecodeInfo{cap_mode: getFlags(pcc_reg)==1'b1};
ScrDecodeInfo{cap_mode: getFlags(pcc_reg[0])==1'b1};
endmodule

View File

@@ -41,6 +41,9 @@ import ScrFile::*;
import StoreBuffer::*;
import VerificationPacket::*;
import RenameDebugIF::*;
import CHERICap::*;
import CHERICC_Fat::*;
import ISA_Decls_CHERI::*;
`ifdef RVFI
import RVFI_DII_Types::*;
@@ -156,7 +159,7 @@ typedef struct {
`ifdef RVFI_DII
ToReorderBuffer x;
`endif
} CommitTrap deriving(Bits, Eq, FShow);
} CommitTrap deriving(Bits, FShow);
`ifdef RVFI
function Bool is_16b_inst (Bit #(n) inst);
@@ -168,7 +171,7 @@ typedef struct {
Data mepc;
Data stvec;
Data mtvec;
} TraceStateBundle deriving(Bits, Eq, FShow);
} TraceStateBundle deriving(Bits, FShow);
function Maybe#(RVFI_DII_Execution#(DataSz,DataSz)) genRVFI(ToReorderBuffer rot, Dii_Id traceCnt, TraceStateBundle tsb, Data next_pc);
Addr addr = 0;
@@ -186,7 +189,7 @@ function Maybe#(RVFI_DII_Execution#(DataSz,DataSz)) genRVFI(ToReorderBuffer rot,
endcase
case (rot.ppc_vaddr_csrData) matches
tagged VAddr .vaddr: begin
addr = vaddr;
addr = getAddr(vaddr);
case (rot.lsqTag) matches
tagged Ld .l: rmask = rot.traceBundle.memByteEn;
tagged St .s: begin
@@ -195,7 +198,7 @@ function Maybe#(RVFI_DII_Execution#(DataSz,DataSz)) genRVFI(ToReorderBuffer rot,
end
endcase
end
tagged PPC .ppc: next_pc = ppc;
tagged PPC .ppc: next_pc = getAddr(ppc);
tagged CSRData .csrdata: data = csrdata;
endcase
end
@@ -623,7 +626,7 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
vaddr = x.tval;
end
else if(x.ppc_vaddr_csrData matches tagged VAddr .va) begin
vaddr = va;
vaddr = getAddr(va);
end
let commitTrap_val = Valid (CommitTrap {
trap: trap,
@@ -872,7 +875,7 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
end
// redirect (Sret and Mret redirect pc is got from CSRF)
Addr next_pc = x.ppc_vaddr_csrData matches tagged PPC .ppc ? ppc : (x.pc + 4);
Addr next_pc = x.ppc_vaddr_csrData matches tagged PPC .ppc ? getAddr(ppc) : (x.pc + 4);
doAssert(next_pc == x.pc + 4, "ppc must be pc + 4");
`ifdef INCLUDE_TANDEM_VERIF
Maybe #(RET_Updates) m_ret_updates = no_ret_updates;
@@ -1083,6 +1086,9 @@ module mkCommitStage#(CommitInput inIfc)(CommitStage);
regRenamingTable.commit[i].commit;
doAssert(x.claimed_phy_reg, "should have renamed");
if (x.ppc_vaddr_csrData matches tagged PPC .ppc)
scaprf.pccWr[i].put(cast(ppc));
`ifdef RENAME_DEBUG
// send debug msg for rename error
if(!x.claimed_phy_reg && !isValid(renameError)) begin

View File

@@ -49,6 +49,9 @@ import ReservationStationAlu::*;
import ReservationStationMem::*;
import ReservationStationFpuMulDiv::*;
import SplitLSQ::*;
import CHERICap::*;
import CHERICC_Fat::*;
import ISA_Decls_CHERI::*;
import Cur_Cycle :: *;
@@ -363,7 +366,7 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
trap: firstTrap,
tval: tval,
// default values of FullResult
ppc_vaddr_csrData: PPC (ppc), // default use PPC
ppc_vaddr_csrData: PPC (setAddr(almightyCap, pc).value), // default use PPC
fflags: 0,
////////
will_dirty_fpu_state: False,
@@ -561,7 +564,7 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
trap: Invalid, // no trap
tval: 0,
// default values of FullResult
ppc_vaddr_csrData: PPC (ppc), // default use PPC
ppc_vaddr_csrData: PPC (setAddr(almightyCap, ppc).value), // default use PPC
fflags: 0,
////////
will_dirty_fpu_state: will_dirty_fpu_state,
@@ -1102,7 +1105,7 @@ module mkRenameStage#(RenameInput inIfc)(RenameStage);
trap: Invalid, // no trap
tval: 0,
// default values of FullResult
ppc_vaddr_csrData: PPC (ppc), // default use PPC
ppc_vaddr_csrData: PPC (setAddr(almightyCap, ppc).value), // default use PPC
fflags: 0,
////////
will_dirty_fpu_state: will_dirty_fpu_state,

View File

@@ -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
@@ -33,6 +33,8 @@ import RevertingVirtualReg::*;
`ifdef RVFI_DII
import RVFI_DII_Types::*;
`endif
import CHERICap::*;
import CHERICC_Fat::*;
import Cur_Cycle :: *;
@@ -44,10 +46,10 @@ import Cur_Cycle :: *;
// csrData is only used by iType = Csr
// vaddr is only used by mem inst in page fault
typedef union tagged {
Addr PPC; // at default store ppc
Addr VAddr; // for mem inst, store vaddr
CapPipe PPC; // at default store ppc
CapPipe VAddr; // for mem inst, store vaddr
Data CSRData; // for Csr inst, store csr_data
} PPCVAddrCSRData deriving(Bits, Eq, FShow);
} PPCVAddrCSRData deriving(Bits, FShow);
`ifdef RVFI
typedef struct {
@@ -100,7 +102,7 @@ typedef struct {
`ifdef RVFI
ExtraTraceBundle traceBundle;
`endif
} ToReorderBuffer deriving(Bits, Eq, FShow);
} ToReorderBuffer deriving(Bits, FShow);
typedef enum {
NotDone,
@@ -253,7 +255,7 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
Wire#(Addr) predPcWire <- mkBypassWire;
(* fire_when_enabled, no_implicit_conditions *)
rule setPcWires;
predPcWire <= ppc_vaddr_csrData[0] matches tagged PPC .a ? a : 0;
predPcWire <= ppc_vaddr_csrData[0] matches tagged PPC .a ? getAddr(a) : 0;
endrule
Vector#(aluExeNum, Row_setExecuted_doFinishAlu) aluSetExe;
@@ -277,7 +279,7 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
ppc_vaddr_csrData[pvc_finishAlu_port(i)] <= CSRData (d);
end
else begin
ppc_vaddr_csrData[pvc_finishAlu_port(i)] <= PPC (cf.nextPc);
ppc_vaddr_csrData[pvc_finishAlu_port(i)] <= PPC (setAddr(almightyCap, cf.nextPc).value);
end
`ifdef RVFI
//$display("%t : traceBundle = ", $time(), fshow(tb), " in Row_setExecuted_doFinishAlu for %x", pc);
@@ -287,13 +289,13 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
endmethod
endinterface);
end
Vector#(fpuMulDivExeNum, Row_setExecuted_doFinishFpuMulDiv) fpuMulDivExe;
for(Integer i = 0; i < valueof(fpuMulDivExeNum); i = i+1) begin
fpuMulDivExe[i] = (interface Row_setExecuted_doFinishFpuMulDiv;
method Action set(Data dst_data, Bit#(5) new_fflags);
// inst is done
rob_inst_state[state_finishFpuMulDiv_port(i)] <= Executed;
rob_inst_state[state_finishFpuMulDiv_port(i)] <= Executed;
rg_dst_data <= dst_data;
// update fflags
fflags[fflags_finishFpuMulDiv_port(i)] <= new_fflags;
@@ -324,7 +326,7 @@ module mkReorderBufferRowEhr(ReorderBufferRowEhr#(aluExeNum, fpuMulDivExeNum)) p
doAssert(iType == St, "must be St");
end
// update VAddr
ppc_vaddr_csrData[pvc_finishMem_port] <= VAddr (vaddr);
ppc_vaddr_csrData[pvc_finishMem_port] <= VAddr (setAddr(almightyCap, vaddr).value);
`ifdef RVFI
//$display("%t : traceBundle = ", $time(), fshow(tb), " in setExecuted_doFinishMem for %x", pc);
traceBundle[pvc_finishMem_port] <= tb;
@@ -551,7 +553,7 @@ interface SupReorderBuffer#(numeric type aluExeNum, numeric type fpuMulDivExeNum
interface Vector#(SupSize, ROB_DeqPort) deqPort;
// record that we have notified LSQ about inst reaching commit
// record that we have notified LSQ about inst reaching commit
method Action setLSQAtCommitNotified(InstTag x);
// deqLSQ rules set ROB state
method Action setExecuted_deqLSQ(InstTag x, Maybe#(Exception) cause, Maybe#(LdKilledBy) ld_killed