Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Double trap - Add Ssdbltrp and Smdbltrp extensions #416

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions c_emulator/riscv_platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,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 @@ -10,6 +10,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 @@ -14,6 +14,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 @@ -23,6 +23,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 @@ -54,6 +54,8 @@ const char *RV32ISA = "RV32IMAC";
#define OPT_PMP_COUNT 1002
#define OPT_PMP_GRAIN 1003
#define OPT_ENABLE_SVINVAL 1004
#define OPT_ENABLE_SSDBLTRP 1006
#define OPT_ENABLE_SMDBLTRP 1007
#define OPT_ENABLE_ZCB 10014

static bool do_dump_dts = false;
Expand Down Expand Up @@ -152,6 +154,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 @@ -408,6 +412,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 @@ -61,6 +61,7 @@ mapping clause csr_name_map = 0xF14 <-> "mhartid"
mapping clause csr_name_map = 0xF15 <-> "mconfigptr"
/* 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 @@ -70,12 +71,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 @@ -47,6 +47,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 @@ -125,14 +126,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();
}
58 changes: 50 additions & 8 deletions model/riscv_sys_control.sail
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,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 @@ -313,26 +314,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 @@ -345,7 +367,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 @@ -358,6 +383,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 @@ -370,7 +398,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 @@ -411,6 +439,10 @@ 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 haveSsdbltrp() & cur_privilege == User
then mstatus[SDT] = 0b0;

if get_config_print_reg()
then print_reg("CSR mstatus <- " ^ BitStr(mstatus.bits));
Expand All @@ -428,6 +460,10 @@ 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 haveSmdbltrp()
then set_mstatus_MDT(0b0);

if get_config_print_reg()
then print_reg("CSR mstatus <- " ^ BitStr(mstatus.bits));
Expand Down Expand Up @@ -505,9 +541,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