From 620033cf478dcfbde257c044eacae6a0988ecb90 Mon Sep 17 00:00:00 2001 From: Ved Shanbhogue Date: Sun, 25 Feb 2024 10:04:18 -0600 Subject: [PATCH] Add Ssdbltrp and Smdbltrp extensions --- c_emulator/riscv_platform.c | 10 ++ c_emulator/riscv_platform.h | 2 + c_emulator/riscv_platform_impl.c | 2 + c_emulator/riscv_platform_impl.h | 2 + c_emulator/riscv_sim.c | 12 +++ model/riscv_csr_map.sail | 3 + model/riscv_insts_zicsr.sail | 4 +- model/riscv_platform.sail | 9 ++ model/riscv_sys_control.sail | 58 ++++++++++-- model/riscv_sys_regs.sail | 147 ++++++++++++++++++++++-------- model/riscv_types.sail | 4 + ocaml_emulator/platform.ml | 4 + ocaml_emulator/riscv_ocaml_sim.ml | 8 +- 13 files changed, 218 insertions(+), 47 deletions(-) diff --git a/c_emulator/riscv_platform.c b/c_emulator/riscv_platform.c index 2fdb63f92..c46cb4069 100644 --- a/c_emulator/riscv_platform.c +++ b/c_emulator/riscv_platform.c @@ -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; diff --git a/c_emulator/riscv_platform.h b/c_emulator/riscv_platform.h index 341bd5964..177d95ad9 100644 --- a/c_emulator/riscv_platform.h +++ b/c_emulator/riscv_platform.h @@ -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); diff --git a/c_emulator/riscv_platform_impl.c b/c_emulator/riscv_platform_impl.c index 077fc50dc..1af2528a1 100644 --- a/c_emulator/riscv_platform_impl.c +++ b/c_emulator/riscv_platform_impl.c @@ -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; diff --git a/c_emulator/riscv_platform_impl.h b/c_emulator/riscv_platform_impl.h index c4289e679..b280a3021 100644 --- a/c_emulator/riscv_platform_impl.h +++ b/c_emulator/riscv_platform_impl.h @@ -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; diff --git a/c_emulator/riscv_sim.c b/c_emulator/riscv_sim.c index 3a9bfc08d..ebece00a0 100644 --- a/c_emulator/riscv_sim.c +++ b/c_emulator/riscv_sim.c @@ -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; @@ -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 } }; @@ -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; diff --git a/model/riscv_csr_map.sail b/model/riscv_csr_map.sail index 22cffd5a6..14579acd4 100644 --- a/model/riscv_csr_map.sail +++ b/model/riscv_csr_map.sail @@ -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" @@ -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" diff --git a/model/riscv_insts_zicsr.sail b/model/riscv_insts_zicsr.sail index f2980fb9e..049a33a4a 100644 --- a/model/riscv_insts_zicsr.sail +++ b/model/riscv_insts_zicsr.sail @@ -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)), @@ -125,7 +126,7 @@ 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) }, @@ -133,6 +134,7 @@ function writeCSR (csr : csreg, value : xlenbits) -> unit = { (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 => { diff --git a/model/riscv_platform.sail b/model/riscv_platform.sail index 19e3d30ae..ca394a3a5 100644 --- a/model/riscv_platform.sail +++ b/model/riscv_platform.sail @@ -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(); +} diff --git a/model/riscv_sys_control.sail b/model/riscv_sys_control.sail index 95ed4d6a5..c46dda072 100644 --- a/model/riscv_sys_control.sail +++ b/model/riscv_sys_control.sail @@ -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), @@ -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; @@ -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); @@ -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; @@ -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); @@ -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)); @@ -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)); @@ -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); diff --git a/model/riscv_sys_regs.sail b/model/riscv_sys_regs.sail index 65d141923..c0676673d 100644 --- a/model/riscv_sys_regs.sail +++ b/model/riscv_sys_regs.sail @@ -104,6 +104,10 @@ val sys_pmp_grain = {c: "sys_pmp_grain", ocaml: "Platform.pmp_grain", _: "sys_pm /* whether misa.v was enabled at boot */ val sys_enable_vext = {c: "sys_enable_vext", ocaml: "Platform.enable_vext", _: "sys_enable_vext"} : unit -> bool +/* whether Ssdbltrp was enabled at boot */ +val sys_enable_ssdbltrp = {c: "sys_enable_ssdbltrp", ocaml: "Platform.enable_ssdbltrp", _: "sys_enable_ssdbltrp"} : unit -> bool +/* whether Smdbltrp was enabled at boot */ +val sys_enable_smdbltrp = {c: "sys_enable_smdbltrp", ocaml: "Platform.enable_smdbltrp", _: "sys_enable_smdbltrp"} : unit -> bool /* This function allows an extension to veto a write to Misa if it would violate an alignment restriction on @@ -168,6 +172,54 @@ function haveZalrsc() -> bool = haveAtomics() /* Zicond extension support */ function haveZicond() -> bool = true +/* Ssdbltrp extension support */ +function haveSsdbltrp() -> bool = sys_enable_ssdbltrp() +/* Smdbltrp extension support */ +function haveSmdbltrp() -> bool = sys_enable_smdbltrp() + +function haveHExt() -> bool = false + +// menvcfg is 64 bits. senvcfg is SXLEN bits and does not have the two +// upper fields so for simplicity we can use the same type. +bitfield MEnvcfg : bits(64) = { + // Supervisor TimeCmp Extension + STCE : 63, + // Page Based Memory Types Extension + PBMTE : 62, + // Reserved WPRI bits. + wpri_2 : 61 .. 60, + // Ssdbltrp: Double Trap Enable + DTE : 59, + // Reserved WPRI bits. + wpri_1 : 58 .. 8, + // Cache Block Zero instruction Enable + CBZE : 7, + // Cache Block Clean and Flush instruction Enable + CBCFE : 6, + // Cache Block Invalidate instruction Enable + CBIE : 5 .. 4, + // Reserved WPRI bits. + wpri_0 : 3 .. 1, + // Fence of I/O implies Memory + FIOM : 0, +} + +bitfield SEnvcfg : xlenbits = { + // Cache Block Zero instruction Enable + CBZE : 7, + // Cache Block Clean and Flush instruction Enable + CBCFE : 6, + // Cache Block Invalidate instruction Enable + CBIE : 5 .. 4, + // Reserved WPRI bits. + wpri_0 : 3 .. 1, + // Fence of I/O implies Memory + FIOM : 0, +} + +register menvcfg : MEnvcfg +register senvcfg : SEnvcfg + /* * Illegal values legalized to least privileged mode supported. * Note: the only valid combinations of supported modes are M, M+U, M+S+U. @@ -184,6 +236,7 @@ function have_privLevel(priv : priv_level) -> bool = } bitfield Mstatush : bits(32) = { + MDT : 13, MBE : 5, SBE : 4 } @@ -192,6 +245,10 @@ register mstatush : Mstatush bitfield Mstatus : xlenbits = { SD : xlen - 1, + // MDT bit introduced by Smdbltrp is also handled in same ad-hoc way + // as done for MBE and SBE + // MDT : 42 + // The MBE and SBE fields are in mstatus in RV64 and absent in RV32. // On RV32, they are in mstatush, which doesn't exist in RV64. For now, // they are handled in an ad-hoc way. @@ -203,6 +260,7 @@ bitfield Mstatus : xlenbits = { // SXL : 35 .. 34, // UXL : 33 .. 32, + SDT : 24, TSR : 22, TW : 21, TVM : 20, @@ -227,6 +285,17 @@ bitfield Mstatus : xlenbits = { } register mstatus : Mstatus +function legalize_mstatush(o : Mstatush, v : bits(32)) -> Mstatush = { + let v : Mstatush = Mk_Mstatush(v); + + /* Smdbltrp: When the MDT bit is set to 1, the MIE bit is cleared to 0. */ + let o = [o with MDT = if haveSmdbltrp() then v[MDT] else 0b0]; + if o[MDT] == 0b1 then mstatus[MIE] = 0b0; + + /* We don't currently support changing MBE and SBE. */ + o +} + function effectivePrivilege(t : AccessType(ext_access_type), m : Mstatus, priv : Privilege) -> Privilege = if t != Execute() & m[MPRV] == 0b1 then privLevel_of_bits(m[MPP]) @@ -262,13 +331,25 @@ function set_mstatus_UXL(m : Mstatus, a : arch_xlen) -> Mstatus = { } } +function set_mstatus_MDT(v : bits(1) ) -> unit = { + if sizeof(xlen) == 32 + then mstatush[MDT] = v + else mstatus.bits[42 .. 42] = v; +} + +function get_mstatus_MDT() -> bits(1) = { + if sizeof(xlen) == 32 + then mstatush[MDT] + else mstatus.bits[42 .. 42] +} + function legalize_mstatus(o : Mstatus, v : xlenbits) -> Mstatus = { /* * Populate all defined fields using the bits of v, stripping anything * that does not have a matching bitfield entry. All bits above 32 are handled * explicitly later. */ - let m : Mstatus = Mk_Mstatus(zero_extend(v[22 .. 7] @ 0b0 @ v[5 .. 3] @ 0b0 @ v[1 .. 0])); + let m : Mstatus = Mk_Mstatus(zero_extend(v[24 .. 24] @ 0b0 @ v[22 .. 7] @ 0b0 @ v[5 .. 3] @ 0b0 @ v[1 .. 0])); /* Legalize MPP */ let m = [m with MPP = if have_privLevel(m[MPP]) then m[MPP] @@ -296,6 +377,26 @@ function legalize_mstatus(o : Mstatus, v : xlenbits) -> Mstatus = { Mk_Mstatus([m.bits with 37 .. 36 = 0b00]) } else m; + /* Smdbltrp: legalize MDT (bit 42 - RV64 only) and SDT */ + let m = if sizeof(xlen) == 64 then { + Mk_Mstatus([m.bits with 42 .. 42 = if haveSmdbltrp() then v[42 .. 42] else 0b0]) + } else m; + let m = if not(haveSsdbltrp()) then [m with SDT = 0b0] else m; + /* + * When the MDT bit is set to 1, the MIE bit is cleared to 0. + * MIE cannot be set unless SDT is already 0 or is being set to 0 + */ + let m = if sizeof(xlen) == 64 then { + if m.bits[42 .. 42] == 0b1 then [m with MIE = 0b0] else m; + } else { + if mstatush[MDT] == 0b1 then [m with MIE = 0b0] else m; + }; + /* + * When the SDT bit is set to 1, the SIE bit is cleared to 0. + * SIE cannot be set unless SDT is already 0 or is being set to 0 + */ + let m = if m[SDT] == 0b1 then [m with SIE = 0b0] else m; + /* Hardwired to zero in the absence of 'U' or 'N'. */ let m = if not(haveNExt()) then { let m = [m with UPIE = 0b0]; @@ -400,6 +501,7 @@ function legalize_mideleg(o : Minterrupts, v : xlenbits) -> Minterrupts = { /* exception processing state */ bitfield Medeleg : xlenbits = { + Double_Trap_Fault : 16, SAMO_Page_Fault : 15, Load_Page_Fault : 13, Fetch_Page_Fault : 12, @@ -419,7 +521,8 @@ register medeleg : Medeleg /* Delegation to S-mode */ function legalize_medeleg(o : Medeleg, v : xlenbits) -> Medeleg = { /* M-EnvCalls delegation is not supported */ - [Mk_Medeleg(v) with MEnvCall = 0b0] + /* Ssdbltrp: Double Trap delegation is not supported */ + [Mk_Medeleg(v) with MEnvCall = 0b0, Double_Trap_Fault = 0b0] } /* registers for trap handling */ @@ -477,6 +580,7 @@ function pc_alignment_mask() -> xlenbits = /* auxiliary exception registers */ +register mtval2 : xlenbits register mtval : xlenbits register mscratch : xlenbits @@ -552,6 +656,7 @@ bitfield Sstatus : xlenbits = { // The UXL field does not exist on RV32, so we define an explicit // getter and setter below. // UXL : 30 .. 29, + SDT : 24, MXR : 19, SUM : 18, XS : 16 .. 15, @@ -590,6 +695,7 @@ function lower_mstatus(m : Mstatus) -> Sstatus = { let s = [s with UPIE = m[UPIE]]; let s = [s with SIE = m[SIE]]; let s = [s with UIE = m[UIE]]; + let s = [s with SDT = if menvcfg[DTE] == 0b1 then m[SDT] else 0b0]; s } @@ -610,6 +716,7 @@ function lift_sstatus(m : Mstatus, s : Sstatus) -> Mstatus = { let m = [m with UPIE = s[UPIE]]; let m = [m with SIE = s[SIE]]; let m = [m with UIE = s[UIE]]; + let m = [m with SDT = if menvcfg[DTE] == 0b1 then s[SDT] else m[SDT]]; m } @@ -799,44 +906,10 @@ function read_seed_csr() -> xlenbits = { /* Writes to the seed CSR are ignored */ function write_seed_csr () -> option(xlenbits) = None() -bitfield MEnvcfg : bits(64) = { - // Supervisor TimeCmp Extension - STCE : 63, - // Page Based Memory Types Extension - PBMTE : 62, - // Reserved WPRI bits. - wpri_1 : 61 .. 8, - // Cache Block Zero instruction Enable - CBZE : 7, - // Cache Block Clean and Flush instruction Enable - CBCFE : 6, - // Cache Block Invalidate instruction Enable - CBIE : 5 .. 4, - // Reserved WPRI bits. - wpri_0 : 3 .. 1, - // Fence of I/O implies Memory - FIOM : 0, -} - -bitfield SEnvcfg : xlenbits = { - // Cache Block Zero instruction Enable - CBZE : 7, - // Cache Block Clean and Flush instruction Enable - CBCFE : 6, - // Cache Block Invalidate instruction Enable - CBIE : 5 .. 4, - // Reserved WPRI bits. - wpri_0 : 3 .. 1, - // Fence of I/O implies Memory - FIOM : 0, -} - -register menvcfg : MEnvcfg -register senvcfg : SEnvcfg - function legalize_menvcfg(o : MEnvcfg, v : bits(64)) -> MEnvcfg = { let v = Mk_MEnvcfg(v); let o = [o with FIOM = if sys_enable_writable_fiom() then v[FIOM] else 0b0]; + let o = [o with DTE = if haveSsdbltrp() then v[DTE] else 0b0]; // Other extensions are not implemented yet so all other fields are read only zero. o } diff --git a/model/riscv_types.sail b/model/riscv_types.sail index 2b1c132ec..e0741c47c 100644 --- a/model/riscv_types.sail +++ b/model/riscv_types.sail @@ -183,6 +183,7 @@ union ExceptionType = { E_Load_Page_Fault : unit, E_Reserved_14 : unit, E_SAMO_Page_Fault : unit, + E_Double_Trap : unit, /* extensions */ E_Extension : ext_exc_type @@ -207,6 +208,7 @@ function exceptionType_to_bits(e) = E_Load_Page_Fault() => 0x0d, E_Reserved_14() => 0x0e, E_SAMO_Page_Fault() => 0x0f, + E_Double_Trap() => 0x10, /* extensions */ E_Extension(e) => ext_exc_type_to_bits(e) @@ -231,6 +233,7 @@ function num_of_ExceptionType(e) = E_Load_Page_Fault() => 13, E_Reserved_14() => 14, E_SAMO_Page_Fault() => 15, + E_Double_Trap() => 16, /* extensions */ E_Extension(e) => num_of_ext_exc_type(e) @@ -256,6 +259,7 @@ function exceptionType_to_str(e) = E_Load_Page_Fault() => "load-page-fault", E_Reserved_14() => "reserved-1", E_SAMO_Page_Fault() => "store/amo-page-fault", + E_Double_Trap() => "double-trap", /* extensions */ E_Extension(e) => ext_exc_type_to_str(e) diff --git a/ocaml_emulator/platform.ml b/ocaml_emulator/platform.ml index 69f271496..1303e0475 100644 --- a/ocaml_emulator/platform.ml +++ b/ocaml_emulator/platform.ml @@ -16,6 +16,8 @@ let config_enable_writable_fiom = ref true let config_enable_vext = ref true let config_pmp_count = ref Big_int.zero let config_pmp_grain = ref Big_int.zero +let config_enable_ssdbltrp = ref false +let config_enable_smdbltrp = ref false let set_config_pmp_count x = config_pmp_count := Big_int.of_int x let set_config_pmp_grain x = config_pmp_grain := Big_int.of_int x @@ -96,6 +98,8 @@ let enable_zfinx () = false let enable_writable_fiom () = !config_enable_writable_fiom let pmp_count () = !config_pmp_count let pmp_grain () = !config_pmp_grain +let enable_ssdbltrp () = !config_enable_ssdbltrp +let enable_smdbltrp () = !config_enable_smdbltrp let rom_base () = arch_bits_of_int64 P.rom_base let rom_size () = arch_bits_of_int !rom_size_ref diff --git a/ocaml_emulator/riscv_ocaml_sim.ml b/ocaml_emulator/riscv_ocaml_sim.ml index 56be8d8a8..ddcacf3e9 100644 --- a/ocaml_emulator/riscv_ocaml_sim.ml +++ b/ocaml_emulator/riscv_ocaml_sim.ml @@ -88,7 +88,13 @@ let options = Arg.align ([("-dump-dts", " requested isa"); ("-with-dtc", Arg.String PI.set_dtc, - " full path to dtc to use") + " full path to dtc to use"); + ("-enable-ssdbltrp", + Arg.Set P.config_enable_ssdbltrp, + " enable ssdbltrp extension"); + ("-enable-smdbltrp", + Arg.Set P.config_enable_smdbltrp, + " enable smdbltrp extension") ]) let usage_msg = "RISC-V platform options:"