Skip to content

Commit 399cdfa

Browse files
committed
Add Smctr, Ssctr, Smcsrind, Sscsrind, Smstateen
1 parent 8ecd4c9 commit 399cdfa

18 files changed

+823
-2
lines changed

Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ SAIL_DEFAULT_INST += riscv_insts_fext.sail riscv_insts_cfext.sail
2828
SAIL_DEFAULT_INST += riscv_insts_dext.sail riscv_insts_cdext.sail
2929

3030
SAIL_DEFAULT_INST += riscv_insts_svinval.sail
31+
SAIL_DEFAULT_INST += riscv_insts_ctr.sail
3132

3233
SAIL_DEFAULT_INST += riscv_insts_zba.sail
3334
SAIL_DEFAULT_INST += riscv_insts_zbb.sail
@@ -68,6 +69,7 @@ SAIL_RMEM_INST_SRCS = riscv_insts_begin.sail $(SAIL_RMEM_INST) riscv_insts_end.s
6869
SAIL_SYS_SRCS = riscv_csr_map.sail
6970
SAIL_SYS_SRCS += riscv_vext_control.sail # helpers for the 'V' extension
7071
SAIL_SYS_SRCS += riscv_next_regs.sail
72+
SAIL_SYS_SRCS += riscv_ctr_regs.sail
7173
SAIL_SYS_SRCS += riscv_sys_exceptions.sail # default basic helpers for exception handling
7274
SAIL_SYS_SRCS += riscv_sync_exception.sail # define the exception structure used in the model
7375
SAIL_SYS_SRCS += riscv_next_control.sail # helpers for the 'N' extension

