From: Gabe Black Date: Thu, 21 Nov 2019 23:36:21 +0000 (-0800) Subject: fastmodel: Enable semihosting, including pseudo insts. X-Git-Tag: v20.0.0.0~184 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=030532c3c199476a2e17979949c7a6a7e4931101;p=gem5.git fastmodel: Enable semihosting, including pseudo insts. It is assumed that the semihosting configuration uses the semihosting number which includes gem5's pseudo insts. Given the complexity and likely limitted value of letting the user arbitrarily configure fast model's semihosting, and the fact that that semihosting implementation would compete with gem5's own, those parameters should be removed from python and set purely within C++. Also note that if this semihosting support is used, the System object needs to have an ArmSemihosting object installed to handle the calls. Change-Id: I8e1de7717c9784dc7873795acd0a06389ec527b1 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/25623 Tested-by: Gem5 Cloud Project GCB service account <345032938727@cloudbuild.gserviceaccount.com> Reviewed-by: Gabe Black Maintainer: Gabe Black --- diff --git a/src/arch/arm/fastmodel/iris/thread_context.cc b/src/arch/arm/fastmodel/iris/thread_context.cc index 9aed27b7c..a2cf2bfc6 100644 --- a/src/arch/arm/fastmodel/iris/thread_context.cc +++ b/src/arch/arm/fastmodel/iris/thread_context.cc @@ -29,11 +29,13 @@ #include +#include "arch/arm/system.hh" #include "arch/arm/utility.hh" #include "iris/detail/IrisCppAdapter.h" #include "iris/detail/IrisObjects.h" #include "mem/se_translating_port_proxy.hh" #include "mem/translating_port_proxy.hh" +#include "sim/pseudo_inst.hh" namespace Iris { @@ -62,6 +64,17 @@ ThreadContext::initFromIrisInstance(const ResourceMap &resources) for (auto it = bps.begin(); it != bps.end(); it++) installBp(it); + + client.registerEventCallback( + this, "ec_IRIS_SEMIHOSTING_CALL_EXTENSION", + "Handle a semihosting call", "Iris::ThreadContext"); + call().event_getEventSource(_instId, evSrcInfo, + "IRIS_SEMIHOSTING_CALL_EXTENSION"); + call().eventStream_create(_instId, semihostingEventStreamId, + evSrcInfo.evSrcId, client.getInstId(), + // Set all arguments to their defaults, except syncEc which is + // changed to true. + nullptr, "", false, 0, nullptr, false, false, true); } iris::ResourceId @@ -243,6 +256,28 @@ ThreadContext::breakpointHit( return iris::E_ok; } +iris::IrisErrorCode +ThreadContext::semihostingEvent( + uint64_t esId, const iris::IrisValueMap &fields, uint64_t time, + uint64_t sInstId, bool syncEc, std::string &error_message_out) +{ + if (ArmSystem::callSemihosting(this, true)) { + // Stop execution in case an exit of the sim loop was scheduled. We + // don't want to keep executing instructions in the mean time. + call().perInstanceExecution_setState(_instId, false); + + // Schedule an event to resume execution right after any exit has + // had a chance to happen. + if (!enableAfterPseudoEvent->scheduled()) + getCpuPtr()->schedule(enableAfterPseudoEvent, curTick()); + + call().semihosting_return(_instId, readIntReg(0)); + } else { + call().semihosting_notImplemented(_instId); + } + 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) : @@ -299,6 +334,14 @@ ThreadContext::ThreadContext( evSrcInfo.evSrcId, client.getInstId()); breakpointEventStreamId = iris::IRIS_UINT64_MAX; + semihostingEventStreamId = iris::IRIS_UINT64_MAX; + + auto enable_lambda = [this]{ + call().perInstanceExecution_setState(_instId, true); + }; + enableAfterPseudoEvent = new EventFunctionWrapper( + enable_lambda, "resume after pseudo inst", + false, Event::Sim_Exit_Pri + 1); } ThreadContext::~ThreadContext() @@ -317,6 +360,10 @@ ThreadContext::~ThreadContext() iris::IrisInstIdGlobalInstance, timeEventStreamId); timeEventStreamId = iris::IRIS_UINT64_MAX; client.unregisterEventCallback("ec_IRIS_SIMULATION_TIME_EVENT"); + + if (enableAfterPseudoEvent->scheduled()) + getCpuPtr()->deschedule(enableAfterPseudoEvent); + delete enableAfterPseudoEvent; } bool @@ -424,6 +471,8 @@ ThreadContext::status() const void ThreadContext::setStatus(Status new_status) { + if (enableAfterPseudoEvent->scheduled()) + getCpuPtr()->deschedule(enableAfterPseudoEvent); if (new_status == Active) { if (_status != Active) call().perInstanceExecution_setState(_instId, true); diff --git a/src/arch/arm/fastmodel/iris/thread_context.hh b/src/arch/arm/fastmodel/iris/thread_context.hh index d4e80f1f9..6b1606942 100644 --- a/src/arch/arm/fastmodel/iris/thread_context.hh +++ b/src/arch/arm/fastmodel/iris/thread_context.hh @@ -69,6 +69,7 @@ class ThreadContext : public ::ThreadContext mutable std::vector vecPredRegs; Status _status = Active; + Event *enableAfterPseudoEvent; virtual void initFromIrisInstance(const ResourceMap &resources); @@ -147,11 +148,15 @@ class ThreadContext : public ::ThreadContext iris::IrisErrorCode breakpointHit( uint64_t esId, const iris::IrisValueMap &fields, uint64_t time, uint64_t sInstId, bool syncEc, std::string &error_message_out); + iris::IrisErrorCode semihostingEvent( + 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; + iris::EventStreamId semihostingEventStreamId; mutable iris::IrisInstance client; iris::IrisCppAdapter &call() const { return client.irisCall(); }