Skip to content

Commit 38f7f22

Browse files
authored
Merge pull request rivosinc#4 from rivosinc/dev/joy/update_to_work_with_latest_spike
Updates to build with the current Spike
2 parents 61f2620 + c4cc29d commit 38f7f22

File tree

5 files changed

+165
-62
lines changed

5 files changed

+165
-62
lines changed

hammer.cpp

Lines changed: 7 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,11 @@ Hammer::Hammer(const char *isa, const char *privilege_levels, const char *vector
4242
const char *bootargs = nullptr;
4343
bool real_time_clint = false;
4444

45-
cfg_t cfg = cfg_t(initrd_bounds, bootargs, isa, privilege_levels, vector_arch, memory_layout,
45+
reg_t num_pmpregions = 16;
46+
47+
endianness_t endinaness = endianness_little;
48+
49+
cfg_t cfg = cfg_t(initrd_bounds, bootargs, isa, privilege_levels, vector_arch, endinaness, num_pmpregions, memory_layout,
4650
hart_ids, real_time_clint);
4751

4852
if (start_pc.has_value()) {
@@ -56,9 +60,10 @@ Hammer::Hammer(const char *isa, const char *privilege_levels, const char *vector
5660

5761
bool halted = false;
5862
bool dtb_enabled = true;
63+
bool socket_enabled = false;
5964

6065
simulator = new sim_t(&cfg, halted, mems, plugin_devices, htif_args, dm_config, log_path,
61-
dtb_enabled, dtb_file, cmd_file);
66+
dtb_enabled, dtb_file, socket_enabled, cmd_file);
6267

6368
// Initializes everything
6469
simulator->start();
@@ -148,50 +153,3 @@ std::vector<uint64_t> Hammer::get_vector_reg(uint8_t hart_id, uint8_t vector_reg
148153
return vector_reg_value;
149154
}
150155

151-
std::vector<uint8_t> Hammer::get_memory_at_VA(uint8_t hart_id, uint64_t virtual_address,
152-
size_t num_bytes_to_read) {
153-
std::vector<uint8_t> memory_contents;
154-
155-
processor_t *hart = simulator->get_core(hart_id);
156-
mmu_t *mmu = hart->get_mmu();
157-
158-
while (num_bytes_to_read > 0) {
159-
uint64_t bytes_read = 0;
160-
size_t num_bytes_read = 0;
161-
162-
if ((num_bytes_to_read > 8) && (virtual_address % 8) == 0) {
163-
bytes_read = mmu->load_uint64(virtual_address);
164-
num_bytes_read = 8;
165-
} else if ((num_bytes_to_read > 4) && (virtual_address % 4) == 0) {
166-
bytes_read = mmu->load_uint32(virtual_address);
167-
num_bytes_read = 4;
168-
} else if ((num_bytes_to_read > 2) && (virtual_address % 2) == 0) {
169-
bytes_read = mmu->load_uint16(virtual_address);
170-
num_bytes_read = 2;
171-
} else {
172-
bytes_read = mmu->load_uint8(virtual_address);
173-
num_bytes_read = 1;
174-
}
175-
176-
for (size_t i = 0; i < num_bytes_read; ++i) {
177-
memory_contents.push_back(bytes_read & 0xFF);
178-
bytes_read >>= 8;
179-
}
180-
181-
virtual_address += num_bytes_read;
182-
num_bytes_to_read -= num_bytes_read;
183-
}
184-
185-
return memory_contents;
186-
}
187-
188-
void Hammer::set_memory_at_VA(uint8_t hart_id, uint64_t virtual_address,
189-
const std::vector<uint8_t> &memory_contents) {
190-
processor_t *hart = simulator->get_core(hart_id);
191-
mmu_t *mmu = hart->get_mmu();
192-
193-
for (uint8_t byte_to_write : memory_contents) {
194-
mmu->store_uint8(virtual_address, byte_to_write);
195-
++virtual_address;
196-
}
197-
}

hammer.h

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#pragma once
66

77
#include "hammer_enums.h"
8+
#include "riscv/mmu.h"
89
#include "riscv/sim.h"
910

1011
#include <iostream>
@@ -35,10 +36,36 @@ class Hammer {
3536

3637
std::vector<uint64_t> get_vector_reg(uint8_t hart_id, uint8_t vector_reg_id);
3738

38-
std::vector<uint8_t> get_memory_at_VA(uint8_t hart_id, uint64_t virtual_address,
39-
size_t num_bytes_to_read);
40-
void set_memory_at_VA(uint8_t hart_id, uint64_t virtual_address,
41-
const std::vector<uint8_t> &memory_contents);
39+
template <typename T>
40+
std::optional<std::vector<T>> get_memory_at_VA(uint8_t hart_id, uint64_t virtual_address,
41+
size_t num_bytes_to_read) {
42+
if (num_bytes_to_read % sizeof(T))
43+
return std::nullopt;
44+
mmu_t *mmu = simulator->get_core(hart_id)->get_mmu();
45+
std::vector<T> data;
46+
try {
47+
for (size_t i = 0; i < num_bytes_to_read; i += sizeof(T))
48+
data.push_back(mmu->load<T>(virtual_address + i));
49+
} catch (trap_t &t) {
50+
return std::nullopt;
51+
}
52+
return data;
53+
}
54+
55+
template <typename T>
56+
int set_memory_at_VA(uint8_t hart_id, uint64_t virtual_address,
57+
const std::vector<T> &memory_contents) {
58+
mmu_t *mmu = simulator->get_core(hart_id)->get_mmu();
59+
try {
60+
for (auto &i : memory_contents) {
61+
mmu->store<T>(virtual_address, i);
62+
virtual_address += sizeof(T);
63+
}
64+
} catch (trap_t &t) {
65+
return -EFAULT;
66+
}
67+
return 0;
68+
}
4269

4370
void hello_world() { printf("Hammer: Hello World.\n"); }
4471

hammer_pybind.cpp

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,48 @@ PYBIND11_MODULE(hammer, m) {
2929
.def("get_vlen", &Hammer::get_vlen)
3030
.def("get_elen", &Hammer::get_elen)
3131
.def("get_vector_reg", &Hammer::get_vector_reg)
32-
.def("get_memory_at_VA", &Hammer::get_memory_at_VA)
33-
.def("set_memory_at_VA", &Hammer::set_memory_at_VA)
32+
.def("get_memory_at_VA",
33+
[](Hammer &h, uint8_t hart_id, uint64_t virtual_address, size_t num_bytes_to_read,
34+
size_t stride) -> pybind11::object {
35+
switch (stride) {
36+
case 1:
37+
return pybind11::cast(
38+
h.get_memory_at_VA<uint8_t>(hart_id, virtual_address, num_bytes_to_read));
39+
case 2:
40+
return pybind11::cast(
41+
h.get_memory_at_VA<uint16_t>(hart_id, virtual_address, num_bytes_to_read));
42+
case 4:
43+
return pybind11::cast(
44+
h.get_memory_at_VA<uint32_t>(hart_id, virtual_address, num_bytes_to_read));
45+
case 8:
46+
return pybind11::cast(
47+
h.get_memory_at_VA<uint64_t>(hart_id, virtual_address, num_bytes_to_read));
48+
default:
49+
throw std::length_error("Invalid stride");
50+
}
51+
return pybind11::none();
52+
})
53+
.def("set_memory_at_VA",
54+
[](Hammer &h, uint8_t hart_id, uint64_t virtual_address, pybind11::list &data,
55+
size_t stride) {
56+
switch (stride) {
57+
case 1:
58+
return h.set_memory_at_VA<uint8_t>(hart_id, virtual_address,
59+
data.cast<std::vector<uint8_t>>());
60+
case 2:
61+
return h.set_memory_at_VA<uint16_t>(hart_id, virtual_address,
62+
data.cast<std::vector<uint16_t>>());
63+
case 4:
64+
return h.set_memory_at_VA<uint32_t>(hart_id, virtual_address,
65+
data.cast<std::vector<uint32_t>>());
66+
case 8:
67+
return h.set_memory_at_VA<uint64_t>(hart_id, virtual_address,
68+
data.cast<std::vector<uint64_t>>());
69+
default:
70+
throw std::length_error("Invalid stride");
71+
}
72+
return -EINVAL;
73+
})
3474
.def("single_step", &Hammer::single_step);
3575

3676
// Reference:

pytests/pytest002.py

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@ def main():
3232
# Reads memory using Hammer::get_memory_at_VA(), single steps a load that
3333
# reads the same address and compares values.
3434
virtual_address = 0x80001000
35-
memory_contents = hammer.get_memory_at_VA(0, virtual_address, 8)
35+
memory_contents = hammer.get_memory_at_VA(0, virtual_address, 8, 1)
36+
37+
if (memory_contents is None):
38+
sys.exit("ERROR: Unable to read memory")
3639

3740
value_at_address = 0
3841
i = 0
@@ -50,6 +53,22 @@ def main():
5053
"the load instruction which returned {current_x2}")
5154
sys.exit(1)
5255

56+
memory_contents = hammer.get_memory_at_VA(0, virtual_address, 8, 8)
57+
if (memory_contents[0] != current_x2):
58+
sys.exit(f'unexpected data read: 0x{memory_contents[0]:x}')
59+
60+
memory_contents = hammer.get_memory_at_VA(0, virtual_address, 8, 4)
61+
memory_contents[0] |= memory_contents[1] << 32
62+
if (memory_contents[0] != current_x2):
63+
sys.exit(f'unexpected data read: 0x{memory_contents[0]:x}')
64+
65+
memory_contents = hammer.get_memory_at_VA(0, virtual_address, 8, 2)
66+
memory_contents[0] |= memory_contents[1] << 16
67+
memory_contents[0] |= memory_contents[2] << 32
68+
memory_contents[0] |= memory_contents[3] << 48
69+
if (memory_contents[0] != current_x2):
70+
sys.exit(f'unexpected data read: 0x{memory_contents[0]:x}')
71+
5372
# Writes memory using Hammer::set_memory_at_VA(), single steps a load that
5473
# reads the same address and compares values.
5574
new_memory_contents = [0xab, 0xcd, 0xef, 0xde, 0x11, 0x22, 0x33, 0x44]
@@ -59,7 +78,8 @@ def main():
5978
new_value_at_address |= (byte_value << (i * 8))
6079
i = i + 1
6180

62-
hammer.set_memory_at_VA(0, virtual_address, new_memory_contents)
81+
if (hammer.set_memory_at_VA(0, virtual_address, new_memory_contents, 1)):
82+
sys.exit("ERROR: set_memory_at_VA() failed")
6383

6484
# Step the next load that will read the same location
6585
hammer.single_step(0)
@@ -71,6 +91,46 @@ def main():
7191
"the load instruction returned {current_x2:x}")
7292
sys.exit(1)
7393

94+
# Tests the fail case.
95+
memory_contents = hammer.get_memory_at_VA(0, 0xabcdabcdabcd, 1, 1)
96+
if (memory_contents is not None):
97+
sys.exit("ERROR: Expected memory load to fail.")
98+
99+
if (hammer.set_memory_at_VA(0, 0xabcdabcdabcd, new_memory_contents, 1) == 0):
100+
sys.exit("ERROR: Expected memory store to fail.")
101+
102+
# Test set of various sizes (8/4/2)
103+
new_memory_contents = [0xdeadbeef01234567]
104+
if (hammer.set_memory_at_VA(0, virtual_address, new_memory_contents, 8)):
105+
sys.exit("ERROR: set_memory_at_VA() failed")
106+
memory_contents = hammer.get_memory_at_VA(0, virtual_address, 8, 8)
107+
if (memory_contents[0] != new_memory_contents[0]):
108+
sys.exit(f'unexpected data read: 0x{memory_contents[0]:x}')
109+
110+
new_memory_contents = [0xdeadbeef]
111+
if (hammer.set_memory_at_VA(0, virtual_address, new_memory_contents, 4)):
112+
sys.exit("ERROR: set_memory_at_VA() failed")
113+
memory_contents = hammer.get_memory_at_VA(0, virtual_address, 4, 4)
114+
if (memory_contents[0] != new_memory_contents[0]):
115+
sys.exit(f'unexpected data read: 0x{memory_contents[0]:x}')
116+
117+
new_memory_contents = [0xdead]
118+
if (hammer.set_memory_at_VA(0, virtual_address, new_memory_contents, 2)):
119+
sys.exit("ERROR: set_memory_at_VA() failed")
120+
memory_contents = hammer.get_memory_at_VA(0, virtual_address, 2, 2)
121+
if (memory_contents[0] != new_memory_contents[0]):
122+
sys.exit(f'unexpected data read: 0x{memory_contents[0]:x}')
123+
124+
# Invalid stride
125+
try:
126+
hammer.set_memory_at_VA(0, virtual_address, new_memory_contents, 3)
127+
except ValueError:
128+
pass
129+
try:
130+
hammer.get_memory_at_VA(0, virtual_address, 2, 5)
131+
except ValueError:
132+
pass
133+
74134
pass
75135

76136

tests/test002.cpp

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,17 +29,20 @@ int main(int argc, char *argv[]) {
2929

3030
uint64_t virtual_address = data_area_start_address;
3131
for (uint32_t bytes_to_read = 8; bytes_to_read > 0; --bytes_to_read) {
32-
std::vector<uint8_t> memory_contents =
33-
hammer.get_memory_at_VA(0, virtual_address, bytes_to_read);
32+
auto memory_contents = hammer.get_memory_at_VA<uint8_t>(0, virtual_address, bytes_to_read);
33+
if (memory_contents.has_value() == false) {
34+
printf("ERROR: Unable to read memory\n");
35+
exit(1);
36+
}
3437

35-
if (memory_contents.size() != bytes_to_read) {
38+
if (memory_contents.value().size() != bytes_to_read) {
3639
printf("ERROR: Bytes read did not match requested num bytes\n");
3740
exit(1);
3841
}
3942

4043
uint64_t value_at_address = 0;
4144
uint8_t i = 0;
42-
for (uint64_t byte_value : memory_contents) {
45+
for (uint64_t byte_value : memory_contents.value()) {
4346
value_at_address |= (byte_value << (i * 8));
4447
++i;
4548
}
@@ -67,7 +70,10 @@ int main(int argc, char *argv[]) {
6770
}
6871

6972
virtual_address = data_area_start_address;
70-
hammer.set_memory_at_VA(0, virtual_address, new_memory_contents);
73+
if (hammer.set_memory_at_VA<uint8_t>(0, virtual_address, new_memory_contents)) {
74+
printf("ERROR: set_memory_at_VA() failed\n");
75+
exit(1);
76+
}
7177

7278
// Step the next load that will read the same location
7379
hammer.single_step(0);
@@ -81,4 +87,16 @@ int main(int argc, char *argv[]) {
8187
new_value_at_address, current_x2);
8288
exit(1);
8389
}
90+
91+
// Tests the fail case.
92+
auto memory_contents = hammer.get_memory_at_VA<uint32_t>(0, 0xabcdabcdabcd, 1);
93+
if (memory_contents.has_value()) {
94+
printf("ERROR: Expected memory load to fail.\n");
95+
exit(1);
96+
}
97+
98+
if (hammer.set_memory_at_VA<uint8_t>(0, 0xabcdabcdabcd, new_memory_contents) == 0) {
99+
printf("ERROR: Expected memory store to fail.\n");
100+
exit(1);
101+
}
84102
}

0 commit comments

Comments
 (0)