aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--riscv/mmu.cc4
-rw-r--r--riscv/mmu.h10
-rw-r--r--riscv/triggers.cc8
-rw-r--r--riscv/triggers.h6
4 files changed, 15 insertions, 13 deletions
diff --git a/riscv/mmu.cc b/riscv/mmu.cc
index d0a55f0..0dbb94e 100644
--- a/riscv/mmu.cc
+++ b/riscv/mmu.cc
@@ -155,7 +155,7 @@ void mmu_t::load_slow_path(reg_t addr, reg_t len, uint8_t* bytes, uint32_t xlate
if (!matched_trigger) {
reg_t data = reg_from_bytes(len, bytes);
- matched_trigger = trigger_exception(triggers::OPERATION_LOAD, addr, data);
+ matched_trigger = trigger_exception(triggers::OPERATION_LOAD, addr, true, data);
if (matched_trigger)
throw *matched_trigger;
}
@@ -167,7 +167,7 @@ void mmu_t::store_slow_path(reg_t addr, reg_t len, const uint8_t* bytes, uint32_
if (!matched_trigger) {
reg_t data = reg_from_bytes(len, bytes);
- matched_trigger = trigger_exception(triggers::OPERATION_STORE, addr, data);
+ matched_trigger = trigger_exception(triggers::OPERATION_STORE, addr, true, data);
if (matched_trigger)
throw *matched_trigger;
}
diff --git a/riscv/mmu.h b/riscv/mmu.h
index ca8b792..ebe4f9b 100644
--- a/riscv/mmu.h
+++ b/riscv/mmu.h
@@ -113,7 +113,7 @@ public:
if ((xlate_flags) == 0 && unlikely(tlb_load_tag[vpn % TLB_ENTRIES] == (vpn | TLB_CHECK_TRIGGERS))) { \
type##_t data = from_target(*(target_endian<type##_t>*)(tlb_data[vpn % TLB_ENTRIES].host_offset + addr)); \
if (!matched_trigger) { \
- matched_trigger = trigger_exception(triggers::OPERATION_LOAD, addr, data); \
+ matched_trigger = trigger_exception(triggers::OPERATION_LOAD, addr, true, data); \
if (matched_trigger) \
throw *matched_trigger; \
} \
@@ -178,7 +178,7 @@ public:
else if ((xlate_flags) == 0 && unlikely(tlb_store_tag[vpn % TLB_ENTRIES] == (vpn | TLB_CHECK_TRIGGERS))) { \
if (actually_store) { \
if (!matched_trigger) { \
- matched_trigger = trigger_exception(triggers::OPERATION_STORE, addr, val); \
+ matched_trigger = trigger_exception(triggers::OPERATION_STORE, addr, true, val); \
if (matched_trigger) \
throw *matched_trigger; \
} \
@@ -479,7 +479,7 @@ private:
}
target_endian<uint16_t>* ptr = (target_endian<uint16_t>*)(result.host_offset + addr);
triggers::action_t action;
- auto match = proc->TM.memory_access_match(&action, triggers::OPERATION_EXECUTE, addr, from_target(*ptr));
+ auto match = proc->TM.memory_access_match(&action, triggers::OPERATION_EXECUTE, addr, true, from_target(*ptr));
if (match != triggers::MATCH_NONE) {
throw triggers::matched_t(triggers::OPERATION_EXECUTE, addr, from_target(*ptr), action);
}
@@ -491,13 +491,13 @@ private:
}
inline triggers::matched_t *trigger_exception(triggers::operation_t operation,
- reg_t address, reg_t data)
+ reg_t address, bool has_data, reg_t data=0)
{
if (!proc) {
return NULL;
}
triggers::action_t action;
- auto match = proc->TM.memory_access_match(&action, operation, address, data);
+ auto match = proc->TM.memory_access_match(&action, operation, address, has_data, data);
if (match == triggers::MATCH_NONE)
return NULL;
if (match == triggers::MATCH_FIRE_BEFORE) {
diff --git a/riscv/triggers.cc b/riscv/triggers.cc
index 4b73715..e357b4a 100644
--- a/riscv/triggers.cc
+++ b/riscv/triggers.cc
@@ -101,7 +101,7 @@ bool mcontrol_t::simple_match(unsigned xlen, reg_t value) const {
assert(0);
}
-match_result_t mcontrol_t::memory_access_match(processor_t * const proc, operation_t operation, reg_t address, reg_t data) {
+match_result_t mcontrol_t::memory_access_match(processor_t * const proc, operation_t operation, reg_t address, bool has_data, reg_t data) {
state_t * const state = proc->get_state();
if ((operation == triggers::OPERATION_EXECUTE && !execute_bit) ||
(operation == triggers::OPERATION_STORE && !store_bit) ||
@@ -115,6 +115,8 @@ match_result_t mcontrol_t::memory_access_match(processor_t * const proc, operati
reg_t value;
if (select) {
value = data;
+ if (!has_data)
+ return MATCH_NONE;
} else {
value = address;
}
@@ -150,7 +152,7 @@ module_t::~module_t() {
}
}
-match_result_t module_t::memory_access_match(action_t * const action, operation_t operation, reg_t address, reg_t data)
+match_result_t module_t::memory_access_match(action_t * const action, operation_t operation, reg_t address, bool has_data, reg_t data)
{
state_t * const state = proc->get_state();
if (state->debug_mode)
@@ -170,7 +172,7 @@ match_result_t module_t::memory_access_match(action_t * const action, operation_
* entire chain did not match. This is allowed by the spec, because the final
* trigger in the chain will never get `hit` set unless the entire chain
* matches. */
- match_result_t result = triggers[i]->memory_access_match(proc, operation, address, data);
+ match_result_t result = triggers[i]->memory_access_match(proc, operation, address, has_data, data);
if (result != MATCH_NONE && !triggers[i]->chain()) {
*action = triggers[i]->action;
return result;
diff --git a/riscv/triggers.h b/riscv/triggers.h
index 8f1b81d..b7512ef 100644
--- a/riscv/triggers.h
+++ b/riscv/triggers.h
@@ -43,7 +43,7 @@ class matched_t
class trigger_t {
public:
virtual match_result_t memory_access_match(processor_t * const proc,
- operation_t operation, reg_t address, reg_t data) = 0;
+ operation_t operation, reg_t address, bool has_data, reg_t data=0) = 0;
virtual reg_t tdata1_read(const processor_t * const proc) const noexcept = 0;
virtual bool tdata1_write(processor_t * const proc, const reg_t val) noexcept = 0;
@@ -88,7 +88,7 @@ public:
virtual bool load() const override { return load_bit; }
virtual match_result_t memory_access_match(processor_t * const proc,
- operation_t operation, reg_t address, reg_t data) override;
+ operation_t operation, reg_t address, bool has_data, reg_t data=0) override;
private:
bool simple_match(unsigned xlen, reg_t value) const;
@@ -115,7 +115,7 @@ public:
unsigned count() const { return triggers.size(); }
match_result_t memory_access_match(action_t * const action,
- operation_t operation, reg_t address, reg_t data);
+ operation_t operation, reg_t address, bool has_data, reg_t data=0);
reg_t tdata1_read(const processor_t * const proc, unsigned index) const noexcept;
bool tdata1_write(processor_t * const proc, unsigned index, const reg_t val) noexcept;