diff --git a/src/clua-cartesi.cpp b/src/clua-cartesi.cpp index beccff0fa..9d513edaf 100644 --- a/src/clua-cartesi.cpp +++ b/src/clua-cartesi.cpp @@ -192,7 +192,6 @@ CM_API int luaopen_cartesi(lua_State *L) { clua_setintegerfield(L, CM_VERSION_MINOR, "VERSION_MINOR", -1); clua_setintegerfield(L, CM_VERSION_PATCH, "VERSION_PATCH", -1); clua_setintegerfield(L, CM_HASH_SIZE, "HASH_SIZE", -1); - clua_setintegerfield(L, CM_REG_COUNT, "REG_COUNT", -1); clua_setintegerfield(L, CM_TREE_LOG2_WORD_SIZE, "TREE_LOG2_WORD_SIZE", -1); clua_setintegerfield(L, CM_TREE_LOG2_PAGE_SIZE, "TREE_LOG2_PAGE_SIZE", -1); clua_setintegerfield(L, CM_TREE_LOG2_ROOT_SIZE, "TREE_LOG2_ROOT_SIZE", -1); diff --git a/src/clua-i-virtual-machine.cpp b/src/clua-i-virtual-machine.cpp index c4753b656..549056ef3 100644 --- a/src/clua-i-virtual-machine.cpp +++ b/src/clua-i-virtual-machine.cpp @@ -206,6 +206,9 @@ cm_reg clua_check_cm_proc_reg(lua_State *L, int idx) try { {"uarch_pc", CM_REG_UARCH_PC}, {"uarch_cycle", CM_REG_UARCH_CYCLE}, {"uarch_halt_flag", CM_REG_UARCH_HALT_FLAG}, + {"unknown_", CM_REG_UNKNOWN_}, + {"first_", CM_REG_FIRST_}, + {"last_", CM_REG_LAST_}, // clang-format on }; const char *name = luaL_checkstring(L, idx); @@ -216,10 +219,10 @@ cm_reg clua_check_cm_proc_reg(lua_State *L, int idx) try { return got->second; } catch (const std::exception &e) { luaL_error(L, "%s", e.what()); - return CM_REG_UNKNOWN; // will not be reached + return CM_REG_UNKNOWN_; // will not be reached } catch (...) { luaL_error(L, "unknown error with register type conversion"); - return CM_REG_UNKNOWN; // will not be reached + return CM_REG_UNKNOWN_; // will not be reached } void clua_check_cm_hash(lua_State *L, int idx, cm_hash *c_hash) { diff --git a/src/i-virtual-machine.h b/src/i-virtual-machine.h index 3d5d2f22d..2ea1dd3cd 100644 --- a/src/i-virtual-machine.h +++ b/src/i-virtual-machine.h @@ -45,7 +45,7 @@ namespace cartesi { class i_virtual_machine { public: using hash_type = machine_merkle_tree::hash_type; - using reg = machine::reg; + using reg = machine_reg; /// \brief Constructor i_virtual_machine() = default; diff --git a/src/jsonrpc-virtual-machine.cpp b/src/jsonrpc-virtual-machine.cpp index 86b5a4d54..1d55de042 100644 --- a/src/jsonrpc-virtual-machine.cpp +++ b/src/jsonrpc-virtual-machine.cpp @@ -309,10 +309,15 @@ void jsonrpc_request(std::unique_ptr &ioc, std::unique_ namespace cartesi { +template +void jsonrpc_virtual_machine::request(const std::string &method, const std::tuple &tp, R &result, + bool keep_alive) const { + jsonrpc_request(m_ioc, m_stream, m_address, method, tp, result, m_timeout, keep_alive); +} + void jsonrpc_virtual_machine::shutdown_server() { bool result = false; - jsonrpc_request(m_ioc, m_stream, m_address, "shutdown", std::tie(), result, m_timeout, false); - + request("shutdown", std::tie(), result, false); // Destroy ASIO context early to release its socket before the destructor, // otherwise we may end up with too many open sockets in garbage collected environments. // This will also invalidate any further jsonrpc request. @@ -322,7 +327,7 @@ void jsonrpc_virtual_machine::shutdown_server() { void jsonrpc_virtual_machine::delay_next_request(uint64_t ms) const { bool result = false; - jsonrpc_request(m_ioc, m_stream, m_address, "delay_next_request", std::tie(ms), result, m_timeout); + request("delay_next_request", std::tie(ms), result); } void jsonrpc_virtual_machine::set_timeout(int64_t ms) { @@ -512,12 +517,12 @@ jsonrpc_virtual_machine::jsonrpc_virtual_machine(const std::string & /*address*/ void jsonrpc_virtual_machine::do_load(const std::string &directory, const machine_runtime_config &runtime) { bool result = false; - jsonrpc_request(m_ioc, m_stream, m_address, "machine.load", std::tie(directory, runtime), result, m_timeout); + request("machine.load", std::tie(directory, runtime), result); } bool jsonrpc_virtual_machine::do_is_empty() const { bool result = false; - jsonrpc_request(m_ioc, m_stream, m_address, "machine.is_empty", std::tie(), result, m_timeout); + request("machine.is_empty", std::tie(), result); return result; } @@ -542,7 +547,7 @@ i_virtual_machine *jsonrpc_virtual_machine::do_clone_empty() const { void jsonrpc_virtual_machine::do_create(const machine_config &config, const machine_runtime_config &runtime) { bool result = false; - jsonrpc_request(m_ioc, m_stream, m_address, "machine.create", std::tie(config, runtime), result, m_timeout); + request("machine.create", std::tie(config, runtime), result); } jsonrpc_virtual_machine::~jsonrpc_virtual_machine() { @@ -574,77 +579,76 @@ jsonrpc_virtual_machine::~jsonrpc_virtual_machine() { machine_config jsonrpc_virtual_machine::do_get_initial_config() const { machine_config result; - jsonrpc_request(m_ioc, m_stream, m_address, "machine.get_initial_config", std::tie(), result, m_timeout); + request("machine.get_initial_config", std::tie(), result); return result; } machine_runtime_config jsonrpc_virtual_machine::do_get_runtime_config() const { machine_runtime_config result; - jsonrpc_request(m_ioc, m_stream, m_address, "machine.get_runtime_config", std::tie(), result, m_timeout); + request("machine.get_runtime_config", std::tie(), result); return result; } void jsonrpc_virtual_machine::do_set_runtime_config(const machine_runtime_config &r) { bool result = false; - jsonrpc_request(m_ioc, m_stream, m_address, "machine.set_runtime_config", std::tie(r), result, m_timeout); + request("machine.set_runtime_config", std::tie(r), result); } semantic_version jsonrpc_virtual_machine::get_server_version() const { semantic_version result; - jsonrpc_request(m_ioc, m_stream, m_address, "get_version", std::tie(), result, m_timeout); + request("get_version", std::tie(), result); return result; } interpreter_break_reason jsonrpc_virtual_machine::do_run(uint64_t mcycle_end) { interpreter_break_reason result = interpreter_break_reason::failed; - jsonrpc_request(m_ioc, m_stream, m_address, "machine.run", std::tie(mcycle_end), result, m_timeout); + request("machine.run", std::tie(mcycle_end), result); return result; } interpreter_break_reason jsonrpc_virtual_machine::do_log_step(uint64_t mcycle_count, const std::string &filename) { interpreter_break_reason result = interpreter_break_reason::failed; - jsonrpc_request(m_ioc, m_stream, m_address, "machine.log_step", std::tie(mcycle_count, filename), result, - m_timeout); + request("machine.log_step", std::tie(mcycle_count, filename), result); return result; } void jsonrpc_virtual_machine::do_store(const std::string &directory) const { bool result = false; - jsonrpc_request(m_ioc, m_stream, m_address, "machine.store", std::tie(directory), result, m_timeout); + request("machine.store", std::tie(directory), result); } uint64_t jsonrpc_virtual_machine::do_read_reg(reg r) const { uint64_t result = 0; - jsonrpc_request(m_ioc, m_stream, m_address, "machine.read_reg", std::tie(r), result, m_timeout); + request("machine.read_reg", std::tie(r), result); return result; } void jsonrpc_virtual_machine::do_write_reg(reg w, uint64_t val) { bool result = false; - jsonrpc_request(m_ioc, m_stream, m_address, "machine.write_reg", std::tie(w, val), result, m_timeout); + request("machine.write_reg", std::tie(w, val), result); } auto jsonrpc_virtual_machine::fork_server() const -> fork_result { fork_result result{}; - jsonrpc_request(m_ioc, m_stream, m_address, "fork", std::tie(), result, m_timeout, false); + request("fork", std::tie(), result, false); return result; } std::string jsonrpc_virtual_machine::rebind_server(const std::string &address) { std::string result; - jsonrpc_request(m_ioc, m_stream, m_address, "rebind", std::tie(address), result, m_timeout, false); + request("rebind", std::tie(address), result, false); m_address = result; return result; } void jsonrpc_virtual_machine::emancipate_server() const { bool result = false; - jsonrpc_request(m_ioc, m_stream, m_address, "emancipate", std::tie(), result, m_timeout); + request("emancipate", std::tie(), result); } void jsonrpc_virtual_machine::do_read_memory(uint64_t address, unsigned char *data, uint64_t length) const { std::string result; - jsonrpc_request(m_ioc, m_stream, m_address, "machine.read_memory", std::tie(address, length), result, m_timeout); + request("machine.read_memory", std::tie(address, length), result); std::string bin = cartesi::decode_base64(result); if (bin.size() != length) { throw std::runtime_error("jsonrpc server error: invalid decoded base64 data length"); @@ -655,13 +659,12 @@ void jsonrpc_virtual_machine::do_read_memory(uint64_t address, unsigned char *da void jsonrpc_virtual_machine::do_write_memory(uint64_t address, const unsigned char *data, uint64_t length) { bool result = false; std::string b64 = cartesi::encode_base64(data, length); - jsonrpc_request(m_ioc, m_stream, m_address, "machine.write_memory", std::tie(address, b64), result, m_timeout); + request("machine.write_memory", std::tie(address, b64), result); } void jsonrpc_virtual_machine::do_read_virtual_memory(uint64_t address, unsigned char *data, uint64_t length) { std::string result; - jsonrpc_request(m_ioc, m_stream, m_address, "machine.read_virtual_memory", std::tie(address, length), result, - m_timeout); + request("machine.read_virtual_memory", std::tie(address, length), result); std::string bin = cartesi::decode_base64(result); if (bin.size() != length) { throw std::runtime_error("jsonrpc server error: invalid decoded base64 data length"); @@ -672,25 +675,23 @@ void jsonrpc_virtual_machine::do_read_virtual_memory(uint64_t address, unsigned void jsonrpc_virtual_machine::do_write_virtual_memory(uint64_t address, const unsigned char *data, uint64_t length) { bool result = false; std::string b64 = cartesi::encode_base64(data, length); - jsonrpc_request(m_ioc, m_stream, m_address, "machine.write_virtual_memory", std::tie(address, b64), result, - m_timeout); + request("machine.write_virtual_memory", std::tie(address, b64), result); } uint64_t jsonrpc_virtual_machine::do_translate_virtual_address(uint64_t vaddr) { uint64_t result = 0; - jsonrpc_request(m_ioc, m_stream, m_address, "machine.translate_virtual_address", std::tie(vaddr), result, - m_timeout); + request("machine.translate_virtual_address", std::tie(vaddr), result); return result; } void jsonrpc_virtual_machine::do_reset_uarch() { bool result = false; - jsonrpc_request(m_ioc, m_stream, m_address, "machine.reset_uarch", std::tie(), result, m_timeout); + request("machine.reset_uarch", std::tie(), result); } access_log jsonrpc_virtual_machine::do_log_reset_uarch(const access_log::type &log_type) { not_default_constructible result; - jsonrpc_request(m_ioc, m_stream, m_address, "machine.log_reset_uarch", std::tie(log_type), result, m_timeout); + request("machine.log_reset_uarch", std::tie(log_type), result); if (!result.has_value()) { throw std::runtime_error("jsonrpc server error: missing result"); } @@ -698,12 +699,12 @@ access_log jsonrpc_virtual_machine::do_log_reset_uarch(const access_log::type &l } void jsonrpc_virtual_machine::do_get_root_hash(hash_type &hash) const { - jsonrpc_request(m_ioc, m_stream, m_address, "machine.get_root_hash", std::tie(), hash, m_timeout); + request("machine.get_root_hash", std::tie(), hash); } machine_merkle_tree::proof_type jsonrpc_virtual_machine::do_get_proof(uint64_t address, int log2_size) const { not_default_constructible result; - jsonrpc_request(m_ioc, m_stream, m_address, "machine.get_proof", std::tie(address, log2_size), result, m_timeout); + request("machine.get_proof", std::tie(address, log2_size), result); if (!result.has_value()) { throw std::runtime_error("jsonrpc server error: missing result"); } @@ -712,12 +713,12 @@ machine_merkle_tree::proof_type jsonrpc_virtual_machine::do_get_proof(uint64_t a void jsonrpc_virtual_machine::do_replace_memory_range(const memory_range_config &new_range) { bool result = false; - jsonrpc_request(m_ioc, m_stream, m_address, "machine.replace_memory_range", std::tie(new_range), result, m_timeout); + request("machine.replace_memory_range", std::tie(new_range), result); } access_log jsonrpc_virtual_machine::do_log_step_uarch(const access_log::type &log_type) { not_default_constructible result; - jsonrpc_request(m_ioc, m_stream, m_address, "machine.log_step_uarch", std::tie(log_type), result, m_timeout); + request("machine.log_step_uarch", std::tie(log_type), result); if (!result.has_value()) { throw std::runtime_error("jsonrpc server error: missing result"); } @@ -726,51 +727,50 @@ access_log jsonrpc_virtual_machine::do_log_step_uarch(const access_log::type &lo void jsonrpc_virtual_machine::do_destroy() { bool result = false; - jsonrpc_request(m_ioc, m_stream, m_address, "machine.destroy", std::tie(), result, m_timeout); + request("machine.destroy", std::tie(), result); } bool jsonrpc_virtual_machine::do_verify_dirty_page_maps() const { bool result = false; - jsonrpc_request(m_ioc, m_stream, m_address, "machine.verify_dirty_page_maps", std::tie(), result, m_timeout); + request("machine.verify_dirty_page_maps", std::tie(), result); return result; } uint64_t jsonrpc_virtual_machine::do_read_word(uint64_t address) const { uint64_t result = 0; - jsonrpc_request(m_ioc, m_stream, m_address, "machine.read_word", std::tie(address), result, m_timeout); + request("machine.read_word", std::tie(address), result); return result; } bool jsonrpc_virtual_machine::do_verify_merkle_tree() const { bool result = false; - jsonrpc_request(m_ioc, m_stream, m_address, "machine.verify_merkle_tree", std::tie(), result, m_timeout); + request("machine.verify_merkle_tree", std::tie(), result); return result; } uarch_interpreter_break_reason jsonrpc_virtual_machine::do_run_uarch(uint64_t uarch_cycle_end) { uarch_interpreter_break_reason result = uarch_interpreter_break_reason::reached_target_cycle; - jsonrpc_request(m_ioc, m_stream, m_address, "machine.run_uarch", std::tie(uarch_cycle_end), result, m_timeout); + request("machine.run_uarch", std::tie(uarch_cycle_end), result); return result; } machine_memory_range_descrs jsonrpc_virtual_machine::do_get_memory_ranges() const { machine_memory_range_descrs result; - jsonrpc_request(m_ioc, m_stream, m_address, "machine.get_memory_ranges", std::tie(), result, m_timeout); + request("machine.get_memory_ranges", std::tie(), result); return result; } void jsonrpc_virtual_machine::do_send_cmio_response(uint16_t reason, const unsigned char *data, uint64_t length) { bool result = false; std::string b64 = cartesi::encode_base64(data, length); - jsonrpc_request(m_ioc, m_stream, m_address, "machine.send_cmio_response", std::tie(reason, b64), result, m_timeout); + request("machine.send_cmio_response", std::tie(reason, b64), result); } access_log jsonrpc_virtual_machine::do_log_send_cmio_response(uint16_t reason, const unsigned char *data, uint64_t length, const access_log::type &log_type) { not_default_constructible result; std::string b64 = cartesi::encode_base64(data, length); - jsonrpc_request(m_ioc, m_stream, m_address, "machine.log_send_cmio_response", std::tie(reason, b64, log_type), - result, m_timeout); + request("machine.log_send_cmio_response", std::tie(reason, b64, log_type), result); if (!result.has_value()) { throw std::runtime_error("jsonrpc server error: missing result"); } @@ -779,13 +779,13 @@ access_log jsonrpc_virtual_machine::do_log_send_cmio_response(uint16_t reason, c uint64_t jsonrpc_virtual_machine::do_get_reg_address(reg r) const { uint64_t result = 0; - jsonrpc_request(m_ioc, m_stream, m_address, "machine.get_reg_address", std::tie(r), result, m_timeout); + request("machine.get_reg_address", std::tie(r), result); return result; } machine_config jsonrpc_virtual_machine::do_get_default_config() const { machine_config result; - jsonrpc_request(m_ioc, m_stream, m_address, "machine.get_default_config", std::tie(), result, m_timeout); + request("machine.get_default_config", std::tie(), result); return result; } @@ -794,8 +794,8 @@ interpreter_break_reason jsonrpc_virtual_machine::do_verify_step(const hash_type interpreter_break_reason result = interpreter_break_reason::failed; auto b64_root_hash_before = encode_base64(root_hash_before); auto b64_root_hash_after = encode_base64(root_hash_after); - jsonrpc_request(m_ioc, m_stream, m_address, "machine.verify_step", - std::tie(b64_root_hash_before, log_filename, mcycle_count, b64_root_hash_after), result, m_timeout); + request("machine.verify_step", std::tie(b64_root_hash_before, log_filename, mcycle_count, b64_root_hash_after), + result); return result; } @@ -804,8 +804,7 @@ void jsonrpc_virtual_machine::do_verify_step_uarch(const hash_type &root_hash_be bool result = false; auto b64_root_hash_before = encode_base64(root_hash_before); auto b64_root_hash_after = encode_base64(root_hash_after); - jsonrpc_request(m_ioc, m_stream, m_address, "machine.verify_step_uarch", - std::tie(b64_root_hash_before, log, b64_root_hash_after), result, m_timeout); + request("machine.verify_step_uarch", std::tie(b64_root_hash_before, log, b64_root_hash_after), result); } void jsonrpc_virtual_machine::do_verify_reset_uarch(const hash_type &root_hash_before, const access_log &log, @@ -813,8 +812,7 @@ void jsonrpc_virtual_machine::do_verify_reset_uarch(const hash_type &root_hash_b bool result = false; auto b64_root_hash_before = encode_base64(root_hash_before); auto b64_root_hash_after = encode_base64(root_hash_after); - jsonrpc_request(m_ioc, m_stream, m_address, "machine.verify_reset_uarch", - std::tie(b64_root_hash_before, log, b64_root_hash_after), result, m_timeout); + request("machine.verify_reset_uarch", std::tie(b64_root_hash_before, log, b64_root_hash_after), result); } void jsonrpc_virtual_machine::do_verify_send_cmio_response(uint16_t reason, const unsigned char *data, uint64_t length, @@ -823,8 +821,8 @@ void jsonrpc_virtual_machine::do_verify_send_cmio_response(uint16_t reason, cons std::string b64_data = cartesi::encode_base64(data, length); auto b64_root_hash_before = encode_base64(root_hash_before); auto b64_root_hash_after = encode_base64(root_hash_after); - jsonrpc_request(m_ioc, m_stream, m_address, "machine.verify_send_cmio_response", - std::tie(reason, b64_data, b64_root_hash_before, log, b64_root_hash_after), result, m_timeout); + request("machine.verify_send_cmio_response", + std::tie(reason, b64_data, b64_root_hash_before, log, b64_root_hash_after), result); } bool jsonrpc_virtual_machine::do_is_jsonrpc_virtual_machine() const { diff --git a/src/jsonrpc-virtual-machine.h b/src/jsonrpc-virtual-machine.h index b3b184058..d7f3c9592 100644 --- a/src/jsonrpc-virtual-machine.h +++ b/src/jsonrpc-virtual-machine.h @@ -140,6 +140,8 @@ class jsonrpc_virtual_machine final : public i_virtual_machine { bool do_is_jsonrpc_virtual_machine() const override; void check_server_version() const; + template + void request(const std::string &method, const std::tuple &tp, R &result, bool keep_alive = true) const; mutable std::unique_ptr m_ioc; // The io_context is required for all I/O mutable std::unique_ptr m_stream; // TCP stream for keep alive connections diff --git a/src/machine-c-api.cpp b/src/machine-c-api.cpp index 0f112112c..1a3735b04 100644 --- a/src/machine-c-api.cpp +++ b/src/machine-c-api.cpp @@ -125,6 +125,316 @@ cm_error cm_result_success() { // -------------------------------------------- // Conversion functions // -------------------------------------------- + +static cartesi::machine_reg convert_from_c(cm_reg r) { + using reg = cartesi::machine_reg; + switch (r) { + case CM_REG_X0: + return reg::x0; + case CM_REG_X1: + return reg::x1; + case CM_REG_X2: + return reg::x2; + case CM_REG_X3: + return reg::x3; + case CM_REG_X4: + return reg::x4; + case CM_REG_X5: + return reg::x5; + case CM_REG_X6: + return reg::x6; + case CM_REG_X7: + return reg::x7; + case CM_REG_X8: + return reg::x8; + case CM_REG_X9: + return reg::x9; + case CM_REG_X10: + return reg::x10; + case CM_REG_X11: + return reg::x11; + case CM_REG_X12: + return reg::x12; + case CM_REG_X13: + return reg::x13; + case CM_REG_X14: + return reg::x14; + case CM_REG_X15: + return reg::x15; + case CM_REG_X16: + return reg::x16; + case CM_REG_X17: + return reg::x17; + case CM_REG_X18: + return reg::x18; + case CM_REG_X19: + return reg::x19; + case CM_REG_X20: + return reg::x20; + case CM_REG_X21: + return reg::x21; + case CM_REG_X22: + return reg::x22; + case CM_REG_X23: + return reg::x23; + case CM_REG_X24: + return reg::x24; + case CM_REG_X25: + return reg::x25; + case CM_REG_X26: + return reg::x26; + case CM_REG_X27: + return reg::x27; + case CM_REG_X28: + return reg::x28; + case CM_REG_X29: + return reg::x29; + case CM_REG_X30: + return reg::x30; + case CM_REG_X31: + return reg::x31; + case CM_REG_F0: + return reg::f0; + case CM_REG_F1: + return reg::f1; + case CM_REG_F2: + return reg::f2; + case CM_REG_F3: + return reg::f3; + case CM_REG_F4: + return reg::f4; + case CM_REG_F5: + return reg::f5; + case CM_REG_F6: + return reg::f6; + case CM_REG_F7: + return reg::f7; + case CM_REG_F8: + return reg::f8; + case CM_REG_F9: + return reg::f9; + case CM_REG_F10: + return reg::f10; + case CM_REG_F11: + return reg::f11; + case CM_REG_F12: + return reg::f12; + case CM_REG_F13: + return reg::f13; + case CM_REG_F14: + return reg::f14; + case CM_REG_F15: + return reg::f15; + case CM_REG_F16: + return reg::f16; + case CM_REG_F17: + return reg::f17; + case CM_REG_F18: + return reg::f18; + case CM_REG_F19: + return reg::f19; + case CM_REG_F20: + return reg::f20; + case CM_REG_F21: + return reg::f21; + case CM_REG_F22: + return reg::f22; + case CM_REG_F23: + return reg::f23; + case CM_REG_F24: + return reg::f24; + case CM_REG_F25: + return reg::f25; + case CM_REG_F26: + return reg::f26; + case CM_REG_F27: + return reg::f27; + case CM_REG_F28: + return reg::f28; + case CM_REG_F29: + return reg::f29; + case CM_REG_F30: + return reg::f30; + case CM_REG_F31: + return reg::f31; + case CM_REG_PC: + return reg::pc; + case CM_REG_FCSR: + return reg::fcsr; + case CM_REG_MVENDORID: + return reg::mvendorid; + case CM_REG_MARCHID: + return reg::marchid; + case CM_REG_MIMPID: + return reg::mimpid; + case CM_REG_MCYCLE: + return reg::mcycle; + case CM_REG_ICYCLEINSTRET: + return reg::icycleinstret; + case CM_REG_MSTATUS: + return reg::mstatus; + case CM_REG_MTVEC: + return reg::mtvec; + case CM_REG_MSCRATCH: + return reg::mscratch; + case CM_REG_MEPC: + return reg::mepc; + case CM_REG_MCAUSE: + return reg::mcause; + case CM_REG_MTVAL: + return reg::mtval; + case CM_REG_MISA: + return reg::misa; + case CM_REG_MIE: + return reg::mie; + case CM_REG_MIP: + return reg::mip; + case CM_REG_MEDELEG: + return reg::medeleg; + case CM_REG_MIDELEG: + return reg::mideleg; + case CM_REG_MCOUNTEREN: + return reg::mcounteren; + case CM_REG_MENVCFG: + return reg::menvcfg; + case CM_REG_STVEC: + return reg::stvec; + case CM_REG_SSCRATCH: + return reg::sscratch; + case CM_REG_SEPC: + return reg::sepc; + case CM_REG_SCAUSE: + return reg::scause; + case CM_REG_STVAL: + return reg::stval; + case CM_REG_SATP: + return reg::satp; + case CM_REG_SCOUNTEREN: + return reg::scounteren; + case CM_REG_SENVCFG: + return reg::senvcfg; + case CM_REG_ILRSC: + return reg::ilrsc; + case CM_REG_IFLAGS: + return reg::iflags; + case CM_REG_IUNREP: + return reg::iunrep; + case CM_REG_CLINT_MTIMECMP: + return reg::clint_mtimecmp; + case CM_REG_PLIC_GIRQPEND: + return reg::plic_girqpend; + case CM_REG_PLIC_GIRQSRVD: + return reg::plic_girqsrvd; + case CM_REG_HTIF_TOHOST: + return reg::htif_tohost; + case CM_REG_HTIF_FROMHOST: + return reg::htif_fromhost; + case CM_REG_HTIF_IHALT: + return reg::htif_ihalt; + case CM_REG_HTIF_ICONSOLE: + return reg::htif_iconsole; + case CM_REG_HTIF_IYIELD: + return reg::htif_iyield; + case CM_REG_UARCH_X0: + return reg::uarch_x0; + case CM_REG_UARCH_X1: + return reg::uarch_x1; + case CM_REG_UARCH_X2: + return reg::uarch_x2; + case CM_REG_UARCH_X3: + return reg::uarch_x3; + case CM_REG_UARCH_X4: + return reg::uarch_x4; + case CM_REG_UARCH_X5: + return reg::uarch_x5; + case CM_REG_UARCH_X6: + return reg::uarch_x6; + case CM_REG_UARCH_X7: + return reg::uarch_x7; + case CM_REG_UARCH_X8: + return reg::uarch_x8; + case CM_REG_UARCH_X9: + return reg::uarch_x9; + case CM_REG_UARCH_X10: + return reg::uarch_x10; + case CM_REG_UARCH_X11: + return reg::uarch_x11; + case CM_REG_UARCH_X12: + return reg::uarch_x12; + case CM_REG_UARCH_X13: + return reg::uarch_x13; + case CM_REG_UARCH_X14: + return reg::uarch_x14; + case CM_REG_UARCH_X15: + return reg::uarch_x15; + case CM_REG_UARCH_X16: + return reg::uarch_x16; + case CM_REG_UARCH_X17: + return reg::uarch_x17; + case CM_REG_UARCH_X18: + return reg::uarch_x18; + case CM_REG_UARCH_X19: + return reg::uarch_x19; + case CM_REG_UARCH_X20: + return reg::uarch_x20; + case CM_REG_UARCH_X21: + return reg::uarch_x21; + case CM_REG_UARCH_X22: + return reg::uarch_x22; + case CM_REG_UARCH_X23: + return reg::uarch_x23; + case CM_REG_UARCH_X24: + return reg::uarch_x24; + case CM_REG_UARCH_X25: + return reg::uarch_x25; + case CM_REG_UARCH_X26: + return reg::uarch_x26; + case CM_REG_UARCH_X27: + return reg::uarch_x27; + case CM_REG_UARCH_X28: + return reg::uarch_x28; + case CM_REG_UARCH_X29: + return reg::uarch_x29; + case CM_REG_UARCH_X30: + return reg::uarch_x30; + case CM_REG_UARCH_X31: + return reg::uarch_x31; + case CM_REG_UARCH_PC: + return reg::uarch_pc; + case CM_REG_UARCH_CYCLE: + return reg::uarch_cycle; + case CM_REG_UARCH_HALT_FLAG: + return reg::uarch_halt_flag; + case CM_REG_IFLAGS_PRV: + return reg::iflags_prv; + case CM_REG_IFLAGS_X: + return reg::iflags_x; + case CM_REG_IFLAGS_Y: + return reg::iflags_y; + case CM_REG_IFLAGS_H: + return reg::iflags_h; + case CM_REG_HTIF_TOHOST_DEV: + return reg::htif_tohost_dev; + case CM_REG_HTIF_TOHOST_CMD: + return reg::htif_tohost_cmd; + case CM_REG_HTIF_TOHOST_REASON: + return reg::htif_tohost_reason; + case CM_REG_HTIF_TOHOST_DATA: + return reg::htif_tohost_data; + case CM_REG_HTIF_FROMHOST_DEV: + return reg::htif_fromhost_dev; + case CM_REG_HTIF_FROMHOST_CMD: + return reg::htif_fromhost_cmd; + case CM_REG_HTIF_FROMHOST_REASON: + return reg::htif_fromhost_reason; + case CM_REG_HTIF_FROMHOST_DATA: + return reg::htif_fromhost_data; + case CM_REG_UNKNOWN_: + return reg::unknown_; + } + throw std::domain_error{"unknown register"}; +} + static cartesi::i_virtual_machine *convert_from_c(cm_machine *m) { if (m == nullptr) { throw std::invalid_argument("invalid machine"); @@ -348,6 +658,9 @@ CM_API cm_error cm_log_step(cm_machine *m, uint64_t mcycle_count, const char *lo } return cm_result_success(); } catch (...) { + if (break_reason != nullptr) { + *break_reason = CM_BREAK_REASON_FAILED; + } return cm_result_failure(); } @@ -386,6 +699,9 @@ cm_error cm_verify_step(const cm_machine *m, const cm_hash *root_hash_before, co } return cm_result_success(); } catch (...) { + if (break_reason != nullptr) { + *break_reason = CM_BREAK_REASON_FAILED; + } return cm_result_failure(); } @@ -476,7 +792,7 @@ cm_error cm_read_reg(const cm_machine *m, cm_reg reg, uint64_t *val) try { throw std::invalid_argument("invalid val output"); } const auto *cpp_m = convert_from_c(m); - auto cpp_reg = static_cast(reg); + auto cpp_reg = convert_from_c(reg); *val = cpp_m->read_reg(cpp_reg); return cm_result_success(); } catch (...) { @@ -488,7 +804,7 @@ cm_error cm_read_reg(const cm_machine *m, cm_reg reg, uint64_t *val) try { cm_error cm_write_reg(cm_machine *m, cm_reg reg, uint64_t val) try { auto *cpp_m = convert_from_c(m); - auto cpp_reg = static_cast(reg); + auto cpp_reg = convert_from_c(reg); cpp_m->write_reg(cpp_reg, val); return cm_result_success(); } catch (...) { @@ -499,7 +815,7 @@ cm_error cm_get_reg_address(const cm_machine *m, cm_reg reg, uint64_t *val) try if (val == nullptr) { throw std::invalid_argument("invalid val output"); } - auto cpp_reg = static_cast(reg); + auto cpp_reg = convert_from_c(reg); if (m != nullptr) { const auto *cpp_m = convert_from_c(m); *val = cpp_m->get_reg_address(cpp_reg); diff --git a/src/machine-c-api.h b/src/machine-c-api.h index 5c15c1ca6..d0d5770be 100644 --- a/src/machine-c-api.h +++ b/src/machine-c-api.h @@ -273,8 +273,6 @@ typedef enum cm_reg { CM_REG_UARCH_PC, CM_REG_UARCH_CYCLE, CM_REG_UARCH_HALT_FLAG, - // Amount of registers - CM_REG_COUNT, // Views of registers CM_REG_IFLAGS_PRV, CM_REG_IFLAGS_X, @@ -288,7 +286,10 @@ typedef enum cm_reg { CM_REG_HTIF_FROMHOST_CMD, CM_REG_HTIF_FROMHOST_REASON, CM_REG_HTIF_FROMHOST_DATA, - CM_REG_UNKNOWN, + // Enumeration helpers + CM_REG_UNKNOWN_, + CM_REG_FIRST_ = CM_REG_X0, + CM_REG_LAST_ = CM_REG_UARCH_HALT_FLAG, } cm_reg; /// \brief Storage for machine hash. @@ -625,7 +626,7 @@ CM_API cm_error cm_set_uarch_halt_flag(cm_machine *m); /// \brief Runs the machine until CM_REG_MCYCLE reaches mcycle_end, machine yields, or halts. /// \param m Pointer to a non-empty machine object (holds a machine instance). /// \param mcycle_end End cycle value. -/// \param break_reason Receives reason for returning (can be NULL). +/// \param break_reason Receives reason for returning (can be NULL). Set to CM_BREAK_REASON_FAILED on failure. /// \returns 0 for success, non zero code for error. /// \details You may want to receive cmio requests depending on the run break reason. CM_API cm_error cm_run(cm_machine *m, uint64_t mcycle_end, cm_break_reason *break_reason); @@ -676,7 +677,7 @@ CM_API cm_error cm_send_cmio_response(cm_machine *m, uint16_t reason, const uint /// \param m Pointer to a non-empty machine object (holds a machine instance). /// \param mcycle_count Number of mcycles to run /// \param log_filename Name of the log file to be generated -/// \param break_reason Receives reason for returning (can be NULL). +/// \param break_reason Receives reason for returning (can be NULL). Set to CM_BREAK_REASON_FAILED on failure. /// \returns 0 for success, non zero code for error. CM_API cm_error cm_log_step(cm_machine *m, uint64_t mcycle_count, const char *log_filename, cm_break_reason *break_reason_result); @@ -719,6 +720,7 @@ CM_API cm_error cm_log_send_cmio_response(cm_machine *m, uint16_t reason, const /// \param log_filename Path to the step log file to be verified /// \param mcycle_count Number of mcycles in the step /// \param root_hash_after State hash after step +/// \param break_reason Receives reason for returning (can be NULL). Set to CM_BREAK_REASON_FAILED on failure. /// \returns 0 for success, non zero code for error CM_API cm_error cm_verify_step(const cm_machine *m, const cm_hash *root_hash_before, const char *log_filename, uint64_t mcycle_count, const cm_hash *root_hash_after, cm_break_reason *break_reason); diff --git a/src/machine-reg.h b/src/machine-reg.h new file mode 100644 index 000000000..0adafed9b --- /dev/null +++ b/src/machine-reg.h @@ -0,0 +1,300 @@ +// Copyright Cartesi and individual authors (see AUTHORS) +// SPDX-License-Identifier: LGPL-3.0-or-later +// +// This program is free software: you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License as published by the Free +// Software Foundation, either version 3 of the License, or (at your option) any +// later version. +// +// This program is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +// PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License along +// with this program (see COPYING). If not, see . +// + +#ifndef MACHINE_REG_H +#define MACHINE_REG_H + +#include "pma-constants.h" +#include "shadow-state.h" +#include "shadow-uarch-state.h" + +/// \file +/// \brief Cartesi machine registers + +namespace cartesi { + +/// \brief List of machine registers +enum class machine_reg : uint64_t { + // Processor x registers + x0 = PMA_SHADOW_STATE_START + offsetof(shadow_state, x[0]), + x1 = PMA_SHADOW_STATE_START + offsetof(shadow_state, x[1]), + x2 = PMA_SHADOW_STATE_START + offsetof(shadow_state, x[2]), + x3 = PMA_SHADOW_STATE_START + offsetof(shadow_state, x[3]), + x4 = PMA_SHADOW_STATE_START + offsetof(shadow_state, x[4]), + x5 = PMA_SHADOW_STATE_START + offsetof(shadow_state, x[5]), + x6 = PMA_SHADOW_STATE_START + offsetof(shadow_state, x[6]), + x7 = PMA_SHADOW_STATE_START + offsetof(shadow_state, x[7]), + x8 = PMA_SHADOW_STATE_START + offsetof(shadow_state, x[8]), + x9 = PMA_SHADOW_STATE_START + offsetof(shadow_state, x[9]), + x10 = PMA_SHADOW_STATE_START + offsetof(shadow_state, x[10]), + x11 = PMA_SHADOW_STATE_START + offsetof(shadow_state, x[11]), + x12 = PMA_SHADOW_STATE_START + offsetof(shadow_state, x[12]), + x13 = PMA_SHADOW_STATE_START + offsetof(shadow_state, x[13]), + x14 = PMA_SHADOW_STATE_START + offsetof(shadow_state, x[14]), + x15 = PMA_SHADOW_STATE_START + offsetof(shadow_state, x[15]), + x16 = PMA_SHADOW_STATE_START + offsetof(shadow_state, x[16]), + x17 = PMA_SHADOW_STATE_START + offsetof(shadow_state, x[17]), + x18 = PMA_SHADOW_STATE_START + offsetof(shadow_state, x[18]), + x19 = PMA_SHADOW_STATE_START + offsetof(shadow_state, x[19]), + x20 = PMA_SHADOW_STATE_START + offsetof(shadow_state, x[20]), + x21 = PMA_SHADOW_STATE_START + offsetof(shadow_state, x[21]), + x22 = PMA_SHADOW_STATE_START + offsetof(shadow_state, x[22]), + x23 = PMA_SHADOW_STATE_START + offsetof(shadow_state, x[23]), + x24 = PMA_SHADOW_STATE_START + offsetof(shadow_state, x[24]), + x25 = PMA_SHADOW_STATE_START + offsetof(shadow_state, x[25]), + x26 = PMA_SHADOW_STATE_START + offsetof(shadow_state, x[26]), + x27 = PMA_SHADOW_STATE_START + offsetof(shadow_state, x[27]), + x28 = PMA_SHADOW_STATE_START + offsetof(shadow_state, x[28]), + x29 = PMA_SHADOW_STATE_START + offsetof(shadow_state, x[29]), + x30 = PMA_SHADOW_STATE_START + offsetof(shadow_state, x[30]), + x31 = PMA_SHADOW_STATE_START + offsetof(shadow_state, x[31]), + f0 = PMA_SHADOW_STATE_START + offsetof(shadow_state, f[0]), + f1 = PMA_SHADOW_STATE_START + offsetof(shadow_state, f[1]), + f2 = PMA_SHADOW_STATE_START + offsetof(shadow_state, f[2]), + f3 = PMA_SHADOW_STATE_START + offsetof(shadow_state, f[3]), + f4 = PMA_SHADOW_STATE_START + offsetof(shadow_state, f[4]), + f5 = PMA_SHADOW_STATE_START + offsetof(shadow_state, f[5]), + f6 = PMA_SHADOW_STATE_START + offsetof(shadow_state, f[6]), + f7 = PMA_SHADOW_STATE_START + offsetof(shadow_state, f[7]), + f8 = PMA_SHADOW_STATE_START + offsetof(shadow_state, f[8]), + f9 = PMA_SHADOW_STATE_START + offsetof(shadow_state, f[9]), + f10 = PMA_SHADOW_STATE_START + offsetof(shadow_state, f[10]), + f11 = PMA_SHADOW_STATE_START + offsetof(shadow_state, f[11]), + f12 = PMA_SHADOW_STATE_START + offsetof(shadow_state, f[12]), + f13 = PMA_SHADOW_STATE_START + offsetof(shadow_state, f[13]), + f14 = PMA_SHADOW_STATE_START + offsetof(shadow_state, f[14]), + f15 = PMA_SHADOW_STATE_START + offsetof(shadow_state, f[15]), + f16 = PMA_SHADOW_STATE_START + offsetof(shadow_state, f[16]), + f17 = PMA_SHADOW_STATE_START + offsetof(shadow_state, f[17]), + f18 = PMA_SHADOW_STATE_START + offsetof(shadow_state, f[18]), + f19 = PMA_SHADOW_STATE_START + offsetof(shadow_state, f[19]), + f20 = PMA_SHADOW_STATE_START + offsetof(shadow_state, f[20]), + f21 = PMA_SHADOW_STATE_START + offsetof(shadow_state, f[21]), + f22 = PMA_SHADOW_STATE_START + offsetof(shadow_state, f[22]), + f23 = PMA_SHADOW_STATE_START + offsetof(shadow_state, f[23]), + f24 = PMA_SHADOW_STATE_START + offsetof(shadow_state, f[24]), + f25 = PMA_SHADOW_STATE_START + offsetof(shadow_state, f[25]), + f26 = PMA_SHADOW_STATE_START + offsetof(shadow_state, f[26]), + f27 = PMA_SHADOW_STATE_START + offsetof(shadow_state, f[27]), + f28 = PMA_SHADOW_STATE_START + offsetof(shadow_state, f[28]), + f29 = PMA_SHADOW_STATE_START + offsetof(shadow_state, f[29]), + f30 = PMA_SHADOW_STATE_START + offsetof(shadow_state, f[30]), + f31 = PMA_SHADOW_STATE_START + offsetof(shadow_state, f[31]), + pc = PMA_SHADOW_STATE_START + offsetof(shadow_state, pc), + fcsr = PMA_SHADOW_STATE_START + offsetof(shadow_state, fcsr), + mvendorid = PMA_SHADOW_STATE_START + offsetof(shadow_state, mvendorid), + marchid = PMA_SHADOW_STATE_START + offsetof(shadow_state, marchid), + mimpid = PMA_SHADOW_STATE_START + offsetof(shadow_state, mimpid), + mcycle = PMA_SHADOW_STATE_START + offsetof(shadow_state, mcycle), + icycleinstret = PMA_SHADOW_STATE_START + offsetof(shadow_state, icycleinstret), + mstatus = PMA_SHADOW_STATE_START + offsetof(shadow_state, mstatus), + mtvec = PMA_SHADOW_STATE_START + offsetof(shadow_state, mtvec), + mscratch = PMA_SHADOW_STATE_START + offsetof(shadow_state, mscratch), + mepc = PMA_SHADOW_STATE_START + offsetof(shadow_state, mepc), + mcause = PMA_SHADOW_STATE_START + offsetof(shadow_state, mcause), + mtval = PMA_SHADOW_STATE_START + offsetof(shadow_state, mtval), + misa = PMA_SHADOW_STATE_START + offsetof(shadow_state, misa), + mie = PMA_SHADOW_STATE_START + offsetof(shadow_state, mie), + mip = PMA_SHADOW_STATE_START + offsetof(shadow_state, mip), + medeleg = PMA_SHADOW_STATE_START + offsetof(shadow_state, medeleg), + mideleg = PMA_SHADOW_STATE_START + offsetof(shadow_state, mideleg), + mcounteren = PMA_SHADOW_STATE_START + offsetof(shadow_state, mcounteren), + menvcfg = PMA_SHADOW_STATE_START + offsetof(shadow_state, menvcfg), + stvec = PMA_SHADOW_STATE_START + offsetof(shadow_state, stvec), + sscratch = PMA_SHADOW_STATE_START + offsetof(shadow_state, sscratch), + sepc = PMA_SHADOW_STATE_START + offsetof(shadow_state, sepc), + scause = PMA_SHADOW_STATE_START + offsetof(shadow_state, scause), + stval = PMA_SHADOW_STATE_START + offsetof(shadow_state, stval), + satp = PMA_SHADOW_STATE_START + offsetof(shadow_state, satp), + scounteren = PMA_SHADOW_STATE_START + offsetof(shadow_state, scounteren), + senvcfg = PMA_SHADOW_STATE_START + offsetof(shadow_state, senvcfg), + ilrsc = PMA_SHADOW_STATE_START + offsetof(shadow_state, ilrsc), + iflags = PMA_SHADOW_STATE_START + offsetof(shadow_state, iflags), + iunrep = PMA_SHADOW_STATE_START + offsetof(shadow_state, iunrep), + clint_mtimecmp = PMA_SHADOW_STATE_START + offsetof(shadow_state, clint_mtimecmp), + plic_girqpend = PMA_SHADOW_STATE_START + offsetof(shadow_state, plic_girqpend), + plic_girqsrvd = PMA_SHADOW_STATE_START + offsetof(shadow_state, plic_girqsrvd), + htif_tohost = PMA_SHADOW_STATE_START + offsetof(shadow_state, htif_tohost), + htif_fromhost = PMA_SHADOW_STATE_START + offsetof(shadow_state, htif_fromhost), + htif_ihalt = PMA_SHADOW_STATE_START + offsetof(shadow_state, htif_ihalt), + htif_iconsole = PMA_SHADOW_STATE_START + offsetof(shadow_state, htif_iconsole), + htif_iyield = PMA_SHADOW_STATE_START + offsetof(shadow_state, htif_iyield), + first_ = x0, + last_ = htif_iyield, + + uarch_halt_flag = PMA_SHADOW_UARCH_STATE_START + offsetof(shadow_uarch_state, halt_flag), + uarch_cycle = PMA_SHADOW_UARCH_STATE_START + offsetof(shadow_uarch_state, cycle), + uarch_pc = PMA_SHADOW_UARCH_STATE_START + offsetof(shadow_uarch_state, pc), + uarch_x0 = PMA_SHADOW_UARCH_STATE_START + offsetof(shadow_uarch_state, x[0]), + uarch_x1 = PMA_SHADOW_UARCH_STATE_START + offsetof(shadow_uarch_state, x[1]), + uarch_x2 = PMA_SHADOW_UARCH_STATE_START + offsetof(shadow_uarch_state, x[2]), + uarch_x3 = PMA_SHADOW_UARCH_STATE_START + offsetof(shadow_uarch_state, x[3]), + uarch_x4 = PMA_SHADOW_UARCH_STATE_START + offsetof(shadow_uarch_state, x[4]), + uarch_x5 = PMA_SHADOW_UARCH_STATE_START + offsetof(shadow_uarch_state, x[5]), + uarch_x6 = PMA_SHADOW_UARCH_STATE_START + offsetof(shadow_uarch_state, x[6]), + uarch_x7 = PMA_SHADOW_UARCH_STATE_START + offsetof(shadow_uarch_state, x[7]), + uarch_x8 = PMA_SHADOW_UARCH_STATE_START + offsetof(shadow_uarch_state, x[8]), + uarch_x9 = PMA_SHADOW_UARCH_STATE_START + offsetof(shadow_uarch_state, x[9]), + uarch_x10 = PMA_SHADOW_UARCH_STATE_START + offsetof(shadow_uarch_state, x[10]), + uarch_x11 = PMA_SHADOW_UARCH_STATE_START + offsetof(shadow_uarch_state, x[11]), + uarch_x12 = PMA_SHADOW_UARCH_STATE_START + offsetof(shadow_uarch_state, x[12]), + uarch_x13 = PMA_SHADOW_UARCH_STATE_START + offsetof(shadow_uarch_state, x[13]), + uarch_x14 = PMA_SHADOW_UARCH_STATE_START + offsetof(shadow_uarch_state, x[14]), + uarch_x15 = PMA_SHADOW_UARCH_STATE_START + offsetof(shadow_uarch_state, x[15]), + uarch_x16 = PMA_SHADOW_UARCH_STATE_START + offsetof(shadow_uarch_state, x[16]), + uarch_x17 = PMA_SHADOW_UARCH_STATE_START + offsetof(shadow_uarch_state, x[17]), + uarch_x18 = PMA_SHADOW_UARCH_STATE_START + offsetof(shadow_uarch_state, x[18]), + uarch_x19 = PMA_SHADOW_UARCH_STATE_START + offsetof(shadow_uarch_state, x[19]), + uarch_x20 = PMA_SHADOW_UARCH_STATE_START + offsetof(shadow_uarch_state, x[20]), + uarch_x21 = PMA_SHADOW_UARCH_STATE_START + offsetof(shadow_uarch_state, x[21]), + uarch_x22 = PMA_SHADOW_UARCH_STATE_START + offsetof(shadow_uarch_state, x[22]), + uarch_x23 = PMA_SHADOW_UARCH_STATE_START + offsetof(shadow_uarch_state, x[23]), + uarch_x24 = PMA_SHADOW_UARCH_STATE_START + offsetof(shadow_uarch_state, x[24]), + uarch_x25 = PMA_SHADOW_UARCH_STATE_START + offsetof(shadow_uarch_state, x[25]), + uarch_x26 = PMA_SHADOW_UARCH_STATE_START + offsetof(shadow_uarch_state, x[26]), + uarch_x27 = PMA_SHADOW_UARCH_STATE_START + offsetof(shadow_uarch_state, x[27]), + uarch_x28 = PMA_SHADOW_UARCH_STATE_START + offsetof(shadow_uarch_state, x[28]), + uarch_x29 = PMA_SHADOW_UARCH_STATE_START + offsetof(shadow_uarch_state, x[29]), + uarch_x30 = PMA_SHADOW_UARCH_STATE_START + offsetof(shadow_uarch_state, x[30]), + uarch_x31 = PMA_SHADOW_UARCH_STATE_START + offsetof(shadow_uarch_state, x[31]), + uarch_first_ = uarch_halt_flag, + uarch_last_ = uarch_x31, + + // Views of registers + iflags_prv, + iflags_x, + iflags_y, + iflags_h, + htif_tohost_dev, + htif_tohost_cmd, + htif_tohost_reason, + htif_tohost_data, + htif_fromhost_dev, + htif_fromhost_cmd, + htif_fromhost_reason, + htif_fromhost_data, + unknown_, +}; + +constexpr uint64_t machine_reg_address(machine_reg reg, int i = 0) { + return static_cast(reg) + i * sizeof(uint64_t); +} + +constexpr machine_reg machine_reg_enum(machine_reg reg, int i) { + return static_cast(static_cast(reg) + i * sizeof(uint64_t)); +} + +static_assert(machine_reg_address(machine_reg::uarch_first_) > machine_reg_address(machine_reg::last_)); + +static_assert(machine_reg_address(machine_reg::x0, 1) == machine_reg_address(machine_reg::x1)); +static_assert(machine_reg_address(machine_reg::x0, 2) == machine_reg_address(machine_reg::x2)); +static_assert(machine_reg_address(machine_reg::x0, 3) == machine_reg_address(machine_reg::x3)); +static_assert(machine_reg_address(machine_reg::x0, 4) == machine_reg_address(machine_reg::x4)); +static_assert(machine_reg_address(machine_reg::x0, 5) == machine_reg_address(machine_reg::x5)); +static_assert(machine_reg_address(machine_reg::x0, 6) == machine_reg_address(machine_reg::x6)); +static_assert(machine_reg_address(machine_reg::x0, 7) == machine_reg_address(machine_reg::x7)); +static_assert(machine_reg_address(machine_reg::x0, 8) == machine_reg_address(machine_reg::x8)); +static_assert(machine_reg_address(machine_reg::x0, 9) == machine_reg_address(machine_reg::x9)); +static_assert(machine_reg_address(machine_reg::x0, 10) == machine_reg_address(machine_reg::x10)); +static_assert(machine_reg_address(machine_reg::x0, 11) == machine_reg_address(machine_reg::x11)); +static_assert(machine_reg_address(machine_reg::x0, 12) == machine_reg_address(machine_reg::x12)); +static_assert(machine_reg_address(machine_reg::x0, 13) == machine_reg_address(machine_reg::x13)); +static_assert(machine_reg_address(machine_reg::x0, 14) == machine_reg_address(machine_reg::x14)); +static_assert(machine_reg_address(machine_reg::x0, 15) == machine_reg_address(machine_reg::x15)); +static_assert(machine_reg_address(machine_reg::x0, 16) == machine_reg_address(machine_reg::x16)); +static_assert(machine_reg_address(machine_reg::x0, 17) == machine_reg_address(machine_reg::x17)); +static_assert(machine_reg_address(machine_reg::x0, 18) == machine_reg_address(machine_reg::x18)); +static_assert(machine_reg_address(machine_reg::x0, 19) == machine_reg_address(machine_reg::x19)); +static_assert(machine_reg_address(machine_reg::x0, 20) == machine_reg_address(machine_reg::x20)); +static_assert(machine_reg_address(machine_reg::x0, 21) == machine_reg_address(machine_reg::x21)); +static_assert(machine_reg_address(machine_reg::x0, 22) == machine_reg_address(machine_reg::x22)); +static_assert(machine_reg_address(machine_reg::x0, 23) == machine_reg_address(machine_reg::x23)); +static_assert(machine_reg_address(machine_reg::x0, 24) == machine_reg_address(machine_reg::x24)); +static_assert(machine_reg_address(machine_reg::x0, 25) == machine_reg_address(machine_reg::x25)); +static_assert(machine_reg_address(machine_reg::x0, 26) == machine_reg_address(machine_reg::x26)); +static_assert(machine_reg_address(machine_reg::x0, 27) == machine_reg_address(machine_reg::x27)); +static_assert(machine_reg_address(machine_reg::x0, 28) == machine_reg_address(machine_reg::x28)); +static_assert(machine_reg_address(machine_reg::x0, 29) == machine_reg_address(machine_reg::x29)); +static_assert(machine_reg_address(machine_reg::x0, 30) == machine_reg_address(machine_reg::x30)); +static_assert(machine_reg_address(machine_reg::x0, 31) == machine_reg_address(machine_reg::x31)); + +static_assert(machine_reg_address(machine_reg::f0, 1) == machine_reg_address(machine_reg::f1)); +static_assert(machine_reg_address(machine_reg::f0, 2) == machine_reg_address(machine_reg::f2)); +static_assert(machine_reg_address(machine_reg::f0, 3) == machine_reg_address(machine_reg::f3)); +static_assert(machine_reg_address(machine_reg::f0, 4) == machine_reg_address(machine_reg::f4)); +static_assert(machine_reg_address(machine_reg::f0, 5) == machine_reg_address(machine_reg::f5)); +static_assert(machine_reg_address(machine_reg::f0, 6) == machine_reg_address(machine_reg::f6)); +static_assert(machine_reg_address(machine_reg::f0, 7) == machine_reg_address(machine_reg::f7)); +static_assert(machine_reg_address(machine_reg::f0, 8) == machine_reg_address(machine_reg::f8)); +static_assert(machine_reg_address(machine_reg::f0, 9) == machine_reg_address(machine_reg::f9)); +static_assert(machine_reg_address(machine_reg::f0, 10) == machine_reg_address(machine_reg::f10)); +static_assert(machine_reg_address(machine_reg::f0, 11) == machine_reg_address(machine_reg::f11)); +static_assert(machine_reg_address(machine_reg::f0, 12) == machine_reg_address(machine_reg::f12)); +static_assert(machine_reg_address(machine_reg::f0, 13) == machine_reg_address(machine_reg::f13)); +static_assert(machine_reg_address(machine_reg::f0, 14) == machine_reg_address(machine_reg::f14)); +static_assert(machine_reg_address(machine_reg::f0, 15) == machine_reg_address(machine_reg::f15)); +static_assert(machine_reg_address(machine_reg::f0, 16) == machine_reg_address(machine_reg::f16)); +static_assert(machine_reg_address(machine_reg::f0, 17) == machine_reg_address(machine_reg::f17)); +static_assert(machine_reg_address(machine_reg::f0, 18) == machine_reg_address(machine_reg::f18)); +static_assert(machine_reg_address(machine_reg::f0, 19) == machine_reg_address(machine_reg::f19)); +static_assert(machine_reg_address(machine_reg::f0, 20) == machine_reg_address(machine_reg::f20)); +static_assert(machine_reg_address(machine_reg::f0, 21) == machine_reg_address(machine_reg::f21)); +static_assert(machine_reg_address(machine_reg::f0, 22) == machine_reg_address(machine_reg::f22)); +static_assert(machine_reg_address(machine_reg::f0, 23) == machine_reg_address(machine_reg::f23)); +static_assert(machine_reg_address(machine_reg::f0, 24) == machine_reg_address(machine_reg::f24)); +static_assert(machine_reg_address(machine_reg::f0, 25) == machine_reg_address(machine_reg::f25)); +static_assert(machine_reg_address(machine_reg::f0, 26) == machine_reg_address(machine_reg::f26)); +static_assert(machine_reg_address(machine_reg::f0, 27) == machine_reg_address(machine_reg::f27)); +static_assert(machine_reg_address(machine_reg::f0, 28) == machine_reg_address(machine_reg::f28)); +static_assert(machine_reg_address(machine_reg::f0, 29) == machine_reg_address(machine_reg::f29)); +static_assert(machine_reg_address(machine_reg::f0, 30) == machine_reg_address(machine_reg::f30)); +static_assert(machine_reg_address(machine_reg::f0, 31) == machine_reg_address(machine_reg::f31)); + +static_assert(machine_reg_address(machine_reg::uarch_x0, 1) == machine_reg_address(machine_reg::uarch_x1)); +static_assert(machine_reg_address(machine_reg::uarch_x0, 2) == machine_reg_address(machine_reg::uarch_x2)); +static_assert(machine_reg_address(machine_reg::uarch_x0, 3) == machine_reg_address(machine_reg::uarch_x3)); +static_assert(machine_reg_address(machine_reg::uarch_x0, 4) == machine_reg_address(machine_reg::uarch_x4)); +static_assert(machine_reg_address(machine_reg::uarch_x0, 5) == machine_reg_address(machine_reg::uarch_x5)); +static_assert(machine_reg_address(machine_reg::uarch_x0, 6) == machine_reg_address(machine_reg::uarch_x6)); +static_assert(machine_reg_address(machine_reg::uarch_x0, 7) == machine_reg_address(machine_reg::uarch_x7)); +static_assert(machine_reg_address(machine_reg::uarch_x0, 8) == machine_reg_address(machine_reg::uarch_x8)); +static_assert(machine_reg_address(machine_reg::uarch_x0, 9) == machine_reg_address(machine_reg::uarch_x9)); +static_assert(machine_reg_address(machine_reg::uarch_x0, 10) == machine_reg_address(machine_reg::uarch_x10)); +static_assert(machine_reg_address(machine_reg::uarch_x0, 11) == machine_reg_address(machine_reg::uarch_x11)); +static_assert(machine_reg_address(machine_reg::uarch_x0, 12) == machine_reg_address(machine_reg::uarch_x12)); +static_assert(machine_reg_address(machine_reg::uarch_x0, 13) == machine_reg_address(machine_reg::uarch_x13)); +static_assert(machine_reg_address(machine_reg::uarch_x0, 14) == machine_reg_address(machine_reg::uarch_x14)); +static_assert(machine_reg_address(machine_reg::uarch_x0, 15) == machine_reg_address(machine_reg::uarch_x15)); +static_assert(machine_reg_address(machine_reg::uarch_x0, 16) == machine_reg_address(machine_reg::uarch_x16)); +static_assert(machine_reg_address(machine_reg::uarch_x0, 17) == machine_reg_address(machine_reg::uarch_x17)); +static_assert(machine_reg_address(machine_reg::uarch_x0, 18) == machine_reg_address(machine_reg::uarch_x18)); +static_assert(machine_reg_address(machine_reg::uarch_x0, 19) == machine_reg_address(machine_reg::uarch_x19)); +static_assert(machine_reg_address(machine_reg::uarch_x0, 20) == machine_reg_address(machine_reg::uarch_x20)); +static_assert(machine_reg_address(machine_reg::uarch_x0, 21) == machine_reg_address(machine_reg::uarch_x21)); +static_assert(machine_reg_address(machine_reg::uarch_x0, 22) == machine_reg_address(machine_reg::uarch_x22)); +static_assert(machine_reg_address(machine_reg::uarch_x0, 23) == machine_reg_address(machine_reg::uarch_x23)); +static_assert(machine_reg_address(machine_reg::uarch_x0, 24) == machine_reg_address(machine_reg::uarch_x24)); +static_assert(machine_reg_address(machine_reg::uarch_x0, 25) == machine_reg_address(machine_reg::uarch_x25)); +static_assert(machine_reg_address(machine_reg::uarch_x0, 26) == machine_reg_address(machine_reg::uarch_x26)); +static_assert(machine_reg_address(machine_reg::uarch_x0, 27) == machine_reg_address(machine_reg::uarch_x27)); +static_assert(machine_reg_address(machine_reg::uarch_x0, 28) == machine_reg_address(machine_reg::uarch_x28)); +static_assert(machine_reg_address(machine_reg::uarch_x0, 29) == machine_reg_address(machine_reg::uarch_x29)); +static_assert(machine_reg_address(machine_reg::uarch_x0, 30) == machine_reg_address(machine_reg::uarch_x30)); +static_assert(machine_reg_address(machine_reg::uarch_x0, 31) == machine_reg_address(machine_reg::uarch_x31)); + +} // namespace cartesi + +#endif // MACHINE_REG_H diff --git a/src/machine.cpp b/src/machine.cpp index 715e85775..8525836b3 100644 --- a/src/machine.cpp +++ b/src/machine.cpp @@ -306,14 +306,15 @@ machine::machine(const machine_config &c, const machine_runtime_config &r) : m_c // General purpose registers for (int i = 1; i < X_REG_COUNT; i++) { - write_reg(static_cast(reg::x0 + i), m_c.processor.x[i]); + write_reg(machine_reg_enum(reg::x0, i), m_c.processor.x[i]); } // Floating-point registers for (int i = 0; i < F_REG_COUNT; i++) { - write_reg(static_cast(reg::f0 + i), m_c.processor.f[i]); + write_reg(machine_reg_enum(reg::f0, i), m_c.processor.f[i]); } + // Named registers write_reg(reg::pc, m_c.processor.pc); write_reg(reg::fcsr, m_c.processor.fcsr); write_reg(reg::mcycle, m_c.processor.mcycle); @@ -633,10 +634,10 @@ machine_config machine::get_serialization_config() const { machine_config c = m_c; // Copy current processor state to config for (int i = 1; i < X_REG_COUNT; ++i) { - c.processor.x[i] = read_reg(static_cast(reg::x0 + i)); + c.processor.x[i] = read_reg(machine_reg_enum(reg::x0, i)); } for (int i = 0; i < F_REG_COUNT; ++i) { - c.processor.f[i] = read_reg(static_cast(reg::f0 + i)); + c.processor.f[i] = read_reg(machine_reg_enum(reg::f0, i)); } c.processor.pc = read_reg(reg::pc); c.processor.fcsr = read_reg(reg::fcsr); @@ -699,7 +700,7 @@ machine_config machine::get_serialization_config() const { c.uarch.processor.halt_flag = (read_reg(reg::uarch_halt_flag) != 0); c.uarch.processor.pc = read_reg(reg::uarch_pc); for (int i = 1; i < UARCH_X_REG_COUNT; i++) { - c.uarch.processor.x[i] = read_reg(static_cast(reg::uarch_x0 + i)); + c.uarch.processor.x[i] = read_reg(machine_reg_enum(reg::uarch_x0, i)); } return c; } @@ -1642,286 +1643,15 @@ void machine::write_reg(reg w, uint64_t value) { } uint64_t machine::get_reg_address(reg r) { - switch (r) { - case reg::x0: - return shadow_state_get_reg_abs_addr(shadow_state_reg::x0); - case reg::x1: - return shadow_state_get_reg_abs_addr(shadow_state_reg::x1); - case reg::x2: - return shadow_state_get_reg_abs_addr(shadow_state_reg::x2); - case reg::x3: - return shadow_state_get_reg_abs_addr(shadow_state_reg::x3); - case reg::x4: - return shadow_state_get_reg_abs_addr(shadow_state_reg::x4); - case reg::x5: - return shadow_state_get_reg_abs_addr(shadow_state_reg::x5); - case reg::x6: - return shadow_state_get_reg_abs_addr(shadow_state_reg::x6); - case reg::x7: - return shadow_state_get_reg_abs_addr(shadow_state_reg::x7); - case reg::x8: - return shadow_state_get_reg_abs_addr(shadow_state_reg::x8); - case reg::x9: - return shadow_state_get_reg_abs_addr(shadow_state_reg::x9); - case reg::x10: - return shadow_state_get_reg_abs_addr(shadow_state_reg::x10); - case reg::x11: - return shadow_state_get_reg_abs_addr(shadow_state_reg::x11); - case reg::x12: - return shadow_state_get_reg_abs_addr(shadow_state_reg::x12); - case reg::x13: - return shadow_state_get_reg_abs_addr(shadow_state_reg::x13); - case reg::x14: - return shadow_state_get_reg_abs_addr(shadow_state_reg::x14); - case reg::x15: - return shadow_state_get_reg_abs_addr(shadow_state_reg::x15); - case reg::x16: - return shadow_state_get_reg_abs_addr(shadow_state_reg::x16); - case reg::x17: - return shadow_state_get_reg_abs_addr(shadow_state_reg::x17); - case reg::x18: - return shadow_state_get_reg_abs_addr(shadow_state_reg::x18); - case reg::x19: - return shadow_state_get_reg_abs_addr(shadow_state_reg::x19); - case reg::x20: - return shadow_state_get_reg_abs_addr(shadow_state_reg::x20); - case reg::x21: - return shadow_state_get_reg_abs_addr(shadow_state_reg::x21); - case reg::x22: - return shadow_state_get_reg_abs_addr(shadow_state_reg::x22); - case reg::x23: - return shadow_state_get_reg_abs_addr(shadow_state_reg::x23); - case reg::x24: - return shadow_state_get_reg_abs_addr(shadow_state_reg::x24); - case reg::x25: - return shadow_state_get_reg_abs_addr(shadow_state_reg::x25); - case reg::x26: - return shadow_state_get_reg_abs_addr(shadow_state_reg::x26); - case reg::x27: - return shadow_state_get_reg_abs_addr(shadow_state_reg::x27); - case reg::x28: - return shadow_state_get_reg_abs_addr(shadow_state_reg::x28); - case reg::x29: - return shadow_state_get_reg_abs_addr(shadow_state_reg::x29); - case reg::x30: - return shadow_state_get_reg_abs_addr(shadow_state_reg::x30); - case reg::x31: - return shadow_state_get_reg_abs_addr(shadow_state_reg::x31); - case reg::f0: - return shadow_state_get_reg_abs_addr(shadow_state_reg::f0); - case reg::f1: - return shadow_state_get_reg_abs_addr(shadow_state_reg::f1); - case reg::f2: - return shadow_state_get_reg_abs_addr(shadow_state_reg::f2); - case reg::f3: - return shadow_state_get_reg_abs_addr(shadow_state_reg::f3); - case reg::f4: - return shadow_state_get_reg_abs_addr(shadow_state_reg::f4); - case reg::f5: - return shadow_state_get_reg_abs_addr(shadow_state_reg::f5); - case reg::f6: - return shadow_state_get_reg_abs_addr(shadow_state_reg::f6); - case reg::f7: - return shadow_state_get_reg_abs_addr(shadow_state_reg::f7); - case reg::f8: - return shadow_state_get_reg_abs_addr(shadow_state_reg::f8); - case reg::f9: - return shadow_state_get_reg_abs_addr(shadow_state_reg::f9); - case reg::f10: - return shadow_state_get_reg_abs_addr(shadow_state_reg::f10); - case reg::f11: - return shadow_state_get_reg_abs_addr(shadow_state_reg::f11); - case reg::f12: - return shadow_state_get_reg_abs_addr(shadow_state_reg::f12); - case reg::f13: - return shadow_state_get_reg_abs_addr(shadow_state_reg::f13); - case reg::f14: - return shadow_state_get_reg_abs_addr(shadow_state_reg::f14); - case reg::f15: - return shadow_state_get_reg_abs_addr(shadow_state_reg::f15); - case reg::f16: - return shadow_state_get_reg_abs_addr(shadow_state_reg::f16); - case reg::f17: - return shadow_state_get_reg_abs_addr(shadow_state_reg::f17); - case reg::f18: - return shadow_state_get_reg_abs_addr(shadow_state_reg::f18); - case reg::f19: - return shadow_state_get_reg_abs_addr(shadow_state_reg::f19); - case reg::f20: - return shadow_state_get_reg_abs_addr(shadow_state_reg::f20); - case reg::f21: - return shadow_state_get_reg_abs_addr(shadow_state_reg::f21); - case reg::f22: - return shadow_state_get_reg_abs_addr(shadow_state_reg::f22); - case reg::f23: - return shadow_state_get_reg_abs_addr(shadow_state_reg::f23); - case reg::f24: - return shadow_state_get_reg_abs_addr(shadow_state_reg::f24); - case reg::f25: - return shadow_state_get_reg_abs_addr(shadow_state_reg::f25); - case reg::f26: - return shadow_state_get_reg_abs_addr(shadow_state_reg::f26); - case reg::f27: - return shadow_state_get_reg_abs_addr(shadow_state_reg::f27); - case reg::f28: - return shadow_state_get_reg_abs_addr(shadow_state_reg::f28); - case reg::f29: - return shadow_state_get_reg_abs_addr(shadow_state_reg::f29); - case reg::f30: - return shadow_state_get_reg_abs_addr(shadow_state_reg::f30); - case reg::f31: - return shadow_state_get_reg_abs_addr(shadow_state_reg::f31); - case reg::pc: - return shadow_state_get_reg_abs_addr(shadow_state_reg::pc); - case reg::fcsr: - return shadow_state_get_reg_abs_addr(shadow_state_reg::fcsr); - case reg::mvendorid: - return shadow_state_get_reg_abs_addr(shadow_state_reg::mvendorid); - case reg::marchid: - return shadow_state_get_reg_abs_addr(shadow_state_reg::marchid); - case reg::mimpid: - return shadow_state_get_reg_abs_addr(shadow_state_reg::mimpid); - case reg::mcycle: - return shadow_state_get_reg_abs_addr(shadow_state_reg::mcycle); - case reg::icycleinstret: - return shadow_state_get_reg_abs_addr(shadow_state_reg::icycleinstret); - case reg::mstatus: - return shadow_state_get_reg_abs_addr(shadow_state_reg::mstatus); - case reg::mtvec: - return shadow_state_get_reg_abs_addr(shadow_state_reg::mtvec); - case reg::mscratch: - return shadow_state_get_reg_abs_addr(shadow_state_reg::mscratch); - case reg::mepc: - return shadow_state_get_reg_abs_addr(shadow_state_reg::mepc); - case reg::mcause: - return shadow_state_get_reg_abs_addr(shadow_state_reg::mcause); - case reg::mtval: - return shadow_state_get_reg_abs_addr(shadow_state_reg::mtval); - case reg::misa: - return shadow_state_get_reg_abs_addr(shadow_state_reg::misa); - case reg::mie: - return shadow_state_get_reg_abs_addr(shadow_state_reg::mie); - case reg::mip: - return shadow_state_get_reg_abs_addr(shadow_state_reg::mip); - case reg::medeleg: - return shadow_state_get_reg_abs_addr(shadow_state_reg::medeleg); - case reg::mideleg: - return shadow_state_get_reg_abs_addr(shadow_state_reg::mideleg); - case reg::mcounteren: - return shadow_state_get_reg_abs_addr(shadow_state_reg::mcounteren); - case reg::menvcfg: - return shadow_state_get_reg_abs_addr(shadow_state_reg::menvcfg); - case reg::stvec: - return shadow_state_get_reg_abs_addr(shadow_state_reg::stvec); - case reg::sscratch: - return shadow_state_get_reg_abs_addr(shadow_state_reg::sscratch); - case reg::sepc: - return shadow_state_get_reg_abs_addr(shadow_state_reg::sepc); - case reg::scause: - return shadow_state_get_reg_abs_addr(shadow_state_reg::scause); - case reg::stval: - return shadow_state_get_reg_abs_addr(shadow_state_reg::stval); - case reg::satp: - return shadow_state_get_reg_abs_addr(shadow_state_reg::satp); - case reg::scounteren: - return shadow_state_get_reg_abs_addr(shadow_state_reg::scounteren); - case reg::senvcfg: - return shadow_state_get_reg_abs_addr(shadow_state_reg::senvcfg); - case reg::ilrsc: - return shadow_state_get_reg_abs_addr(shadow_state_reg::ilrsc); - case reg::iflags: - return shadow_state_get_reg_abs_addr(shadow_state_reg::iflags); - case reg::iunrep: - return shadow_state_get_reg_abs_addr(shadow_state_reg::iunrep); - case reg::htif_tohost: - return shadow_state_get_reg_abs_addr(shadow_state_reg::htif_tohost); - case reg::htif_fromhost: - return shadow_state_get_reg_abs_addr(shadow_state_reg::htif_fromhost); - case reg::htif_ihalt: - return shadow_state_get_reg_abs_addr(shadow_state_reg::htif_ihalt); - case reg::htif_iconsole: - return shadow_state_get_reg_abs_addr(shadow_state_reg::htif_iconsole); - case reg::htif_iyield: - return shadow_state_get_reg_abs_addr(shadow_state_reg::htif_iyield); - case reg::clint_mtimecmp: - return shadow_state_get_reg_abs_addr(shadow_state_reg::clint_mtimecmp); - case reg::plic_girqpend: - return shadow_state_get_reg_abs_addr(shadow_state_reg::plic_girqpend); - case reg::plic_girqsrvd: - return shadow_state_get_reg_abs_addr(shadow_state_reg::plic_girqsrvd); - case reg::uarch_x0: - return shadow_uarch_state_get_reg_abs_addr(shadow_uarch_state_reg::x0); - case reg::uarch_x1: - return shadow_uarch_state_get_reg_abs_addr(shadow_uarch_state_reg::x1); - case reg::uarch_x2: - return shadow_uarch_state_get_reg_abs_addr(shadow_uarch_state_reg::x2); - case reg::uarch_x3: - return shadow_uarch_state_get_reg_abs_addr(shadow_uarch_state_reg::x3); - case reg::uarch_x4: - return shadow_uarch_state_get_reg_abs_addr(shadow_uarch_state_reg::x4); - case reg::uarch_x5: - return shadow_uarch_state_get_reg_abs_addr(shadow_uarch_state_reg::x5); - case reg::uarch_x6: - return shadow_uarch_state_get_reg_abs_addr(shadow_uarch_state_reg::x6); - case reg::uarch_x7: - return shadow_uarch_state_get_reg_abs_addr(shadow_uarch_state_reg::x7); - case reg::uarch_x8: - return shadow_uarch_state_get_reg_abs_addr(shadow_uarch_state_reg::x8); - case reg::uarch_x9: - return shadow_uarch_state_get_reg_abs_addr(shadow_uarch_state_reg::x9); - case reg::uarch_x10: - return shadow_uarch_state_get_reg_abs_addr(shadow_uarch_state_reg::x10); - case reg::uarch_x11: - return shadow_uarch_state_get_reg_abs_addr(shadow_uarch_state_reg::x11); - case reg::uarch_x12: - return shadow_uarch_state_get_reg_abs_addr(shadow_uarch_state_reg::x12); - case reg::uarch_x13: - return shadow_uarch_state_get_reg_abs_addr(shadow_uarch_state_reg::x13); - case reg::uarch_x14: - return shadow_uarch_state_get_reg_abs_addr(shadow_uarch_state_reg::x14); - case reg::uarch_x15: - return shadow_uarch_state_get_reg_abs_addr(shadow_uarch_state_reg::x15); - case reg::uarch_x16: - return shadow_uarch_state_get_reg_abs_addr(shadow_uarch_state_reg::x16); - case reg::uarch_x17: - return shadow_uarch_state_get_reg_abs_addr(shadow_uarch_state_reg::x17); - case reg::uarch_x18: - return shadow_uarch_state_get_reg_abs_addr(shadow_uarch_state_reg::x18); - case reg::uarch_x19: - return shadow_uarch_state_get_reg_abs_addr(shadow_uarch_state_reg::x19); - case reg::uarch_x20: - return shadow_uarch_state_get_reg_abs_addr(shadow_uarch_state_reg::x20); - case reg::uarch_x21: - return shadow_uarch_state_get_reg_abs_addr(shadow_uarch_state_reg::x21); - case reg::uarch_x22: - return shadow_uarch_state_get_reg_abs_addr(shadow_uarch_state_reg::x22); - case reg::uarch_x23: - return shadow_uarch_state_get_reg_abs_addr(shadow_uarch_state_reg::x23); - case reg::uarch_x24: - return shadow_uarch_state_get_reg_abs_addr(shadow_uarch_state_reg::x24); - case reg::uarch_x25: - return shadow_uarch_state_get_reg_abs_addr(shadow_uarch_state_reg::x25); - case reg::uarch_x26: - return shadow_uarch_state_get_reg_abs_addr(shadow_uarch_state_reg::x26); - case reg::uarch_x27: - return shadow_uarch_state_get_reg_abs_addr(shadow_uarch_state_reg::x27); - case reg::uarch_x28: - return shadow_uarch_state_get_reg_abs_addr(shadow_uarch_state_reg::x28); - case reg::uarch_x29: - return shadow_uarch_state_get_reg_abs_addr(shadow_uarch_state_reg::x29); - case reg::uarch_x30: - return shadow_uarch_state_get_reg_abs_addr(shadow_uarch_state_reg::x30); - case reg::uarch_x31: - return shadow_uarch_state_get_reg_abs_addr(shadow_uarch_state_reg::x31); - case reg::uarch_pc: - return shadow_uarch_state_get_reg_abs_addr(shadow_uarch_state_reg::pc); - case reg::uarch_cycle: - return shadow_uarch_state_get_reg_abs_addr(shadow_uarch_state_reg::cycle); - case reg::uarch_halt_flag: - return shadow_uarch_state_get_reg_abs_addr(shadow_uarch_state_reg::halt_flag); - default: - throw std::invalid_argument{"unknown register"}; + if (machine_reg_address(r) >= machine_reg_address(reg::uarch_first_) && + machine_reg_address(r) <= machine_reg_address(reg::uarch_last_)) { + return machine_reg_address(r); + } + if (machine_reg_address(r) >= machine_reg_address(reg::first_) && + machine_reg_address(r) <= machine_reg_address(reg::last_)) { + return machine_reg_address(r); } + throw std::domain_error{"invalid register"}; } void machine::mark_write_tlb_dirty_pages() const { diff --git a/src/machine.h b/src/machine.h index 859905149..2c500d33c 100644 --- a/src/machine.h +++ b/src/machine.h @@ -33,6 +33,7 @@ #include "machine-config.h" #include "machine-memory-range-descr.h" #include "machine-merkle-tree.h" +#include "machine-reg.h" #include "machine-runtime-config.h" #include "machine-state.h" #include "os.h" @@ -128,168 +129,7 @@ class machine final { /// \brief Type of hash using hash_type = machine_merkle_tree::hash_type; - /// \brief List of register to use with read_reg and write_reg - enum reg { - // Processor x registers - x0 = 0, - x1, - x2, - x3, - x4, - x5, - x6, - x7, - x8, - x9, - x10, - x11, - x12, - x13, - x14, - x15, - x16, - x17, - x18, - x19, - x20, - x21, - x22, - x23, - x24, - x25, - x26, - x27, - x28, - x29, - x30, - x31, - // Processor f registers - f0, - f1, - f2, - f3, - f4, - f5, - f6, - f7, - f8, - f9, - f10, - f11, - f12, - f13, - f14, - f15, - f16, - f17, - f18, - f19, - f20, - f21, - f22, - f23, - f24, - f25, - f26, - f27, - f28, - f29, - f30, - f31, - // Processor CSRs - pc, - fcsr, - mvendorid, - marchid, - mimpid, - mcycle, - icycleinstret, - mstatus, - mtvec, - mscratch, - mepc, - mcause, - mtval, - misa, - mie, - mip, - medeleg, - mideleg, - mcounteren, - menvcfg, - stvec, - sscratch, - sepc, - scause, - stval, - satp, - scounteren, - senvcfg, - ilrsc, - iflags, - iunrep, - clint_mtimecmp, - plic_girqpend, - plic_girqsrvd, - htif_tohost, - htif_fromhost, - htif_ihalt, - htif_iconsole, - htif_iyield, - // Microarchitecture processor - uarch_x0, - uarch_x1, - uarch_x2, - uarch_x3, - uarch_x4, - uarch_x5, - uarch_x6, - uarch_x7, - uarch_x8, - uarch_x9, - uarch_x10, - uarch_x11, - uarch_x12, - uarch_x13, - uarch_x14, - uarch_x15, - uarch_x16, - uarch_x17, - uarch_x18, - uarch_x19, - uarch_x20, - uarch_x21, - uarch_x22, - uarch_x23, - uarch_x24, - uarch_x25, - uarch_x26, - uarch_x27, - uarch_x28, - uarch_x29, - uarch_x30, - uarch_x31, - uarch_pc, - uarch_cycle, - uarch_halt_flag, - last, - // Views of registers - iflags_prv, - iflags_x, - iflags_y, - iflags_h, - htif_tohost_dev, - htif_tohost_cmd, - htif_tohost_reason, - htif_tohost_data, - htif_fromhost_dev, - htif_fromhost_cmd, - htif_fromhost_reason, - htif_fromhost_data, - unknown, - }; - - static constexpr auto num_reg = static_cast(reg::last); + using reg = machine_reg; /// \brief Constructor from machine configuration /// \param config Machine config to use instantiating machine diff --git a/src/record-state-access.h b/src/record-state-access.h index fcc0800dd..f7e7a4804 100644 --- a/src/record-state-access.h +++ b/src/record-state-access.h @@ -202,7 +202,7 @@ class record_state_access : public i_state_access(m_m.get_state().iflags.X), 0 /* Y */, static_cast(m_m.get_state().iflags.H)); - const uint64_t iflags_addr = shadow_state_get_reg_abs_addr(shadow_state_reg::iflags); + const uint64_t iflags_addr = machine_reg_address(machine_reg::iflags); log_read(iflags_addr, "iflags.Y"); log_before_write(iflags_addr, new_iflags, "iflags.Y"); m_m.get_state().iflags.Y = false; @@ -210,12 +210,12 @@ class record_state_access : public i_state_access(shadow_state_get_x_abs_addr(reg)); + return raw_read_memory(machine_reg_address(machine_reg::x0, reg)); } void do_write_x(int reg, uint64_t val) { - raw_write_memory(shadow_state_get_x_abs_addr(reg), val); + raw_write_memory(machine_reg_address(machine_reg::x0, reg), val); } uint64_t do_read_f(int reg) { - return raw_read_memory(shadow_state_get_f_abs_addr(reg)); + return raw_read_memory(machine_reg_address(machine_reg::f0, reg)); } void do_write_f(int reg, uint64_t val) { - raw_write_memory(shadow_state_get_f_abs_addr(reg), val); + raw_write_memory(machine_reg_address(machine_reg::f0, reg), val); } uint64_t do_read_pc() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::pc)); + return raw_read_memory(machine_reg_address(machine_reg::pc)); } void do_write_pc(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::pc), val); + raw_write_memory(machine_reg_address(machine_reg::pc), val); } uint64_t do_read_fcsr() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::fcsr)); + return raw_read_memory(machine_reg_address(machine_reg::fcsr)); } void do_write_fcsr(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::fcsr), val); + raw_write_memory(machine_reg_address(machine_reg::fcsr), val); } uint64_t do_read_icycleinstret() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::icycleinstret)); + return raw_read_memory(machine_reg_address(machine_reg::icycleinstret)); } void do_write_icycleinstret(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::icycleinstret), val); + raw_write_memory(machine_reg_address(machine_reg::icycleinstret), val); } uint64_t do_read_mvendorid() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mvendorid)); + return raw_read_memory(machine_reg_address(machine_reg::mvendorid)); } uint64_t do_read_marchid() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::marchid)); + return raw_read_memory(machine_reg_address(machine_reg::marchid)); } uint64_t do_read_mimpid() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mimpid)); + return raw_read_memory(machine_reg_address(machine_reg::mimpid)); } uint64_t do_read_mcycle() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mcycle)); + return raw_read_memory(machine_reg_address(machine_reg::mcycle)); } void do_write_mcycle(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mcycle), val); + raw_write_memory(machine_reg_address(machine_reg::mcycle), val); } uint64_t do_read_mstatus() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mstatus)); + return raw_read_memory(machine_reg_address(machine_reg::mstatus)); } void do_write_mstatus(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mstatus), val); + raw_write_memory(machine_reg_address(machine_reg::mstatus), val); } uint64_t do_read_mtvec() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mtvec)); + return raw_read_memory(machine_reg_address(machine_reg::mtvec)); } void do_write_mtvec(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mtvec), val); + raw_write_memory(machine_reg_address(machine_reg::mtvec), val); } uint64_t do_read_mscratch() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mscratch)); + return raw_read_memory(machine_reg_address(machine_reg::mscratch)); } void do_write_mscratch(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mscratch), val); + raw_write_memory(machine_reg_address(machine_reg::mscratch), val); } uint64_t do_read_mepc() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mepc)); + return raw_read_memory(machine_reg_address(machine_reg::mepc)); } void do_write_mepc(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mepc), val); + raw_write_memory(machine_reg_address(machine_reg::mepc), val); } uint64_t do_read_mcause() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mcause)); + return raw_read_memory(machine_reg_address(machine_reg::mcause)); } void do_write_mcause(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mcause), val); + raw_write_memory(machine_reg_address(machine_reg::mcause), val); } uint64_t do_read_mtval() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mtval)); + return raw_read_memory(machine_reg_address(machine_reg::mtval)); } void do_write_mtval(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mtval), val); + raw_write_memory(machine_reg_address(machine_reg::mtval), val); } uint64_t do_read_misa() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::misa)); + return raw_read_memory(machine_reg_address(machine_reg::misa)); } void do_write_misa(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::misa), val); + raw_write_memory(machine_reg_address(machine_reg::misa), val); } uint64_t do_read_mie() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mie)); + return raw_read_memory(machine_reg_address(machine_reg::mie)); } void do_write_mie(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mie), val); + raw_write_memory(machine_reg_address(machine_reg::mie), val); } uint64_t do_read_mip() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mip)); + return raw_read_memory(machine_reg_address(machine_reg::mip)); } void do_write_mip(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mip), val); + raw_write_memory(machine_reg_address(machine_reg::mip), val); } uint64_t do_read_medeleg() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::medeleg)); + return raw_read_memory(machine_reg_address(machine_reg::medeleg)); } void do_write_medeleg(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::medeleg), val); + raw_write_memory(machine_reg_address(machine_reg::medeleg), val); } uint64_t do_read_mideleg() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mideleg)); + return raw_read_memory(machine_reg_address(machine_reg::mideleg)); } void do_write_mideleg(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mideleg), val); + raw_write_memory(machine_reg_address(machine_reg::mideleg), val); } uint64_t do_read_mcounteren() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mcounteren)); + return raw_read_memory(machine_reg_address(machine_reg::mcounteren)); } void do_write_mcounteren(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mcounteren), val); + raw_write_memory(machine_reg_address(machine_reg::mcounteren), val); } uint64_t do_read_senvcfg() const { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::senvcfg)); + return raw_read_memory(machine_reg_address(machine_reg::senvcfg)); } void do_write_senvcfg(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::senvcfg), val); + raw_write_memory(machine_reg_address(machine_reg::senvcfg), val); } uint64_t do_read_menvcfg() const { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::menvcfg)); + return raw_read_memory(machine_reg_address(machine_reg::menvcfg)); } void do_write_menvcfg(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::menvcfg), val); + raw_write_memory(machine_reg_address(machine_reg::menvcfg), val); } uint64_t do_read_stvec() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::stvec)); + return raw_read_memory(machine_reg_address(machine_reg::stvec)); } void do_write_stvec(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::stvec), val); + raw_write_memory(machine_reg_address(machine_reg::stvec), val); } uint64_t do_read_sscratch() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::sscratch)); + return raw_read_memory(machine_reg_address(machine_reg::sscratch)); } void do_write_sscratch(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::sscratch), val); + raw_write_memory(machine_reg_address(machine_reg::sscratch), val); } uint64_t do_read_sepc() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::sepc)); + return raw_read_memory(machine_reg_address(machine_reg::sepc)); } void do_write_sepc(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::sepc), val); + raw_write_memory(machine_reg_address(machine_reg::sepc), val); } uint64_t do_read_scause() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::scause)); + return raw_read_memory(machine_reg_address(machine_reg::scause)); } void do_write_scause(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::scause), val); + raw_write_memory(machine_reg_address(machine_reg::scause), val); } uint64_t do_read_stval() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::stval)); + return raw_read_memory(machine_reg_address(machine_reg::stval)); } void do_write_stval(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::stval), val); + raw_write_memory(machine_reg_address(machine_reg::stval), val); } uint64_t do_read_satp() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::satp)); + return raw_read_memory(machine_reg_address(machine_reg::satp)); } void do_write_satp(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::satp), val); + raw_write_memory(machine_reg_address(machine_reg::satp), val); } uint64_t do_read_scounteren() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::scounteren)); + return raw_read_memory(machine_reg_address(machine_reg::scounteren)); } void do_write_scounteren(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::scounteren), val); + raw_write_memory(machine_reg_address(machine_reg::scounteren), val); } uint64_t do_read_ilrsc() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::ilrsc)); + return raw_read_memory(machine_reg_address(machine_reg::ilrsc)); } void do_write_ilrsc(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::ilrsc), val); + raw_write_memory(machine_reg_address(machine_reg::ilrsc), val); } uint64_t do_read_iflags() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::iflags)); + return raw_read_memory(machine_reg_address(machine_reg::iflags)); } void do_write_iflags(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::iflags), val); + raw_write_memory(machine_reg_address(machine_reg::iflags), val); } void do_set_iflags_H() { @@ -788,63 +788,63 @@ class replay_step_state_access : public i_state_access(shadow_state_get_reg_abs_addr(shadow_state_reg::iunrep)); + return raw_read_memory(machine_reg_address(machine_reg::iunrep)); } void do_write_iunrep(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::iunrep), val); + raw_write_memory(machine_reg_address(machine_reg::iunrep), val); } uint64_t do_read_clint_mtimecmp() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::clint_mtimecmp)); + return raw_read_memory(machine_reg_address(machine_reg::clint_mtimecmp)); } void do_write_clint_mtimecmp(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::clint_mtimecmp), val); + raw_write_memory(machine_reg_address(machine_reg::clint_mtimecmp), val); } uint64_t do_read_plic_girqpend() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::plic_girqpend)); + return raw_read_memory(machine_reg_address(machine_reg::plic_girqpend)); } void do_write_plic_girqpend(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::plic_girqpend), val); + raw_write_memory(machine_reg_address(machine_reg::plic_girqpend), val); } uint64_t do_read_plic_girqsrvd() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::plic_girqsrvd)); + return raw_read_memory(machine_reg_address(machine_reg::plic_girqsrvd)); } void do_write_plic_girqsrvd(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::plic_girqsrvd), val); + raw_write_memory(machine_reg_address(machine_reg::plic_girqsrvd), val); } uint64_t do_read_htif_fromhost() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::htif_fromhost)); + return raw_read_memory(machine_reg_address(machine_reg::htif_fromhost)); } void do_write_htif_fromhost(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::htif_fromhost), val); + raw_write_memory(machine_reg_address(machine_reg::htif_fromhost), val); } uint64_t do_read_htif_tohost() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::htif_tohost)); + return raw_read_memory(machine_reg_address(machine_reg::htif_tohost)); } void do_write_htif_tohost(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::htif_tohost), val); + raw_write_memory(machine_reg_address(machine_reg::htif_tohost), val); } uint64_t do_read_htif_ihalt() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::htif_ihalt)); + return raw_read_memory(machine_reg_address(machine_reg::htif_ihalt)); } uint64_t do_read_htif_iconsole() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::htif_iconsole)); + return raw_read_memory(machine_reg_address(machine_reg::htif_iconsole)); } uint64_t do_read_htif_iyield() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::htif_iyield)); + return raw_read_memory(machine_reg_address(machine_reg::htif_iyield)); } // NOLINTNEXTLINE(readability-convert-member-functions-to-static) diff --git a/src/shadow-state-factory.cpp b/src/shadow-state-factory.cpp index 2739d279e..9470eefe6 100644 --- a/src/shadow-state-factory.cpp +++ b/src/shadow-state-factory.cpp @@ -46,52 +46,54 @@ static bool shadow_state_peek(const pma_entry & /*pma*/, const machine &m, uint6 // Copy general-purpose registers for (int i = 0; i < X_REG_COUNT; ++i) { - s->x[i] = m.read_reg(static_cast(machine::reg::x0 + i)); + s->x[i] = m.read_reg(machine_reg_enum(machine_reg::x0, i)); } + // Copy floating-point registers for (int i = 0; i < F_REG_COUNT; ++i) { - s->f[i] = m.read_reg(static_cast(machine::reg::f0 + i)); + s->f[i] = m.read_reg(machine_reg_enum(machine_reg::f0, i)); } + // Copy named registers - s->pc = m.read_reg(machine::reg::pc); - s->fcsr = m.read_reg(machine::reg::fcsr); - s->mvendorid = m.read_reg(machine::reg::mvendorid); - s->marchid = m.read_reg(machine::reg::marchid); - s->mimpid = m.read_reg(machine::reg::mimpid); - s->mcycle = m.read_reg(machine::reg::mcycle); - s->icycleinstret = m.read_reg(machine::reg::icycleinstret); - s->mstatus = m.read_reg(machine::reg::mstatus); - s->mtvec = m.read_reg(machine::reg::mtvec); - s->mscratch = m.read_reg(machine::reg::mscratch); - s->mepc = m.read_reg(machine::reg::mepc); - s->mcause = m.read_reg(machine::reg::mcause); - s->mtval = m.read_reg(machine::reg::mtval); - s->misa = m.read_reg(machine::reg::misa); - s->mie = m.read_reg(machine::reg::mie); - s->mip = m.read_reg(machine::reg::mip); - s->medeleg = m.read_reg(machine::reg::medeleg); - s->mideleg = m.read_reg(machine::reg::mideleg); - s->mcounteren = m.read_reg(machine::reg::mcounteren); - s->menvcfg = m.read_reg(machine::reg::menvcfg); - s->stvec = m.read_reg(machine::reg::stvec); - s->sscratch = m.read_reg(machine::reg::sscratch); - s->sepc = m.read_reg(machine::reg::sepc); - s->scause = m.read_reg(machine::reg::scause); - s->stval = m.read_reg(machine::reg::stval); - s->satp = m.read_reg(machine::reg::satp); - s->scounteren = m.read_reg(machine::reg::scounteren); - s->senvcfg = m.read_reg(machine::reg::senvcfg); - s->ilrsc = m.read_reg(machine::reg::ilrsc); - s->iflags = m.read_reg(machine::reg::iflags); - s->iunrep = m.read_reg(machine::reg::iunrep); - s->clint_mtimecmp = m.read_reg(machine::reg::clint_mtimecmp); - s->plic_girqpend = m.read_reg(machine::reg::plic_girqpend); - s->plic_girqsrvd = m.read_reg(machine::reg::plic_girqsrvd); - s->htif_tohost = m.read_reg(machine::reg::htif_tohost); - s->htif_fromhost = m.read_reg(machine::reg::htif_fromhost); - s->htif_ihalt = m.read_reg(machine::reg::htif_ihalt); - s->htif_iconsole = m.read_reg(machine::reg::htif_iconsole); - s->htif_iyield = m.read_reg(machine::reg::htif_iyield); + s->pc = m.read_reg(machine_reg::pc); + s->fcsr = m.read_reg(machine_reg::fcsr); + s->mvendorid = m.read_reg(machine_reg::mvendorid); + s->marchid = m.read_reg(machine_reg::marchid); + s->mimpid = m.read_reg(machine_reg::mimpid); + s->mcycle = m.read_reg(machine_reg::mcycle); + s->icycleinstret = m.read_reg(machine_reg::icycleinstret); + s->mstatus = m.read_reg(machine_reg::mstatus); + s->mtvec = m.read_reg(machine_reg::mtvec); + s->mscratch = m.read_reg(machine_reg::mscratch); + s->mepc = m.read_reg(machine_reg::mepc); + s->mcause = m.read_reg(machine_reg::mcause); + s->mtval = m.read_reg(machine_reg::mtval); + s->misa = m.read_reg(machine_reg::misa); + s->mie = m.read_reg(machine_reg::mie); + s->mip = m.read_reg(machine_reg::mip); + s->medeleg = m.read_reg(machine_reg::medeleg); + s->mideleg = m.read_reg(machine_reg::mideleg); + s->mcounteren = m.read_reg(machine_reg::mcounteren); + s->menvcfg = m.read_reg(machine_reg::menvcfg); + s->stvec = m.read_reg(machine_reg::stvec); + s->sscratch = m.read_reg(machine_reg::sscratch); + s->sepc = m.read_reg(machine_reg::sepc); + s->scause = m.read_reg(machine_reg::scause); + s->stval = m.read_reg(machine_reg::stval); + s->satp = m.read_reg(machine_reg::satp); + s->scounteren = m.read_reg(machine_reg::scounteren); + s->senvcfg = m.read_reg(machine_reg::senvcfg); + s->ilrsc = m.read_reg(machine_reg::ilrsc); + s->iflags = m.read_reg(machine_reg::iflags); + s->iunrep = m.read_reg(machine_reg::iunrep); + s->clint_mtimecmp = m.read_reg(machine_reg::clint_mtimecmp); + s->plic_girqpend = m.read_reg(machine_reg::plic_girqpend); + s->plic_girqsrvd = m.read_reg(machine_reg::plic_girqsrvd); + s->htif_tohost = m.read_reg(machine_reg::htif_tohost); + s->htif_fromhost = m.read_reg(machine_reg::htif_fromhost); + s->htif_ihalt = m.read_reg(machine_reg::htif_ihalt); + s->htif_iconsole = m.read_reg(machine_reg::htif_iconsole); + s->htif_iyield = m.read_reg(machine_reg::htif_iyield); *page_data = scratch; return true; } diff --git a/src/shadow-state.h b/src/shadow-state.h index 96b85b57f..30abf2f30 100644 --- a/src/shadow-state.h +++ b/src/shadow-state.h @@ -22,7 +22,6 @@ #include #include "compiler-defines.h" -#include "pma-constants.h" #include "pma-driver.h" #include "riscv-constants.h" @@ -79,149 +78,6 @@ struct PACKED shadow_state { /// \brief Global instance of the processor shadow device driver. extern const pma_driver shadow_state_driver; -/// \brief Mapping between registers and their relative addresses in shadow memory -enum class shadow_state_reg { - x0 = offsetof(shadow_state, x[0]), - x1 = offsetof(shadow_state, x[1]), - x2 = offsetof(shadow_state, x[2]), - x3 = offsetof(shadow_state, x[3]), - x4 = offsetof(shadow_state, x[4]), - x5 = offsetof(shadow_state, x[5]), - x6 = offsetof(shadow_state, x[6]), - x7 = offsetof(shadow_state, x[7]), - x8 = offsetof(shadow_state, x[8]), - x9 = offsetof(shadow_state, x[9]), - x10 = offsetof(shadow_state, x[10]), - x11 = offsetof(shadow_state, x[11]), - x12 = offsetof(shadow_state, x[12]), - x13 = offsetof(shadow_state, x[13]), - x14 = offsetof(shadow_state, x[14]), - x15 = offsetof(shadow_state, x[15]), - x16 = offsetof(shadow_state, x[16]), - x17 = offsetof(shadow_state, x[17]), - x18 = offsetof(shadow_state, x[18]), - x19 = offsetof(shadow_state, x[19]), - x20 = offsetof(shadow_state, x[20]), - x21 = offsetof(shadow_state, x[21]), - x22 = offsetof(shadow_state, x[22]), - x23 = offsetof(shadow_state, x[23]), - x24 = offsetof(shadow_state, x[24]), - x25 = offsetof(shadow_state, x[25]), - x26 = offsetof(shadow_state, x[26]), - x27 = offsetof(shadow_state, x[27]), - x28 = offsetof(shadow_state, x[28]), - x29 = offsetof(shadow_state, x[29]), - x30 = offsetof(shadow_state, x[30]), - x31 = offsetof(shadow_state, x[31]), - f0 = offsetof(shadow_state, f[0]), - f1 = offsetof(shadow_state, f[1]), - f2 = offsetof(shadow_state, f[2]), - f3 = offsetof(shadow_state, f[3]), - f4 = offsetof(shadow_state, f[4]), - f5 = offsetof(shadow_state, f[5]), - f6 = offsetof(shadow_state, f[6]), - f7 = offsetof(shadow_state, f[7]), - f8 = offsetof(shadow_state, f[8]), - f9 = offsetof(shadow_state, f[9]), - f10 = offsetof(shadow_state, f[10]), - f11 = offsetof(shadow_state, f[11]), - f12 = offsetof(shadow_state, f[12]), - f13 = offsetof(shadow_state, f[13]), - f14 = offsetof(shadow_state, f[14]), - f15 = offsetof(shadow_state, f[15]), - f16 = offsetof(shadow_state, f[16]), - f17 = offsetof(shadow_state, f[17]), - f18 = offsetof(shadow_state, f[18]), - f19 = offsetof(shadow_state, f[19]), - f20 = offsetof(shadow_state, f[20]), - f21 = offsetof(shadow_state, f[21]), - f22 = offsetof(shadow_state, f[22]), - f23 = offsetof(shadow_state, f[23]), - f24 = offsetof(shadow_state, f[24]), - f25 = offsetof(shadow_state, f[25]), - f26 = offsetof(shadow_state, f[26]), - f27 = offsetof(shadow_state, f[27]), - f28 = offsetof(shadow_state, f[28]), - f29 = offsetof(shadow_state, f[29]), - f30 = offsetof(shadow_state, f[30]), - f31 = offsetof(shadow_state, f[31]), - pc = offsetof(shadow_state, pc), - fcsr = offsetof(shadow_state, fcsr), - mvendorid = offsetof(shadow_state, mvendorid), - marchid = offsetof(shadow_state, marchid), - mimpid = offsetof(shadow_state, mimpid), - mcycle = offsetof(shadow_state, mcycle), - icycleinstret = offsetof(shadow_state, icycleinstret), - mstatus = offsetof(shadow_state, mstatus), - mtvec = offsetof(shadow_state, mtvec), - mscratch = offsetof(shadow_state, mscratch), - mepc = offsetof(shadow_state, mepc), - mcause = offsetof(shadow_state, mcause), - mtval = offsetof(shadow_state, mtval), - misa = offsetof(shadow_state, misa), - mie = offsetof(shadow_state, mie), - mip = offsetof(shadow_state, mip), - medeleg = offsetof(shadow_state, medeleg), - mideleg = offsetof(shadow_state, mideleg), - mcounteren = offsetof(shadow_state, mcounteren), - menvcfg = offsetof(shadow_state, menvcfg), - stvec = offsetof(shadow_state, stvec), - sscratch = offsetof(shadow_state, sscratch), - sepc = offsetof(shadow_state, sepc), - scause = offsetof(shadow_state, scause), - stval = offsetof(shadow_state, stval), - satp = offsetof(shadow_state, satp), - scounteren = offsetof(shadow_state, scounteren), - senvcfg = offsetof(shadow_state, senvcfg), - ilrsc = offsetof(shadow_state, ilrsc), - iflags = offsetof(shadow_state, iflags), - iunrep = offsetof(shadow_state, iunrep), - clint_mtimecmp = offsetof(shadow_state, clint_mtimecmp), - plic_girqpend = offsetof(shadow_state, plic_girqpend), - plic_girqsrvd = offsetof(shadow_state, plic_girqsrvd), - htif_tohost = offsetof(shadow_state, htif_tohost), - htif_fromhost = offsetof(shadow_state, htif_fromhost), - htif_ihalt = offsetof(shadow_state, htif_ihalt), - htif_iconsole = offsetof(shadow_state, htif_iconsole), - htif_iyield = offsetof(shadow_state, htif_iyield), -}; - -/// \brief Obtains the relative address of a register in shadow memory. -/// \param reg Register name. -/// \returns The address. -constexpr uint64_t shadow_state_get_reg_rel_addr(shadow_state_reg reg) { - return static_cast(reg); -} - -/// \brief Obtains the absolute address of a register in shadow memory. -constexpr uint64_t shadow_state_get_reg_abs_addr(shadow_state_reg reg) { - return PMA_SHADOW_STATE_START + shadow_state_get_reg_rel_addr(reg); -} - -/// \brief Obtains the relative address of a general purpose register -/// in shadow memory. -/// \param reg Register index in 0...31, for x0...x31, respectively. -/// \returns The address. -static inline uint64_t shadow_state_get_x_rel_addr(int reg) { - assert(reg >= 0 && reg < X_REG_COUNT); - return offsetof(shadow_state, x) + reg * sizeof(uint64_t); -} - -/// \brief Obtains the absolute address of a general purpose register -static inline uint64_t shadow_state_get_x_abs_addr(int reg) { - return PMA_SHADOW_STATE_START + shadow_state_get_x_rel_addr(reg); -} -/// \brief Obtains the relative address of a floating-point register -static inline uint64_t shadow_state_get_f_rel_addr(int reg) { - assert(reg >= 0 && reg < F_REG_COUNT); - return offsetof(shadow_state, f) + reg * sizeof(uint64_t); -} - -/// \brief Obtains the absolute address of a floating-point register -static inline uint64_t shadow_state_get_f_abs_addr(int reg) { - return PMA_SHADOW_STATE_START + shadow_state_get_f_rel_addr(reg); -} - } // namespace cartesi #endif diff --git a/src/shadow-uarch-state-factory.cpp b/src/shadow-uarch-state-factory.cpp index bf4659dbe..e96801730 100644 --- a/src/shadow-uarch-state-factory.cpp +++ b/src/shadow-uarch-state-factory.cpp @@ -44,11 +44,11 @@ static bool shadow_uarch_state_peek(const pma_entry & /*pma*/, const machine &m, // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) auto *s = reinterpret_cast(scratch); - s->halt_flag = m.read_reg(machine::reg::uarch_halt_flag); - s->cycle = m.read_reg(machine::reg::uarch_cycle); - s->pc = m.read_reg(machine::reg::uarch_pc); + s->halt_flag = m.read_reg(machine_reg::uarch_halt_flag); + s->cycle = m.read_reg(machine_reg::uarch_cycle); + s->pc = m.read_reg(machine_reg::uarch_pc); for (int i = 0; i < UARCH_X_REG_COUNT; ++i) { - s->x[i] = m.read_reg(static_cast(machine::reg::uarch_x0 + i)); + s->x[i] = m.read_reg(machine_reg_enum(machine_reg::uarch_x0, i)); } *page_data = scratch; return true; diff --git a/src/shadow-uarch-state.h b/src/shadow-uarch-state.h index 564528867..36c7ea34f 100644 --- a/src/shadow-uarch-state.h +++ b/src/shadow-uarch-state.h @@ -22,7 +22,6 @@ #include #include "compiler-defines.h" -#include "pma-constants.h" #include "pma-driver.h" #include "riscv-constants.h" @@ -42,71 +41,6 @@ struct PACKED shadow_uarch_state { /// \brief Global instance of theprocessor shadow uarch state device driver. extern const pma_driver shadow_uarch_state_driver; -/// \brief Mapping between registers and their relative addresses in shadow uarch state memory -enum class shadow_uarch_state_reg { - halt_flag = offsetof(shadow_uarch_state, halt_flag), - cycle = offsetof(shadow_uarch_state, cycle), - pc = offsetof(shadow_uarch_state, pc), - x0 = offsetof(shadow_uarch_state, x[0]), - x1 = offsetof(shadow_uarch_state, x[1]), - x2 = offsetof(shadow_uarch_state, x[2]), - x3 = offsetof(shadow_uarch_state, x[3]), - x4 = offsetof(shadow_uarch_state, x[4]), - x5 = offsetof(shadow_uarch_state, x[5]), - x6 = offsetof(shadow_uarch_state, x[6]), - x7 = offsetof(shadow_uarch_state, x[7]), - x8 = offsetof(shadow_uarch_state, x[8]), - x9 = offsetof(shadow_uarch_state, x[9]), - x10 = offsetof(shadow_uarch_state, x[10]), - x11 = offsetof(shadow_uarch_state, x[11]), - x12 = offsetof(shadow_uarch_state, x[12]), - x13 = offsetof(shadow_uarch_state, x[13]), - x14 = offsetof(shadow_uarch_state, x[14]), - x15 = offsetof(shadow_uarch_state, x[15]), - x16 = offsetof(shadow_uarch_state, x[16]), - x17 = offsetof(shadow_uarch_state, x[17]), - x18 = offsetof(shadow_uarch_state, x[18]), - x19 = offsetof(shadow_uarch_state, x[19]), - x20 = offsetof(shadow_uarch_state, x[20]), - x21 = offsetof(shadow_uarch_state, x[21]), - x22 = offsetof(shadow_uarch_state, x[22]), - x23 = offsetof(shadow_uarch_state, x[23]), - x24 = offsetof(shadow_uarch_state, x[24]), - x25 = offsetof(shadow_uarch_state, x[25]), - x26 = offsetof(shadow_uarch_state, x[26]), - x27 = offsetof(shadow_uarch_state, x[27]), - x28 = offsetof(shadow_uarch_state, x[28]), - x29 = offsetof(shadow_uarch_state, x[29]), - x30 = offsetof(shadow_uarch_state, x[30]), - x31 = offsetof(shadow_uarch_state, x[31]), -}; - -/// \brief Obtains the relative address of a register in shadow uarch state memory. -/// \param reg Register name. -/// \returns The address. -constexpr uint64_t shadow_uarch_state_get_reg_rel_addr(shadow_uarch_state_reg reg) { - return static_cast(reg); -} - -/// \brief Obtains the absolute address of a register in shadow uarch state memory. -constexpr uint64_t shadow_uarch_state_get_reg_abs_addr(shadow_uarch_state_reg reg) { - return PMA_SHADOW_UARCH_STATE_START + shadow_uarch_state_get_reg_rel_addr(reg); -} - -/// \brief Obtains the relative address of a general purpose uarch register -/// in shadow uarch state memory. -/// \param reg Register index in 0...31, for x0...x31, respectively. -/// \brief Obtains the relative address of a microarchitecture general purpose register in shadow uarch state memory -static inline uint64_t shadow_uarch_state_get_x_rel_addr(int reg) { - assert(reg >= 0 && reg < UARCH_X_REG_COUNT); - return offsetof(shadow_uarch_state, x) + reg * sizeof(uint64_t); -} - -/// \brief Obtains the absolute address of a microarchitecture general purpose register -static inline uint64_t shadow_uarch_state_get_x_abs_addr(int reg) { - return PMA_SHADOW_UARCH_STATE_START + shadow_uarch_state_get_x_rel_addr(reg); -} - } // namespace cartesi #endif diff --git a/src/uarch-bridge.h b/src/uarch-bridge.h index 4e4810ffb..b4862fe4d 100644 --- a/src/uarch-bridge.h +++ b/src/uarch-bridge.h @@ -23,6 +23,7 @@ #include #include +#include "machine-reg.h" #include "machine-state.h" #include "pma-constants.h" #include "riscv-constants.h" @@ -43,293 +44,294 @@ class uarch_bridge { /// An exception is thrown if paddr can't me mapped to a valid state register. //// \} static void write_register(uint64_t paddr, machine_state &s, uint64_t data) { - switch (static_cast(paddr)) { - case shadow_state_reg::x0: + using reg = machine_reg; + switch (static_cast(paddr)) { + case reg::x0: s.x[0] = data; return; - case shadow_state_reg::x1: + case reg::x1: s.x[1] = data; return; - case shadow_state_reg::x2: + case reg::x2: s.x[2] = data; return; - case shadow_state_reg::x3: + case reg::x3: s.x[3] = data; return; - case shadow_state_reg::x4: + case reg::x4: s.x[4] = data; return; - case shadow_state_reg::x5: + case reg::x5: s.x[5] = data; return; - case shadow_state_reg::x6: + case reg::x6: s.x[6] = data; return; - case shadow_state_reg::x7: + case reg::x7: s.x[7] = data; return; - case shadow_state_reg::x8: + case reg::x8: s.x[8] = data; return; - case shadow_state_reg::x9: + case reg::x9: s.x[9] = data; return; - case shadow_state_reg::x10: + case reg::x10: s.x[10] = data; return; - case shadow_state_reg::x11: + case reg::x11: s.x[11] = data; return; - case shadow_state_reg::x12: + case reg::x12: s.x[12] = data; return; - case shadow_state_reg::x13: + case reg::x13: s.x[13] = data; return; - case shadow_state_reg::x14: + case reg::x14: s.x[14] = data; return; - case shadow_state_reg::x15: + case reg::x15: s.x[15] = data; return; - case shadow_state_reg::x16: + case reg::x16: s.x[16] = data; return; - case shadow_state_reg::x17: + case reg::x17: s.x[17] = data; return; - case shadow_state_reg::x18: + case reg::x18: s.x[18] = data; return; - case shadow_state_reg::x19: + case reg::x19: s.x[19] = data; return; - case shadow_state_reg::x20: + case reg::x20: s.x[20] = data; return; - case shadow_state_reg::x21: + case reg::x21: s.x[21] = data; return; - case shadow_state_reg::x22: + case reg::x22: s.x[22] = data; return; - case shadow_state_reg::x23: + case reg::x23: s.x[23] = data; return; - case shadow_state_reg::x24: + case reg::x24: s.x[24] = data; return; - case shadow_state_reg::x25: + case reg::x25: s.x[25] = data; return; - case shadow_state_reg::x26: + case reg::x26: s.x[26] = data; return; - case shadow_state_reg::x27: + case reg::x27: s.x[27] = data; return; - case shadow_state_reg::x28: + case reg::x28: s.x[28] = data; return; - case shadow_state_reg::x29: + case reg::x29: s.x[29] = data; return; - case shadow_state_reg::x30: + case reg::x30: s.x[30] = data; return; - case shadow_state_reg::x31: + case reg::x31: s.x[31] = data; return; - case shadow_state_reg::f0: + case reg::f0: s.f[0] = data; return; - case shadow_state_reg::f1: + case reg::f1: s.f[1] = data; return; - case shadow_state_reg::f2: + case reg::f2: s.f[2] = data; return; - case shadow_state_reg::f3: + case reg::f3: s.f[3] = data; return; - case shadow_state_reg::f4: + case reg::f4: s.f[4] = data; return; - case shadow_state_reg::f5: + case reg::f5: s.f[5] = data; return; - case shadow_state_reg::f6: + case reg::f6: s.f[6] = data; return; - case shadow_state_reg::f7: + case reg::f7: s.f[7] = data; return; - case shadow_state_reg::f8: + case reg::f8: s.f[8] = data; return; - case shadow_state_reg::f9: + case reg::f9: s.f[9] = data; return; - case shadow_state_reg::f10: + case reg::f10: s.f[10] = data; return; - case shadow_state_reg::f11: + case reg::f11: s.f[11] = data; return; - case shadow_state_reg::f12: + case reg::f12: s.f[12] = data; return; - case shadow_state_reg::f13: + case reg::f13: s.f[13] = data; return; - case shadow_state_reg::f14: + case reg::f14: s.f[14] = data; return; - case shadow_state_reg::f15: + case reg::f15: s.f[15] = data; return; - case shadow_state_reg::f16: + case reg::f16: s.f[16] = data; return; - case shadow_state_reg::f17: + case reg::f17: s.f[17] = data; return; - case shadow_state_reg::f18: + case reg::f18: s.f[18] = data; return; - case shadow_state_reg::f19: + case reg::f19: s.f[19] = data; return; - case shadow_state_reg::f20: + case reg::f20: s.f[20] = data; return; - case shadow_state_reg::f21: + case reg::f21: s.f[21] = data; return; - case shadow_state_reg::f22: + case reg::f22: s.f[22] = data; return; - case shadow_state_reg::f23: + case reg::f23: s.f[23] = data; return; - case shadow_state_reg::f24: + case reg::f24: s.f[24] = data; return; - case shadow_state_reg::f25: + case reg::f25: s.f[25] = data; return; - case shadow_state_reg::f26: + case reg::f26: s.f[26] = data; return; - case shadow_state_reg::f27: + case reg::f27: s.f[27] = data; return; - case shadow_state_reg::f28: + case reg::f28: s.f[28] = data; return; - case shadow_state_reg::f29: + case reg::f29: s.f[29] = data; return; - case shadow_state_reg::f30: + case reg::f30: s.f[30] = data; return; - case shadow_state_reg::f31: + case reg::f31: s.f[31] = data; return; - case shadow_state_reg::pc: + case reg::pc: s.pc = data; return; - case shadow_state_reg::fcsr: + case reg::fcsr: s.fcsr = data; return; - case shadow_state_reg::mcycle: + case reg::mcycle: s.mcycle = data; return; - case shadow_state_reg::icycleinstret: + case reg::icycleinstret: s.icycleinstret = data; return; - case shadow_state_reg::mstatus: + case reg::mstatus: s.mstatus = data; return; - case shadow_state_reg::mtvec: + case reg::mtvec: s.mtvec = data; return; - case shadow_state_reg::mscratch: + case reg::mscratch: s.mscratch = data; return; - case shadow_state_reg::mepc: + case reg::mepc: s.mepc = data; return; - case shadow_state_reg::mcause: + case reg::mcause: s.mcause = data; return; - case shadow_state_reg::mtval: + case reg::mtval: s.mtval = data; return; - case shadow_state_reg::misa: + case reg::misa: s.misa = data; return; - case shadow_state_reg::mie: + case reg::mie: s.mie = data; return; - case shadow_state_reg::mip: + case reg::mip: s.mip = data; return; - case shadow_state_reg::medeleg: + case reg::medeleg: s.medeleg = data; return; - case shadow_state_reg::mideleg: + case reg::mideleg: s.mideleg = data; return; - case shadow_state_reg::mcounteren: + case reg::mcounteren: s.mcounteren = data; return; - case shadow_state_reg::menvcfg: + case reg::menvcfg: s.menvcfg = data; return; - case shadow_state_reg::stvec: + case reg::stvec: s.stvec = data; return; - case shadow_state_reg::sscratch: + case reg::sscratch: s.sscratch = data; return; - case shadow_state_reg::sepc: + case reg::sepc: s.sepc = data; return; - case shadow_state_reg::scause: + case reg::scause: s.scause = data; return; - case shadow_state_reg::stval: + case reg::stval: s.stval = data; return; - case shadow_state_reg::satp: + case reg::satp: s.satp = data; return; - case shadow_state_reg::scounteren: + case reg::scounteren: s.scounteren = data; return; - case shadow_state_reg::senvcfg: + case reg::senvcfg: s.senvcfg = data; return; - case shadow_state_reg::ilrsc: + case reg::ilrsc: s.ilrsc = data; return; - case shadow_state_reg::iflags: + case reg::iflags: s.write_iflags(data); return; - case shadow_state_reg::clint_mtimecmp: + case reg::clint_mtimecmp: s.clint.mtimecmp = data; return; - case shadow_state_reg::plic_girqpend: + case reg::plic_girqpend: s.plic.girqpend = data; return; - case shadow_state_reg::plic_girqsrvd: + case reg::plic_girqsrvd: s.plic.girqsrvd = data; return; - case shadow_state_reg::htif_tohost: + case reg::htif_tohost: s.htif.tohost = data; return; - case shadow_state_reg::htif_fromhost: + case reg::htif_fromhost: s.htif.fromhost = data; return; default: @@ -349,210 +351,211 @@ class uarch_bridge { /// An exception is thrown if paddr can't me mapped to a valid state register. //// \} static uint64_t read_register(uint64_t paddr, machine_state &s) { - switch (static_cast(paddr)) { - case shadow_state_reg::x0: + using reg = machine_reg; + switch (static_cast(paddr)) { + case reg::x0: return s.x[0]; - case shadow_state_reg::x1: + case reg::x1: return s.x[1]; - case shadow_state_reg::x2: + case reg::x2: return s.x[2]; - case shadow_state_reg::x3: + case reg::x3: return s.x[3]; - case shadow_state_reg::x4: + case reg::x4: return s.x[4]; - case shadow_state_reg::x5: + case reg::x5: return s.x[5]; - case shadow_state_reg::x6: + case reg::x6: return s.x[6]; - case shadow_state_reg::x7: + case reg::x7: return s.x[7]; - case shadow_state_reg::x8: + case reg::x8: return s.x[8]; - case shadow_state_reg::x9: + case reg::x9: return s.x[9]; - case shadow_state_reg::x10: + case reg::x10: return s.x[10]; - case shadow_state_reg::x11: + case reg::x11: return s.x[11]; - case shadow_state_reg::x12: + case reg::x12: return s.x[12]; - case shadow_state_reg::x13: + case reg::x13: return s.x[13]; - case shadow_state_reg::x14: + case reg::x14: return s.x[14]; - case shadow_state_reg::x15: + case reg::x15: return s.x[15]; - case shadow_state_reg::x16: + case reg::x16: return s.x[16]; - case shadow_state_reg::x17: + case reg::x17: return s.x[17]; - case shadow_state_reg::x18: + case reg::x18: return s.x[18]; - case shadow_state_reg::x19: + case reg::x19: return s.x[19]; - case shadow_state_reg::x20: + case reg::x20: return s.x[20]; - case shadow_state_reg::x21: + case reg::x21: return s.x[21]; - case shadow_state_reg::x22: + case reg::x22: return s.x[22]; - case shadow_state_reg::x23: + case reg::x23: return s.x[23]; - case shadow_state_reg::x24: + case reg::x24: return s.x[24]; - case shadow_state_reg::x25: + case reg::x25: return s.x[25]; - case shadow_state_reg::x26: + case reg::x26: return s.x[26]; - case shadow_state_reg::x27: + case reg::x27: return s.x[27]; - case shadow_state_reg::x28: + case reg::x28: return s.x[28]; - case shadow_state_reg::x29: + case reg::x29: return s.x[29]; - case shadow_state_reg::x30: + case reg::x30: return s.x[30]; - case shadow_state_reg::x31: + case reg::x31: return s.x[31]; - case shadow_state_reg::f0: + case reg::f0: return s.f[0]; - case shadow_state_reg::f1: + case reg::f1: return s.f[1]; - case shadow_state_reg::f2: + case reg::f2: return s.f[2]; - case shadow_state_reg::f3: + case reg::f3: return s.f[3]; - case shadow_state_reg::f4: + case reg::f4: return s.f[4]; - case shadow_state_reg::f5: + case reg::f5: return s.f[5]; - case shadow_state_reg::f6: + case reg::f6: return s.f[6]; - case shadow_state_reg::f7: + case reg::f7: return s.f[7]; - case shadow_state_reg::f8: + case reg::f8: return s.f[8]; - case shadow_state_reg::f9: + case reg::f9: return s.f[9]; - case shadow_state_reg::f10: + case reg::f10: return s.f[10]; - case shadow_state_reg::f11: + case reg::f11: return s.f[11]; - case shadow_state_reg::f12: + case reg::f12: return s.f[12]; - case shadow_state_reg::f13: + case reg::f13: return s.f[13]; - case shadow_state_reg::f14: + case reg::f14: return s.f[14]; - case shadow_state_reg::f15: + case reg::f15: return s.f[15]; - case shadow_state_reg::f16: + case reg::f16: return s.f[16]; - case shadow_state_reg::f17: + case reg::f17: return s.f[17]; - case shadow_state_reg::f18: + case reg::f18: return s.f[18]; - case shadow_state_reg::f19: + case reg::f19: return s.f[19]; - case shadow_state_reg::f20: + case reg::f20: return s.f[20]; - case shadow_state_reg::f21: + case reg::f21: return s.f[21]; - case shadow_state_reg::f22: + case reg::f22: return s.f[22]; - case shadow_state_reg::f23: + case reg::f23: return s.f[23]; - case shadow_state_reg::f24: + case reg::f24: return s.f[24]; - case shadow_state_reg::f25: + case reg::f25: return s.f[25]; - case shadow_state_reg::f26: + case reg::f26: return s.f[26]; - case shadow_state_reg::f27: + case reg::f27: return s.f[27]; - case shadow_state_reg::f28: + case reg::f28: return s.f[28]; - case shadow_state_reg::f29: + case reg::f29: return s.f[29]; - case shadow_state_reg::f30: + case reg::f30: return s.f[30]; - case shadow_state_reg::f31: + case reg::f31: return s.f[31]; - case shadow_state_reg::pc: + case reg::pc: return s.pc; - case shadow_state_reg::fcsr: + case reg::fcsr: return s.fcsr; - case shadow_state_reg::mvendorid: + case reg::mvendorid: return MVENDORID_INIT; - case shadow_state_reg::marchid: + case reg::marchid: return MARCHID_INIT; - case shadow_state_reg::mimpid: + case reg::mimpid: return MIMPID_INIT; - case shadow_state_reg::mcycle: + case reg::mcycle: return s.mcycle; - case shadow_state_reg::icycleinstret: + case reg::icycleinstret: return s.icycleinstret; - case shadow_state_reg::mstatus: + case reg::mstatus: return s.mstatus; - case shadow_state_reg::mtvec: + case reg::mtvec: return s.mtvec; - case shadow_state_reg::mscratch: + case reg::mscratch: return s.mscratch; - case shadow_state_reg::mepc: + case reg::mepc: return s.mepc; - case shadow_state_reg::mcause: + case reg::mcause: return s.mcause; - case shadow_state_reg::mtval: + case reg::mtval: return s.mtval; - case shadow_state_reg::misa: + case reg::misa: return s.misa; - case shadow_state_reg::mie: + case reg::mie: return s.mie; - case shadow_state_reg::mip: + case reg::mip: return s.mip; - case shadow_state_reg::medeleg: + case reg::medeleg: return s.medeleg; - case shadow_state_reg::mideleg: + case reg::mideleg: return s.mideleg; - case shadow_state_reg::mcounteren: + case reg::mcounteren: return s.mcounteren; - case shadow_state_reg::menvcfg: + case reg::menvcfg: return s.menvcfg; - case shadow_state_reg::stvec: + case reg::stvec: return s.stvec; - case shadow_state_reg::sscratch: + case reg::sscratch: return s.sscratch; - case shadow_state_reg::sepc: + case reg::sepc: return s.sepc; - case shadow_state_reg::scause: + case reg::scause: return s.scause; - case shadow_state_reg::stval: + case reg::stval: return s.stval; - case shadow_state_reg::satp: + case reg::satp: return s.satp; - case shadow_state_reg::scounteren: + case reg::scounteren: return s.scounteren; - case shadow_state_reg::senvcfg: + case reg::senvcfg: return s.senvcfg; - case shadow_state_reg::ilrsc: + case reg::ilrsc: return s.ilrsc; - case shadow_state_reg::iflags: + case reg::iflags: return s.read_iflags(); - case shadow_state_reg::clint_mtimecmp: + case reg::clint_mtimecmp: return s.clint.mtimecmp; - case shadow_state_reg::plic_girqpend: + case reg::plic_girqpend: return s.plic.girqpend; - case shadow_state_reg::plic_girqsrvd: + case reg::plic_girqsrvd: return s.plic.girqsrvd; - case shadow_state_reg::htif_tohost: + case reg::htif_tohost: return s.htif.tohost; - case shadow_state_reg::htif_fromhost: + case reg::htif_fromhost: return s.htif.fromhost; - case shadow_state_reg::htif_ihalt: + case reg::htif_ihalt: return s.htif.ihalt; - case shadow_state_reg::htif_iconsole: + case reg::htif_iconsole: return s.htif.iconsole; - case shadow_state_reg::htif_iyield: + case reg::htif_iyield: return s.htif.iyield; default: break; @@ -571,220 +574,221 @@ class uarch_bridge { /// \param paddr Address of the state register. /// \returns The register name, if paddr maps to a register, or nullptr otherwise. static const char *get_register_name(uint64_t paddr) { - switch (static_cast(paddr)) { - case shadow_state_reg::x0: + using reg = machine_reg; + switch (static_cast(paddr)) { + case reg::x0: return "x0"; - case shadow_state_reg::x1: + case reg::x1: return "x1"; - case shadow_state_reg::x2: + case reg::x2: return "x2"; - case shadow_state_reg::x3: + case reg::x3: return "x3"; - case shadow_state_reg::x4: + case reg::x4: return "x4"; - case shadow_state_reg::x5: + case reg::x5: return "x5"; - case shadow_state_reg::x6: + case reg::x6: return "x6"; - case shadow_state_reg::x7: + case reg::x7: return "x7"; - case shadow_state_reg::x8: + case reg::x8: return "x8"; - case shadow_state_reg::x9: + case reg::x9: return "x9"; - case shadow_state_reg::x10: + case reg::x10: return "x10"; - case shadow_state_reg::x11: + case reg::x11: return "x11"; - case shadow_state_reg::x12: + case reg::x12: return "x12"; - case shadow_state_reg::x13: + case reg::x13: return "x13"; - case shadow_state_reg::x14: + case reg::x14: return "x14"; - case shadow_state_reg::x15: + case reg::x15: return "x15"; - case shadow_state_reg::x16: + case reg::x16: return "x16"; - case shadow_state_reg::x17: + case reg::x17: return "x17"; - case shadow_state_reg::x18: + case reg::x18: return "x18"; - case shadow_state_reg::x19: + case reg::x19: return "x19"; - case shadow_state_reg::x20: + case reg::x20: return "x20"; - case shadow_state_reg::x21: + case reg::x21: return "x21"; - case shadow_state_reg::x22: + case reg::x22: return "x22"; - case shadow_state_reg::x23: + case reg::x23: return "x23"; - case shadow_state_reg::x24: + case reg::x24: return "x24"; - case shadow_state_reg::x25: + case reg::x25: return "x25"; - case shadow_state_reg::x26: + case reg::x26: return "x26"; - case shadow_state_reg::x27: + case reg::x27: return "x27"; - case shadow_state_reg::x28: + case reg::x28: return "x28"; - case shadow_state_reg::x29: + case reg::x29: return "x29"; - case shadow_state_reg::x30: + case reg::x30: return "x30"; - case shadow_state_reg::x31: + case reg::x31: return "x31"; - case shadow_state_reg::f0: + case reg::f0: return "f0"; - case shadow_state_reg::f1: + case reg::f1: return "f1"; - case shadow_state_reg::f2: + case reg::f2: return "f2"; - case shadow_state_reg::f3: + case reg::f3: return "f3"; - case shadow_state_reg::f4: + case reg::f4: return "f4"; - case shadow_state_reg::f5: + case reg::f5: return "f5"; - case shadow_state_reg::f6: + case reg::f6: return "f6"; - case shadow_state_reg::f7: + case reg::f7: return "f7"; - case shadow_state_reg::f8: + case reg::f8: return "f8"; - case shadow_state_reg::f9: + case reg::f9: return "f9"; - case shadow_state_reg::f10: + case reg::f10: return "f10"; - case shadow_state_reg::f11: + case reg::f11: return "f11"; - case shadow_state_reg::f12: + case reg::f12: return "f12"; - case shadow_state_reg::f13: + case reg::f13: return "f13"; - case shadow_state_reg::f14: + case reg::f14: return "f14"; - case shadow_state_reg::f15: + case reg::f15: return "f15"; - case shadow_state_reg::f16: + case reg::f16: return "f16"; - case shadow_state_reg::f17: + case reg::f17: return "f17"; - case shadow_state_reg::f18: + case reg::f18: return "f18"; - case shadow_state_reg::f19: + case reg::f19: return "f19"; - case shadow_state_reg::f20: + case reg::f20: return "f20"; - case shadow_state_reg::f21: + case reg::f21: return "f21"; - case shadow_state_reg::f22: + case reg::f22: return "f22"; - case shadow_state_reg::f23: + case reg::f23: return "f23"; - case shadow_state_reg::f24: + case reg::f24: return "f24"; - case shadow_state_reg::f25: + case reg::f25: return "f25"; - case shadow_state_reg::f26: + case reg::f26: return "f26"; - case shadow_state_reg::f27: + case reg::f27: return "f27"; - case shadow_state_reg::f28: + case reg::f28: return "f28"; - case shadow_state_reg::f29: + case reg::f29: return "f29"; - case shadow_state_reg::f30: + case reg::f30: return "f30"; - case shadow_state_reg::f31: + case reg::f31: return "f31"; - case shadow_state_reg::pc: + case reg::pc: return "pc"; - case shadow_state_reg::fcsr: + case reg::fcsr: return "fcsr"; - case shadow_state_reg::mvendorid: + case reg::mvendorid: return "mvendorid"; - case shadow_state_reg::marchid: + case reg::marchid: return "marchid"; - case shadow_state_reg::mimpid: + case reg::mimpid: return "mimpid"; - case shadow_state_reg::mcycle: + case reg::mcycle: return "mcycle"; - case shadow_state_reg::icycleinstret: + case reg::icycleinstret: return "icycleinstret"; - case shadow_state_reg::mstatus: + case reg::mstatus: return "mstatus"; - case shadow_state_reg::mtvec: + case reg::mtvec: return "mtvec"; - case shadow_state_reg::mscratch: + case reg::mscratch: return "mscratch"; - case shadow_state_reg::mepc: + case reg::mepc: return "mepc"; - case shadow_state_reg::mcause: + case reg::mcause: return "mcause"; - case shadow_state_reg::mtval: + case reg::mtval: return "mtval"; - case shadow_state_reg::misa: + case reg::misa: return "misa"; - case shadow_state_reg::mie: + case reg::mie: return "mie"; - case shadow_state_reg::mip: + case reg::mip: return "mip"; - case shadow_state_reg::medeleg: + case reg::medeleg: return "medeleg"; - case shadow_state_reg::mideleg: + case reg::mideleg: return "mideleg"; - case shadow_state_reg::mcounteren: + case reg::mcounteren: return "mcounteren"; - case shadow_state_reg::menvcfg: + case reg::menvcfg: return "menvcfg"; - case shadow_state_reg::stvec: + case reg::stvec: return "stvec"; - case shadow_state_reg::sscratch: + case reg::sscratch: return "sscratch"; - case shadow_state_reg::sepc: + case reg::sepc: return "sepc"; - case shadow_state_reg::scause: + case reg::scause: return "scause"; - case shadow_state_reg::stval: + case reg::stval: return "stval"; - case shadow_state_reg::satp: + case reg::satp: return "satp"; - case shadow_state_reg::scounteren: + case reg::scounteren: return "scounteren"; - case shadow_state_reg::senvcfg: + case reg::senvcfg: return "senvcfg"; - case shadow_state_reg::ilrsc: + case reg::ilrsc: return "ilrsc"; - case shadow_state_reg::iflags: + case reg::iflags: return "iflags"; - case shadow_state_reg::clint_mtimecmp: + case reg::clint_mtimecmp: return "clint.mtimecmp"; - case shadow_state_reg::plic_girqpend: + case reg::plic_girqpend: return "plic.girqpend"; - case shadow_state_reg::plic_girqsrvd: + case reg::plic_girqsrvd: return "plic.girqsrvd"; - case shadow_state_reg::htif_tohost: + case reg::htif_tohost: return "htif.tohost"; - case shadow_state_reg::htif_fromhost: + case reg::htif_fromhost: return "htif.fromhost"; - case shadow_state_reg::htif_ihalt: + case reg::htif_ihalt: return "htif.ihalt"; - case shadow_state_reg::htif_iconsole: + case reg::htif_iconsole: return "htif.iconsole"; - case shadow_state_reg::htif_iyield: + case reg::htif_iyield: return "htif.iyield"; default: break; } - if (paddr >= shadow_state_get_x_abs_addr(0) && paddr <= shadow_state_get_x_abs_addr(X_REG_COUNT - 1) && + if (paddr >= machine_reg_address(machine_reg::x0) && paddr <= machine_reg_address(machine_reg::x31) && (paddr & 0b111) == 0) { return "x"; } - if (paddr >= shadow_state_get_f_abs_addr(0) && paddr <= shadow_state_get_f_abs_addr(F_REG_COUNT - 1) && + if (paddr >= machine_reg_address(machine_reg::f0) && paddr <= machine_reg_address(machine_reg::f31) && (paddr & 0b111) == 0) { return "f"; } diff --git a/src/uarch-record-state-access.h b/src/uarch-record-state-access.h index 4b664c5f2..bec3a9c7e 100644 --- a/src/uarch-record-state-access.h +++ b/src/uarch-record-state-access.h @@ -300,45 +300,44 @@ class uarch_record_state_access : public i_uarch_state_access(m_us.halt_flag), "uarch.halt_flag") != 0; + return log_read(machine_reg_address(machine_reg::uarch_halt_flag), static_cast(m_us.halt_flag), + "uarch.halt_flag") != 0; } void do_set_halt_flag() { - log_before_write_write_and_update(shadow_uarch_state_get_reg_abs_addr(shadow_uarch_state_reg::halt_flag), - m_us.halt_flag, true, "uarch.halt_flag"); + log_before_write_write_and_update(machine_reg_address(machine_reg::uarch_halt_flag), m_us.halt_flag, true, + "uarch.halt_flag"); } void do_reset_halt_flag() { - log_before_write_write_and_update(shadow_uarch_state_get_reg_abs_addr(shadow_uarch_state_reg::halt_flag), - m_us.halt_flag, false, "uarch.halt_flag"); + log_before_write_write_and_update(machine_reg_address(machine_reg::uarch_halt_flag), m_us.halt_flag, false, + "uarch.halt_flag"); } uint64_t do_read_word(uint64_t paddr) { diff --git a/src/uarch-replay-state-access.h b/src/uarch-replay-state-access.h index 939466630..ab53c31bf 100644 --- a/src/uarch-replay-state-access.h +++ b/src/uarch-replay-state-access.h @@ -266,43 +266,40 @@ class uarch_replay_state_access : public i_uarch_state_access(true), - "uarch.halt_flag"); + check_write(machine_reg_address(machine_reg::uarch_halt_flag), static_cast(true), "uarch.halt_flag"); } void do_reset_halt_flag() { - check_write(shadow_uarch_state_get_reg_abs_addr(shadow_uarch_state_reg::halt_flag), - static_cast(false), "uarch.halt_flag"); + check_write(machine_reg_address(machine_reg::uarch_halt_flag), static_cast(false), "uarch.halt_flag"); } uint64_t do_read_word(uint64_t paddr) { diff --git a/tests/lua/htif-console.lua b/tests/lua/htif-console.lua index 8d296c539..de1b69bff 100755 --- a/tests/lua/htif-console.lua +++ b/tests/lua/htif-console.lua @@ -33,8 +33,8 @@ local function stderr(...) io.stderr:write(string.format(...)) end -local final_mcycle = 2137 -local exit_payload = 42 +local expected_final_mcycle = 2137 +local expected_exit_payload = 42 local function test(config, console_getchar_enable) stderr(" testing console_getchar:%s\n", console_getchar_enable and "on" or "off") @@ -48,15 +48,17 @@ local function test(config, console_getchar_enable) assert(machine:read_iflags_H(), "expected iflags_H set") -- with the expected payload + local exit_payload = machine:read_reg("htif_tohost_data") >> 1 assert( - (machine:read_reg("htif_tohost_data") >> 1) == exit_payload, - string.format("exit payload: expected %u, got %u\n", exit_payload, machine:read_reg("htif_tohost_data") >> 1) + exit_payload == expected_exit_payload, + string.format("exit payload: expected %u, got %u\n", expected_exit_payload, exit_payload) ) -- at the expected mcycle + local final_mcycle = machine:read_mcycle() assert( - machine:read_mcycle() == final_mcycle, - string.format("mcycle: expected, %u got %u", final_mcycle, machine:read_mcycle()) + final_mcycle == expected_final_mcycle, + string.format("mcycle: expected, %u got %u", expected_final_mcycle, final_mcycle) ) stderr(" passed\n") diff --git a/uarch/uarch-machine-state-access.h b/uarch/uarch-machine-state-access.h index 01254115a..f9b33cdf9 100644 --- a/uarch/uarch-machine-state-access.h +++ b/uarch/uarch-machine-state-access.h @@ -26,8 +26,7 @@ #include "i-state-access.h" #include "pma-constants.h" #include "riscv-constants.h" -#include "shadow-state.h" -#include "shadow-uarch-state.h" +#include "machine-reg.h" #include "shadow-pmas.h" #include "uarch-constants.h" #include "uarch-defines.h" @@ -171,247 +170,247 @@ class uarch_machine_state_access : public i_state_access(shadow_state_get_x_abs_addr(reg)); + return raw_read_memory(machine_reg_address(machine_reg::x0, reg)); } void do_write_x(int reg, uint64_t val) { - raw_write_memory(shadow_state_get_x_abs_addr(reg), val); + raw_write_memory(machine_reg_address(machine_reg::x0, reg), val); } uint64_t do_read_f(int reg) { - return raw_read_memory(shadow_state_get_f_abs_addr(reg)); + return raw_read_memory(machine_reg_address(machine_reg::f0, reg)); } void do_write_f(int reg, uint64_t val) { - raw_write_memory(shadow_state_get_f_abs_addr(reg), val); + raw_write_memory(machine_reg_address(machine_reg::f0, reg), val); } uint64_t do_read_pc() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::pc)); + return raw_read_memory(machine_reg_address(machine_reg::pc)); } void do_write_pc(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::pc), val); + raw_write_memory(machine_reg_address(machine_reg::pc), val); } uint64_t do_read_fcsr() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::fcsr)); + return raw_read_memory(machine_reg_address(machine_reg::fcsr)); } void do_write_fcsr(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::fcsr), val); + raw_write_memory(machine_reg_address(machine_reg::fcsr), val); } uint64_t do_read_icycleinstret() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::icycleinstret)); + return raw_read_memory(machine_reg_address(machine_reg::icycleinstret)); } void do_write_icycleinstret(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::icycleinstret), val); + raw_write_memory(machine_reg_address(machine_reg::icycleinstret), val); } uint64_t do_read_mvendorid() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mvendorid)); + return raw_read_memory(machine_reg_address(machine_reg::mvendorid)); } uint64_t do_read_marchid() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::marchid)); + return raw_read_memory(machine_reg_address(machine_reg::marchid)); } uint64_t do_read_mimpid() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mimpid)); + return raw_read_memory(machine_reg_address(machine_reg::mimpid)); } uint64_t do_read_mcycle() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mcycle)); + return raw_read_memory(machine_reg_address(machine_reg::mcycle)); } void do_write_mcycle(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mcycle), val); + raw_write_memory(machine_reg_address(machine_reg::mcycle), val); } uint64_t do_read_mstatus() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mstatus)); + return raw_read_memory(machine_reg_address(machine_reg::mstatus)); } void do_write_mstatus(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mstatus), val); + raw_write_memory(machine_reg_address(machine_reg::mstatus), val); } uint64_t do_read_mtvec() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mtvec)); + return raw_read_memory(machine_reg_address(machine_reg::mtvec)); } void do_write_mtvec(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mtvec), val); + raw_write_memory(machine_reg_address(machine_reg::mtvec), val); } uint64_t do_read_mscratch() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mscratch)); + return raw_read_memory(machine_reg_address(machine_reg::mscratch)); } void do_write_mscratch(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mscratch), val); + raw_write_memory(machine_reg_address(machine_reg::mscratch), val); } uint64_t do_read_mepc() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mepc)); + return raw_read_memory(machine_reg_address(machine_reg::mepc)); } void do_write_mepc(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mepc), val); + raw_write_memory(machine_reg_address(machine_reg::mepc), val); } uint64_t do_read_mcause() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mcause)); + return raw_read_memory(machine_reg_address(machine_reg::mcause)); } void do_write_mcause(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mcause), val); + raw_write_memory(machine_reg_address(machine_reg::mcause), val); } uint64_t do_read_mtval() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mtval)); + return raw_read_memory(machine_reg_address(machine_reg::mtval)); } void do_write_mtval(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mtval), val); + raw_write_memory(machine_reg_address(machine_reg::mtval), val); } uint64_t do_read_misa() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::misa)); + return raw_read_memory(machine_reg_address(machine_reg::misa)); } void do_write_misa(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::misa), val); + raw_write_memory(machine_reg_address(machine_reg::misa), val); } uint64_t do_read_mie() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mie)); + return raw_read_memory(machine_reg_address(machine_reg::mie)); } void do_write_mie(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mie), val); + raw_write_memory(machine_reg_address(machine_reg::mie), val); } uint64_t do_read_mip() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mip)); + return raw_read_memory(machine_reg_address(machine_reg::mip)); } void do_write_mip(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mip), val); + raw_write_memory(machine_reg_address(machine_reg::mip), val); } uint64_t do_read_medeleg() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::medeleg)); + return raw_read_memory(machine_reg_address(machine_reg::medeleg)); } void do_write_medeleg(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::medeleg), val); + raw_write_memory(machine_reg_address(machine_reg::medeleg), val); } uint64_t do_read_mideleg() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mideleg)); + return raw_read_memory(machine_reg_address(machine_reg::mideleg)); } void do_write_mideleg(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mideleg), val); + raw_write_memory(machine_reg_address(machine_reg::mideleg), val); } uint64_t do_read_mcounteren() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mcounteren)); + return raw_read_memory(machine_reg_address(machine_reg::mcounteren)); } void do_write_mcounteren(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::mcounteren), val); + raw_write_memory(machine_reg_address(machine_reg::mcounteren), val); } uint64_t do_read_senvcfg() const { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::senvcfg)); + return raw_read_memory(machine_reg_address(machine_reg::senvcfg)); } void do_write_senvcfg(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::senvcfg), val); + raw_write_memory(machine_reg_address(machine_reg::senvcfg), val); } uint64_t do_read_menvcfg() const { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::menvcfg)); + return raw_read_memory(machine_reg_address(machine_reg::menvcfg)); } void do_write_menvcfg(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::menvcfg), val); + raw_write_memory(machine_reg_address(machine_reg::menvcfg), val); } uint64_t do_read_stvec() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::stvec)); + return raw_read_memory(machine_reg_address(machine_reg::stvec)); } void do_write_stvec(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::stvec), val); + raw_write_memory(machine_reg_address(machine_reg::stvec), val); } uint64_t do_read_sscratch() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::sscratch)); + return raw_read_memory(machine_reg_address(machine_reg::sscratch)); } void do_write_sscratch(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::sscratch), val); + raw_write_memory(machine_reg_address(machine_reg::sscratch), val); } uint64_t do_read_sepc() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::sepc)); + return raw_read_memory(machine_reg_address(machine_reg::sepc)); } void do_write_sepc(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::sepc), val); + raw_write_memory(machine_reg_address(machine_reg::sepc), val); } uint64_t do_read_scause() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::scause)); + return raw_read_memory(machine_reg_address(machine_reg::scause)); } void do_write_scause(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::scause), val); + raw_write_memory(machine_reg_address(machine_reg::scause), val); } uint64_t do_read_stval() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::stval)); + return raw_read_memory(machine_reg_address(machine_reg::stval)); } void do_write_stval(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::stval), val); + raw_write_memory(machine_reg_address(machine_reg::stval), val); } uint64_t do_read_satp() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::satp)); + return raw_read_memory(machine_reg_address(machine_reg::satp)); } void do_write_satp(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::satp), val); + raw_write_memory(machine_reg_address(machine_reg::satp), val); } uint64_t do_read_scounteren() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::scounteren)); + return raw_read_memory(machine_reg_address(machine_reg::scounteren)); } void do_write_scounteren(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::scounteren), val); + raw_write_memory(machine_reg_address(machine_reg::scounteren), val); } uint64_t do_read_ilrsc() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::ilrsc)); + return raw_read_memory(machine_reg_address(machine_reg::ilrsc)); } void do_write_ilrsc(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::ilrsc), val); + raw_write_memory(machine_reg_address(machine_reg::ilrsc), val); } uint64_t do_read_iflags() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::iflags)); + return raw_read_memory(machine_reg_address(machine_reg::iflags)); } void do_write_iflags(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::iflags), val); + raw_write_memory(machine_reg_address(machine_reg::iflags), val); } void do_set_iflags_H() { @@ -472,69 +471,69 @@ class uarch_machine_state_access : public i_state_access(shadow_state_get_reg_abs_addr(shadow_state_reg::iunrep)); + return raw_read_memory(machine_reg_address(machine_reg::iunrep)); } void do_write_iunrep(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::iunrep), val); + raw_write_memory(machine_reg_address(machine_reg::iunrep), val); } uint64_t do_read_clint_mtimecmp() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::clint_mtimecmp)); + return raw_read_memory(machine_reg_address(machine_reg::clint_mtimecmp)); } void do_write_clint_mtimecmp(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::clint_mtimecmp), val); + raw_write_memory(machine_reg_address(machine_reg::clint_mtimecmp), val); } uint64_t do_read_plic_girqpend() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::plic_girqpend)); + return raw_read_memory(machine_reg_address(machine_reg::plic_girqpend)); } void do_write_plic_girqpend(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::plic_girqpend), val); + raw_write_memory(machine_reg_address(machine_reg::plic_girqpend), val); } uint64_t do_read_plic_girqsrvd() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::plic_girqsrvd)); + return raw_read_memory(machine_reg_address(machine_reg::plic_girqsrvd)); } void do_write_plic_girqsrvd(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::plic_girqsrvd), val); + raw_write_memory(machine_reg_address(machine_reg::plic_girqsrvd), val); } uint64_t do_read_htif_fromhost() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::htif_fromhost)); + return raw_read_memory(machine_reg_address(machine_reg::htif_fromhost)); } void do_write_htif_fromhost(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::htif_fromhost), val); + raw_write_memory(machine_reg_address(machine_reg::htif_fromhost), val); } uint64_t do_read_htif_tohost() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::htif_tohost)); + return raw_read_memory(machine_reg_address(machine_reg::htif_tohost)); } void do_write_htif_tohost(uint64_t val) { - raw_write_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::htif_tohost), val); + raw_write_memory(machine_reg_address(machine_reg::htif_tohost), val); } uint64_t do_read_htif_ihalt() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::htif_ihalt)); + return raw_read_memory(machine_reg_address(machine_reg::htif_ihalt)); } uint64_t do_read_htif_iconsole() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::htif_iconsole)); + return raw_read_memory(machine_reg_address(machine_reg::htif_iconsole)); } uint64_t do_read_htif_iyield() { - return raw_read_memory(shadow_state_get_reg_abs_addr(shadow_state_reg::htif_iyield)); + return raw_read_memory(machine_reg_address(machine_reg::htif_iyield)); } std::pair do_poll_external_interrupts(uint64_t mcycle, uint64_t /*mcycle_max*/) { return {mcycle, false}; } - + uint64_t do_read_pma_istart(int i) { return raw_read_memory(shadow_pmas_get_pma_abs_addr(i)); }