Skip to content

Commit

Permalink
workaround to support access to large 64-bit physical addresses
Browse files Browse the repository at this point in the history
Current spike implementation erroneously assumes that a maximum physical
address is limited to (1 << MAX_PADDR_BITS).

There are few issues with this assumption:

1. if satp.MODE == Bare, then virtual addresses are equal to physical
   and there are no limitations and no additional requirements on the
   number of address bits and address values one may use.
2. the actual limit can only be derived from the current privilege mode
   and CSR configuration and thus can be determined only in runtime.

This patch implements a simple workaround by making queries to the
platform configuration as a last-ditch effort before memory access
abort.

To figure out if the current configuration supports large 64-bit
addresses only ordinary memory regions are taken into account - bus
devices (abstract devices) are excluded. Proper support for such cases
may require significant refactoring.
  • Loading branch information
aap-sc committed Oct 4, 2022
1 parent 98dd935 commit 86b2085
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 13 deletions.
38 changes: 36 additions & 2 deletions riscv/sim.cc
Original file line number Diff line number Diff line change
Expand Up @@ -267,9 +267,43 @@ void sim_t::set_procs_debug(bool value)
procs[i]->set_debug(value);
}

static bool paddr_ok(reg_t addr)
static bool is_ascending(const std::pair<reg_t, mem_t*> &L,
const std::pair<reg_t, mem_t*> &R)
{
return (addr >> MAX_PADDR_BITS) == 0;
return L.first < R.first;
}

bool sim_t::paddr_ok(reg_t addr) const
{
// TODO: this implementation erroneously assumes that a maximum physical
// address is limited to (1 << MAX_PADDR_BITS).
// There are a few issues with this assumption:
// 1. if satp.MODE == Bare, then virtual addresses are equal to physical
// and there are no limitations on the number of bits one may use.
// 2. the actual limit can only be derived from the current privilege
// mode and CSR configuration and thus can be determined only in runtime.
//
// To do such a check properly the translation routine must return some
// auxiliary attributes, like translation mode, memory attributes, etc.
// These could be later consumed by routines like paddr_ok.
//
// In the meantime, to allow access to large physical addresses and to
// minimize the scope of changes we implement a small add-hoc solution to
// lookup platform configuration and figure out if we have any memory
// above (1 << MAX_PADDR_BITS)
if ((addr >> MAX_PADDR_BITS) == 0)
return true;

if (mems.empty())
return false;

assert(std::is_sorted(mems.begin(), mems.end(), is_ascending));
// last-ditch effort to detect if the platform has physical memory
// at the addresses greater than (1 << MAX_PADDR_BITS)
reg_t base_addr = mems.back().first;
reg_t size = mems.back().second->size();
reg_t last_available_pa = base_addr + size - 1;
return (last_available_pa >= (1ull << MAX_PADDR_BITS));
}

bool sim_t::mmio_load(reg_t addr, size_t len, uint8_t* bytes)
Expand Down
2 changes: 2 additions & 0 deletions riscv/sim.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ class sim_t : public htif_t, public simif_t
// Callback for processors to let the simulation know they were reset.
void proc_reset(unsigned id);

bool paddr_ok(reg_t addr) const;

private:
isa_parser_t isa;
const cfg_t * const cfg;
Expand Down
11 changes: 0 additions & 11 deletions spike_main/spike.cc
Original file line number Diff line number Diff line change
Expand Up @@ -236,17 +236,6 @@ static std::vector<mem_cfg_t> parse_mem_layout(const char* arg)
exit(EXIT_FAILURE);
}

const uint64_t max_allowed_pa = (1ull << MAX_PADDR_BITS) - 1ull;
if (mem_region.get_inclusive_end() > max_allowed_pa) {
fprintf(stderr, "unsupported memory region [0x%llX, 0x%llX] specified ("
"currently, spike does not support physical adresses "
"larger than 0x%llX)\n",
(unsigned long long)mem_region.get_base(),
(unsigned long long)mem_region.get_inclusive_end(),
(unsigned long long)max_allowed_pa);
exit(EXIT_FAILURE);
}

res.push_back(mem_region);
if (!*p)
break;
Expand Down

0 comments on commit 86b2085

Please sign in to comment.