Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add a dense memory backend implementation #1342

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ci-tests/testlib.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ static std::vector<std::pair<reg_t, mem_t*>> make_mems(const std::vector<mem_cfg
std::vector<std::pair<reg_t, mem_t*>> mems;
mems.reserve(layout.size());
for (const auto &cfg : layout) {
mems.push_back(std::make_pair(cfg.get_base(), new mem_t(cfg.get_size())));
mems.push_back(std::make_pair(cfg.get_base(), new sparse_mem_t(cfg.get_size())));
}
return mems;
}
Expand Down
13 changes: 9 additions & 4 deletions riscv/devices.cc
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,18 @@ mem_t::mem_t(reg_t size)
throw std::runtime_error("memory size must be a positive multiple of 4 KiB");
}

mem_t::~mem_t()
sparse_mem_t::sparse_mem_t(reg_t size)
: mem_t(size)
{
}

sparse_mem_t::~sparse_mem_t()
{
for (auto& entry : sparse_memory_map)
free(entry.second);
}

bool mem_t::load_store(reg_t addr, size_t len, uint8_t* bytes, bool store)
bool sparse_mem_t::load_store(reg_t addr, size_t len, uint8_t* bytes, bool store)
{
if (addr + len < addr || addr + len > sz)
return false;
Expand All @@ -125,7 +130,7 @@ bool mem_t::load_store(reg_t addr, size_t len, uint8_t* bytes, bool store)
return true;
}

char* mem_t::contents(reg_t addr) {
char* sparse_mem_t::contents(reg_t addr) {
reg_t ppn = addr >> PGSHIFT, pgoff = addr % PGSIZE;
auto search = sparse_memory_map.find(ppn);
if (search == sparse_memory_map.end()) {
Expand All @@ -138,7 +143,7 @@ char* mem_t::contents(reg_t addr) {
return search->second + pgoff;
}

void mem_t::dump(std::ostream& o) {
void sparse_mem_t::dump(std::ostream& o) {
const char empty[PGSIZE] = {0};
for (reg_t i = 0; i < sz; i += PGSIZE) {
reg_t ppn = i >> PGSHIFT;
Expand Down
24 changes: 19 additions & 5 deletions riscv/devices.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,33 @@ class mem_t : public abstract_device_t {
public:
mem_t(reg_t size);
mem_t(const mem_t& that) = delete;
~mem_t();
virtual ~mem_t() = default;

bool load(reg_t addr, size_t len, uint8_t* bytes) { return load_store(addr, len, bytes, false); }
bool store(reg_t addr, size_t len, const uint8_t* bytes) { return load_store(addr, len, const_cast<uint8_t*>(bytes), true); }
char* contents(reg_t addr);
reg_t size() { return sz; }
void dump(std::ostream& o);
virtual char* contents(reg_t addr) = 0;
virtual void dump(std::ostream& o) = 0;

protected:
reg_t sz;

private:
bool load_store(reg_t addr, size_t len, uint8_t* bytes, bool store);
virtual bool load_store(reg_t addr, size_t len, uint8_t* bytes, bool store) = 0;
};

class sparse_mem_t : public mem_t {
public:
sparse_mem_t(reg_t size);
~sparse_mem_t();

virtual char* contents(reg_t addr) override;
virtual void dump(std::ostream& o) override;

private:
bool load_store(reg_t addr, size_t len, uint8_t* bytes, bool store) override;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs virtual


std::map<reg_t, char*> sparse_memory_map;
reg_t sz;
};

class clint_t : public abstract_device_t {
Expand Down
2 changes: 1 addition & 1 deletion spike_main/spike.cc
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ static std::vector<std::pair<reg_t, mem_t*>> make_mems(const std::vector<mem_cfg
std::vector<std::pair<reg_t, mem_t*>> mems;
mems.reserve(layout.size());
for (const auto &cfg : layout) {
mems.push_back(std::make_pair(cfg.get_base(), new mem_t(cfg.get_size())));
mems.push_back(std::make_pair(cfg.get_base(), new sparse_mem_t(cfg.get_size())));
}
return mems;
}
Expand Down