Skip to content

Commit a55cbef

Browse files
committed
refactor: shadow PMAs becomes PMAS memory range
1 parent 7725d25 commit a55cbef

12 files changed

+109
-149
lines changed

src/address-range.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ class address_range {
233233
/// \brief Returns packed address range istart field as per whitepaper
234234
/// \returns Packed address range istart
235235
uint64_t get_istart() const noexcept {
236-
return pack_pma_istart(m_flags, m_start);
236+
return pma_pack_istart(m_flags, m_start);
237237
}
238238

239239
/// \brief Returns encoded addres range ilength field as per whitepaper

src/machine.cpp

+12-13
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,15 @@
5454
#include "machine-runtime-config.h"
5555
#include "memory-address-range.h"
5656
#include "plic-address-range.h"
57-
#include "pma-constants.h"
57+
#include "pma.h"
58+
#include "pmas-address-range.h"
5859
#include "record-send-cmio-state-access.h"
5960
#include "record-step-state-access.h"
6061
#include "replay-send-cmio-state-access.h"
6162
#include "replay-step-state-access.h"
6263
#include "riscv-constants.h"
6364
#include "rtc.h"
6465
#include "send-cmio-response.h"
65-
#include "shadow-pmas-address-range.h"
6666
#include "shadow-state-address-range.h"
6767
#include "shadow-tlb-address-range.h"
6868
#include "shadow-uarch-state-address-range.h"
@@ -504,14 +504,13 @@ void machine::init_sentinel_ars() {
504504
}
505505
}
506506

