aboutsummaryrefslogtreecommitdiff
path: root/spike_main
diff options
context:
space:
mode:
authorParshintsev Anatoly <anatoly.parshintsev@syntacore.com>2023-01-09 19:23:43 +0300
committerAndrew Waterman <andrew@sifive.com>2023-01-10 15:44:16 -0800
commitca1a5fd8f0280cca41ed54cb98c21514a882dacd (patch)
tree54f1ed0177fdfc2284ceb9e3d24b7806af36ba78 /spike_main
parent28eb7aa8bece565adac4245815c80ba3fc65fc8a (diff)
downloadriscv-isa-sim-ca1a5fd8f0280cca41ed54cb98c21514a882dacd.zip
riscv-isa-sim-ca1a5fd8f0280cca41ed54cb98c21514a882dacd.tar.gz
riscv-isa-sim-ca1a5fd8f0280cca41ed54cb98c21514a882dacd.tar.bz2
improve merge_mem_regions to handle memory region covering the whole 64-bit address space
Diffstat (limited to 'spike_main')
-rw-r--r--spike_main/spike.cc24
1 files changed, 24 insertions, 0 deletions
diff --git a/spike_main/spike.cc b/spike_main/spike.cc
index b3cffae..8386a49 100644
--- a/spike_main/spike.cc
+++ b/spike_main/spike.cc
@@ -131,6 +131,18 @@ static bool check_mem_overlap(const mem_cfg_t& L, const mem_cfg_t& R)
return std::max(L.get_base(), R.get_base()) <= std::min(L.get_inclusive_end(), R.get_inclusive_end());
}
+static bool check_if_merge_covers_64bit_space(const mem_cfg_t& L,
+ const mem_cfg_t& R)
+{
+ if (!check_mem_overlap(L, R))
+ return false;
+
+ auto start = std::min(L.get_base(), R.get_base());
+ auto end = std::max(L.get_inclusive_end(), R.get_inclusive_end());
+
+ return (start == 0ull) && (end == std::numeric_limits<uint64_t>::max());
+}
+
static mem_cfg_t merge_mem_regions(const mem_cfg_t& L, const mem_cfg_t& R)
{
// one can merge only intersecting regions
@@ -162,6 +174,18 @@ merge_overlapping_memory_regions(std::vector<mem_cfg_t> mems)
merged_mem.push_back(mem_int);
continue;
}
+ // there is a weird corner case preventing two memory regions from being
+ // merged: if the resulting size of a region is 2^64 bytes - currently,
+ // such regions are not representable by mem_cfg_t class (because the
+ // actual size field is effectively a 64 bit value)
+ // so we create two smaller memory regions that total for 2^64 bytes as
+ // a workaround
+ if (check_if_merge_covers_64bit_space(merged_mem.back(), mem_int)) {
+ merged_mem.clear();
+ merged_mem.push_back(mem_cfg_t(0ull, 0ull - PGSIZE));
+ merged_mem.push_back(mem_cfg_t(0ull - PGSIZE, PGSIZE));
+ break;
+ }
merged_mem.back() = merge_mem_regions(merged_mem.back(), mem_int);
}