aboutsummaryrefslogtreecommitdiff
path: root/riscv
diff options
context:
space:
mode:
authorYenHaoChen <howard25336284@gmail.com>2022-09-30 12:01:09 +0800
committerYenHaoChen <howard25336284@gmail.com>2022-09-30 12:18:39 +0800
commit99cb603973b3f9575b411b80934035f3ee7fbcf3 (patch)
treebe8325ccebc588a7730dab229e0b32297a2b698b /riscv
parenta5752cebafa75b8dc539ee327bac8630e3fb84f1 (diff)
downloadspike-99cb603973b3f9575b411b80934035f3ee7fbcf3.zip
spike-99cb603973b3f9575b411b80934035f3ee7fbcf3.tar.gz
spike-99cb603973b3f9575b411b80934035f3ee7fbcf3.tar.bz2
Fix priority of mcontrol trigger load address before
The spec defines the mcontrol load address has a higher priority over page fault and address misaligned (Debug spec, Table 5.2). Thus, the trigger checking should be before the translation and alignment checking. The previous implementation checks the trigger after the translation and alignment, resulting in incorrect priority. For instance, when page fault and trigger occur on the same instruction, the previous implementation will choose to raise the page fault, which contradicts the priority requirement. This commit adds an address-only trigger checking before the misaligned checking and translation. The trigger will fire on the instruction instead of the page fault in the above case.
Diffstat (limited to 'riscv')
-rw-r--r--riscv/mmu.cc7
-rw-r--r--riscv/mmu.h5
2 files changed, 12 insertions, 0 deletions
diff --git a/riscv/mmu.cc b/riscv/mmu.cc
index 0dbb94e..3048bde 100644
--- a/riscv/mmu.cc
+++ b/riscv/mmu.cc
@@ -141,6 +141,13 @@ bool mmu_t::mmio_store(reg_t addr, size_t len, const uint8_t* bytes)
void mmu_t::load_slow_path(reg_t addr, reg_t len, uint8_t* bytes, uint32_t xlate_flags)
{
+ if (!matched_trigger) {
+ reg_t data = reg_from_bytes(len, bytes);
+ matched_trigger = trigger_exception(triggers::OPERATION_LOAD, addr, false);
+ if (matched_trigger)
+ throw *matched_trigger;
+ }
+
reg_t paddr = translate(addr, len, LOAD, xlate_flags);
if (auto host_addr = sim->addr_to_mem(paddr)) {
diff --git a/riscv/mmu.h b/riscv/mmu.h
index d076aeb..3a06c1e 100644
--- a/riscv/mmu.h
+++ b/riscv/mmu.h
@@ -101,6 +101,11 @@ public:
#define load_func(type, prefix, xlate_flags) \
type##_t ALWAYS_INLINE prefix##_##type(reg_t addr, bool require_alignment = false) { \
if (unlikely(addr & (sizeof(type##_t)-1))) { \
+ if (!matched_trigger) { \
+ matched_trigger = trigger_exception(triggers::OPERATION_LOAD, addr, false); \
+ if (matched_trigger) \
+ throw *matched_trigger; \
+ } \
if (require_alignment) load_reserved_address_misaligned(addr); \
else return misaligned_load(addr, sizeof(type##_t), xlate_flags); \
} \