Skip to content

Commit

Permalink
Add Ssdbltrp and Smdbltrp extensions
Browse files Browse the repository at this point in the history
  • Loading branch information
ved-rivos committed Apr 14, 2024
1 parent e187e02 commit e32aff1
Show file tree
Hide file tree
Showing 13 changed files with 216 additions and 47 deletions.
10 changes: 10 additions & 0 deletions c_emulator/riscv_platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,16 @@ bool sys_enable_writable_misa(unit u)
return rv_enable_writable_misa;
}

bool sys_enable_ssdbltrp(unit u)
{
return rv_enable_ssdbltrp;
}

bool sys_enable_smdbltrp(unit u)
{
return rv_enable_smdbltrp;
}

bool plat_enable_dirty_update(unit u)
{
return rv_enable_dirty_update;
Expand Down
2 changes: 2 additions & 0 deletions c_emulator/riscv_platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ bool sys_enable_zfinx(unit);
bool sys_enable_writable_misa(unit);
bool sys_enable_writable_fiom(unit);
bool sys_enable_vext(unit);
bool sys_enable_ssdbltrp(unit);
bool sys_enable_smdbltrp(unit);

uint64_t sys_pmp_count(unit);
uint64_t sys_pmp_grain(unit);
Expand Down
2 changes: 2 additions & 0 deletions c_emulator/riscv_platform_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ bool rv_enable_next = false;
bool rv_enable_writable_misa = true;
bool rv_enable_fdext = true;
bool rv_enable_vext = true;
bool rv_enable_ssdbltrp = false;
bool rv_enable_smdbltrp = false;

bool rv_enable_dirty_update = false;
bool rv_enable_misaligned = false;
Expand Down
2 changes: 2 additions & 0 deletions c_emulator/riscv_platform_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ extern bool rv_enable_dirty_update;
extern bool rv_enable_misaligned;
extern bool rv_mtval_has_illegal_inst_bits;
extern bool rv_enable_writable_fiom;
extern bool rv_enable_ssdbltrp;
extern bool rv_enable_smdbltrp;

extern uint64_t rv_ram_base;
extern uint64_t rv_ram_size;
Expand Down
12 changes: 12 additions & 0 deletions c_emulator/riscv_sim.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ const char *RV32ISA = "RV32IMAC";
#define OPT_ENABLE_WRITABLE_FIOM 1001
#define OPT_PMP_COUNT 1002
#define OPT_PMP_GRAIN 1003
#define OPT_ENABLE_SSDBLTRP 1006
#define OPT_ENABLE_SMDBLTRP 1007

static bool do_dump_dts = false;
static bool do_show_times = false;
Expand Down Expand Up @@ -148,6 +150,8 @@ static struct option options[] = {
#ifdef SAILCOV
{"sailcov-file", required_argument, 0, 'c' },
#endif
{"enable-ssdbltrp", no_argument, 0, OPT_ENABLE_SSDBLTRP },
{"enable-smdbltrp", no_argument, 0, OPT_ENABLE_SMDBLTRP },
{0, 0, 0, 0 }
};

Expand Down Expand Up @@ -400,6 +404,14 @@ static int process_args(int argc, char **argv)
trace_log_path = optarg;
fprintf(stderr, "using %s for trace output.\n", trace_log_path);
break;
case OPT_ENABLE_SSDBLTRP:
fprintf(stderr, "enabling Ssdbltrp extension.\n");
rv_enable_ssdbltrp = true;
break;
case OPT_ENABLE_SMDBLTRP:
fprintf(stderr, "enabling Smdbltrp extension.\n");
rv_enable_smdbltrp = true;
break;
case '?':
print_usage(argv[0], 1);
break;
Expand Down
3 changes: 3 additions & 0 deletions model/riscv_csr_map.sail
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ mapping clause csr_name_map = 0xF13 <-> "mimpid"
mapping clause csr_name_map = 0xF14 <-> "mhartid"
/* machine trap setup */
mapping clause csr_name_map = 0x300 <-> "mstatus"
mapping clause csr_name_map = 0x310 <-> "mstatush"
mapping clause csr_name_map = 0x301 <-> "misa"
mapping clause csr_name_map = 0x302 <-> "medeleg"
mapping clause csr_name_map = 0x303 <-> "mideleg"
Expand All @@ -69,12 +70,14 @@ mapping clause csr_name_map = 0x306 <-> "mcounteren"
mapping clause csr_name_map = 0x320 <-> "mcountinhibit"
/* machine envcfg */
mapping clause csr_name_map = 0x30A <-> "menvcfg"
mapping clause csr_name_map = 0x31A <-> "menvcfgh"
/* 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"
mapping clause csr_name_map = 0x34B <-> "mtval2"
/* machine protection and translation */
mapping clause csr_name_map = 0x3A0 <-> "pmpcfg0"
mapping clause csr_name_map = 0x3A1 <-> "pmpcfg1"
Expand Down
4 changes: 3 additions & 1 deletion model/riscv_insts_zicsr.sail
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ function readCSR csr : csreg -> xlenbits = {
(0x342, _) => mcause.bits,
(0x343, _) => mtval,
(0x344, _) => mip.bits,
(0x34B, _) => mtval2,

// pmpcfgN
(0x3A @ idx : bits(4), _) if idx[0] == bitzero | sizeof(xlen) == 32 => pmpReadCfgReg(unsigned(idx)),
Expand Down Expand Up @@ -124,14 +125,15 @@ function writeCSR (csr : csreg, value : xlenbits) -> unit = {
(0x306, _) => { mcounteren = legalize_mcounteren(mcounteren, value); Some(zero_extend(mcounteren.bits)) },
(0x30A, 32) => { menvcfg = legalize_menvcfg(menvcfg, menvcfg.bits[63 .. 32] @ value); Some(menvcfg.bits[31 .. 0]) },
(0x30A, 64) => { menvcfg = legalize_menvcfg(menvcfg, value); Some(menvcfg.bits) },
(0x310, 32) => { Some(mstatush.bits) }, // ignore writes for now
(0x310, 32) => { mstatush = legalize_mstatush(mstatush, value); Some(mstatush.bits) },
(0x31A, 32) => { menvcfg = legalize_menvcfg(menvcfg, value @ menvcfg.bits[31 .. 0]); Some(menvcfg.bits[63 .. 32]) },
(0x320, _) => { mcountinhibit = legalize_mcountinhibit(mcountinhibit, value); Some(zero_extend(mcountinhibit.bits)) },
(0x340, _) => { mscratch = value; Some(mscratch) },
(0x341, _) => { Some(set_xret_target(Machine, value)) },
(0x342, _) => { mcause.bits = value; Some(mcause.bits) },
(0x343, _) => { mtval = value; Some(mtval) },
(0x344, _) => { mip = legalize_mip(mip, value); Some(mip.bits) },
(0x34B, _) => { mtval = value; Some(mtval) },

// pmpcfgN
(0x3A @ idx : bits(4), _) if idx[0] == bitzero | sizeof(xlen) == 32 => {
Expand Down
9 changes: 9 additions & 0 deletions model/riscv_platform.sail
Original file line number Diff line number Diff line change
Expand Up @@ -454,3 +454,12 @@ function platform_wfi() -> unit = {
mcycle = mtimecmp;
}
}
function platform_handle_critical_error() -> unit = {
/* When Debug Mode is added to model, then add Sddbltrp
* to wait for halt request.
*/
if get_config_print_platform()
then print_platform("handling M-mode critical error");
htif_done = true;
htif_exit_code = zeros();
}
54 changes: 46 additions & 8 deletions model/riscv_sys_control.sail
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ function is_CSR_defined (csr : csreg, p : Privilege) -> bool =
0x342 => p == Machine, // mcause
0x343 => p == Machine, // mtval
0x344 => p == Machine, // mip
0x34B => p == Machine & (haveHExt() | haveSsdbltrp()), // mtval2

// pmpcfgN
0x3A @ idx : bits(4) => p == Machine & sys_pmp_count() > unsigned(idx) & (idx[0] == bitzero | sizeof(xlen) == 32),
Expand Down Expand Up @@ -312,26 +313,47 @@ val rvfi_trap : unit -> unit
function rvfi_trap () = ()
$endif

val platform_handle_critical_error : unit -> unit

function m_mode_double_trap_handler(intr: bool, c : exc_code, pc : xlenbits, info : option(xlenbits), ext : option(ext_exception)) -> xlenbits = {
/* When Smrnmi PR is merged add the handling for redirection to RNMI handler */
platform_handle_critical_error();
zeros()
}

/* handle exceptional ctl flow by updating nextPC and operating privilege */

function trap_handler(del_priv : Privilege, intr : bool, c : exc_code, pc : xlenbits, info : option(xlenbits), ext : option(ext_exception))
-> xlenbits = {
function trap_handler(xdeleg_del_priv : Privilege, intr : bool, c : exc_code, pc : xlenbits, info : option(xlenbits), ext : option(ext_exception)) -> xlenbits = {
rvfi_trap();
if get_config_print_platform()
then print_platform("handling " ^ (if intr then "int#" else "exc#")
^ BitStr(c) ^ " at priv " ^ to_str(del_priv)
^ BitStr(c) ^ " at priv " ^ to_str(xdeleg_del_priv)
^ " with tval " ^ BitStr(tval(info)));

cancel_reservation();

match (del_priv) {
Machine => {
/* Ssdbltrp/Smdbltrp : Determine if a double trap condition occurred */
let m_mode_double_trap : bool = if (xdeleg_del_priv == Machine & get_mstatus_MDT() == 0b1)
then true else false;
let double_trap : bool = if m_mode_double_trap | (xdeleg_del_priv == Supervisor & mstatus[SDT] == 0b1 & menvcfg[DTE] == 0b1)
then true else false;
let del_priv : Privilege = if double_trap then Machine else xdeleg_del_priv;

match (m_mode_double_trap, del_priv) {
(false, Machine) => {
mcause[IsInterrupt] = bool_to_bits(intr);
mcause[Cause] = zero_extend(c);

if double_trap then mtval2 = mcause.bits;
if double_trap then mcause[IsInterrupt] = 0b0;
if double_trap then mcause[Cause] = zero_extend(exceptionType_to_bits(E_Double_Trap()));

mstatus[MPIE] = mstatus[MIE];
mstatus[MIE] = 0b0;
mstatus[MPP] = privLevel_to_bits(cur_privilege);
if haveSmdbltrp()
then set_mstatus_MDT(0b1);

mtval = tval(info);
mepc = pc;

Expand All @@ -344,7 +366,10 @@ function trap_handler(del_priv : Privilege, intr : bool, c : exc_code, pc : xlen

prepare_trap_vector(del_priv, mcause)
},
Supervisor => {
(true, Machine) => {
m_mode_double_trap_handler(intr, c, pc, info, ext);
},
(_, Supervisor) => {
assert (haveSupMode(), "no supervisor mode present for delegation");

scause[IsInterrupt] = bool_to_bits(intr);
Expand All @@ -357,6 +382,9 @@ function trap_handler(del_priv : Privilege, intr : bool, c : exc_code, pc : xlen
Supervisor => 0b1,
Machine => internal_error(__FILE__, __LINE__, "invalid privilege for s-mode trap")
};
if haveSsdbltrp() & menvcfg[DTE] == 0b1
then mstatus[SDT] = 0b1;

stval = tval(info);
sepc = pc;

Expand All @@ -369,7 +397,7 @@ function trap_handler(del_priv : Privilege, intr : bool, c : exc_code, pc : xlen

prepare_trap_vector(del_priv, scause)
},
User => {
(_, User) => {
assert(haveUsrMode(), "no user mode present for delegation");

ucause[IsInterrupt] = bool_to_bits(intr);
Expand Down Expand Up @@ -410,6 +438,8 @@ function exception_handler(cur_priv : Privilege, ctl : ctl_result,
mstatus[MPP] = privLevel_to_bits(if haveUsrMode() then User else Machine);
if cur_privilege != Machine
then mstatus[MPRV] = 0b0;
if haveSmdbltrp()
then set_mstatus_MDT(0b0);

if get_config_print_reg()
then print_reg("CSR mstatus <- " ^ BitStr(mstatus.bits));
Expand All @@ -427,6 +457,8 @@ function exception_handler(cur_priv : Privilege, ctl : ctl_result,
mstatus[SPP] = 0b0;
if cur_privilege != Machine
then mstatus[MPRV] = 0b0;
if haveSsdbltrp()
then mstatus[SDT] = 0b0;

if get_config_print_reg()
then print_reg("CSR mstatus <- " ^ BitStr(mstatus.bits));
Expand Down Expand Up @@ -502,9 +534,15 @@ function init_sys() -> unit = {

/* set to little-endian mode */
if sizeof(xlen) == 64 then {
mstatus = Mk_Mstatus([mstatus.bits with 37 .. 36 = 0b00])
mstatus = Mk_Mstatus([mstatus.bits with 37 .. 36 = 0b00]);
if haveSmdbltrp() then {
/* Smdbltrp: reset value of MDT is 1 */
mstatus = Mk_Mstatus([mstatus.bits with 45 .. 45 = 0b1])
}
};
mstatush.bits = zero_extend(0b0);
/* Smdbltrp: reset value of MDT is 1 */
mstatush[MDT] = if haveSmdbltrp() then 0b1 else 0b0;

mip.bits = zero_extend(0b0);
mie.bits = zero_extend(0b0);
Expand Down
Loading

0 comments on commit e32aff1

Please sign in to comment.