Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/cartesi/util.lua
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,8 @@ local function accessdatastring(data, data_hash, data_log2_size, address)
if data_size < #data then
-- access data is smaller than the tree leaf size
-- the logged data is the entire tree leaf, but we only need the data that was accessed
local leaf_aligned_address = (address >> cartesi.TREE_LOG2_WORD_SIZE) << cartesi.TREE_LOG2_WORD_SIZE
local leaf_aligned_address = (address >> cartesi.HASH_TREE_LOG2_WORD_SIZE)
<< cartesi.HASH_TREE_LOG2_WORD_SIZE
local word_offset = address - leaf_aligned_address
data = data:sub(word_offset + 1, word_offset + data_size)
end
Expand Down
10 changes: 7 additions & 3 deletions src/clua-cartesi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,9 +214,9 @@ CM_API int luaopen_cartesi(lua_State *L) {
clua_setintegerfield(L, CM_HASH_SIZE, "HASH_SIZE", -1);
clua_setintegerfield(L, CM_MCYCLE_MAX, "MCYCLE_MAX", -1);
clua_setintegerfield(L, CM_UARCH_CYCLE_MAX, "UARCH_CYCLE_MAX", -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);
clua_setintegerfield(L, CM_HASH_TREE_LOG2_WORD_SIZE, "HASH_TREE_LOG2_WORD_SIZE", -1);
clua_setintegerfield(L, CM_HASH_TREE_LOG2_PAGE_SIZE, "HASH_TREE_LOG2_PAGE_SIZE", -1);
clua_setintegerfield(L, CM_HASH_TREE_LOG2_ROOT_SIZE, "HASH_TREE_LOG2_ROOT_SIZE", -1);
clua_setintegerfield(L, CM_BREAK_REASON_FAILED, "BREAK_REASON_FAILED", -1);
clua_setintegerfield(L, CM_BREAK_REASON_HALTED, "BREAK_REASON_HALTED", -1);
clua_setintegerfield(L, CM_BREAK_REASON_YIELDED_MANUALLY, "BREAK_REASON_YIELDED_MANUALLY", -1);
Expand All @@ -243,10 +243,12 @@ CM_API int luaopen_cartesi(lua_State *L) {
clua_setintegerfield(L, CM_SHARING_ALL, "SHARING_ALL", -1);
clua_setintegerfield(L, CM_AR_CMIO_RX_BUFFER_START, "AR_CMIO_RX_BUFFER_START", -1);
clua_setintegerfield(L, CM_AR_CMIO_RX_BUFFER_LOG2_SIZE, "AR_CMIO_RX_BUFFER_LOG2_SIZE", -1);
clua_setintegerfield(L, CM_AR_SHADOW_TLB_LENGTH, "AR_SHADOW_TLB_LENGTH", -1);
clua_setintegerfield(L, CM_AR_CMIO_TX_BUFFER_START, "AR_CMIO_TX_BUFFER_START", -1);
clua_setintegerfield(L, CM_AR_CMIO_TX_BUFFER_LOG2_SIZE, "AR_CMIO_TX_BUFFER_LOG2_SIZE", -1);
clua_setintegerfield(L, CM_AR_SHADOW_REVERT_ROOT_HASH_START, "AR_SHADOW_REVERT_ROOT_HASH_START", -1);
clua_setintegerfield(L, CM_AR_RAM_START, "AR_RAM_START", -1);
clua_setintegerfield(L, CM_AR_SHADOW_TLB_START, "AR_SHADOW_TLB_START", -1);
// HTIF masks
clua_setintegerfield(L, HTIF_HALT_CMD_HALT_MASK, "HTIF_HALT_CMD_HALT_MASK", -1);
clua_setintegerfield(L, HTIF_CONSOLE_CMD_GETCHAR_MASK, "HTIF_CONSOLE_CMD_GETCHAR_MASK", -1);
Expand All @@ -262,6 +264,8 @@ CM_API int luaopen_cartesi(lua_State *L) {
clua_setintegerfield(L, UARCH_RAM_START_ADDRESS, "UARCH_RAM_START_ADDRESS", -1);
clua_setintegerfield(L, UARCH_ECALL_FN_HALT, "UARCH_ECALL_FN_HALT", -1);
clua_setintegerfield(L, UARCH_ECALL_FN_PUTCHAR, "UARCH_ECALL_FN_PUTCHAR", -1);
clua_setintegerfield(L, UARCH_ECALL_FN_MARK_DIRTY_PAGE, "UARCH_ECALL_FN_MARK_DIRTY_PAGE", -1);
clua_setintegerfield(L, UARCH_ECALL_FN_WRITE_TLB, "UARCH_ECALL_FN_WRITE_TLB", -1);
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
clua_setlstringfield(L, reinterpret_cast<const char *>(uarch_pristine_hash), uarch_pristine_hash_len,
"UARCH_PRISTINE_STATE_HASH", -1);
Expand Down
10 changes: 6 additions & 4 deletions src/machine-c-api.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ extern "C" {
/// \brief Constants.
typedef enum cm_constant {
CM_HASH_SIZE = 32,
CM_TREE_LOG2_WORD_SIZE = 5,
CM_TREE_LOG2_PAGE_SIZE = 12,
CM_TREE_LOG2_ROOT_SIZE = 64,
CM_HASH_TREE_LOG2_WORD_SIZE = 5,
CM_HASH_TREE_LOG2_PAGE_SIZE = 12,
CM_HASH_TREE_LOG2_ROOT_SIZE = 64,
} cm_constant;

/// \brief Physical memory addresses (only the most useful are exposed in the API).
Expand All @@ -59,6 +59,8 @@ typedef enum cm_pmas_constant {
CM_AR_CMIO_TX_BUFFER_LOG2_SIZE = 21,
CM_AR_SHADOW_REVERT_ROOT_HASH_START = 0xfe0,
CM_AR_RAM_START = 0x80000000,
CM_AR_SHADOW_TLB_START = 0x1000,
CM_AR_SHADOW_TLB_LENGTH = 0x6000,
} cm_pmas_constant;

/// \brief Error codes returned from the C API.
Expand Down Expand Up @@ -557,7 +559,7 @@ CM_API cm_error cm_get_node_hash(const cm_machine *m, uint64_t address, int32_t
/// \param m Pointer to a non-empty machine object (holds a machine instance).
/// \param address Address of target node. Must be aligned to a 2^log2_size boundary.
/// \param log2_size The log base 2 of the size subtended by the target node.
/// Must be between CM_TREE_LOG2_WORD_SIZE (for a word) and CM_TREE_LOG2_ROOT_SIZE
/// Must be between CM_HASH_TREE_LOG2_WORD_SIZE (for a word) and CM_HASH_TREE_LOG2_ROOT_SIZE
/// (for the entire address space), inclusive.
/// \param proof Receives the proof as a JSON object in a string,
/// guaranteed to remain valid only until the next CM_API function is called from the same thread.
Expand Down
16 changes: 10 additions & 6 deletions src/machine.h
Original file line number Diff line number Diff line change
Expand Up @@ -559,14 +559,16 @@ class machine final {
/// \param pma_index Index of PMA where address falls
void write_tlb(TLB_set_index set_index, uint64_t slot_index, uint64_t vaddr_page, host_addr vh_offset,
uint64_t pma_index) {
uint64_t vp_offset = 0;
if (vaddr_page != TLB_INVALID_PAGE) [[likely]] {
vp_offset = get_paddr(vh_offset, pma_index);
}
m_s->penumbra.tlb[set_index][slot_index].vaddr_page = vaddr_page;
m_s->penumbra.tlb[set_index][slot_index].vh_offset = vh_offset;
m_s->shadow.tlb[set_index][slot_index].vaddr_page = vaddr_page;
m_s->shadow.tlb[set_index][slot_index].vp_offset = vp_offset;
if (vaddr_page != TLB_INVALID_PAGE) [[likely]] {
m_s->shadow.tlb[set_index][slot_index].vp_offset = get_paddr(vh_offset, pma_index);
} else {
// simply store the vh_offset as vp_offset when vaddr_page is invalid
// so that the uarch replay can compute the same written hash.
m_s->shadow.tlb[set_index][slot_index].vp_offset = static_cast<uint64_t>(vh_offset);
}
m_s->shadow.tlb[set_index][slot_index].pma_index = pma_index;
m_s->shadow.tlb[set_index][slot_index].zero_padding_ = 0;
}
Expand All @@ -584,7 +586,9 @@ class machine final {
const auto vh_offset = get_host_addr(paddr_page, pma_index) - vaddr_page;
write_tlb(set_index, slot_index, vaddr_page, vh_offset, pma_index);
} else {
write_tlb(set_index, slot_index, TLB_INVALID_PAGE, host_addr{0}, TLB_INVALID_PMA_INDEX);
// vp_offset is unused when vaddr_page is invalid but its value needs to be stored in the shadow TLB
// so that the uarch replay can compute the same written hash.
write_tlb(set_index, slot_index, TLB_INVALID_PAGE, static_cast<host_addr>(vp_offset), pma_index);
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/uarch-constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ enum uarch_state_constants : uint64_t {
UARCH_STATE_MASK = ~UARCH_STATE_ALIGN_MASK, ///< Mask for uarch state address space
UARCH_STATE_CHILD_ALIGN_MASK =
(UINT64_C(1) << UARCH_STATE_CHILD_LOG2_SIZE) - 1, ///< Mask for uarch state child alignment
UARCH_LOG2_MAX_CYCLE = EXPAND_UINT64_C(UARCH_LOG2_MAX_CYCLE_DEF),
UARCH_MAX_CYCLE = (UINT64_C(1) << UARCH_LOG2_MAX_CYCLE),
UARCH_LOG2_CYCLE_MAX = EXPAND_UINT64_C(UARCH_LOG2_CYCLE_MAX_DEF),
UARCH_CYCLE_MAX = (UINT64_C(1) << UARCH_LOG2_CYCLE_MAX),
};

static_assert((UARCH_STATE_START_ADDRESS & UARCH_STATE_ALIGN_MASK) == 0,
Expand All @@ -64,7 +64,7 @@ static_assert(UARCH_SHADOW_START_ADDRESS < UARCH_RAM_START_ADDRESS,
"UARCH_SHADOW_START_ADDRESS must be smaller than UARCH_RAN_START_ADDRESS");
static_assert((UARCH_SHADOW_LENGTH & (AR_PAGE_SIZE - 1)) == 0, "UARCH_SHADOW_LENGTH must be multiple of AR_PAGE_SIZE");
static_assert((UARCH_RAM_LENGTH & (AR_PAGE_SIZE - 1)) == 0, "UARCH_RAM_LENGTH must be multiple of AR_PAGE_SIZE");
static_assert(UARCH_MAX_CYCLE == CM_UARCH_CYCLE_MAX, "CM_UARCH_CYCLE_MAX must be equal to UARCH_MAX_CYCLE");
static_assert(UARCH_CYCLE_MAX == CM_UARCH_CYCLE_MAX, "CM_UARCH_CYCLE_MAX must be equal to UARCH_CYCLE_MAX");

/// \brief ecall function codes
enum uarch_ecall_functions : uint64_t {
Expand Down
2 changes: 1 addition & 1 deletion src/uarch-defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
#define UARCH_STATE_LOG2_SIZE_DEF 22

/// \brief Log2 of the expected maximum uarch cycle
#define UARCH_LOG2_MAX_CYCLE_DEF 20
#define UARCH_LOG2_CYCLE_MAX_DEF 20

// microarchitecture ecall function codes
#define UARCH_ECALL_FN_HALT_DEF 1 // halt uarch
Expand Down
4 changes: 2 additions & 2 deletions src/uarch-step.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1096,7 +1096,7 @@ UArchStepStatus uarch_step(const UarchState a) {
// This must be the first read in order to match the first log access in machine::verify_step_uarch
uint64 cycle = readCycle(a);
// do not advance if cycle will overflow
if (cycle >= UARCH_MAX_CYCLE) {
if (cycle >= UARCH_CYCLE_MAX) {
return UArchStepStatus::CycleOverflow;
}
// do not advance if machine is halted
Expand All @@ -1121,7 +1121,7 @@ template UArchStepStatus uarch_step(const uarch_record_state_access a);
// Explicit instantiation for uarch_replay_state_access
template UArchStepStatus uarch_step(const uarch_replay_state_access a);

// Explicit instantiation for uarch_replay_state_access
// Explicit instantiation for collect_uarch_cycle_hashes_state_access
template UArchStepStatus uarch_step(const collect_uarch_cycle_hashes_state_access a);

} // namespace cartesi
Expand Down
6 changes: 3 additions & 3 deletions tests/lua/machine-bind.lua
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ do_test("should provide proof for values in registers", function(machine)
-- Check proofs
local hash_fn = machine:get_initial_config().hash_tree.hash_function
for _, v in pairs(initial_reg_values) do
for el = cartesi.TREE_LOG2_WORD_SIZE, cartesi.TREE_LOG2_ROOT_SIZE - 1 do
for el = cartesi.HASH_TREE_LOG2_WORD_SIZE, cartesi.HASH_TREE_LOG2_ROOT_SIZE - 1 do
local a = test_util.align(v, el)
assert(test_util.check_proof(assert(machine:get_proof(a, el), "no proof"), hash_fn), "proof failed")
end
Expand Down Expand Up @@ -1581,7 +1581,7 @@ test_util.make_do_test(build_machine, machine_type, {
},
},
})("Log of word access unaligned to hash tree leaf ", function(machine)
local leaf_size = 1 << cartesi.TREE_LOG2_WORD_SIZE
local leaf_size = 1 << cartesi.HASH_TREE_LOG2_WORD_SIZE
local word_size = 8
local t0 = 5 -- x5 register
local t1 = t0 + 1 -- x6 register
Expand All @@ -1594,7 +1594,7 @@ test_util.make_do_test(build_machine, machine_type, {
-- write initial leaf data
local leaf_data = make_leaf("\x11", "\x22", "\x33", "\x44")
assert(#leaf_data == leaf_size)
local leaf_address = cartesi.UARCH_RAM_START_ADDRESS + (1 << cartesi.TREE_LOG2_WORD_SIZE)
local leaf_address = cartesi.UARCH_RAM_START_ADDRESS + (1 << cartesi.HASH_TREE_LOG2_WORD_SIZE)
machine:write_memory(leaf_address, leaf_data, leaf_size)

-- step and log one instruction that stores the word in t0 to the address in t1
Expand Down
2 changes: 1 addition & 1 deletion tests/lua/spec-collect-hashes.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ local util = require("cartesi.tests.util")

local function expect_consistent_root_hash(machine)
local root_hash = machine:get_root_hash()
local node_hash = machine:get_node_hash(0, cartesi.TREE_LOG2_ROOT_SIZE)
local node_hash = machine:get_node_hash(0, cartesi.HASH_TREE_LOG2_ROOT_SIZE)
local external_root_hash = util.calculate_emulator_hash(machine)
expect.equal(root_hash, node_hash)
expect.equal(external_root_hash, root_hash)
Expand Down
2 changes: 1 addition & 1 deletion tests/lua/spec-hash-tree.lua
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ local function expect_consistent_root_hash(machine)
local root_hash = machine:get_root_hash()
local external_root_hash = util.calculate_emulator_hash(machine)
expect.truthy(machine:verify_hash_tree())
local node_hash = machine:get_node_hash(0, cartesi.TREE_LOG2_ROOT_SIZE)
local node_hash = machine:get_node_hash(0, cartesi.HASH_TREE_LOG2_ROOT_SIZE)
expect.truthy(root_hash == node_hash)
expect.equal(root_hash, external_root_hash)
end
Expand Down
2 changes: 2 additions & 0 deletions tests/lua/uarch-riscv-tests.lua
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ local riscv_tests = {
{ "rv64ui-uarch-xori.bin", 177 },
{ "rv64ui-uarch-fence.bin", 12 },
{ "rv64ui-uarch-ecall-putchar.bin", 14 },
{ "rv64ui-uarch-ecall-mark-page-dirty.bin", 15 },
{ "rv64ui-uarch-ecall-write-tlb.bin", 46 },
{ "rv64ui-uarch-ecall-unsupported.bin", 1, "unsupported ecall function" },
{ "rv64ui-uarch-ebreak.bin", 1, "uarch aborted" },
}
Expand Down
2 changes: 1 addition & 1 deletion tests/misc/test-machine-c-api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ BOOST_FIXTURE_TEST_CASE_NOLINT(get_proof_inconsistent_tree_test, ordinary_machin
BOOST_CHECK_EQUAL(error_code, CM_ERROR_OK);

// Hash tree is always consistent now as it updates on access
error_code = cm_get_proof(_machine, 0, CM_TREE_LOG2_PAGE_SIZE, &proof);
error_code = cm_get_proof(_machine, 0, CM_HASH_TREE_LOG2_PAGE_SIZE, &proof);
BOOST_CHECK_EQUAL(error_code, CM_ERROR_OK);
}

Expand Down
8 changes: 4 additions & 4 deletions tests/misc/test-utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,10 @@ static cartesi::machine_hash calculate_proof_root_hash(cartesi::variant_hasher &
static cartesi::machine_hash calculate_emulator_hash(cm_machine *machine) {
const auto hash_function = get_machine_hash_function(machine);
cartesi::variant_hasher h{hash_function};
const auto pristine_pad_hashes = cartesi::back_merkle_tree::make_pristine_pad_hashes(CM_TREE_LOG2_ROOT_SIZE,
CM_TREE_LOG2_PAGE_SIZE, CM_TREE_LOG2_WORD_SIZE, hash_function);
cartesi::back_merkle_tree tree{CM_TREE_LOG2_ROOT_SIZE, CM_TREE_LOG2_PAGE_SIZE, CM_TREE_LOG2_WORD_SIZE,
hash_function};
const auto pristine_pad_hashes = cartesi::back_merkle_tree::make_pristine_pad_hashes(CM_HASH_TREE_LOG2_ROOT_SIZE,
CM_HASH_TREE_LOG2_PAGE_SIZE, CM_HASH_TREE_LOG2_WORD_SIZE, hash_function);
cartesi::back_merkle_tree tree{CM_HASH_TREE_LOG2_ROOT_SIZE, CM_HASH_TREE_LOG2_PAGE_SIZE,
CM_HASH_TREE_LOG2_WORD_SIZE, hash_function};
std::string page;
page.resize(detail::HASH_TREE_PAGE_SIZE);
const char *ranges_jsonstr{};
Expand Down
2 changes: 1 addition & 1 deletion tests/uarch/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ RISCV_OBJDUMP ?= $(RISCV_PREFIX)objdump --disassemble-all --disassemble-zeroes -
RISCV_OBJCOPY ?= $(RISCV_PREFIX)objcopy -S -O binary

# Tests provided by us
TESTS = fence ebreak ecall-putchar ecall-unsupported
TESTS = fence ebreak ecall-putchar ecall-unsupported ecall-mark-page-dirty ecall-write-tlb
SRC_DIR = $(abspath .)
BUILDDIR ?= $(abspath ./build)
TEST_NAMES = $(addprefix rv64ui-uarch-, $(TESTS))
Expand Down
36 changes: 36 additions & 0 deletions tests/uarch/ecall-mark-page-dirty.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/* Copyright Cartesi and individual authors (see AUTHORS)
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/


#include "riscv_test.h"
#include "test_macros.h"

RVTEST_RV64U
RVTEST_CODE_BEGIN

li a7, UARCH_ECALL_FN_MARK_DIRTY_PAGE_DEF
li a0, 0 // physical address in page to be marked dirty
li a1, 0 // index of PMA where page falls
ecall

RVTEST_PASS

RVTEST_CODE_END

.data
RVTEST_DATA_BEGIN
TEST_DATA
RVTEST_DATA_END
2 changes: 1 addition & 1 deletion tests/uarch/ecall-putchar.S
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ RVTEST_RV64U
RVTEST_CODE_BEGIN

li a7, UARCH_ECALL_FN_PUTCHAR_DEF
li a6, 'X' // char to print
li a0, 'X' // char to print
ecall

RVTEST_PASS
Expand Down
Loading