Skip to content

Commit 609b535

Browse files
committed
Machine: extend memory-backed to support large/64-bit memory
Signed-off-by: Pavel Pisa <pisa@fel.cvut.cz>
1 parent 75bf27d commit 609b535

3 files changed

Lines changed: 30 additions & 32 deletions

File tree

src/machine/memory/backend/backend_memory.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace machine {
1515
/**
1616
* Relative index within an instance of backend memory.
1717
*/
18-
typedef size_t Offset;
18+
typedef uint64_t Offset;
1919

2020
/**
2121
* Interface for physical memory or periphery.
@@ -105,8 +105,8 @@ class BackendMemory : public QObject {
105105
*/
106106
void external_backend_change_notify(
107107
const BackendMemory *mem_access,
108-
uint32_t start_addr,
109-
uint32_t last_addr,
108+
Offset start_addr,
109+
Offset last_addr,
110110
AccessEffects type) const;
111111
};
112112

src/machine/memory/backend/memory.cpp

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@ WriteResult
1919
MemorySection::write(Offset dst_offset, const void *source, size_t size, WriteOptions options) {
2020
UNUSED(options)
2121

22-
auto destination = static_cast<size_t>(dst_offset);
23-
24-
if (destination >= length()) {
22+
if (dst_offset >= length()) {
2523
throw SIMULATOR_EXCEPTION(
2624
OutOfMemoryAccess, "Trying to write outside of the memory section",
27-
QString("Accessing using offset: ") + QString::number(destination));
25+
QString("Accessing using offset: ") + QString::number(dst_offset));
2826
}
2927

28+
size_t destination = static_cast<size_t>(dst_offset);
29+
3030
// Size the can be read from this section
3131
const size_t available_size = std::min(destination + size, length()) - destination;
3232

@@ -41,16 +41,16 @@ ReadResult
4141
MemorySection::read(void *destination, Offset src_offset, size_t size, ReadOptions options) const {
4242
UNUSED(options)
4343

44-
auto source = static_cast<size_t>(src_offset);
45-
46-
size = std::min(source + size, length()) - source;
47-
48-
if (source >= length()) {
44+
if (src_offset >= length()) {
4945
throw SIMULATOR_EXCEPTION(
5046
OutOfMemoryAccess, "Trying to read outside of the memory section",
51-
QString("Accessing using offset: ") + QString::number(source));
47+
QString("Accessing using offset: ") + QString::number(src_offset));
5248
}
5349

50+
size_t source = static_cast<size_t>(src_offset);
51+
52+
size = std::min(source + size, length()) - source;
53+
5454
memcpy(destination, &dt[source], size);
5555

5656
return { .n_bytes = size };
@@ -80,10 +80,6 @@ bool MemorySection::operator!=(const MemorySection &ms) const {
8080
// Settings sanity checks
8181
static_assert(MEMORY_SECTION_SIZE != 0, "Nonzero memory section size is required.");
8282
static_assert(MEMORY_TREE_ROW_SIZE != 0, "Nonzero memory tree row size is required.");
83-
static_assert(
84-
((32 - MEMORY_SECTION_BITS) % MEMORY_TREE_BITS) == 0,
85-
"Number of bits in tree row has to be exact division of available number "
86-
"of bits.");
8783

8884
/**
8985
* Generate mask to get memory section index from address.
@@ -96,14 +92,15 @@ static_assert(
9692
* ```address & generate_mask(8, 0)```
9793
*/
9894
constexpr uint64_t generate_mask(size_t section_size, size_t unit_size) {
99-
return ((1U << section_size) - 1) << unit_size;
95+
return ((1LLU << section_size) - 1) << unit_size;
10096
}
10197

10298
/**
10399
* Get index in row for given offset and row number i
104100
*/
105101
constexpr size_t tree_row_bit_offset(size_t i) {
106-
return 32 - MEMORY_TREE_BITS - i * MEMORY_TREE_BITS;
102+
return (MEMORY_TREE_BITS * MEMORY_TREE_DEPTH + MEMORY_SECTION_BITS)
103+
- MEMORY_TREE_BITS * (i + 1);
107104
}
108105

109106
/*
@@ -143,7 +140,7 @@ void Memory::reset(const Memory &m) {
143140
this->mt_root = copy_section_tree(m.get_memory_tree_root(), 0);
144141
}
145142

146-
MemorySection *Memory::get_section(size_t offset, bool create) const {
143+
MemorySection *Memory::get_section(Offset offset, bool create) const {
147144
union MemoryTree *w = this->mt_root;
148145
size_t row_num;
149146
// Walk memory tree branch from root to leaf and create new nodes when
@@ -221,7 +218,7 @@ union machine::MemoryTree *Memory::allocate_section_tree() {
221218
return mt;
222219
}
223220

224-
void Memory::free_section_tree(union MemoryTree *mt, size_t depth) {
221+
void Memory::free_section_tree(union MemoryTree *mt, unsigned depth) {
225222
if (depth < (MEMORY_TREE_DEPTH - 1)) { // Following level is memory tree
226223
for (size_t i = 0; i < MEMORY_TREE_ROW_SIZE; i++) {
227224
if (mt[i].subtree != nullptr) {
@@ -239,7 +236,7 @@ void Memory::free_section_tree(union MemoryTree *mt, size_t depth) {
239236
bool Memory::compare_section_tree(
240237
const union MemoryTree *mt1,
241238
const union MemoryTree *mt2,
242-
size_t depth) {
239+
unsigned depth) {
243240
if (depth < (MEMORY_TREE_DEPTH - 1)) { // Following level is memory tree
244241
for (size_t i = 0; i < MEMORY_TREE_ROW_SIZE; i++) {
245242
if (((mt1[i].subtree == nullptr || mt2[i].subtree == nullptr)
@@ -260,7 +257,7 @@ bool Memory::compare_section_tree(
260257
return true;
261258
}
262259

263-
union machine::MemoryTree *Memory::copy_section_tree(const union MemoryTree *mt, size_t depth) {
260+
union machine::MemoryTree *Memory::copy_section_tree(const union MemoryTree *mt, unsigned depth) {
264261
union MemoryTree *nmt = allocate_section_tree();
265262
if (depth < (MEMORY_TREE_DEPTH - 1)) { // Following level is memory tree
266263
for (size_t i = 0; i < MEMORY_TREE_ROW_SIZE; i++) {

src/machine/memory/backend/memory.h

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,17 @@ class MemorySection final : public BackendMemory {
4545
//////////////////////////////////////////////////////////////////////////////
4646
/// Some optimisation options
4747
// How big memory sections will be in bits (2^8=256 bytes)
48-
constexpr size_t MEMORY_SECTION_BITS = 8;
48+
constexpr unsigned MEMORY_SECTION_BITS = 12;
4949
// How big one row of lookup tree will be in bits (2^4=16)
50-
constexpr size_t MEMORY_TREE_BITS = 4;
50+
constexpr unsigned MEMORY_TREE_BITS = 9;
5151
//////////////////////////////////////////////////////////////////////////////
5252
// Size of one section
53-
constexpr size_t MEMORY_SECTION_SIZE = (1u << MEMORY_SECTION_BITS);
53+
constexpr size_t MEMORY_SECTION_SIZE = (1llu << MEMORY_SECTION_BITS);
5454
// Size of one memory row
55-
constexpr size_t MEMORY_TREE_ROW_SIZE = (1u << MEMORY_TREE_BITS);
55+
constexpr size_t MEMORY_TREE_ROW_SIZE = (1llu << MEMORY_TREE_BITS);
5656
// Depth of tree
57-
constexpr size_t MEMORY_TREE_DEPTH = ((32 - MEMORY_SECTION_BITS) / MEMORY_TREE_BITS);
57+
constexpr unsigned MEMORY_TREE_DEPTH = ((64 - MEMORY_SECTION_BITS
58+
+ MEMORY_TREE_BITS - 1) / MEMORY_TREE_BITS);
5859

5960
union MemoryTree {
6061
union MemoryTree *subtree;
@@ -78,7 +79,7 @@ class Memory final : public BackendMemory {
7879
void reset(const Memory &);
7980

8081
// returns section containing given address
81-
[[nodiscard]] MemorySection *get_section(size_t offset, bool create) const;
82+
[[nodiscard]] MemorySection *get_section(Offset offset, bool create) const;
8283

8384
WriteResult
8485
write(Offset destination, const void *source, size_t size, WriteOptions options) override;
@@ -97,10 +98,10 @@ class Memory final : public BackendMemory {
9798
union MemoryTree *mt_root;
9899
uint32_t change_counter = 0;
99100
static union MemoryTree *allocate_section_tree();
100-
static void free_section_tree(union MemoryTree *, size_t depth);
101+
static void free_section_tree(union MemoryTree *, unsigned depth);
101102
static bool
102-
compare_section_tree(const union MemoryTree *, const union MemoryTree *, size_t depth);
103-
static union MemoryTree *copy_section_tree(const union MemoryTree *, size_t depth);
103+
compare_section_tree(const union MemoryTree *, const union MemoryTree *, unsigned depth);
104+
static union MemoryTree *copy_section_tree(const union MemoryTree *, unsigned depth);
104105
[[nodiscard]] uint32_t get_change_counter() const;
105106
};
106107
} // namespace machine

0 commit comments

Comments
 (0)