507-
void machine::init_shadow_pmas_contents(memory_address_range &shadow_pmas) const {
508-
static_assert(sizeof(shadow_pmas_state) == PMA_MAX * 2 * sizeof(uint64_t), "inconsistent shadow PMAs length");
509-
static_assert(PMA_SHADOW_PMAS_LENGTH >= sizeof(shadow_pmas_state), "shadow PMAs not long enough");
507+
void machine::init_pmas_contents(memory_address_range &pmas) const {
508+
static_assert(sizeof(pmas_state) == PMA_MAX * 2 * sizeof(uint64_t), "inconsistent PMAs state length");
509+
static_assert(PMA_PMAS_LENGTH >= sizeof(pmas_state), "PMAs address range too short");
510510
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
511-
auto &dest = *reinterpret_cast<shadow_pmas_state *>(shadow_pmas.get_host_memory());
512-
std::ranges::transform(m_s.pmas, dest.begin(), [this](auto i) {
513-
return shadow_pmas_entry{.istart = m_ars[i]->get_istart(), .ilength = m_ars[i]->get_ilength()};
514-
});
511+
auto &dest = *reinterpret_cast<pmas_state *>(pmas.get_host_memory());
512+
std::ranges::transform(m_s.pmas, dest.begin(),
513+
[this](auto i) { return pma_entry{.istart = m_ars[i]->get_istart(), .ilength = m_ars[i]->get_ilength()}; });
515514
}
516515

517516
void machine::init_tlb_contents(const std::string &image_filename) {
@@ -583,13 +582,13 @@ machine::machine(machine_config c, machine_runtime_config r) : m_c{std::move(c)}
583582
make_shadow_state_address_range(PMA_SHADOW_STATE_START, PMA_SHADOW_STATE_LENGTH, throw_invalid_argument),
584583
register_where{.merkle = true, .interpret = false});
585584
// Will populate when initialization of PMAs is done
586-
auto &shpmas = register_address_range(make_shadow_pmas_address_range(PMA_SHADOW_PMAS_START, PMA_SHADOW_PMAS_LENGTH),
585+
auto &shpmas = register_address_range(make_pmas_address_range(PMA_PMAS_START, PMA_PMAS_LENGTH),
587586
register_where{.merkle = true, .interpret = true});
588587
init_virtio_ars(m_c.virtio, m_c.processor.iunrep);
589588
init_sentinel_ars();
590589
// Populate shadow PMAs contents.
591590
// This must be done after all PMA entries are already registered, so we encode them into the shadow
592-
init_shadow_pmas_contents(shpmas);
591+
init_pmas_contents(shpmas);
593592
// Initialize TLB contents.
594593
// This must be done after all PMA entries are already registered, so we can lookup page addresses
595594
init_tlb_contents(m_c.tlb.image_filename);
@@ -2016,8 +2015,8 @@ const char *machine::get_what_name(uint64_t paddr) {
20162015
if (paddr >= PMA_SHADOW_STATE_START && paddr - PMA_SHADOW_STATE_START < PMA_SHADOW_STATE_LENGTH) {
20172016
return shadow_state_get_what_name(shadow_state_get_what(paddr));
20182017
}
2019-
if (paddr >= PMA_SHADOW_PMAS_START && paddr - PMA_SHADOW_PMAS_START < PMA_SHADOW_PMAS_LENGTH) {
2020-
return shadow_pmas_get_what_name(shadow_pmas_get_what(paddr));
2018+
if (paddr >= PMA_PMAS_START && paddr - PMA_PMAS_START < PMA_PMAS_LENGTH) {
2019+
return pma_get_what_name(pma_get_what(paddr));
20212020
}
20222021
if (paddr >= PMA_SHADOW_UARCH_STATE_START && paddr - PMA_SHADOW_UARCH_STATE_START < PMA_SHADOW_UARCH_STATE_LENGTH) {
20232022
return shadow_uarch_state_get_what_name(shadow_uarch_state_get_what(paddr));

src/machine.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -189,9 +189,9 @@ class machine final {
189189
void init_sentinel_ars();
190190

191191
/// \brief Initializes contents of the shadow PMAs memory
192-
/// \param shadow_pmas PMA entry for the shadow PMAs
192+
/// \param pmas PMA entry for the shadow PMAs
193193
/// \detail This can only be called after all PMAs have been added
194-
void init_shadow_pmas_contents(memory_address_range &shadow_pmas) const;
194+
void init_pmas_contents(memory_address_range &pmas) const;
195195

196196
/// \brief Initializes contents of machine TLB, from image in disk or with default values
197197
/// \param image_filename File containing image, or empty for default values

src/mock-address-range.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ static inline mock_address_range check_mock_flags(AR &&ar, const pma_flags &flag
5151
template <typename ABRT>
5252
static inline mock_address_range make_mock_address_range(uint64_t istart, uint64_t ilength, ABRT abrt) {
5353
uint64_t start{};
54-
auto flags = unpack_pma_istart(istart, start);
54+
auto flags = pma_unpack_istart(istart, start);
5555
if (flags.M) {
5656
return make_address_range(pma_get_DID_name(flags.DID), start, ilength, flags, abrt);
5757
}

src/pma-constants.h

+2-3
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ namespace cartesi {
2727
enum PMA_ranges : uint64_t {
2828
PMA_SHADOW_STATE_START = EXPAND_UINT64_C(PMA_SHADOW_STATE_START_DEF), ///< Start of processor shadow range
2929
PMA_SHADOW_STATE_LENGTH = EXPAND_UINT64_C(PMA_SHADOW_STATE_LENGTH_DEF), ///< Length of processor shadow range
30-
PMA_SHADOW_PMAS_START = EXPAND_UINT64_C(PMA_SHADOW_PMAS_START_DEF), ///< Start of pma board shadow range
31-
PMA_SHADOW_PMAS_LENGTH = EXPAND_UINT64_C(PMA_SHADOW_PMAS_LENGTH_DEF), ///< Length of pma board shadow range
30+
PMA_PMAS_START = EXPAND_UINT64_C(PMA_PMAS_START_DEF), ///< Start of pma board shadow range
31+
PMA_PMAS_LENGTH = EXPAND_UINT64_C(PMA_PMAS_LENGTH_DEF), ///< Length of pma board shadow range
3232
PMA_DTB_START = EXPAND_UINT64_C(PMA_DTB_START_DEF), ///< Start of DTB range
3333
PMA_DTB_LENGTH = EXPAND_UINT64_C(PMA_DTB_LENGTH_DEF), ///< Length of DTB range
3434
PMA_SHADOW_TLB_START = EXPAND_UINT64_C(PMA_SHADOW_TLB_START_DEF), ///< Start of TLB shadow range
@@ -110,7 +110,6 @@ enum PMA_ISTART_masks : uint64_t {
110110
enum class PMA_ISTART_DID {
111111
memory = PMA_MEMORY_DID_DEF, ///< DID for memory
112112
shadow_state = PMA_SHADOW_STATE_DID_DEF, ///< DID for shadow device
113-
shadow_pmas = PMA_SHADOW_PMAS_DID_DEF, ///< DID for shadow pma array device
114113
shadow_TLB = PMA_SHADOW_TLB_DID_DEF, ///< DID for shadow TLB device
115114
flash_drive = PMA_FLASH_DRIVE_DID_DEF, ///< DID for drive device
116115
CLINT = PMA_CLINT_DID_DEF, ///< DID for CLINT device

src/pma-defines.h

+11-12
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@
1919
// NOLINTBEGIN(cppcoreguidelines-macro-usage,cppcoreguidelines-macro-to-enum,modernize-macro-to-enum)
2020
#define PMA_SHADOW_STATE_START_DEF 0x0 ///< Shadow start address
2121
#define PMA_SHADOW_STATE_LENGTH_DEF 0x1000 ///< Shadow length in bytes
22-
#define PMA_SHADOW_PMAS_START_DEF 0x10000 ///< PMA Array start address
23-
#define PMA_SHADOW_PMAS_LENGTH_DEF 0x1000 ///< PMA Array length in bytes
22+
#define PMA_PMAS_START_DEF 0x10000 ///< PMA Array start address
23+
#define PMA_PMAS_LENGTH_DEF 0x1000 ///< PMA Array length in bytes
2424
#define PMA_SHADOW_TLB_START_DEF 0x20000 ///< TLB start address
2525
#define PMA_SHADOW_TLB_LENGTH_DEF 0x6000 ///< TLB length in bytes
2626
#define PMA_SHADOW_UARCH_STATE_START_DEF 0x400000 ///< microarchitecture shadow state start address
@@ -53,16 +53,15 @@
5353

5454
#define PMA_MEMORY_DID_DEF 0 ///< Device ID for memory
5555
#define PMA_SHADOW_STATE_DID_DEF 1 ///< Device ID for shadow state device
56-
#define PMA_SHADOW_PMAS_DID_DEF 2 ///< Device ID for shadow pma array device
57-
#define PMA_FLASH_DRIVE_DID_DEF 3 ///< Device ID for flash drive device
58-
#define PMA_CLINT_DID_DEF 4 ///< Device ID for CLINT device
59-
#define PMA_HTIF_DID_DEF 5 ///< Device ID for HTIF device
60-
#define PMA_SHADOW_TLB_DID_DEF 6 ///< Device ID for shadow TLB device
61-
#define PMA_CMIO_RX_BUFFER_DID_DEF 7 ///< Device ID for cmio RX buffer
62-
#define PMA_CMIO_TX_BUFFER_DID_DEF 8 ///< Device ID for cmio TX buffer
63-
#define PMA_PLIC_DID_DEF 10 ///< Device ID for PLIC device
64-
#define PMA_VIRTIO_DID_DEF 11 ///< Device ID for VirtIO devices
65-
#define PMA_SHADOW_UARCH_STATE_DID_DEF 12 ///< Device ID for uarch shadow state device
56+
#define PMA_FLASH_DRIVE_DID_DEF 2 ///< Device ID for flash drive device
57+
#define PMA_CLINT_DID_DEF 3 ///< Device ID for CLINT device
58+
#define PMA_HTIF_DID_DEF 4 ///< Device ID for HTIF device
59+
#define PMA_SHADOW_TLB_DID_DEF 5 ///< Device ID for shadow TLB device
60+
#define PMA_CMIO_RX_BUFFER_DID_DEF 6 ///< Device ID for cmio RX buffer
61+
#define PMA_CMIO_TX_BUFFER_DID_DEF 7 ///< Device ID for cmio TX buffer
62+
#define PMA_PLIC_DID_DEF 9 ///< Device ID for PLIC device
63+
#define PMA_VIRTIO_DID_DEF 10 ///< Device ID for VirtIO devices
64+
#define PMA_SHADOW_UARCH_STATE_DID_DEF 11 ///< Device ID for uarch shadow state device
6665

6766
// helper for using UINT64_C with defines
6867
#ifndef EXPAND_UINT64_C

src/pma.h

+65-4
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,10 @@
1717
#ifndef PMA_H
1818
#define PMA_H
1919

20+
#include <array>
2021
#include <cstdint>
2122

23+
#include "compiler-defines.h"
2224
#include "pma-constants.h"
2325

2426
namespace cartesi {
@@ -32,8 +34,6 @@ static constexpr const char *pma_get_DID_name(PMA_ISTART_DID did) {
3234
return "DID.memory";
3335
case PMA_ISTART_DID::shadow_state:
3436
return "DID.shadow_state";
35-
case PMA_ISTART_DID::shadow_pmas:
36-
return "DID.shadow_pmas";
3737
case PMA_ISTART_DID::shadow_TLB:
3838
return "DID.shadow_TLB";
3939
case PMA_ISTART_DID::flash_drive:
@@ -73,7 +73,7 @@ struct pma_flags {
7373
bool operator==(const pma_flags &) const = default;
7474
};
7575

76-
static constexpr pma_flags unpack_pma_istart(uint64_t istart, uint64_t &start) {
76+
static constexpr pma_flags pma_unpack_istart(uint64_t istart, uint64_t &start) {
7777
start = istart & PMA_ISTART_START_MASK;
7878
return pma_flags{.M = ((istart & PMA_ISTART_M_MASK) >> PMA_ISTART_M_SHIFT) != 0,
7979
.IO = ((istart & PMA_ISTART_IO_MASK) >> PMA_ISTART_IO_SHIFT) != 0,
@@ -86,7 +86,7 @@ static constexpr pma_flags unpack_pma_istart(uint64_t istart, uint64_t &start) {
8686
.DID = static_cast<PMA_ISTART_DID>((istart & PMA_ISTART_DID_MASK) >> PMA_ISTART_DID_SHIFT)};
8787
}
8888

89-
static constexpr uint64_t pack_pma_istart(const pma_flags &flags, uint64_t start) {
89+
static constexpr uint64_t pma_pack_istart(const pma_flags &flags, uint64_t start) {
9090
uint64_t istart = start;
9191
istart |= (static_cast<uint64_t>(flags.M) << PMA_ISTART_M_SHIFT);
9292
istart |= (static_cast<uint64_t>(flags.IO) << PMA_ISTART_IO_SHIFT);
@@ -100,6 +100,67 @@ static constexpr uint64_t pack_pma_istart(const pma_flags &flags, uint64_t start
100100
return istart;
101101
}
102102

103+
/// \brief Shadow memory layout
104+
struct PACKED pma_entry {
105+
uint64_t istart;
106+
uint64_t ilength;
107+
};
108+
109+
using pmas_state = std::array<pma_entry, PMA_MAX>;
110+
111+
/// \brief List of field types
112+
enum class pma_what : uint64_t {
113+
istart = offsetof(pma_entry, istart),
114+
ilength = offsetof(pma_entry, ilength),
115+
unknown_ = UINT64_C(1) << 63, // Outside of RISC-V address space
116+
};
117+
118+
/// \brief Obtains the absolute address of a PMA entry.
119+
/// \param p Index of desired PMA entry
120+
/// \returns The address.
121+
static constexpr uint64_t pma_get_abs_addr(uint64_t p) {
122+
return PMA_PMAS_START + (p * sizeof(pma_entry));
123+
}
124+
125+
/// \brief Obtains the absolute address of a PMA entry.
126+
/// \param p Index of desired PMA entry
127+
/// \param what Desired field
128+
/// \returns The address.
129+
static constexpr uint64_t pma_get_abs_addr(uint64_t p, pma_what what) {
130+
return pma_get_abs_addr(p) + static_cast<uint64_t>(what);
131+
}
132+
133+
static constexpr pma_what pma_get_what(uint64_t paddr) {
134+
if (paddr < PMA_PMAS_START || paddr - PMA_PMAS_START >= sizeof(pmas_state) ||
135+
(paddr & (sizeof(uint64_t) - 1)) != 0) {
136+
return pma_what::unknown_;
137+
}
138+
//??D First condition ensures offset = (paddr-PMA_PMAS_START) >= 0
139+
//??D Second ensures offset < sizeof(pmas_state)
140+
//??D Third ensures offset is aligned to sizeof(uint64_t)
141+
//??D pma_entry only contains uint64_t fields
142+
//??D pmas_state_what contains one entry with the offset of each field in pma_entry
143+
//??D I don't see how the cast can produce something outside the enum...
144+
// NOLINTNEXTLINE(clang-analyzer-optin.core.EnumCastOutOfRange)
145+
return pma_what{(paddr - PMA_PMAS_START) % sizeof(pma_entry)};
146+
}
147+
148+
static constexpr const char *pma_get_what_name(pma_what what) {
149+
const auto paddr = static_cast<uint64_t>(what);
150+
if (paddr >= sizeof(pma_entry) || (paddr & (sizeof(uint64_t) - 1)) != 0) {
151+
return "pma.unknown_";
152+
}
153+
switch (what) {
154+
case pma_what::istart:
155+
return "pma.istart";
156+
case pma_what::ilength:
157+
return "pma.ilength";
158+
case pma_what::unknown_:
159+
return "pma.unknown_";
160+
}
161+
return "pmas.unknown_";
162+
}
163+
103164
} // namespace cartesi
104165

105166
#endif

src/shadow-pmas-address-range.h src/pmas-address-range.h

+7-8
Original file line numberDiff line numberDiff line change
@@ -14,23 +14,22 @@
1414
// with this program (see COPYING). If not, see <https://www.gnu.org/licenses/>.
1515
//
1616

17-
#ifndef SHADOW_PMAS_ADDRESS_RANGE_H
18-
#define SHADOW_PMAS_ADDRESS_RANGE_H
17+
#ifndef PMAS_ADDRESS_RANGE_H
18+
#define PMAS_ADDRESS_RANGE_H
1919

2020
#include <cstdint>
2121
#include <stdexcept>
2222

2323
#include "memory-address-range.h"
24-
#include "pma-constants.h"
25-
#include "shadow-pmas.h"
24+
#include "pma.h"
2625

2726
/// \file
2827
/// \brief Shadow device.
2928

3029
namespace cartesi {
3130

32-
static inline auto make_shadow_pmas_address_range(uint64_t start, uint64_t length) {
33-
static constexpr pma_flags shadow_pmas_flags{
31+
static inline auto make_pmas_address_range(uint64_t start, uint64_t length) {
32+
static constexpr pma_flags m_flags{
3433
.M = true,
3534
.IO = false,
3635
.E = false,
@@ -39,9 +38,9 @@ static inline auto make_shadow_pmas_address_range(uint64_t start, uint64_t lengt
3938
.X = false,
4039
.IR = false,
4140
.IW = false,
42-
.DID = PMA_ISTART_DID::shadow_pmas,
41+
.DID = PMA_ISTART_DID::memory,
4342
};
44-
return make_callocd_memory_address_range("shadow PMAs", start, length, shadow_pmas_flags);
43+
return make_callocd_memory_address_range("PMAs", start, length, m_flags);
4544
}
4645

4746
} // namespace cartesi

src/record-step-state-access.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
#include "i-prefer-shadow-state.h"
2828
#include "i-state-access.h"
2929
#include "machine.h"
30-
#include "shadow-pmas-address-range.h"
30+
#include "pma.h"
3131
#include "shadow-tlb.h"
3232
#include "unique-c-ptr.h"
3333

@@ -235,8 +235,8 @@ class record_step_state_access :
235235
// replay_step_state_access reconstructs a mock_address_range from the
236236
// corresponding istart and ilength fields in the shadow pmas
237237
// so we mark the page where they live here
238-
touch_page(shadow_pmas_get_pma_abs_addr(index, shadow_pmas_what::istart));
239-
touch_page(shadow_pmas_get_pma_abs_addr(index, shadow_pmas_what::ilength));
238+
touch_page(pma_get_abs_addr(index, pma_what::istart));
239+
touch_page(pma_get_abs_addr(index, pma_what::ilength));
240240
return m_m.read_pma(index);
241241
}
242242

src/replay-step-state-access.h

+3-4
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,9 @@
2727
#include "i-prefer-shadow-state.h"
2828
#include "i-state-access.h"
2929
#include "mock-address-range.h"
30-
#include "pma-constants.h"
30+
#include "pma.h"
3131
#include "replay-step-state-access-interop.h"
3232
#include "riscv-constants.h"
33-
#include "shadow-pmas-address-range.h"
3433
#include "shadow-state.h"
3534
#include "shadow-tlb.h"
3635
#include "shadow-uarch-state.h"
@@ -405,12 +404,12 @@ class replay_step_state_access :
405404
}
406405

407406
uint64_t read_pma_istart(uint64_t index) const {
408-
const auto haddr = do_get_faddr(shadow_pmas_get_pma_abs_addr(index, shadow_pmas_what::istart));
407+
const auto haddr = do_get_faddr(pma_get_abs_addr(index, pma_what::istart));
409408
return aliased_aligned_read<uint64_t>(haddr);
410409
}
411410

412411
uint64_t read_pma_ilength(uint64_t index) const {
413-
const auto haddr = do_get_faddr(shadow_pmas_get_pma_abs_addr(index, shadow_pmas_what::ilength));
412+
const auto haddr = do_get_faddr(pma_get_abs_addr(index, pma_what::ilength));
414413
return aliased_aligned_read<uint64_t>(haddr);
415414
}
416415

0 commit comments

Comments
 (0)