summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGabe Black <gabeblack@google.com>2019-10-22 21:42:51 -0700
committerGabe Black <gabeblack@google.com>2019-12-23 20:57:59 +0000
commit6e91bb9dcb276780b2474d73ca4f0a0ece17aca7 (patch)
tree173b34784f5f1a0e124cd523025807bba1d7b4a7 /src
parent62d75e7105fe172eb906d4f80f360ff8591d4178 (diff)
downloadgem5-6e91bb9dcb276780b2474d73ca4f0a0ece17aca7.tar.xz
fastmodel: Implement PC based events.
These use the IRIS breakpoint API to stop the models at the appropriate points. There seems to be a slightly wonky interaction between breakpoints and stepping, where if you stop at a breakpoint and then step, you might end up moving forward more than the number of requested instructions. Change-Id: I31f13a120cfc1ad2ec3669ee8befd6d21b328bb2 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/22122 Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com> Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com> Tested-by: kokoro <noreply+kokoro@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/arch/arm/fastmodel/iris/thread_context.cc102
-rw-r--r--src/arch/arm/fastmodel/iris/thread_context.hh37
2 files changed, 137 insertions, 2 deletions
diff --git a/src/arch/arm/fastmodel/iris/thread_context.cc b/src/arch/arm/fastmodel/iris/thread_context.cc
index 00c41ba9c..872136615 100644
--- a/src/arch/arm/fastmodel/iris/thread_context.cc
+++ b/src/arch/arm/fastmodel/iris/thread_context.cc
@@ -29,6 +29,8 @@
#include "arch/arm/fastmodel/iris/thread_context.hh"
+#include <utility>
+
#include "iris/detail/IrisCppAdapter.h"
#include "iris/detail/IrisObjects.h"
#include "mem/fs_translating_port_proxy.hh"
@@ -48,6 +50,19 @@ ThreadContext::initFromIrisInstance(const ResourceMap &resources)
call().memory_getMemorySpaces(_instId, memorySpaces);
call().memory_getUsefulAddressTranslations(_instId, translations);
+
+ typedef ThreadContext Self;
+ iris::EventSourceInfo evSrcInfo;
+
+ client.registerEventCallback<Self, &Self::breakpointHit>(
+ this, "ec_IRIS_BREAKPOINT_HIT",
+ "Handle hitting a breakpoint", "Iris::ThreadContext");
+ call().event_getEventSource(_instId, evSrcInfo, "IRIS_BREAKPOINT_HIT");
+ call().eventStream_create(_instId, breakpointEventStreamId,
+ evSrcInfo.evSrcId, client.getInstId());
+
+ for (auto it = bps.begin(); it != bps.end(); it++)
+ installBp(it);
}
iris::ResourceId
@@ -102,6 +117,47 @@ ThreadContext::maintainStepping()
}
}
+ThreadContext::BpInfoIt
+ThreadContext::getOrAllocBp(Addr pc)
+{
+ auto pc_it = bps.find(pc);
+
+ if (pc_it != bps.end())
+ return pc_it;
+
+ auto res = bps.emplace(std::make_pair(pc, new BpInfo(pc)));
+ panic_if(!res.second, "Inserting breakpoint failed.");
+ return res.first;
+}
+
+void
+ThreadContext::installBp(BpInfoIt it)
+{
+ BpId id;
+ // Hard code address space 5 for now.
+ call().breakpoint_set_code(_instId, id, it->second->pc, 5, 0, true);
+ it->second->id = id;
+}
+
+void
+ThreadContext::uninstallBp(BpInfoIt it)
+{
+ call().breakpoint_delete(_instId, it->second->id);
+ it->second->clearId();
+}
+
+void
+ThreadContext::delBp(BpInfoIt it)
+{
+ panic_if(!it->second->empty(),
+ "BP info still had events associated with it.");
+
+ if (it->second->validId())
+ uninstallBp(it);
+
+ bps.erase(it);
+}
+
iris::IrisErrorCode
ThreadContext::instanceRegistryChanged(
uint64_t esId, const iris::IrisValueMap &fields, uint64_t time,
@@ -163,6 +219,26 @@ ThreadContext::simulationTimeEvent(
return iris::E_ok;
}
+iris::IrisErrorCode
+ThreadContext::breakpointHit(
+ uint64_t esId, const iris::IrisValueMap &fields, uint64_t time,
+ uint64_t sInstId, bool syncEc, std::string &error_message_out)
+{
+ Addr pc = fields.at("PC").getU64();
+
+ auto it = getOrAllocBp(pc);
+
+ auto e_it = it->second->events.begin();
+ while (e_it != it->second->events.end()) {
+ PCEvent *e = *e_it;
+ // Advance e_it here since e might remove itself from the list.
+ e_it++;
+ e->process(this);
+ }
+
+ return iris::E_ok;
+}
+
ThreadContext::ThreadContext(
BaseCPU *cpu, int id, System *system, ::BaseTLB *dtb, ::BaseTLB *itb,
iris::IrisConnectionInterface *iris_if, const std::string &iris_path) :
@@ -216,6 +292,8 @@ ThreadContext::ThreadContext(
call().eventStream_create(
iris::IrisInstIdSimulationEngine, timeEventStreamId,
evSrcInfo.evSrcId, client.getInstId());
+
+ breakpointEventStreamId = iris::IRIS_UINT64_MAX;
}
ThreadContext::~ThreadContext()
@@ -237,6 +315,30 @@ ThreadContext::~ThreadContext()
}
bool
+ThreadContext::schedule(PCEvent *e)
+{
+ auto it = getOrAllocBp(e->pc());
+ it->second->events.push_back(e);
+
+ if (_instId != iris::IRIS_UINT64_MAX && !it->second->validId())
+ installBp(it);
+
+ return true;
+}
+
+bool
+ThreadContext::remove(PCEvent *e)
+{
+ auto it = getOrAllocBp(e->pc());
+ it->second->events.remove(e);
+
+ if (it->second->empty())
+ delBp(it);
+
+ return true;
+}
+
+bool
ThreadContext::translateAddress(Addr &paddr, iris::MemorySpaceId p_space,
Addr vaddr, iris::MemorySpaceId v_space)
{
diff --git a/src/arch/arm/fastmodel/iris/thread_context.hh b/src/arch/arm/fastmodel/iris/thread_context.hh
index 8d2070a02..4175e9363 100644
--- a/src/arch/arm/fastmodel/iris/thread_context.hh
+++ b/src/arch/arm/fastmodel/iris/thread_context.hh
@@ -30,6 +30,8 @@
#ifndef __ARCH_ARM_FASTMODEL_IRIS_THREAD_CONTEXT_HH__
#define __ARCH_ARM_FASTMODEL_IRIS_THREAD_CONTEXT_HH__
+#include <list>
+#include <map>
#include <memory>
#include "cpu/base.hh"
@@ -91,6 +93,33 @@ class ThreadContext : public ::ThreadContext
void maintainStepping();
+ using BpId = uint64_t;
+ struct BpInfo
+ {
+ Addr pc;
+ BpId id;
+ std::list<PCEvent *> events;
+
+ BpInfo(Addr _pc) : pc(_pc), id(iris::IRIS_UINT64_MAX) {}
+
+ bool empty() const { return events.empty(); }
+ bool validId() const { return id != iris::IRIS_UINT64_MAX; }
+ void clearId() { id = iris::IRIS_UINT64_MAX; }
+ };
+
+ using BpInfoPtr = std::unique_ptr<BpInfo>;
+ using BpInfoMap = std::map<Addr, BpInfoPtr>;
+ using BpInfoIt = BpInfoMap::iterator;
+
+ BpInfoMap bps;
+
+ BpInfoIt getOrAllocBp(Addr pc);
+
+ void installBp(BpInfoIt it);
+ void uninstallBp(BpInfoIt it);
+ void delBp(BpInfoIt it);
+
+
iris::IrisErrorCode instanceRegistryChanged(
uint64_t esId, const iris::IrisValueMap &fields, uint64_t time,
uint64_t sInstId, bool syncEc, std::string &error_message_out);
@@ -100,10 +129,14 @@ class ThreadContext : public ::ThreadContext
iris::IrisErrorCode simulationTimeEvent(
uint64_t esId, const iris::IrisValueMap &fields, uint64_t time,
uint64_t sInstId, bool syncEc, std::string &error_message_out);
+ iris::IrisErrorCode breakpointHit(
+ uint64_t esId, const iris::IrisValueMap &fields, uint64_t time,
+ uint64_t sInstId, bool syncEc, std::string &error_message_out);
iris::EventStreamId regEventStreamId;
iris::EventStreamId initEventStreamId;
iris::EventStreamId timeEventStreamId;
+ iris::EventStreamId breakpointEventStreamId;
mutable iris::IrisInstance client;
iris::IrisCppAdapter &call() const { return client.irisCall(); }
@@ -121,8 +154,8 @@ class ThreadContext : public ::ThreadContext
virtual bool translateAddress(Addr &paddr, Addr vaddr) = 0;
- bool schedule(PCEvent *e) override { return false; }
- bool remove(PCEvent *e) override { return false; }
+ bool schedule(PCEvent *e) override;
+ bool remove(PCEvent *e) override;
void scheduleInstCountEvent(Event *event, Tick count) override;
void descheduleInstCountEvent(Event *event) override;