aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrbuchner <ryan.buchner@arilinc.com>2023-04-28 16:28:16 -0700
committerrbuchner <ryan.buchner@arilinc.com>2023-05-11 23:00:59 -0700
commit33fbc2df39df914d3462bede4112db7966d49a3c (patch)
tree0d4e292c8edf3a4d771f39a32708540e8bff48ce
parent36b8c12e9f4d92f3cb97daf4ea0613436724438f (diff)
downloadspike-33fbc2df39df914d3462bede4112db7966d49a3c.zip
spike-33fbc2df39df914d3462bede4112db7966d49a3c.tar.gz
spike-33fbc2df39df914d3462bede4112db7966d49a3c.tar.bz2
Plumb in effective virtual bit to take_trigger_action()
-rw-r--r--riscv/execute.cc6
-rw-r--r--riscv/mmu.cc16
-rw-r--r--riscv/mmu.h2
-rw-r--r--riscv/processor.cc2
-rw-r--r--riscv/processor.h2
-rw-r--r--riscv/triggers.h5
6 files changed, 17 insertions, 16 deletions
diff --git a/riscv/execute.cc b/riscv/execute.cc
index acf0e90..295879d 100644
--- a/riscv/execute.cc
+++ b/riscv/execute.cc
@@ -267,7 +267,7 @@ void processor_t::step(size_t n)
auto match = TM.detect_icount_match();
if (match.has_value()) {
assert(match->timing == triggers::TIMING_BEFORE);
- throw triggers::matched_t((triggers::operation_t)0, 0, match->action);
+ throw triggers::matched_t((triggers::operation_t)0, 0, match->action, state.v);
}
}
@@ -310,7 +310,7 @@ void processor_t::step(size_t n)
// Trigger action takes priority over single step
auto match = TM.detect_trap_match(t);
if (match.has_value())
- take_trigger_action(match->action, 0, state.pc);
+ take_trigger_action(match->action, 0, state.pc, 0);
else if (unlikely(state.single_step == state.STEP_STEPPED)) {
state.single_step = state.STEP_NONE;
enter_debug_mode(DCSR_CAUSE_STEP);
@@ -322,7 +322,7 @@ void processor_t::step(size_t n)
delete mmu->matched_trigger;
mmu->matched_trigger = NULL;
}
- take_trigger_action(t.action, t.address, pc);
+ take_trigger_action(t.action, t.address, pc, t.gva);
}
catch(trap_debug_mode&)
{
diff --git a/riscv/mmu.cc b/riscv/mmu.cc
index 734e8cd..358ccd3 100644
--- a/riscv/mmu.cc
+++ b/riscv/mmu.cc
@@ -71,7 +71,7 @@ reg_t mmu_t::translate(mem_access_info_t access_info, reg_t len)
tlb_entry_t mmu_t::fetch_slow_path(reg_t vaddr)
{
auto access_info = generate_access_info(vaddr, FETCH, {false, false, false});
- check_triggers(triggers::OPERATION_EXECUTE, vaddr);
+ check_triggers(triggers::OPERATION_EXECUTE, vaddr, access_info.effective_virt);
tlb_entry_t result;
reg_t vpn = vaddr >> PGSHIFT;
@@ -88,7 +88,7 @@ tlb_entry_t mmu_t::fetch_slow_path(reg_t vaddr)
result = tlb_data[vpn % TLB_ENTRIES];
}
- check_triggers(triggers::OPERATION_EXECUTE, vaddr, from_le(*(const uint16_t*)(result.host_offset + vaddr)));
+ check_triggers(triggers::OPERATION_EXECUTE, vaddr, access_info.effective_virt, from_le(*(const uint16_t*)(result.host_offset + vaddr)));
return result;
}
@@ -169,7 +169,7 @@ bool mmu_t::mmio(reg_t paddr, size_t len, uint8_t* bytes, access_type type)
return true;
}
-void mmu_t::check_triggers(triggers::operation_t operation, reg_t address, std::optional<reg_t> data)
+void mmu_t::check_triggers(triggers::operation_t operation, reg_t address, bool virt, std::optional<reg_t> data)
{
if (matched_trigger || !proc)
return;
@@ -179,13 +179,13 @@ void mmu_t::check_triggers(triggers::operation_t operation, reg_t address, std::
if (match.has_value())
switch (match->timing) {
case triggers::TIMING_BEFORE:
- throw triggers::matched_t(operation, address, match->action);
+ throw triggers::matched_t(operation, address, match->action, virt);
case triggers::TIMING_AFTER:
// We want to take this exception on the next instruction. We check
// whether to do so in the I$ refill path, so flush the I$.
flush_icache();
- matched_trigger = new triggers::matched_t(operation, address, match->action);
+ matched_trigger = new triggers::matched_t(operation, address, match->action, virt);
}
}
@@ -224,7 +224,7 @@ void mmu_t::load_slow_path_intrapage(reg_t len, uint8_t* bytes, mem_access_info_
void mmu_t::load_slow_path(reg_t addr, reg_t len, uint8_t* bytes, xlate_flags_t xlate_flags)
{
auto access_info = generate_access_info(addr, LOAD, xlate_flags);
- check_triggers(triggers::OPERATION_LOAD, addr);
+ check_triggers(triggers::OPERATION_LOAD, addr, access_info.effective_virt);
if ((addr & (len - 1)) == 0) {
load_slow_path_intrapage(len, bytes, access_info);
@@ -242,7 +242,7 @@ void mmu_t::load_slow_path(reg_t addr, reg_t len, uint8_t* bytes, xlate_flags_t
load_slow_path_intrapage(len - len_page0, bytes + len_page0, access_info.split_misaligned_access(len_page0));
}
- check_triggers(triggers::OPERATION_LOAD, addr, reg_from_bytes(len, bytes));
+ check_triggers(triggers::OPERATION_LOAD, addr, access_info.effective_virt, reg_from_bytes(len, bytes));
}
void mmu_t::store_slow_path_intrapage(reg_t len, const uint8_t* bytes, mem_access_info_t access_info, bool actually_store)
@@ -276,7 +276,7 @@ void mmu_t::store_slow_path(reg_t addr, reg_t len, const uint8_t* bytes, xlate_f
{
auto access_info = generate_access_info(addr, STORE, xlate_flags);
if (actually_store)
- check_triggers(triggers::OPERATION_STORE, addr, reg_from_bytes(len, bytes));
+ check_triggers(triggers::OPERATION_STORE, addr, access_info.effective_virt, reg_from_bytes(len, bytes));
if (addr & (len - 1)) {
bool gva = access_info.effective_virt;
diff --git a/riscv/mmu.h b/riscv/mmu.h
index 2f93863..5a4835c 100644
--- a/riscv/mmu.h
+++ b/riscv/mmu.h
@@ -391,7 +391,7 @@ private:
bool mmio_store(reg_t paddr, size_t len, const uint8_t* bytes);
bool mmio(reg_t paddr, size_t len, uint8_t* bytes, access_type type);
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);
+ void check_triggers(triggers::operation_t operation, reg_t address, bool virt, std::optional<reg_t> data = std::nullopt);
reg_t translate(mem_access_info_t access_info, reg_t len);
reg_t pte_load(reg_t pte_paddr, reg_t addr, bool virt, access_type trap_type, size_t ptesize) {
diff --git a/riscv/processor.cc b/riscv/processor.cc
index 330bd30..0ccb651 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -885,7 +885,7 @@ void processor_t::take_trap(trap_t& t, reg_t epc)
}
}
-void processor_t::take_trigger_action(triggers::action_t action, reg_t breakpoint_tval, reg_t epc)
+void processor_t::take_trigger_action(triggers::action_t action, reg_t breakpoint_tval, reg_t epc, bool virt)
{
if (debug) {
std::stringstream s; // first put everything in a string, later send it to output
diff --git a/riscv/processor.h b/riscv/processor.h
index 8117568..1b74cc2 100644
--- a/riscv/processor.h
+++ b/riscv/processor.h
@@ -331,7 +331,7 @@ private:
void take_pending_interrupt() { take_interrupt(state.mip->read() & state.mie->read()); }
void take_interrupt(reg_t mask); // take first enabled interrupt in mask
void take_trap(trap_t& t, reg_t epc); // take an exception
- void take_trigger_action(triggers::action_t action, reg_t breakpoint_tval, reg_t epc);
+ void take_trigger_action(triggers::action_t action, reg_t breakpoint_tval, reg_t epc, bool virt);
void disasm(insn_t insn); // disassemble and print an instruction
int paddr_bits();
diff --git a/riscv/triggers.h b/riscv/triggers.h
index 6e3d74d..aeda4d5 100644
--- a/riscv/triggers.h
+++ b/riscv/triggers.h
@@ -54,12 +54,13 @@ struct match_result_t {
class matched_t
{
public:
- matched_t(triggers::operation_t operation, reg_t address, action_t action) :
- operation(operation), address(address), action(action) {}
+ matched_t(triggers::operation_t operation, reg_t address, action_t action, bool gva) :
+ operation(operation), address(address), action(action), gva(gva) {}
triggers::operation_t operation;
reg_t address;
action_t action;
+ bool gva;
};
class trigger_t {