Skip to content

Commit

Permalink
refactor(!): split iflags into 4 registers
Browse files Browse the repository at this point in the history
This simplifies the implementation and paves the way for a lot of
further simplifications.
  • Loading branch information
diegonehab committed Dec 23, 2024
1 parent 407fa87 commit 0b141d8
Show file tree
Hide file tree
Showing 41 changed files with 590 additions and 991 deletions.
26 changes: 13 additions & 13 deletions src/cartesi-machine.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1609,7 +1609,7 @@ for _, a in ipairs(arg) do
end

local function print_root_hash(machine, print)
(print or stderr)("%u: %s\n", machine:read_mcycle(), util.hexhash(machine:get_root_hash()))
(print or stderr)("%u: %s\n", machine:read_reg("mcycle"), util.hexhash(machine:get_root_hash()))
end

local function dump_value_proofs(machine, desired_proofs, config)
Expand Down Expand Up @@ -1906,7 +1906,7 @@ local function get_and_print_yield(machine, htif)
reason_str = cmio_yield_manual_reason[reason] or reason_str
end
stderr("\n%s yield %s (%d) (0x%06x data)\n", cmd_str, reason_str, reason, #data)
stderr("Cycles: %u\n", machine:read_mcycle())
stderr("Cycles: %u\n", machine:read_reg("mcycle"))
return cmd, reason, data
end

Expand Down Expand Up @@ -2068,25 +2068,25 @@ local backup_closer <close> = setmetatable({}, {
-- once all inputs for advance state have been consumed, we check if the user selected cmio inspect state
-- if so, we feed the query, reset iflags_Y, and resume the machine
-- the machine can now continue processing and may yield automatic to produce reports we save
while math.ult(machine:read_mcycle(), max_mcycle) do
while math.ult(machine:read_reg("mcycle"), max_mcycle) do
local next_mcycle = math.min(next_hash_mcycle, max_mcycle)
if gdb_stub and gdb_stub:is_connected() then
gdb_stub:run(next_mcycle)
else
machine:run(next_mcycle)
end
-- deal with halt
if machine:read_iflags_H() then
if machine:read_reg("iflags_H") ~= 0 then
exit_code = machine:read_reg("htif_tohost_data") >> 1
if exit_code ~= 0 then
stderr("\nHalted with payload: %u\n", exit_code)
else
stderr("\nHalted\n")
end
stderr("Cycles: %u\n", machine:read_mcycle())
stderr("Cycles: %u\n", machine:read_reg("mcycle"))
break
-- deal with yield manual
elseif machine:read_iflags_Y() then
elseif machine:read_reg("iflags_Y") ~= 0 then
local _, reason, data = get_and_print_yield(machine, config.htif)
-- there was an exception
if reason == cartesi.CMIO_YIELD_MANUAL_REASON_TX_EXCEPTION then
Expand Down Expand Up @@ -2150,7 +2150,7 @@ while math.ult(machine:read_mcycle(), max_mcycle) do
end
end
-- deal with yield automatic
elseif machine:read_iflags_X() then
elseif machine:read_reg("iflags_X") ~= 0 then
local _, reason, data = get_and_print_yield(machine, config.htif)
-- we have fed an advance state input
if cmio_advance and cmio_advance.next_input_index > cmio_advance.input_index_begin then
Expand All @@ -2172,12 +2172,12 @@ while math.ult(machine:read_mcycle(), max_mcycle) do
end
-- otherwise ignore
end
if machine:read_iflags_Y() then
if machine:read_reg("iflags_Y") ~= 0 then
-- commit any pending snapshot
do_commit()
break
end
if machine:read_mcycle() == next_hash_mcycle then
if machine:read_reg("mcycle") == next_hash_mcycle then
print_root_hash(machine)
next_hash_mcycle = next_hash_mcycle + periodic_hashes_period
end
Expand All @@ -2192,16 +2192,16 @@ end
-- Advance micro cycles
if max_uarch_cycle > 0 then
-- Save halt flag before micro cycles
local previously_halted = machine:read_iflags_H()
local previously_halted = machine:read_reg("iflags_H") ~= 0
if machine:run_uarch(max_uarch_cycle) == cartesi.UARCH_BREAK_REASON_UARCH_HALTED then
-- Microarchitecture halted. This means that one "macro" instruction was totally executed
-- The mcycle counter was incremented, unless the machine was already halted
if machine:read_iflags_H() and not previously_halted then stderr("Halted\n") end
stderr("Cycles: %u\n", machine:read_mcycle())
if machine:read_reg("iflags_H") ~= 0 and not previously_halted then stderr("Halted\n") end
stderr("Cycles: %u\n", machine:read_reg("mcycle"))
if auto_reset_uarch then
machine:reset_uarch()
else
stderr("uCycles: %u\n", machine:read_uarch_cycle())
stderr("uCycles: %u\n", machine:read_reg("uarch_cycle"))
end
end
end
Expand Down
22 changes: 11 additions & 11 deletions src/cartesi/gdbstub.lua
Original file line number Diff line number Diff line change
Expand Up @@ -189,16 +189,16 @@ function GDBStub:_handle_query(_, query)
elseif query:find("^qRcmd,") then -- custom command
local payload = hex2str(query:sub(7))
if payload:find("^stepc %d+$") then -- step a fixed number of cycles
self.mcycle_limit = self.machine:read_mcycle() + tonumber(payload:match("^stepc (%d+)$"))
self.mcycle_limit = self.machine:read_reg("mcycle") + tonumber(payload:match("^stepc (%d+)$"))
return self:_send_ok()
elseif payload:find("^stepu %d+$") then -- step until a cycle number
self.mcycle_limit = math.max(self.machine:read_mcycle(), tonumber(payload:match("^stepu (%d+)$")))
self.mcycle_limit = math.max(self.machine:read_reg("mcycle"), tonumber(payload:match("^stepu (%d+)$")))
return self:_send_ok()
elseif payload == "stepc_clear" then -- remove stepping breakpoint
self.mcycle_limit = nil
return self:_send_ok()
elseif payload == "cycles" then -- print current cycle
self:_send_rcmd_reply(string.format("%u\n", self.machine:read_mcycle()))
self:_send_rcmd_reply(string.format("%u\n", self.machine:read_reg("mcycle")))
return self:_send_ok()
elseif payload:find("^reg [%w_]+$") then -- read machine registers
local reg_name = payload:match("^reg ([%w_]+)$")
Expand Down Expand Up @@ -244,7 +244,7 @@ function GDBStub:_handle_query(_, query)
self.performed_first_hash = true
end
local hash = self.machine:get_root_hash()
self:_send_rcmd_reply(string.format("%u: %s\n", self.machine:read_mcycle(), str2hex(hash)))
self:_send_rcmd_reply(string.format("%u: %s\n", self.machine:read_reg("mcycle"), str2hex(hash)))
return self:_send_ok()
elseif payload:find("^store .*$") then -- store the machine state
local store_dir = payload:match("^store (.*)$")
Expand Down Expand Up @@ -393,7 +393,7 @@ end
-- GDB is asking to let the machine continue.
function GDBStub:_handle_continue()
local machine = self.machine
local mcycle = machine:read_mcycle()
local mcycle = machine:read_reg("mcycle")
local mcycle_end = self.max_mcycle
local ult = math.ult -- localized to speed up Lua loop
if self.mcycle_limit and ult(self.mcycle_limit, self.max_mcycle) then
Expand All @@ -407,22 +407,22 @@ function GDBStub:_handle_continue()
machine:run(mcycle + 1)
if breakpoints[machine:read_reg("pc")] then -- breakpoint reached
return self:_send_signal(signals.SIGTRAP)
elseif machine:read_iflags_H() then -- machined halted
elseif machine:read_reg("iflags_H") ~= 0 then -- machined halted
return self:_send_signal(signals.SIGTERM)
elseif machine:read_iflags_Y() or machine:read_iflags_X() then -- machine yielded
elseif machine:read_reg("iflags_Y") ~= 0 or machine:read_reg("iflags_X") ~= 0 then -- machine yielded
self.yielded = true
return true -- a reply will be sent to GDB in the next run loop
end
mcycle = machine:read_mcycle()
mcycle = machine:read_reg("mcycle")
end
else -- no breakpoint set, we can run through the fast path
machine:run(mcycle_end)
end
if machine:read_iflags_H() then -- machine halted
if machine:read_reg("iflags_H") ~= 0 then -- machine halted
return self:_send_signal(signals.SIGTERM)
elseif machine:read_mcycle() == self.max_mcycle then -- reached max cycles
elseif machine:read_reg("mcycle") == self.max_mcycle then -- reached max cycles
return self:_send_signal(signals.SIGQUIT)
elseif machine:read_iflags_Y() or machine:read_iflags_X() then -- machine yielded
elseif machine:read_reg("iflags_Y") ~= 0 or machine:read_reg("iflags_X") ~= 0 then -- machine yielded
self.yielded = true
return true -- a reply will be sent to GDB in the next run loop
else -- reached step cycles limit
Expand Down
166 changes: 29 additions & 137 deletions src/clua-i-virtual-machine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,11 +149,10 @@ cm_reg clua_check_cm_proc_reg(lua_State *L, int idx) try {
{"scounteren", CM_REG_SCOUNTEREN},
{"senvcfg", CM_REG_SENVCFG},
{"ilrsc", CM_REG_ILRSC},
{"iflags", CM_REG_IFLAGS},
{"iflags_prv", CM_REG_IFLAGS_PRV},
{"iflags_x", CM_REG_IFLAGS_X},
{"iflags_y", CM_REG_IFLAGS_Y},
{"iflags_h", CM_REG_IFLAGS_H},
{"iprv", CM_REG_IPRV},
{"iflags_X", CM_REG_IFLAGS_X},
{"iflags_Y", CM_REG_IFLAGS_Y},
{"iflags_H", CM_REG_IFLAGS_H},
{"iunrep", CM_REG_IUNREP},
{"clint_mtimecmp", CM_REG_CLINT_MTIMECMP},
{"plic_girqpend", CM_REG_PLIC_GIRQPEND},
Expand Down Expand Up @@ -577,26 +576,6 @@ static int machine_obj_index_get_root_hash(lua_State *L) {
return 1;
}

static int machine_obj_index_read_mcycle(lua_State *L) {
auto &m = clua_check<clua_managed_cm_ptr<cm_machine>>(L, 1);
uint64_t val{};
if (cm_read_mcycle(m.get(), &val) != 0) {
return luaL_error(L, "%s", cm_get_last_error_message());
}
lua_pushinteger(L, static_cast<lua_Integer>(val));
return 1;
}

static int machine_obj_index_read_uarch_cycle(lua_State *L) {
auto &m = clua_check<clua_managed_cm_ptr<cm_machine>>(L, 1);
uint64_t val{};
if (cm_read_uarch_cycle(m.get(), &val) != 0) {
return luaL_error(L, "%s", cm_get_last_error_message());
}
lua_pushinteger(L, static_cast<lua_Integer>(val));
return 1;
}

/// \brief This is the machine:read_reg() method implementation.
/// \param L Lua state.
static int machine_obj_index_read_reg(lua_State *L) {
Expand All @@ -609,62 +588,6 @@ static int machine_obj_index_read_reg(lua_State *L) {
return 1;
}

/// \brief This is the machine:read_iflags_H() method implementation.
/// \param L Lua state.
static int machine_obj_index_read_iflags_H(lua_State *L) {
auto &m = clua_check<clua_managed_cm_ptr<cm_machine>>(L, 1);
bool val{};
if (cm_read_iflags_H(m.get(), &val) != 0) {
return luaL_error(L, "%s", cm_get_last_error_message());
}
lua_pushboolean(L, static_cast<int>(val));
return 1;
}

/// \brief This is the machine:read_iflags_Y() method implementation.
/// \param L Lua state.
static int machine_obj_index_read_iflags_Y(lua_State *L) {
auto &m = clua_check<clua_managed_cm_ptr<cm_machine>>(L, 1);
bool val{};
if (cm_read_iflags_Y(m.get(), &val) != 0) {
return luaL_error(L, "%s", cm_get_last_error_message());
}
lua_pushboolean(L, static_cast<int>(val));
return 1;
}

/// \brief This is the machine:read_iflags_X() method implementation.
/// \param L Lua state.
static int machine_obj_index_read_iflags_X(lua_State *L) {
auto &m = clua_check<clua_managed_cm_ptr<cm_machine>>(L, 1);
bool val{};
if (cm_read_iflags_X(m.get(), &val) != 0) {
return luaL_error(L, "%s", cm_get_last_error_message());
}
lua_pushboolean(L, static_cast<int>(val));
return 1;
}

/// \brief This is the machine:set_iflags_Y() method implementation.
/// \param L Lua state.
static int machine_obj_index_set_iflags_Y(lua_State *L) {
auto &m = clua_check<clua_managed_cm_ptr<cm_machine>>(L, 1);
if (cm_set_iflags_Y(m.get()) != 0) {
return luaL_error(L, "%s", cm_get_last_error_message());
}
return 0;
}

/// \brief This is the machine:reset_iflags_Y() method implementation.
/// \param L Lua state.
static int machine_obj_index_reset_iflags_Y(lua_State *L) {
auto &m = clua_check<clua_managed_cm_ptr<cm_machine>>(L, 1);
if (cm_reset_iflags_Y(m.get()) != 0) {
return luaL_error(L, "%s", cm_get_last_error_message());
}
return 0;
}

/// \brief This is the machine:read_memory() method implementation.
/// \param L Lua state.
static int machine_obj_index_read_memory(lua_State *L) {
Expand Down Expand Up @@ -746,28 +669,6 @@ static int machine_obj_index_log_step(lua_State *L) {
return 1;
}

/// \brief This is the machine:read_uarch_halt_flag() method implementation.
/// \param L Lua state.
static int machine_obj_index_read_uarch_halt_flag(lua_State *L) {
auto &m = clua_check<clua_managed_cm_ptr<cm_machine>>(L, 1);
bool val{};
if (cm_read_uarch_halt_flag(m.get(), &val) != 0) {
return luaL_error(L, "%s", cm_get_last_error_message());
}
lua_pushboolean(L, static_cast<int>(val));
return 1;
}

/// \brief This is the machine:set_uarch_halt_flag() method implementation.
/// \param L Lua state.
static int machine_obj_index_set_uarch_halt_flag(lua_State *L) {
auto &m = clua_check<clua_managed_cm_ptr<cm_machine>>(L, 1);
if (cm_set_uarch_halt_flag(m.get()) != 0) {
return luaL_error(L, "%s", cm_get_last_error_message());
}
return 0;
}

/// \brief This is the machine:reset_uarch() method implementation.
/// \param L Lua state.
static int machine_obj_index_reset_uarch(lua_State *L) {
Expand Down Expand Up @@ -1141,53 +1042,44 @@ static int machine_obj_index_swap(lua_State *L) {

/// \brief Contents of the machine object metatable __index table.
static const auto machine_obj_index = cartesi::clua_make_luaL_Reg_array({
{"is_empty", machine_obj_index_is_empty},
{"create", machine_obj_index_create},
{"load", machine_obj_index_load},
{"get_proof", machine_obj_index_get_proof},
{"destroy", machine_obj_index_destroy},
{"get_default_config", machine_obj_index_get_default_config},
{"get_initial_config", machine_obj_index_get_initial_config},
{"get_runtime_config", machine_obj_index_get_runtime_config},
{"set_runtime_config", machine_obj_index_set_runtime_config},
{"get_memory_ranges", machine_obj_index_get_memory_ranges},
{"get_proof", machine_obj_index_get_proof},
{"get_reg_address", machine_obj_index_get_reg_address},
{"get_root_hash", machine_obj_index_get_root_hash},
{"read_reg", machine_obj_index_read_reg},
{"read_uarch_cycle", machine_obj_index_read_uarch_cycle},
{"read_iflags_H", machine_obj_index_read_iflags_H},
{"read_iflags_Y", machine_obj_index_read_iflags_Y},
{"read_iflags_X", machine_obj_index_read_iflags_X},
{"set_iflags_Y", machine_obj_index_set_iflags_Y},
{"reset_iflags_Y", machine_obj_index_reset_iflags_Y},
{"read_mcycle", machine_obj_index_read_mcycle},
{"get_runtime_config", machine_obj_index_get_runtime_config},
{"is_empty", machine_obj_index_is_empty},
{"load", machine_obj_index_load},
{"log_reset_uarch", machine_obj_index_log_reset_uarch},
{"log_send_cmio_response", machine_obj_index_log_send_cmio_response},
{"log_step", machine_obj_index_log_step},
{"log_step_uarch", machine_obj_index_log_step_uarch},
{"read_memory", machine_obj_index_read_memory},
{"read_reg", machine_obj_index_read_reg},
{"read_virtual_memory", machine_obj_index_read_virtual_memory},
{"read_word", machine_obj_index_read_word},
{"receive_cmio_request", machine_obj_index_receive_cmio_request},
{"replace_memory_range", machine_obj_index_replace_memory_range},
{"reset_uarch", machine_obj_index_reset_uarch},
{"run", machine_obj_index_run},
{"log_step", machine_obj_index_log_step},
{"run_uarch", machine_obj_index_run_uarch},
{"log_step_uarch", machine_obj_index_log_step_uarch},
{"send_cmio_response", machine_obj_index_send_cmio_response},
{"set_runtime_config", machine_obj_index_set_runtime_config},
{"store", machine_obj_index_store},
{"swap", machine_obj_index_swap},
{"translate_virtual_address", machine_obj_index_translate_virtual_address},
{"verify_dirty_page_maps", machine_obj_index_verify_dirty_page_maps},
{"verify_merkle_tree", machine_obj_index_verify_merkle_tree},
{"write_reg", machine_obj_index_write_reg},
{"write_memory", machine_obj_index_write_memory},
{"write_virtual_memory", machine_obj_index_write_virtual_memory},
{"translate_virtual_address", machine_obj_index_translate_virtual_address},
{"replace_memory_range", machine_obj_index_replace_memory_range},
{"destroy", machine_obj_index_destroy},
{"read_uarch_halt_flag", machine_obj_index_read_uarch_halt_flag},
{"set_uarch_halt_flag", machine_obj_index_set_uarch_halt_flag},
{"get_memory_ranges", machine_obj_index_get_memory_ranges},
{"reset_uarch", machine_obj_index_reset_uarch},
{"log_reset_uarch", machine_obj_index_log_reset_uarch},
{"receive_cmio_request", machine_obj_index_receive_cmio_request},
{"send_cmio_response", machine_obj_index_send_cmio_response},
{"log_send_cmio_response", machine_obj_index_log_send_cmio_response},
{"get_default_config", machine_obj_index_get_default_config},
{"get_reg_address", machine_obj_index_get_reg_address},
{"verify_step", machine_obj_index_verify_step},
{"verify_step_uarch", machine_obj_index_verify_step_uarch},
{"verify_reset_uarch", machine_obj_index_verify_reset_uarch},
{"verify_send_cmio_response", machine_obj_index_verify_send_cmio_response},
{"swap", machine_obj_index_swap},
{"verify_step", machine_obj_index_verify_step},
{"verify_step_uarch", machine_obj_index_verify_step_uarch},
{"write_memory", machine_obj_index_write_memory},
{"write_reg", machine_obj_index_write_reg},
{"write_virtual_memory", machine_obj_index_write_virtual_memory},
});

/// \brief This is the class() constructor implementation.
Expand Down
12 changes: 6 additions & 6 deletions src/device-state-access.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,16 +75,16 @@ class device_state_access : public i_device_state_access {
return m_mcycle;
}

void do_set_iflags_H() override {
m_a.set_iflags_H();
void do_write_iflags_H(uint64_t val) override {
m_a.write_iflags_H(val);
}

void do_set_iflags_Y() override {
m_a.set_iflags_Y();
void do_write_iflags_Y(uint64_t val) override {
m_a.write_iflags_Y(val);
}

void do_set_iflags_X() override {
m_a.set_iflags_X();
void do_write_iflags_X(uint64_t val) override {
m_a.write_iflags_X(val);
}

uint64_t do_read_clint_mtimecmp() override {
Expand Down
Loading

0 comments on commit 0b141d8

Please sign in to comment.