Files
Toooba/src_Core/ISA/ISA_Decls_CHERI.bsv
Jessica Clarke 7eff218288 Replace enums-for-constants with structs wrapping a plain Bit#(n)
BSC does not play nicely with enums whose labels do not start at 0 and
increase linearly. Instead, in such cases, it generates a whole bunch of
conditions to "legalise" any read values, which causes an explosion of
logic in places like the ROB. Thus, use this ugly (but still typed)
alternative that, other than naming conventions enforced by BSC, looks
almost the same as an enum.
2020-07-15 03:16:24 +01:00

236 lines
7.3 KiB
Plaintext
Executable File

/*
* Copyright (c) 2020 Peter Rugg
* 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.
* This work was supported by NCSC programme grant 4212611/RFA 15971 ("SafeBet").
*
* @BERI_LICENSE_HEADER_START@
*
* Licensed to BERI Open Systems C.I.C. (BERI) under one or more contributor
* license agreements. See the NOTICE file distributed with this work for
* additional information regarding copyright ownership. BERI licenses this
* file to you under the BERI Hardware-Software License, Version 1.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
*
* http://www.beri-open-systems.org/legal/license-1-0.txt
*
* Unless required by applicable law or agreed to in writing, Work distributed
* under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
* CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*
* @BERI_LICENSE_HEADER_END@
*/
import ISA_Decls::*;
import CHERICap::*;
import CHERICC_Fat::*;
typedef TMul#(XLEN, 2) CLEN;
// Exception codes
typedef struct { Bit#(5) code; } CHERIException deriving(Bits, Eq);
`define CHERIException(n, v) CHERIException cheriExc``n = CHERIException { code: v };
`include "CHERIExceptions.bsvi"
`undef CHERIException
instance FShow#(CHERIException);
function Fmt fshow(CHERIException exc);
return (case(exc.code)
`define CHERIException(n, v) v: $format(`"``cheriExc``n```");
`include "CHERIExceptions.bsvi"
`undef CHERIException
default: $format("cheriExcUnknown");
endcase);
endfunction
endinstance
typedef struct {
Bit #(6) cheri_exc_reg;
CHERIException cheri_exc_code;
} CSR_XCapCause deriving(Bits, Eq, FShow);
CSR_XCapCause noCapCause = CSR_XCapCause {cheri_exc_code: cheriExcNone,
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
function Reg#(Bit#(64)) csr_capcause(Reg#(CSR_XCapCause) r);
return (interface Reg;
method Bit#(64) _read = xccsr_to_word(r._read);
method Action _write(Bit#(64) x) =
r._write(CSR_XCapCause{cheri_exc_reg: x[15:10], cheri_exc_code: unpack(x[9:5]) });
endinterface);
endfunction
// SCR map
typedef struct { Bit#(5) addr; } SCR deriving(Bits, Eq);
`define SCR(n, v) SCR scrAddr``n = SCR { addr: v };
`include "SCRs.bsvi"
// As with CSRs, SCR that catches all unimplemented SCRs
`SCR(None, 5'd10)
`undef SCR
instance FShow#(SCR);
function Fmt fshow(SCR scr);
return (case(scr.addr)
`define SCR(n, v) v: $format(`"``scrAddr``n```");
`include "SCRs.bsvi"
`undef SCR
default: $format("scrAddrNone");
endcase);
endfunction
endinstance
function SCR unpackSCR(Bit#(5) addr);
return (case(addr)
`define SCR(n, v) v: scrAddr``n;
`include "SCRs.bsvi"
`undef SCR
default: scrAddrNone;
endcase);
endfunction
function CapPipe update_scr_via_csr (CapPipe old_scr, WordXL new_csr, Bool allow_sealed);
let new_scr = setOffset(old_scr, new_csr);
let ret = new_scr.value;
if (!new_scr.exact || (getKind(old_scr) != UNSEALED && !allow_sealed)) begin
ret = setValidCap(ret, False);
end
return ret;
endfunction
RegName cCallRD = 31;
// Instruction field encodings
// Top-level opcodes
Opcode op_cap_Manip = 7'h5b;
//Opcode op_cap_Mem = 7'h0b; // Not yet implemented
// ================================================================
// op_cap_Manip opcode subdivision
// f3 selects between immediate and 3-reg instructions
Bit #(3) f3_cap_ThreeOp = 3'h0;
Bit #(3) f3_cap_CIncOffsetImmediate = 3'h1;
Bit #(3) f3_cap_CSetBoundsImmediate = 3'h2;
// 3'h3-3'h7 unused
// ================================================================
// op_cap_ThreeOp opcode subdivision
// f7 selects between 3-reg operations
// 7'h00 unused
Bit #(7) f7_cap_CSpecialRW = 7'h01;
// 7'h02-7'h07 unused
Bit #(7) f7_cap_CSetBounds = 7'h08;
Bit #(7) f7_cap_CSetBoundsExact = 7'h09;
// 7'h0a unused
Bit #(7) f7_cap_CSeal = 7'h0b;
Bit #(7) f7_cap_CUnseal = 7'h0c;
Bit #(7) f7_cap_CAndPerm = 7'h0d;
Bit #(7) f7_cap_CSetFlags = 7'h0e;
Bit #(7) f7_cap_CSetOffset = 7'h0f;
Bit #(7) f7_cap_CSetAddr = 7'h10;
Bit #(7) f7_cap_CIncOffset = 7'h11;
Bit #(7) f7_cap_CToPtr = 7'h12;
Bit #(7) f7_cap_CFromPtr = 7'h13;
Bit #(7) f7_cap_CSub = 7'h14;
// 7'h15-7'h1c unused
Bit #(7) f7_cap_CBuildCap = 7'h1d;
Bit #(7) f7_cap_CCopyType = 7'h1e;
Bit #(7) f7_cap_CCSeal = 7'h1f;
Bit #(7) f7_cap_CTestSubset = 7'h20;
// 7'h21-7'hfb unused
Bit #(7) f7_cap_Stores = 7'h7c;
Bit #(7) f7_cap_Loads = 7'h7d;
Bit #(7) f7_cap_TwoSrc = 7'h7e;
Bit #(7) f7_cap_TwoOp = 7'h7f;
// ================================================================
// f7_cap_TwoSrc opcode subdivision
// rd selects between 2-reg operations
// 5'h00 unused
Bit #(5) rd_cap_CCall = 5'h01;
// 5'h02-5'h1f unused
// ================================================================
// f7_cap_TwoOp opcode subdivision
// f5rs2 selects between 2-reg operations (f5rs2 instead of f5 because f5
// is already used in RISC-V and is in a different position
Bit #(5) f5rs2_cap_CGetPerm = 5'h00;
Bit #(5) f5rs2_cap_CGetType = 5'h01;
Bit #(5) f5rs2_cap_CGetBase = 5'h02;
Bit #(5) f5rs2_cap_CGetLen = 5'h03;
Bit #(5) f5rs2_cap_CGetTag = 5'h04;
Bit #(5) f5rs2_cap_CGetSealed = 5'h05;
Bit #(5) f5rs2_cap_CGetOffset = 5'h06;
Bit #(5) f5rs2_cap_CGetFlags = 5'h07;
Bit #(5) f5rs2_cap_CRRL = 5'h08;
Bit #(5) f5rs2_cap_CRAM = 5'h09;
Bit #(5) f5rs2_cap_CMove = 5'h0a;
Bit #(5) f5rs2_cap_CClearTag = 5'h0b;
Bit #(5) f5rs2_cap_CJALR = 5'h0c;
Bit #(5) f5rs2_cap_CClearReg = 5'h0d;
// 5'h0e unused
Bit #(5) f5rs2_cap_CGetAddr = 5'h0f;
Bit #(5) f5rs2_cap_CClearFPReg = 5'h10;
Bit #(5) f5rs2_cap_CSealEntry = 5'h11;
// 5'h12-5'h1f unused (5'h1f reserved for 1-reg instructions
// ================================================================
// f7_cap_{Load, Store} opcode subdivision
MemReqSize cap_mem_SIZE_B = 'h0;
MemReqSize cap_mem_SIZE_H = 'h1;
MemReqSize cap_mem_SIZE_W = 'h2;
MemReqSize cap_mem_SIZE_D = 'h3;
//MemReqSize f5rs2_cap_mem_SIZE_Q = 'h4; //TODO
Bit #(1) cap_mem_ddc = 1'h0;
Bit #(1) cap_mem_cap = 1'h1;
Bit #(1) cap_mem_unsigned = 1'h1;
Bit #(1) cap_mem_signed = 1'h0;
// ================================================================
// Other:
// Region in MISC_MEM for LQ
Bit #(3) f3_LQ = 3'h2;
Bit #(3) f3_SQ = 3'b100;
`ifdef RV64
Bit #(3) w_SIZE_CAP = f3_SQ;
Bit #(3) w_SIZE_MAX = f3_SQ;
`else //RV32
Bit #(3) w_SIZE_CAP = f3_SD;
Bit #(3) w_SIZE_MAX = f3_SD;
`endif
Bit #(3) f3_AMO_CAP = w_SIZE_CAP;
// Special cases of Otypes that are extended to XLEN
Bit #(XLEN) otype_unsealed_ext = -1;
Bit #(XLEN) otype_sentry_ext = -2;
Bit #(XLEN) otype_res0_ext = -3;
Bit #(XLEN) otype_res1_ext = -4;