Files
Toooba/src_Core/CHERI/ScrFile.bsv
2020-03-27 15:55:02 +00:00

232 lines
7.1 KiB
Plaintext

// Copyright (c) 2017 Massachusetts Institute of Technology
// Portions Copyright (c) 2019-2020 Bluespec, Inc.
// CHERI modifications:
// Copyright (c) 2020 Jonathan Woodruff
// All rights reserved.
//
// This software was developed by SRI International and the University of
// Cambridge Computer Laboratory (Department of Computer Science and
// Technology) under DARPA contract HR0011-18-C-0016 ("ECATS"), as part of the
// DARPA SSITH research programme.
//
// 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
// restriction, including without limitation the rights to use, copy,
// 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
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
`include "ProcConfig.bsv"
import Types::*;
import ProcTypes::*;
import DefaultValue::*;
import ConfigReg::*;
import Ehr::*;
import GetPut::*;
import Vector::*;
import CHERICap::*;
import CHERICC_Fat::*;
import ISA_Decls_CHERI::*;
// ================================================================
// BSV additional libs
import Cur_Cycle::*;
// ================================================================
// Project imports from Toooba
import SoC_Map::*;
// ================================================================
// Information returned on traps and mret/sret/uret
typedef struct {
Bit#(0) nothing_now;
} Scr_Trap_Updates
deriving (Bits, FShow);
typedef struct {
Addr new_pc;
} Scr_RET_Updates
deriving (Bits, FShow);
typedef struct {
Addr top;
Addr base;
HardPerms perms;
} ScrVMInfo
deriving (Bits, FShow);
typedef struct {
Bool cap_mode;
} ScrDecodeInfo
deriving (Bits, FShow);
// ================================================================
interface ScrFile;
// Read
method CapReg rd(SCR 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);
// Methods for handling traps
method ActionValue#(Scr_Trap_Updates) trap(CapPipe pc, Bit#(2) prv);
method ActionValue#(Scr_RET_Updates) sret;
method ActionValue#(Scr_RET_Updates) mret;
// Outputs for CSRs that the rest of the processor needs to know about
method ScrVMInfo pccCheck;
method ScrVMInfo ddcCheck;
method ScrDecodeInfo decodeInfo;
// terminate
method ActionValue#(void) terminate;
endinterface
// same as EHR except that read port 0 is not ordered with other methods. Read
// port 1 will still get bypassing from write port 0.
module mkConfigEhr#(t init)(Ehr#(n, t)) provisos(Bits#(t, w));
Ehr#(n, t) data <- mkEhr(init);
Wire#(t) read <- mkBypassWire;
(* fire_when_enabled, no_implicit_conditions *)
rule setRead;
read <= data[0];
endrule
Ehr#(n, t) ifc = ?;
ifc[0] = (interface Reg;
method _read = read._read;
method _write = data[0]._write;
endinterface);
for(Integer i = 1; i < valueOf(n); i = i+1) begin
ifc[i] = (interface Reg;
method _read = data[i]._read;
method _write = data[i]._write;
endinterface);
end
return ifc;
endmodule
module mkScrFile (ScrFile);
RiscVISASubset isa = defaultValue;
let mkCsrReg = mkConfigReg;
let mkCsrEhr = mkConfigEhr;
// User level SCRs
Ehr#(SupSize, CapReg) pcc_reg <- mkConfigEhr(defaultValue);
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);
// System level SCRs with accessSysRegs
Reg#(CapReg) stcc_reg <- mkCsrReg(defaultValue);
Reg#(CapReg) stdc_reg <- mkCsrReg(nullCap);
Reg#(CapReg) sScratchC_reg <- mkCsrReg(nullCap);
Reg#(CapReg) sepcc_reg <- mkCsrReg(defaultValue);
// Machine level SCRs with accessSysRegs
Reg#(CapReg) mtcc_reg <- mkCsrReg(defaultValue);
Reg#(CapReg) mtdc_reg <- mkCsrReg(nullCap);
Reg#(CapReg) mScratchC_reg <- mkCsrReg(nullCap);
Ehr#(2, CapReg) mepcc_reg <- mkConfigEhr(defaultValue);
// Function for getting a csr given an index
function Reg#(CapReg) get_scr(SCR scr);
return (case (scr)
// User SCRs
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;
// System CSRs with accessSysRegs
SCR_STCC: stcc_reg;
SCR_STDC: stdc_reg;
SCR_SScratchC: sScratchC_reg;
SCR_SEPCC: sepcc_reg;
// Machine CSRs with accessSysRegs
SCR_MTCC: mtcc_reg;
SCR_MTDC: mtdc_reg;
SCR_MScratchC: mScratchC_reg;
SCR_MEPCC: mepcc_reg[1];
endcase);
endfunction
// ================================================================
// INTERFACE
method CapReg rd(SCR scr);
return get_scr(scr)._read;
endmethod
method Action scrInstWr(SCR csr, CapReg x);
get_scr(csr)._write(x);
endmethod
interface pccWr = map(toPut,pcc_reg);
method ActionValue#(Scr_Trap_Updates) trap(CapPipe pc, Bit#(2) prv);
mepcc_reg[0] <= cast(pc);
pcc_reg[0] <= mtcc_reg;
return ?;
endmethod
method ActionValue#(Scr_RET_Updates) mret;
return ?;
endmethod
method ActionValue#(Scr_RET_Updates) sret;
return ?;
endmethod
method ScrVMInfo pccCheck;
return ScrVMInfo {
top: truncate(getTop(pcc_reg[0])),
base: truncate(getBase(pcc_reg[0])),
perms: getHardPerms(pcc_reg[0])
};
endmethod
method ScrVMInfo ddcCheck;
// for load/store, need to consider MPRV
return ScrVMInfo {
top: truncate(getTop(ddc_reg)),
base: truncate(getBase(ddc_reg)),
perms: getHardPerms(ddc_reg)
};
endmethod
method ScrDecodeInfo decodeInfo =
ScrDecodeInfo{cap_mode: getFlags(pcc_reg[0])==1'b1};
endmodule