aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--riscv/mmu.cc35
-rw-r--r--riscv/mmu.h14
-rw-r--r--riscv/sim.cc26
-rw-r--r--riscv/sim.h8
-rw-r--r--riscv/simif.h11
5 files changed, 50 insertions, 44 deletions
diff --git a/riscv/mmu.cc b/riscv/mmu.cc
index 0ac0d65..b33e383 100644
--- a/riscv/mmu.cc
+++ b/riscv/mmu.cc
@@ -128,37 +128,37 @@ reg_t reg_from_bytes(size_t len, const uint8_t* bytes)
abort();
}
-bool mmu_t::mmio_ok(reg_t addr, access_type UNUSED type)
+bool mmu_t::mmio_ok(reg_t paddr, access_type UNUSED type)
{
// Disallow access to debug region when not in debug mode
- if (addr >= DEBUG_START && addr <= DEBUG_END && proc && !proc->state.debug_mode)
+ if (paddr >= DEBUG_START && paddr <= DEBUG_END && proc && !proc->state.debug_mode)
return false;
return true;
}
-bool mmu_t::mmio_fetch(reg_t addr, size_t len, uint8_t* bytes)
+bool mmu_t::mmio_fetch(reg_t paddr, size_t len, uint8_t* bytes)
{
- if (!mmio_ok(addr, FETCH))
+ if (!mmio_ok(paddr, FETCH))
return false;
- return sim->mmio_fetch(addr, len, bytes);
+ return sim->mmio_fetch(paddr, len, bytes);
}
-bool mmu_t::mmio_load(reg_t addr, size_t len, uint8_t* bytes)
+bool mmu_t::mmio_load(reg_t paddr, size_t len, uint8_t* bytes)
{
- if (!mmio_ok(addr, LOAD))
+ if (!mmio_ok(paddr, LOAD))
return false;
- return sim->mmio_load(addr, len, bytes);
+ return sim->mmio_load(paddr, len, bytes);
}
-bool mmu_t::mmio_store(reg_t addr, size_t len, const uint8_t* bytes)
+bool mmu_t::mmio_store(reg_t paddr, size_t len, const uint8_t* bytes)
{
- if (!mmio_ok(addr, STORE))
+ if (!mmio_ok(paddr, STORE))
return false;
- return sim->mmio_store(addr, len, bytes);
+ return sim->mmio_store(paddr, len, bytes);
}
void mmu_t::check_triggers(triggers::operation_t operation, reg_t address, std::optional<reg_t> data)
@@ -192,6 +192,10 @@ void mmu_t::load_slow_path_intrapage(reg_t addr, reg_t len, uint8_t* bytes, uint
reg_t paddr = translate(addr, len, LOAD, xlate_flags);
+ if ((xlate_flags & RISCV_XLATE_LR) && !sim->reservable(paddr)) {
+ throw trap_load_access_fault((proc) ? proc->state.v : false, addr, 0, 0);
+ }
+
if (auto host_addr = sim->addr_to_mem(paddr)) {
memcpy(bytes, host_addr, len);
if (tracer.interested_in_range(paddr, paddr + PGSIZE, LOAD))
@@ -199,12 +203,13 @@ void mmu_t::load_slow_path_intrapage(reg_t addr, reg_t len, uint8_t* bytes, uint
else if (xlate_flags == 0)
refill_tlb(addr, paddr, host_addr, LOAD);
- if (xlate_flags & RISCV_XLATE_LR) {
- load_reservation_address = paddr;
- }
- } else if ((xlate_flags & RISCV_XLATE_LR) || !mmio_load(paddr, len, bytes)) {
+ } else if (!mmio_load(paddr, len, bytes)) {
throw trap_load_access_fault((proc) ? proc->state.v : false, addr, 0, 0);
}
+
+ if (xlate_flags & RISCV_XLATE_LR) {
+ load_reservation_address = paddr;
+ }
}
void mmu_t::load_slow_path(reg_t addr, reg_t len, uint8_t* bytes, uint32_t xlate_flags)
diff --git a/riscv/mmu.h b/riscv/mmu.h
index 061c5f8..4cc141f 100644
--- a/riscv/mmu.h
+++ b/riscv/mmu.h
@@ -165,7 +165,7 @@ public:
void clean_inval(reg_t addr, bool clean, bool inval) {
convert_load_traps_to_store_traps({
const reg_t paddr = translate(addr, blocksz, LOAD, 0) & ~(blocksz - 1);
- if (sim->addr_to_mem(paddr)) {
+ if (sim->reservable(paddr)) {
if (tracer.interested_in_range(paddr, paddr + PGSIZE, LOAD))
tracer.clean_invalidate(paddr, blocksz, clean, inval);
} else {
@@ -187,10 +187,10 @@ public:
}
reg_t paddr = translate(vaddr, 1, STORE, 0);
- if (sim->addr_to_mem(paddr))
+ if (sim->reservable(paddr))
return load_reservation_address == paddr;
else
- throw trap_store_access_fault((proc) ? proc->state.v : false, vaddr, 0, 0); // disallow SC to I/O space
+ throw trap_store_access_fault((proc) ? proc->state.v : false, vaddr, 0, 0);
}
template<typename T>
@@ -349,10 +349,10 @@ private:
void load_slow_path_intrapage(reg_t addr, reg_t len, uint8_t* bytes, uint32_t xlate_flags);
void store_slow_path(reg_t addr, reg_t len, const uint8_t* bytes, uint32_t xlate_flags, bool actually_store, bool require_alignment);
void store_slow_path_intrapage(reg_t addr, reg_t len, const uint8_t* bytes, uint32_t xlate_flags, bool actually_store);
- bool mmio_fetch(reg_t addr, size_t len, uint8_t* bytes);
- bool mmio_load(reg_t addr, size_t len, uint8_t* bytes);
- bool mmio_store(reg_t addr, size_t len, const uint8_t* bytes);
- bool mmio_ok(reg_t addr, access_type type);
+ bool mmio_fetch(reg_t paddr, size_t len, uint8_t* bytes);
+ bool mmio_load(reg_t paddr, size_t len, uint8_t* bytes);
+ bool mmio_store(reg_t paddr, size_t len, const uint8_t* bytes);
+ bool mmio_ok(reg_t paddr, access_type type);
void check_triggers(triggers::operation_t operation, reg_t address, std::optional<reg_t> data = std::nullopt);
reg_t translate(reg_t addr, reg_t len, access_type type, uint32_t xlate_flags);
diff --git a/riscv/sim.cc b/riscv/sim.cc
index 361008b..84ff98c 100644
--- a/riscv/sim.cc
+++ b/riscv/sim.cc
@@ -309,18 +309,18 @@ static bool paddr_ok(reg_t addr)
return (addr >> MAX_PADDR_BITS) == 0;
}
-bool sim_t::mmio_load(reg_t addr, size_t len, uint8_t* bytes)
+bool sim_t::mmio_load(reg_t paddr, size_t len, uint8_t* bytes)
{
- if (addr + len < addr || !paddr_ok(addr + len - 1))
+ if (paddr + len < paddr || !paddr_ok(paddr + len - 1))
return false;
- return bus.load(addr, len, bytes);
+ return bus.load(paddr, len, bytes);
}
-bool sim_t::mmio_store(reg_t addr, size_t len, const uint8_t* bytes)
+bool sim_t::mmio_store(reg_t paddr, size_t len, const uint8_t* bytes)
{
- if (addr + len < addr || !paddr_ok(addr + len - 1))
+ if (paddr + len < paddr || !paddr_ok(paddr + len - 1))
return false;
- return bus.store(addr, len, bytes);
+ return bus.store(paddr, len, bytes);
}
void sim_t::make_dtb()
@@ -402,19 +402,19 @@ void sim_t::set_rom()
bus.add_device(DEFAULT_RSTVEC, boot_rom.get());
}
-char* sim_t::addr_to_mem(reg_t addr) {
- if (!paddr_ok(addr))
+char* sim_t::addr_to_mem(reg_t paddr) {
+ if (!paddr_ok(paddr))
return NULL;
- auto desc = bus.find_device(addr);
+ auto desc = bus.find_device(paddr);
if (auto mem = dynamic_cast<mem_t*>(desc.second))
- if (addr - desc.first < mem->size())
- return mem->contents(addr - desc.first);
+ if (paddr - desc.first < mem->size())
+ return mem->contents(paddr - desc.first);
return NULL;
}
-const char* sim_t::get_symbol(uint64_t addr)
+const char* sim_t::get_symbol(uint64_t paddr)
{
- return htif_t::get_symbol(addr);
+ return htif_t::get_symbol(paddr);
}
// htif
diff --git a/riscv/sim.h b/riscv/sim.h
index 2c348b3..21b1616 100644
--- a/riscv/sim.h
+++ b/riscv/sim.h
@@ -94,13 +94,13 @@ private:
remote_bitbang_t* remote_bitbang;
// memory-mapped I/O routines
- char* addr_to_mem(reg_t addr);
- bool mmio_load(reg_t addr, size_t len, uint8_t* bytes);
- bool mmio_store(reg_t addr, size_t len, const uint8_t* bytes);
+ char* addr_to_mem(reg_t paddr);
+ bool mmio_load(reg_t paddr, size_t len, uint8_t* bytes);
+ bool mmio_store(reg_t paddr, size_t len, const uint8_t* bytes);
void make_dtb();
void set_rom();
- const char* get_symbol(uint64_t addr);
+ const char* get_symbol(uint64_t paddr);
// presents a prompt for introspection into the simulation
void interactive();
diff --git a/riscv/simif.h b/riscv/simif.h
index 61815e5..c756b9c 100644
--- a/riscv/simif.h
+++ b/riscv/simif.h
@@ -10,15 +10,16 @@ class simif_t
{
public:
// should return NULL for MMIO addresses
- virtual char* addr_to_mem(reg_t addr) = 0;
+ virtual char* addr_to_mem(reg_t paddr) = 0;
+ virtual bool reservable(reg_t paddr) { return addr_to_mem(paddr); }
// used for MMIO addresses
- virtual bool mmio_fetch(reg_t addr, size_t len, uint8_t* bytes) { return mmio_load(addr, len, bytes); };
- virtual bool mmio_load(reg_t addr, size_t len, uint8_t* bytes) = 0;
- virtual bool mmio_store(reg_t addr, size_t len, const uint8_t* bytes) = 0;
+ virtual bool mmio_fetch(reg_t paddr, size_t len, uint8_t* bytes) { return mmio_load(paddr, len, bytes); }
+ virtual bool mmio_load(reg_t paddr, size_t len, uint8_t* bytes) = 0;
+ virtual bool mmio_store(reg_t paddr, size_t len, const uint8_t* bytes) = 0;
// Callback for processors to let the simulation know they were reset.
virtual void proc_reset(unsigned id) = 0;
- virtual const char* get_symbol(uint64_t addr) = 0;
+ virtual const char* get_symbol(uint64_t paddr) = 0;
virtual ~simif_t() = default;