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 <gabeblack@google.com>
Maintainer: Gabe Black <gabeblack@google.com>
This commit is contained in:
Gabe Black
2019-11-21 15:36:21 -08:00
parent 6b2fe440fd
commit 030532c3c1
2 changed files with 54 additions and 0 deletions

View File

@@ -29,11 +29,13 @@
#include <utility>
#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<Self, &Self::semihostingEvent>(
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);

View File

@@ -69,6 +69,7 @@ class ThreadContext : public ::ThreadContext
mutable std::vector<ArmISA::VecPredRegContainer> 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(); }