+ catch(serialize_t& s) {}
+
+ state.pc = pc;
+ update_timer(&state, instret);
+}
+
+void processor_t::push_privilege_stack()
+{
+ reg_t s = state.mstatus;
+ s = set_field(s, MSTATUS_PRV2, get_field(state.mstatus, MSTATUS_PRV1));
+ s = set_field(s, MSTATUS_IE2, get_field(state.mstatus, MSTATUS_IE1));
+ s = set_field(s, MSTATUS_PRV1, get_field(state.mstatus, MSTATUS_PRV));
+ s = set_field(s, MSTATUS_IE1, get_field(state.mstatus, MSTATUS_IE));
+ s = set_field(s, MSTATUS_PRV, PRV_M);
+ s = set_field(s, MSTATUS_MPRV, PRV_M);
+ s = set_field(s, MSTATUS_IE, 0);
+ set_csr(CSR_MSTATUS, s);
+}
+
+void processor_t::pop_privilege_stack()
+{
+ reg_t s = state.mstatus;
+ s = set_field(s, MSTATUS_PRV, get_field(state.mstatus, MSTATUS_PRV1));
+ s = set_field(s, MSTATUS_IE, get_field(state.mstatus, MSTATUS_IE1));
+ s = set_field(s, MSTATUS_PRV1, get_field(state.mstatus, MSTATUS_PRV2));
+ s = set_field(s, MSTATUS_IE1, get_field(state.mstatus, MSTATUS_IE2));
+ s = set_field(s, MSTATUS_PRV2, PRV_U);
+ s = set_field(s, MSTATUS_IE2, 1);
+ set_csr(CSR_MSTATUS, s);
+}
+
+reg_t processor_t::take_trap(trap_t& t, reg_t epc)
+{
+ if (debug)
+ fprintf(stderr, "core %3d: exception %s, epc 0x%016" PRIx64 "\n",
+ id, t.name(), epc);
+
+ reg_t tvec = 0x40 * get_field(state.mstatus, MSTATUS_PRV);
+ push_privilege_stack();
+ yield_load_reservation();
+ state.mcause = t.cause();
+ state.mepc = epc;
+ t.side_effects(&state); // might set badvaddr etc.
+ return tvec;
+}
+
+void processor_t::deliver_ipi()
+{
+ state.mstatus |= MSTATUS_MSIP;
+}
+
+void processor_t::disasm(insn_t insn)
+{
+ uint64_t bits = insn.bits() & ((1ULL << (8 * insn_length(insn.bits()))) - 1);
+ fprintf(stderr, "core %3d: 0x%016" PRIx64 " (0x%08" PRIx64 ") %s\n",
+ id, state.pc, bits, disassembler->disassemble(insn).c_str());
+}
+
+static bool validate_priv(reg_t priv)
+{
+ return priv == PRV_U || priv == PRV_S || priv == PRV_M;
+}
+
+static bool validate_arch(reg_t arch)
+{
+#ifdef RISCV_ENABLE_64BIT
+ if (arch == UA_RV64) return true;
+#endif
+ return arch == UA_RV32;
+}
+
+static bool validate_vm(reg_t vm)
+{
+ // TODO: VM_SV32 support
+#ifdef RISCV_ENABLE_64BIT
+ if (vm == VM_SV43) return true;
+#endif
+ return vm == VM_MBARE;
+}
+
+void processor_t::set_csr(int which, reg_t val)
+{
+ switch (which)