Skip to content

Commit

Permalink
Add Smctr, Ssctr, Smcsrind, Sscsrind, Smstateen
Browse files Browse the repository at this point in the history
  • Loading branch information
ved-rivos committed Jun 4, 2024
1 parent 8ecd4c9 commit 92cddf8
Show file tree
Hide file tree
Showing 18 changed files with 838 additions and 4 deletions.
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ SAIL_DEFAULT_INST += riscv_insts_fext.sail riscv_insts_cfext.sail
SAIL_DEFAULT_INST += riscv_insts_dext.sail riscv_insts_cdext.sail

SAIL_DEFAULT_INST += riscv_insts_svinval.sail
SAIL_DEFAULT_INST += riscv_insts_ctr.sail

SAIL_DEFAULT_INST += riscv_insts_zba.sail
SAIL_DEFAULT_INST += riscv_insts_zbb.sail
Expand Down Expand Up @@ -68,6 +69,7 @@ SAIL_RMEM_INST_SRCS = riscv_insts_begin.sail $(SAIL_RMEM_INST) riscv_insts_end.s
SAIL_SYS_SRCS = riscv_csr_map.sail
SAIL_SYS_SRCS += riscv_vext_control.sail # helpers for the 'V' extension
SAIL_SYS_SRCS += riscv_next_regs.sail
SAIL_SYS_SRCS += riscv_ctr_regs.sail
SAIL_SYS_SRCS += riscv_sys_exceptions.sail # default basic helpers for exception handling
SAIL_SYS_SRCS += riscv_sync_exception.sail # define the exception structure used in the model
SAIL_SYS_SRCS += riscv_next_control.sail # helpers for the 'N' extension
Expand Down
17 changes: 16 additions & 1 deletion c_emulator/riscv_platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,22 @@ bool sys_enable_writable_misa(unit u)
{
return rv_enable_writable_misa;
}

