summaryrefslogtreecommitdiff
path: root/src/arch
diff options
context:
space:
mode:
authorGabe Black <gabeblack@google.com>2019-10-15 16:57:07 -0700
committerGabe Black <gabeblack@google.com>2019-11-06 22:05:29 +0000
commit2c3c7df5fc13ce69358be96d68899ae730c9ac98 (patch)
treeb63ec5de4f704ae8049d7d6f79b944862d18d2f9 /src/arch
parent3791b605f8e89887af23f54d95c202ac1d5a6101 (diff)
downloadgem5-2c3c7df5fc13ce69358be96d68899ae730c9ac98.tar.xz
fastmodel: Implement inst count events in the IRIS thread contexts.
These use the IRIS stepping API. Change-Id: Ib45744cb0928fece664187e4df6b25b064b19f0e Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/22115 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/arch')
-rw-r--r--src/arch/arm/fastmodel/iris/thread_context.cc86
-rw-r--r--src/arch/arm/fastmodel/iris/thread_context.hh16
2 files changed, 100 insertions, 2 deletions
diff --git a/src/arch/arm/fastmodel/iris/thread_context.cc b/src/arch/arm/fastmodel/iris/thread_context.cc
index 43be17142..1380cf3bf 100644
--- a/src/arch/arm/fastmodel/iris/thread_context.cc
+++ b/src/arch/arm/fastmodel/iris/thread_context.cc
@@ -68,6 +68,35 @@ ThreadContext::extractResourceMap(
}
}
+void
+ThreadContext::maintainStepping()
+{
+ Tick now = 0;
+
+ while (true) {
+ if (comInstEventQueue.empty()) {
+ // Set to 0 to deactivate stepping.
+ call().step_setup(_instId, 0, "instruction");
+ break;
+ }
+
+ Tick next = comInstEventQueue.nextTick();
+ if (!now)
+ now = getCurrentInstCount();
+
+ if (next <= now) {
+ comInstEventQueue.serviceEvents(now);
+ // Start over now that comInstEventQueue has likely changed.
+ continue;
+ }
+
+ // Set to the number of instructions still to step through.
+ Tick remaining = next - now;
+ call().step_setup(_instId, remaining, "instruction");
+ break;
+ }
+}
+
iris::IrisErrorCode
ThreadContext::instanceRegistryChanged(
uint64_t esId, const iris::IrisValueMap &fields, uint64_t time,
@@ -107,11 +136,34 @@ ThreadContext::phaseInitLeave(
return iris::E_ok;
}
+iris::IrisErrorCode
+ThreadContext::simulationTimeEvent(
+ uint64_t esId, const iris::IrisValueMap &fields, uint64_t time,
+ uint64_t sInstId, bool syncEc, std::string &error_message_out)
+{
+ if (fields.at("RUNNING").getAsBool()) {
+ // If this is just simulation time starting up, don't do anything.
+ return iris::E_ok;
+ }
+
+ // If simulation time has stopped for any reason, IRIS helpfully clears
+ // all stepping counters and we need to set them back. We might also need
+ // to service events based on the current number of executed instructions.
+ maintainStepping();
+
+ // Restart simulation time to make sure things progress once we give
+ // control back.
+ call().simulationTime_run(iris::IrisInstIdSimulationEngine);
+
+ return iris::E_ok;
+}
+
ThreadContext::ThreadContext(
BaseCPU *cpu, int id, System *system,
iris::IrisConnectionInterface *iris_if, const std::string &iris_path) :
_cpu(cpu), _threadId(id), _system(system), _irisPath(iris_path),
_instId(iris::IRIS_UINT64_MAX), _status(Active),
+ comInstEventQueue("instruction-based event queue"),
client(iris_if, "client." + iris_path)
{
iris::InstanceInfo info;
@@ -148,6 +200,17 @@ ThreadContext::ThreadContext(
call().eventStream_create(
iris::IrisInstIdSimulationEngine, initEventStreamId,
evSrcInfo.evSrcId, client.getInstId());
+
+ client.registerEventCallback<Self, &Self::simulationTimeEvent>(
+ this, "ec_IRIS_SIMULATION_TIME_EVENT",
+ "Handle simulation time stopping for breakpoints or stepping",
+ "Iris::ThreadContext");
+ call().event_getEventSource(iris::IrisInstIdSimulationEngine, evSrcInfo,
+ "IRIS_SIMULATION_TIME_EVENT");
+ timeEventStreamId = iris::IRIS_UINT64_MAX;
+ call().eventStream_create(
+ iris::IrisInstIdSimulationEngine, timeEventStreamId,
+ evSrcInfo.evSrcId, client.getInstId());
}
ThreadContext::~ThreadContext()
@@ -161,6 +224,29 @@ ThreadContext::~ThreadContext()
iris::IrisInstIdGlobalInstance, regEventStreamId);
regEventStreamId = iris::IRIS_UINT64_MAX;
client.unregisterEventCallback("ec_IRIS_INSTANCE_REGISTRY_CHANGED");
+
+ call().eventStream_destroy(
+ iris::IrisInstIdGlobalInstance, timeEventStreamId);
+ timeEventStreamId = iris::IRIS_UINT64_MAX;
+ client.unregisterEventCallback("ec_IRIS_SIMULATION_TIME_EVENT");
+}
+
+void
+ThreadContext::scheduleInstCountEvent(Event *event, Tick count)
+{
+ Tick now = getCurrentInstCount();
+ comInstEventQueue.schedule(event, count);
+ if (count <= now)
+ call().simulationTime_stop(iris::IrisInstIdSimulationEngine);
+ else
+ maintainStepping();
+}
+
+void
+ThreadContext::descheduleInstCountEvent(Event *event)
+{
+ comInstEventQueue.deschedule(event);
+ maintainStepping();
}
Tick
diff --git a/src/arch/arm/fastmodel/iris/thread_context.hh b/src/arch/arm/fastmodel/iris/thread_context.hh
index acb325cdb..bdf12ef8b 100644
--- a/src/arch/arm/fastmodel/iris/thread_context.hh
+++ b/src/arch/arm/fastmodel/iris/thread_context.hh
@@ -73,15 +73,27 @@ class ThreadContext : public ::ThreadContext
ResourceIds intRegIds;
+ // A queue to keep track of instruction count based events.
+ EventQueue comInstEventQueue;
+ // A helper function to maintain the IRIS step count. This makes sure the
+ // step count is correct even after IRIS resets it for us, and also handles
+ // events which are supposed to happen at the current instruction count.
+ void maintainStepping();
+
+
iris::IrisErrorCode instanceRegistryChanged(
uint64_t esId, const iris::IrisValueMap &fields, uint64_t time,
uint64_t sInstId, bool syncEc, std::string &error_message_out);
iris::IrisErrorCode phaseInitLeave(
uint64_t esId, const iris::IrisValueMap &fields, uint64_t time,
uint64_t sInstId, bool syncEc, std::string &error_message_out);
+ iris::IrisErrorCode simulationTimeEvent(
+ 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;
mutable iris::IrisInstance client;
iris::IrisCppAdapter &call() const { return client.irisCall(); }
@@ -96,8 +108,8 @@ class ThreadContext : public ::ThreadContext
bool schedule(PCEvent *e) override { return false; }
bool remove(PCEvent *e) override { return false; }
- void scheduleInstCountEvent(Event *event, Tick count) override {}
- void descheduleInstCountEvent(Event *event) override {}
+ void scheduleInstCountEvent(Event *event, Tick count) override;
+ void descheduleInstCountEvent(Event *event) override;
Tick getCurrentInstCount() override;
::BaseCPU *getCpuPtr() override { return _cpu; }