aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChih-Min Chao <48193236+chihminchao@users.noreply.github.com>2021-01-21 14:30:36 +0800
committerGitHub <noreply@github.com>2021-01-20 22:30:36 -0800
commit5b51752cea5c44916c16731c09985f48e89316b9 (patch)
tree41fadc7c20b546a49a6a2cc49dbe7e7ae59e8518
parent9bfb43c668848a4850d5805b9adb8ad18e7f43b6 (diff)
downloadspike-5b51752cea5c44916c16731c09985f48e89316b9.zip
spike-5b51752cea5c44916c16731c09985f48e89316b9.tar.gz
spike-5b51752cea5c44916c16731c09985f48e89316b9.tar.bz2
add support to page on demand (#634)
This patch splites the target-requested memory regions into pages and only allocates host memory when it is accessed to reduce larget memory sceniaro in 64 bit target system Co-authored-by: Dave.Wen <dave.wen@sifive.com>
-rw-r--r--riscv/devices.cc16
-rw-r--r--riscv/devices.h13
-rw-r--r--riscv/mmu.h3
-rw-r--r--riscv/sim.cc2
4 files changed, 28 insertions, 6 deletions
diff --git a/riscv/devices.cc b/riscv/devices.cc
index 4b768b6..6c78456 100644
--- a/riscv/devices.cc
+++ b/riscv/devices.cc
@@ -1,4 +1,5 @@
#include "devices.h"
+#include "mmu.h"
void bus_t::add_device(reg_t addr, abstract_device_t* dev)
{
@@ -88,3 +89,18 @@ bool mmio_plugin_device_t::store(reg_t addr, size_t len, const uint8_t* bytes)
{
return (*plugin.store)(user_data, addr, len, bytes);
}
+
+char* mem_t::contents() {
+ return data;
+}
+
+char* mem_t::contents(reg_t addr) {
+ reg_t pg_idx = addr & ~reg_t(PGSIZE - 1);
+ auto search = acc_tbl.find(pg_idx);
+ if (search == acc_tbl.end() || !search->second.second) {
+ char* mem_ptr = (char*)calloc(PGSIZE, sizeof(char));
+ acc_tbl[pg_idx] = std::make_pair(mem_ptr, true);
+ }
+ auto offset = addr & (PGSIZE - 1);
+ return acc_tbl[pg_idx].first + offset;
+}
diff --git a/riscv/devices.h b/riscv/devices.h
index 3dd6c66..82aab89 100644
--- a/riscv/devices.h
+++ b/riscv/devices.h
@@ -8,6 +8,7 @@
#include <map>
#include <vector>
#include <stdexcept>
+#include <utility>
class processor_t;
@@ -45,19 +46,21 @@ class mem_t : public abstract_device_t {
mem_t(size_t size) : len(size) {
if (!size)
throw std::runtime_error("zero bytes of target memory requested");
- data = (char*)calloc(1, size);
- if (!data)
- throw std::runtime_error("couldn't allocate " + std::to_string(size) + " bytes of target memory");
+ data = nullptr;
}
mem_t(const mem_t& that) = delete;
- ~mem_t() { free(data); }
+ ~mem_t() {
+ free(data);
+ }
bool load(reg_t addr, size_t len, uint8_t* bytes) { return false; }
bool store(reg_t addr, size_t len, const uint8_t* bytes) { return false; }
- char* contents() { return data; }
+ char* contents();
+ char* contents(reg_t addr);
size_t size() { return len; }
private:
+ std::map<reg_t, std::pair<char*, bool>> acc_tbl;
char* data;
size_t len;
};
diff --git a/riscv/mmu.h b/riscv/mmu.h
index 66571ba..cd454e1 100644
--- a/riscv/mmu.h
+++ b/riscv/mmu.h
@@ -54,6 +54,9 @@ class trigger_matched_t
// an MMU and instruction cache are maintained for simulator performance.
class mmu_t
{
+private:
+ std::map<reg_t, reg_t> alloc_cache;
+ std::vector<std::pair<reg_t, reg_t >> addr_tbl;
public:
mmu_t(simif_t* sim, processor_t* proc);
~mmu_t();
diff --git a/riscv/sim.cc b/riscv/sim.cc
index 5fff0ed..73d2b45 100644
--- a/riscv/sim.cc
+++ b/riscv/sim.cc
@@ -353,7 +353,7 @@ char* sim_t::addr_to_mem(reg_t addr) {
auto desc = bus.find_device(addr);
if (auto mem = dynamic_cast<mem_t*>(desc.second))
if (addr - desc.first < mem->size())
- return mem->contents() + (addr - desc.first);
+ return mem->contents(addr);
return NULL;
}