uint64_t sys_valid_ctr_depth(unit u)
{
return rv_valid_ctr_depth;
}
uint64_t sys_num_cce_bits(unit u)
{
return rv_num_cce_bits;
}
uint64_t sys_mctrctl_warl_mask(unit u)
{
return rv_mctrctl_warl_mask;
}
bool sys_enable_smctr(unit u)
{
return rv_enable_smctr;
}
bool plat_enable_dirty_update(unit u)
{
return rv_enable_dirty_update;
Expand Down
5 changes: 5 additions & 0 deletions c_emulator/riscv_platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ bool sys_enable_writable_misa(unit);
bool sys_enable_writable_fiom(unit);
bool sys_enable_vext(unit);

uint64_t sys_valid_ctr_depth(unit u);
uint64_t sys_num_cce_bits(unit u);
uint64_t sys_mctrctl_warl_mask(unit u);
bool sys_enable_smctr(unit u);

uint64_t sys_pmp_count(unit);
uint64_t sys_pmp_grain(unit);

Expand Down
5 changes: 5 additions & 0 deletions c_emulator/riscv_platform_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
uint64_t rv_pmp_count = 0;
uint64_t rv_pmp_grain = 0;

uint64_t rv_valid_ctr_depth = 0x1F;
uint64_t rv_num_cce_bits = 1;
uint64_t rv_mctrctl_warl_mask = -1;
bool rv_enable_smctr = true;

bool rv_enable_svinval = false;
bool rv_enable_zcb = false;
bool rv_enable_zfinx = false;
Expand Down
5 changes: 5 additions & 0 deletions c_emulator/riscv_platform_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@
extern uint64_t rv_pmp_count;
extern uint64_t rv_pmp_grain;

extern uint64_t rv_valid_ctr_depth;
extern uint64_t rv_num_cce_bits;
extern uint64_t rv_mctrctl_warl_mask;
extern bool rv_enable_smctr;

extern bool rv_enable_svinval;
extern bool rv_enable_zcb;
extern bool rv_enable_zfinx;
Expand Down
43 changes: 43 additions & 0 deletions c_emulator/riscv_sim.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ const char *RV32ISA = "RV32IMAC";
#define OPT_PMP_COUNT 1002
#define OPT_PMP_GRAIN 1003
#define OPT_ENABLE_SVINVAL 1004
#define OPT_ENABLE_SMCTR 1005
#define OPT_VALID_CTR_DEPTH 1006
#define OPT_NUM_CCE_BITS 1007
#define OPT_MCTRCTL_WARL_MASK 1008
#define OPT_ENABLE_ZCB 10014

static bool do_dump_dts = false;
Expand Down Expand Up @@ -149,6 +153,9 @@ static struct option options[] = {
{"enable-writable-fiom", no_argument, 0, OPT_ENABLE_WRITABLE_FIOM},
{"enable-svinval", no_argument, 0, OPT_ENABLE_SVINVAL },
{"enable-zcb", no_argument, 0, OPT_ENABLE_ZCB },
{"valid-ctr-depth", required_argument, 0, OPT_VALID_CTR_DEPTH },
{"num_cce-bits", required_argument, 0, OPT_NUM_CCE_BITS },
{"enable-smctr", no_argument, 0, OPT_ENABLE_SMCTR },
#ifdef SAILCOV
{"sailcov-file", required_argument, 0, 'c' },
#endif
Expand Down Expand Up @@ -245,6 +252,10 @@ static int process_args(int argc, char **argv)
uint64_t ram_size = 0;
uint64_t pmp_count = 0;
uint64_t pmp_grain = 0;
uint64_t valid_ctr_depth = 0;
uint64_t num_cce_bits = 0;
uint64_t mctrctl_warl_mask = 0;

while (true) {
c = getopt_long(argc, argv,
"a"
Expand Down Expand Up @@ -394,6 +405,38 @@ static int process_args(int argc, char **argv)
fprintf(stderr, "enabling Zcb extension.\n");
rv_enable_zcb = true;
break;
case OPT_ENABLE_SMCTR:
fprintf(stderr, "enabling Smctr extension.\n");
rv_enable_smctr = true;
break;
case OPT_VALID_CTR_DEPTH:
rv_valid_ctr_depth = atol(optarg);
fprintf(stderr, "Valid CTR depth: %" PRIu64 "\n", rv_valid_ctr_depth);
if (rv_valid_ctr_depth > 0x1F) {
fprintf(stderr, "invalid CTR depth");
exit(1);
}
break;
case OPT_NUM_CCE_BITS:
num_cce_bits = atol(optarg);
fprintf(stderr, "Num CCE bits: %" PRIu64 "\n", num_cce_bits);
if (num_cce_bits > 4) {
fprintf(stderr, "invalid number of cce bits: must be 0,1,2,3, or 4 ");
exit(1);
}
rv_num_cce_bits = num_cce_bits;
break;
case OPT_MCTRCTL_WARL_MASK:
mctrctl_warl_mask = atol(optarg);
fprintf(stderr, "mctrctl WARL mask: %" PRIu64 "\n", mctrctl_warl_mask);
if (((mctrctl_warl_mask & 0x7) == 0)
|| ((mctrctl_warl_mask & (1 << 11)) == 0)) {
fprintf(stderr,
"invalid mctrctl WARL mask - M/S/U/BPFRZ bits are mandatory");
exit(1);
}
rv_mctrctl_warl_mask = mctrctl_warl_mask;
break;
case 'x':
fprintf(stderr, "enabling Zfinx support.\n");
rv_enable_zfinx = true;
Expand Down
27 changes: 27 additions & 0 deletions model/riscv_csr_map.sail
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,22 @@ mapping clause csr_name_map = 0x141 <-> "sepc"
mapping clause csr_name_map = 0x142 <-> "scause"
mapping clause csr_name_map = 0x143 <-> "stval"
mapping clause csr_name_map = 0x144 <-> "sip"
/* Supervisor Control Transfer Records Control Register */
mapping clause csr_name_map = 0x14E <-> "sctrctl"
/* Supervisor Control Transfer Records Status Register */
mapping clause csr_name_map = 0x14F <-> "sctrstatus"
/* supervisor protection and translation */
mapping clause csr_name_map = 0x180 <-> "satp"
/* supervisor indirect register select and alias CSRs */
mapping clause csr_name_map = 0x150 <-> "siselect"
mapping clause csr_name_map = 0x151 <-> "sireg"
mapping clause csr_name_map = 0x152 <-> "sireg2"
mapping clause csr_name_map = 0x153 <-> "sireg3"
mapping clause csr_name_map = 0x155 <-> "sireg4"
mapping clause csr_name_map = 0x156 <-> "sireg5"
mapping clause csr_name_map = 0x157 <-> "sireg6"
/* Supervisor Control Transfer Records Depth Register */
mapping clause csr_name_map = 0x15F <-> "sctrdepth"
/* supervisor envcfg */
mapping clause csr_name_map = 0x10A <-> "senvcfg"
/* machine information registers */
Expand All @@ -70,12 +84,25 @@ mapping clause csr_name_map = 0x306 <-> "mcounteren"
mapping clause csr_name_map = 0x320 <-> "mcountinhibit"
/* machine envcfg */
mapping clause csr_name_map = 0x30A <-> "menvcfg"
/* Smstateen csrs */
mapping clause csr_name_map = 0x30C <-> "mstateen0"
mapping clause csr_name_map = 0x31C <-> "mstateen0h"
/* machine trap handling */
mapping clause csr_name_map = 0x340 <-> "mscratch"
mapping clause csr_name_map = 0x341 <-> "mepc"
mapping clause csr_name_map = 0x342 <-> "mcause"
mapping clause csr_name_map = 0x343 <-> "mtval"
mapping clause csr_name_map = 0x344 <-> "mip"
/* Machine Control Transfer Records Control Register */
mapping clause csr_name_map = 0x34E <-> "mctrctl"
/* Machine indirect register select and alias CSRs */
mapping clause csr_name_map = 0x350 <-> "miselect"
mapping clause csr_name_map = 0x351 <-> "mireg"
mapping clause csr_name_map = 0x352 <-> "mireg2"
mapping clause csr_name_map = 0x353 <-> "mireg3"
mapping clause csr_name_map = 0x355 <-> "mireg4"
mapping clause csr_name_map = 0x356 <-> "mireg5"
mapping clause csr_name_map = 0x357 <-> "mireg6"
/* machine protection and translation */
mapping clause csr_name_map = 0x3A0 <-> "pmpcfg0"
mapping clause csr_name_map = 0x3A1 <-> "pmpcfg1"
Expand Down
201 changes: 201 additions & 0 deletions model/riscv_ctr_regs.sail
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
/*=======================================================================================*/
/* This Sail RISC-V architecture model, comprising all files and */
/* directories except where otherwise noted is subject the BSD */
/* two-clause license in the LICENSE file. */
/* */
/* SPDX-License-Identifier: BSD-2-Clause */
/*=======================================================================================*/

/* Support CTR depths - if bit n is set then CTR depth 2^n is supported */
val sys_valid_ctr_depth = {c: "sys_valid_ctr_depth", ocaml: "Platform.valid_ctr_depth", _: "sys_valid_ctr_depth"} : unit -> bits(64)
/* Number of CCE bits - ranges from 0 to 4 */
val sys_num_cce_bits = {c: "sys_num_cce_bits", ocaml: "Platform.num_cce_bits", _: "sys_num_cce_bits"} : unit -> range(0, 4)
/* WARL mask for mctrctl - mask bit i is 1 if bit i of mctrctl is writable */
val sys_mctrctl_warl_mask = {c: "sys_mctrctl_warl_mask", ocaml: "Platform.mctrctl_warl_mask", _: "sys_mctrctl_warl_mask"} : unit -> bits(64)

/* Architectural state for the Ssctr and Smctr standard extension. */
bitfield Mctrctl : bits(64) = {
DIRLJMPINH : 47,
INDLJMPINH : 46,
RETINH : 45,
CORSWAPINH : 44,
DIRJMPINH : 43,
INDJMPINH : 42,
DIRCALLINH : 41,
INDCALLINH : 40,
TKBRINH : 37,
NTBREN : 36,
TRETINH : 35,
INTRINH : 34,
EXCINH : 33,

LCOFIFRZ : 12,
BPFRZ : 11,

MTE : 9,
STE : 8,

RASEMU : 7,

M : 2,
S : 1,
U : 0
}
bitfield Sctrctl : bits(64) = {
DIRLJMPINH : 47,
INDLJMPINH : 46,
RETINH : 45,
CORSWAPINH : 44,
DIRJMPINH : 43,
INDJMPINH : 42,
DIRCALLINH : 41,
INDCALLINH : 40,
TKBRINH : 37,
NTBREN : 36,
TRETINH : 35,
INTRINH : 34,
EXCINH : 33,

LCOFIFRZ : 12,
BPFRZ : 11,

STE : 8,

RASEMU : 7,

S : 1,
U : 0
}
bitfield Sctrdepth : bits(32) = {
DEPTH : 2 .. 0
}
bitfield Sctrstatus : bits(32) = {
FROZEN : 31,
WRPTR : 7 .. 0
}
bitfield Ctrsource : xlenbits = {
PC : xlen - 1 .. 1,
V : 0
}
bitfield Ctrtarget : xlenbits = {
PC : xlen - 1 .. 1,
MISP : 0
}
bitfield Ctrdata : bits(64) = {
CCE : 31 .. 28,
CCM : 27 .. 16,
CCV : 15,
TYPE : 3 .. 0
}

register sctrstatus : Sctrstatus
register sctrdepth : Sctrdepth
register mctrctl : Mctrctl
register ctrsource : vector(256, dec, Ctrsource)
register ctrtarget : vector(256, dec, Ctrtarget)
register ctrdata : vector(256, dec, Ctrdata)

register ctr_cycle_counter : bits(27)
register ctr_cycle_counter_valid : bool

function legalize_mctrctl(m : Mctrctl, v : xlenbits) -> Mctrctl = {
let o : Mctrctl = Mk_Mctrctl(zero_extend(v));
let o = Mk_Mctrctl(o.bits & sys_mctrctl_warl_mask());
o
}

function lower_sctrctl(m : Mctrctl) -> Sctrctl = {
let s = Mk_Sctrctl(m.bits);
s
}

function legalize_sctrctl(m : Mctrctl, v : xlenbits) -> Mctrctl = {
let o = legalize_mctrctl(m, zero_extend(v));
let o = [o with M = m[M], MTE = m[MTE]];
o
}

function get_wrptr_mask(d : Sctrdepth) -> bits(8) =
match(d[DEPTH]) {
0b000 => 0b00001111,
0b001 => 0b00011111,
0b010 => 0b00111111,
0b011 => 0b01111111,
0b100 => 0b11111111,
_ => internal_error(__FILE__, __LINE__, "Unexpected DEPTH encoding")
}

function legalize_sctrdepth(s : Sctrdepth, v : xlenbits) -> Sctrdepth = {
let valid_ctr_depth : bits(64) = sys_valid_ctr_depth();
let depth : bits(3) = match(v[2 .. 0]) {
0b000 => if bit_to_bool(valid_ctr_depth[0]) then v[2 .. 0] else s[DEPTH],
0b001 => if bit_to_bool(valid_ctr_depth[1]) then v[2 .. 0] else s[DEPTH],
0b010 => if bit_to_bool(valid_ctr_depth[2]) then v[2 .. 0] else s[DEPTH],
0b011 => if bit_to_bool(valid_ctr_depth[3]) then v[2 .. 0] else s[DEPTH],
0b100 => if bit_to_bool(valid_ctr_depth[4]) then v[2 .. 0] else s[DEPTH],
_ => s[DEPTH]
};
let o = Mk_Sctrdepth(zero_extend(depth));

/* On depth change WRPTR assumes an unspecified but legal value */
sctrstatus[WRPTR] = sctrstatus[WRPTR] & get_wrptr_mask(o);

o
}
function legalize_sctrstatus(s : Sctrstatus, v : xlenbits) -> Sctrstatus = {
let wrptr_mask : bits(8) = get_wrptr_mask(sctrdepth);
let o = Mk_Sctrstatus(zeros());
let o = [o with WRPTR = (v[7 .. 0] & wrptr_mask), FROZEN = v[31 .. 31]];
o
}
function number_of_ctr() -> int = {
let valid_ctr_depth : bits(64) = sys_valid_ctr_depth();
let num = if bit_to_bool(valid_ctr_depth[0]) then 16 else 0;
let num = if bit_to_bool(valid_ctr_depth[1]) then 32 else num;
let num = if bit_to_bool(valid_ctr_depth[2]) then 64 else num;
let num = if bit_to_bool(valid_ctr_depth[3]) then 128 else num;
let num = if bit_to_bool(valid_ctr_depth[4]) then 256 else num;
num
}
function isValidCtrSiselect() -> bool = {
let ctr_select = siselect.bits[7 .. 0];
haveSmctr() & (unsigned(ctr_select) < number_of_ctr())
}
/* Logical entry N, selected by *iselect value of (0x200 | N), is
* physically at ((WRPTR - N - 1) % depth) where depth = 2^(DEPTH+4)
*/
function get_ctr_idx(iselect : SMiselect) -> bits(8) = {
let ctr_idx = sctrstatus[WRPTR] - iselect.bits[7 .. 0] - 1;
ctr_idx & get_wrptr_mask(sctrdepth);
}

function get_ctr_sireg() -> xlenbits =
ctrsource[unsigned(get_ctr_idx(siselect))].bits

function get_ctr_sireg2() -> xlenbits =
ctrtarget[unsigned(get_ctr_idx(siselect))].bits

function get_ctr_sireg3() -> xlenbits =
if sizeof(xlen) == 32
then ctrdata[unsigned(get_ctr_idx(miselect))].bits[31 .. 0]
else ctrdata[unsigned(get_ctr_idx(miselect))].bits[63 .. 0]

function set_ctr_sireg(v: xlenbits) -> unit =
ctrsource[unsigned(get_ctr_idx(siselect))] = Mk_Ctrsource(v)

function set_ctr_sireg2(v: xlenbits) -> unit =
ctrtarget[unsigned(get_ctr_idx(siselect))] = Mk_Ctrtarget(v)

function set_ctr_sireg3(v: xlenbits) -> unit = {
let cce_mask : bits(4) = match sys_num_cce_bits() {
0 => 0b0000,
1 => 0b0001,
2 => 0b0011,
3 => 0b0111,
4 => 0b1111,
_ => internal_error(__FILE__, __LINE__, "Unexpected CCE")
};
let d : Ctrdata = Mk_Ctrdata(zero_extend(v));
let d = [d with CCE = d[CCE] & cce_mask];
ctrdata[unsigned(get_ctr_idx(siselect))] = d;
}
Loading

0 comments on commit 92cddf8

Please sign in to comment.