c_emulator/riscv_platform.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,18 @@ bool sys_enable_writable_misa(unit u)
7171
{
7272
return rv_enable_writable_misa;
7373
}
74-
74+
uint64_t sys_valid_ctr_depth(unit u)
75+
{
76+
return rv_valid_ctr_depth;
77+
}
78+
bool sys_enable_ssctr(unit u)
79+
{
80+
return rv_enable_ssctr;
81+
}
82+
bool sys_enable_smctr(unit u)
83+
{
84+
return rv_enable_smctr;
85+
}
7586
bool plat_enable_dirty_update(unit u)
7687
{
7788
return rv_enable_dirty_update;

c_emulator/riscv_platform.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ bool sys_enable_writable_misa(unit);
1111
bool sys_enable_writable_fiom(unit);
1212
bool sys_enable_vext(unit);
1313

14+
uint64_t sys_valid_ctr_depth(unit u);
15+
bool sys_enable_ssctr(unit u);
16+
bool sys_enable_smctr(unit u);
17+
1418
uint64_t sys_pmp_count(unit);
1519
uint64_t sys_pmp_grain(unit);
1620

c_emulator/riscv_platform_impl.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
uint64_t rv_pmp_count = 0;
77
uint64_t rv_pmp_grain = 0;
88

9+
uint64_t rv_valid_ctr_depth = 0x1F;
10+
bool rv_enable_smctr = true;
11+
bool rv_enable_ssctr = true;
12+
913
bool rv_enable_svinval = false;
1014
bool rv_enable_zcb = false;
1115
bool rv_enable_zfinx = false;

c_emulator/riscv_platform_impl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
extern uint64_t rv_pmp_count;
1212
extern uint64_t rv_pmp_grain;
1313

14+
extern uint64_t rv_valid_ctr_depth;
15+
extern bool rv_enable_smctr;
16+
extern bool rv_enable_ssctr;
17+
1418
extern bool rv_enable_svinval;
1519
extern bool rv_enable_zcb;
1620
extern bool rv_enable_zfinx;

c_emulator/riscv_sim.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ const char *RV32ISA = "RV32IMAC";
5454
#define OPT_PMP_COUNT 1002
5555
#define OPT_PMP_GRAIN 1003
5656
#define OPT_ENABLE_SVINVAL 1004
57+
#define OPT_ENABLE_SMCTR 1005
58+
#define OPT_ENABLE_SSCTR 1006
59+
#define OPT_VALID_CTR_DEPTH 1007
5760
#define OPT_ENABLE_ZCB 10014
5861

5962
static bool do_dump_dts = false;
@@ -149,6 +152,9 @@ static struct option options[] = {
149152
{"enable-writable-fiom", no_argument, 0, OPT_ENABLE_WRITABLE_FIOM},
150153
{"enable-svinval", no_argument, 0, OPT_ENABLE_SVINVAL },
151154
{"enable-zcb", no_argument, 0, OPT_ENABLE_ZCB },
155+
{"valid-ctr-depth", required_argument, 0, OPT_VALID_CTR_DEPTH },
156+
{"enable-smctr", no_argument, 0, OPT_ENABLE_SMCTR },
157+
{"enable-ssctr", no_argument, 0, OPT_ENABLE_SSCTR },
152158
#ifdef SAILCOV
153159
{"sailcov-file", required_argument, 0, 'c' },
154160
#endif
@@ -245,6 +251,8 @@ static int process_args(int argc, char **argv)
245251
uint64_t ram_size = 0;
246252
uint64_t pmp_count = 0;
247253
uint64_t pmp_grain = 0;
254+
uint64_t valid_ctr_depth = 0;
255+
248256
while (true) {
249257
c = getopt_long(argc, argv,
250258
"a"
@@ -394,6 +402,22 @@ static int process_args(int argc, char **argv)
394402
fprintf(stderr, "enabling Zcb extension.\n");
395403
rv_enable_zcb = true;
396404
break;
405+
case OPT_ENABLE_SMCTR:
406+
fprintf(stderr, "enabling Smctr extension.\n");
407+
rv_enable_smctr = true;
408+
break;
409+
case OPT_ENABLE_SSCTR:
410+
fprintf(stderr, "enabling Ssctr extension.\n");
411+
rv_enable_ssctr = true;
412+
break;
413+
case OPT_VALID_CTR_DEPTH:
414+
rv_valid_ctr_depth = atol(optarg);
415+
fprintf(stderr, "Valid CTR depth: %" PRIu64 "\n", rv_valid_ctr_depth);
416+
if (rv_valid_ctr_depth > 0x1F) {
417+
fprintf(stderr, "invalid CTR depth");
418+
exit(1);
419+
}
420+
break;
397421
case 'x':
398422
fprintf(stderr, "enabling Zfinx support.\n");
399423
rv_enable_zfinx = true;

model/riscv_csr_map.sail

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,22 @@ mapping clause csr_name_map = 0x141 <-> "sepc"
4949
mapping clause csr_name_map = 0x142 <-> "scause"
5050
mapping clause csr_name_map = 0x143 <-> "stval"
5151
mapping clause csr_name_map = 0x144 <-> "sip"
52+
/* Supervisor Control Transfer Records Control Register */
53+
mapping clause csr_name_map = 0x14E <-> "sctrctl"
54+
/* Supervisor Control Transfer Records Status Register */
55+
mapping clause csr_name_map = 0x14F <-> "sctrstatus"
5256
/* supervisor protection and translation */
5357
mapping clause csr_name_map = 0x180 <-> "satp"
58+
/* supervisor indirect register select and alias CSRs */
59+
mapping clause csr_name_map = 0x150 <-> "siselect"
60+
mapping clause csr_name_map = 0x151 <-> "sireg"
61+
mapping clause csr_name_map = 0x152 <-> "sireg2"
62+
mapping clause csr_name_map = 0x153 <-> "sireg3"
63+
mapping clause csr_name_map = 0x155 <-> "sireg4"
64+
mapping clause csr_name_map = 0x156 <-> "sireg5"
65+
mapping clause csr_name_map = 0x157 <-> "sireg6"
66+
/* Supervisor Control Transfer Records Depth Register */
67+
mapping clause csr_name_map = 0x15F <-> "sctrdepth"
5468
/* supervisor envcfg */
5569
mapping clause csr_name_map = 0x10A <-> "senvcfg"
5670
/* machine information registers */
@@ -70,12 +84,25 @@ mapping clause csr_name_map = 0x306 <-> "mcounteren"
7084
mapping clause csr_name_map = 0x320 <-> "mcountinhibit"
7185
/* machine envcfg */
7286
mapping clause csr_name_map = 0x30A <-> "menvcfg"
87+
/* Smstateen csrs */
88+
mapping clause csr_name_map = 0x30C <-> "mstateen0"
89+
mapping clause csr_name_map = 0x31C <-> "mstateen0h"
7390
/* machine trap handling */
7491
mapping clause csr_name_map = 0x340 <-> "mscratch"
7592
mapping clause csr_name_map = 0x341 <-> "mepc"
7693
mapping clause csr_name_map = 0x342 <-> "mcause"
7794
mapping clause csr_name_map = 0x343 <-> "mtval"
7895
mapping clause csr_name_map = 0x344 <-> "mip"
96+
/* Machine Control Transfer Records Control Register */
97+
mapping clause csr_name_map = 0x34E <-> "mctrctl"
98+
/* Machine indirect register select and alias CSRs */
99+
mapping clause csr_name_map = 0x350 <-> "miselect"
100+
mapping clause csr_name_map = 0x351 <-> "mireg"
101+
mapping clause csr_name_map = 0x352 <-> "mireg2"
102+
mapping clause csr_name_map = 0x353 <-> "mireg3"
103+
mapping clause csr_name_map = 0x355 <-> "mireg4"
104+
mapping clause csr_name_map = 0x356 <-> "mireg5"
105+
mapping clause csr_name_map = 0x357 <-> "mireg6"
79106
/* machine protection and translation */
80107
mapping clause csr_name_map = 0x3A0 <-> "pmpcfg0"
81108
mapping clause csr_name_map = 0x3A1 <-> "pmpcfg1"

model/riscv_ctr_regs.sail

Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
/*=======================================================================================*/
2+
/* This Sail RISC-V architecture model, comprising all files and */
3+
/* directories except where otherwise noted is subject the BSD */
4+
/* two-clause license in the LICENSE file. */
5+
/* */
6+
/* SPDX-License-Identifier: BSD-2-Clause */
7+
/*=======================================================================================*/
8+
9+
/* Support CTR depths - if bit n is set then CTR depth 2^n is supported */
10+
val sys_valid_ctr_depth = {c: "sys_valid_ctr_depth", ocaml: "Platform.valid_ctr_depth", _: "sys_valid_ctr_depth"} : unit -> bits(64)
11+
12+
/* Architectural state for the Ssctr and Smctr standard extension. */
13+
bitfield Mctrctl : bits(64) = {
14+
DIRLJMPINH : 47,
15+
INDLJMPINH : 46,
16+
RETINH : 45,
17+
CORSWAPINH : 44,
18+
DIRJMPINH : 43,
19+
INDJMPINH : 42,
20+
DIRCALLINH : 41,
21+
INDCALLINH : 40,
22+
TKBRINH : 37,
23+
NTBREN : 36,
24+
TRETINH : 35,
25+
INTRINH : 34,
26+
EXCINH : 33,
27+
28+
LCOFIFRZ : 12,
29+
BPFRZ : 11,
30+
31+
MTE : 9,
32+
STE : 8,
33+
34+
RASEMU : 7,
35+
36+
M : 2,
37+
S : 1,
38+
U : 0
39+
}
40+
bitfield Sctrctl : bits(64) = {
41+
DIRLJMPINH : 47,
42+
INDLJMPINH : 46,
43+
RETINH : 45,
44+
CORSWAPINH : 44,
45+
DIRJMPINH : 43,
46+
INDJMPINH : 42,
47+
DIRCALLINH : 41,
48+
INDCALLINH : 40,
49+
TKBRINH : 37,
50+
NTBREN : 36,
51+
TRETINH : 35,
52+
INTRINH : 34,
53+
EXCINH : 33,
54+
55+
LCOFIFRZ : 12,
56+
BPFRZ : 11,
57+
58+
STE : 8,
59+
60+
RASEMU : 7,
61+
62+
S : 1,
63+
U : 0
64+
}
65+
bitfield Sctrdepth : bits(32) = {
66+
DEPTH : 2 .. 0
67+
}
68+
bitfield Sctrstatus : bits(32) = {
69+
FROZEN : 31,
70+
WRPTR : 7 .. 0
71+
}
72+
bitfield Ctrsource : xlenbits = {
73+
PC : xlen - 1 .. 1,
74+
V : 0
75+
}
76+
bitfield Ctrtarget : xlenbits = {
77+
PC : xlen - 1 .. 1,
78+
MISP : 0
79+
}
80+
bitfield Ctrdata : bits(64) = {
81+
CCE : 31 .. 28,
82+
CCM : 27 .. 16,
83+
CCV : 15,
84+
TYPE : 3 .. 0
85+
}
86+
87+
register sctrstatus : Sctrstatus
88+
register sctrdepth : Sctrdepth
89+
register mctrctl : Mctrctl
90+
register ctrsource : vector(256, dec, Ctrsource)
91+
register ctrtarget : vector(256, dec, Ctrtarget)
92+
register ctrdata : vector(256, dec, Ctrdata)
93+
/* Should parameterize the cycle counter to support wider counters */
94+
register ctr_cycle_counter : bits(13)
95+
register ctr_cycle_counter_valid : bool
96+
97+
function legalize_mctrctl(o : Mctrctl, v : xlenbits) -> Mctrctl = {
98+
let m : Mctrctl = Mk_Mctrctl(zero_extend(v));
99+
m
100+
}
101+
102+
function lower_sctrctl(m : Mctrctl) -> Sctrctl = {
103+
let s = Mk_Sctrctl(m.bits);
104+
s
105+
}
106+
107+
function legalize_sctrctl(m : Mctrctl, v : xlenbits) -> Mctrctl = {
108+
let o = Mk_Mctrctl(zero_extend(v));
109+
let o = [o with M = m[M], MTE = m[MTE]];
110+
o
111+
}
112+
113+
114+
function get_wrptr_mask(d : Sctrdepth) -> bits(8) =
115+
match(d[DEPTH]) {
116+
0b000 => 0b00001111,
117+
0b001 => 0b00011111,
118+
0b010 => 0b00111111,
119+
0b011 => 0b01111111,
120+
0b100 => 0b11111111,
121+
_ => internal_error(__FILE__, __LINE__, "Unexpected DEPTH encoding")
122+
}
123+
124+
function legalize_sctrdepth(s : Sctrdepth, v : xlenbits) -> Sctrdepth = {
125+
let valid_ctr_depth : bits(64) = sys_valid_ctr_depth();
126+
let depth : bits(3) = match(v[2 .. 0]) {
127+
0b000 => if bit_to_bool(valid_ctr_depth[0]) then v[2 .. 0] else s[DEPTH],
128+
0b001 => if bit_to_bool(valid_ctr_depth[1]) then v[2 .. 0] else s[DEPTH],
129+
0b010 => if bit_to_bool(valid_ctr_depth[2]) then v[2 .. 0] else s[DEPTH],
130+
0b011 => if bit_to_bool(valid_ctr_depth[3]) then v[2 .. 0] else s[DEPTH],
131+
0b100 => if bit_to_bool(valid_ctr_depth[4]) then v[2 .. 0] else s[DEPTH],
132+
_ => s[DEPTH]
133+
};
134+
let o = Mk_Sctrdepth(zero_extend(depth));
135+
136+
/* On depth change WRPTR assumes an unspecified but legal value */
137+
sctrstatus[WRPTR] = sctrstatus[WRPTR] & get_wrptr_mask(o);
138+
139+
o
140+
}
141+
function legalize_sctrstatus(s : Sctrstatus, v : xlenbits) -> Sctrstatus = {
142+
let wrptr_mask : bits(8) = get_wrptr_mask(sctrdepth);
143+
let o = Mk_Sctrstatus(zeros());
144+
let o = [o with WRPTR = (v[7 .. 0] & wrptr_mask), FROZEN = v[31 .. 31]];
145+
o
146+
}
147+
function number_of_ctr() -> int = {
148+
let valid_ctr_depth : bits(64) = sys_valid_ctr_depth();
149+
let num = if bit_to_bool(valid_ctr_depth[0]) then 16 else 0;
150+
let num = if bit_to_bool(valid_ctr_depth[1]) then 32 else num;
151+
let num = if bit_to_bool(valid_ctr_depth[2]) then 64 else num;
152+
let num = if bit_to_bool(valid_ctr_depth[3]) then 128 else num;
153+
let num = if bit_to_bool(valid_ctr_depth[4]) then 256 else num;
154+
num
155+
}
156+
function isValidCtrMiselect() -> bool = {
157+
let ctr_select = miselect.bits[7 .. 0];
158+
haveSmctr() & (unsigned(ctr_select) < number_of_ctr())
159+
}
160+
function isValidCtrSiselect() -> bool = {
161+
let ctr_select = siselect.bits[7 .. 0];
162+
haveSsctr() & (unsigned(ctr_select) < number_of_ctr())
163+
}
164+
/* Logical entry N, selected by *iselect value of (0x200 | N), is
165+
* physically at ((WRPTR - N - 1) % depth) where depth = 2^(DEPTH+4)
166+
*/
167+
function get_ctr_idx(iselect : SMiselect) -> bits(8) = {
168+
let ctr_idx = sctrstatus[WRPTR] - iselect.bits[7 .. 0] - 1;
169+
ctr_idx & get_wrptr_mask(sctrdepth);
170+
}
171+
172+
function get_ctr_mireg() -> xlenbits =
173+
ctrsource[unsigned(get_ctr_idx(miselect))].bits
174+
175+
function get_ctr_mireg2() -> xlenbits =
176+
ctrtarget[unsigned(get_ctr_idx(miselect))].bits
177+
178+
function get_ctr_mireg3() -> xlenbits =
179+
ctrdata[unsigned(get_ctr_idx(miselect))].bits
180+
181+
function set_ctr_mireg(v: xlenbits) -> unit =
182+
ctrsource[unsigned(get_ctr_idx(miselect))] = Mk_Ctrsource(v)
183+
184+
function set_ctr_mireg2(v: xlenbits) -> unit =
185+
ctrtarget[unsigned(get_ctr_idx(miselect))] = Mk_Ctrtarget(v)
186+
187+
function set_ctr_mireg3(v: xlenbits) -> unit =
188+
ctrdata[unsigned(get_ctr_idx(miselect))] = Mk_Ctrdata(v)
189+
190+
191+
function get_ctr_sireg() -> xlenbits =
192+
ctrsource[unsigned(get_ctr_idx(siselect))].bits
193+
194+
function get_ctr_sireg2() -> xlenbits =
195+
ctrsource[unsigned(get_ctr_idx(siselect))].bits
196+
197+
function get_ctr_sireg3() -> xlenbits =
198+
ctrsource[unsigned(get_ctr_idx(siselect))].bits
199+
200+
function set_ctr_sireg(v: xlenbits) -> unit =
201+
ctrsource[unsigned(get_ctr_idx(siselect))] = Mk_Ctrsource(v)
202+
203+
function set_ctr_sireg2(v: xlenbits) -> unit =
204+
ctrtarget[unsigned(get_ctr_idx(siselect))] = Mk_Ctrtarget(v)
205+
206+
function set_ctr_sireg3(v: xlenbits) -> unit =
207+
ctrdata[unsigned(get_ctr_idx(siselect))] = Mk_Ctrdata(v)

0 commit comments

Comments
 (0)