53#include "iris/detail/IrisCppAdapter.h"
54#include "iris/detail/IrisObjects.h"
82 iris::EventSourceInfo evSrcInfo;
84 client.registerEventCallback<Self, &Self::breakpointHit>(
85 this,
"ec_IRIS_BREAKPOINT_HIT",
86 "Handle hitting a breakpoint",
"Iris::ThreadContext");
87 call().event_getEventSource(
_instId, evSrcInfo,
"IRIS_BREAKPOINT_HIT");
89 evSrcInfo.evSrcId,
client.getInstId());
91 for (
auto it =
bps.begin(); it !=
bps.end(); it++)
94 client.registerEventCallback<Self, &Self::semihostingEvent>(
95 this,
"ec_IRIS_SEMIHOSTING_CALL_EXTENSION",
96 "Handle a semihosting call",
"Iris::ThreadContext");
98 "IRIS_SEMIHOSTING_CALL_EXTENSION");
100 evSrcInfo.evSrcId,
client.getInstId(),
103 nullptr,
"",
false, 0,
nullptr,
false,
false,
true);
110 return resources.at(
name).rscId;
118 for (
const auto &idx_name: idx_names) {
119 int idx = idx_name.first;
120 const std::string &
name = idx_name.second;
122 if (idx >=
ids.size())
123 ids.resize(idx + 1, iris::IRIS_UINT64_MAX);
133 return it ==
memorySpaceIds.end() ? iris::IRIS_UINT64_MAX : it->second;
159 Tick remaining = next - now;
160 call().step_setup(
_instId, remaining,
"instruction");
168 auto pc_it =
bps.find(
pc);
170 if (pc_it !=
bps.end())
174 panic_if(!res.second,
"Inserting breakpoint failed.");
183 for (
auto sid: space_ids) {
186 it->second->ids.push_back(
id);
193 for (
auto id: it->second->ids)
195 it->second->clearIds();
202 "BP info still had events associated with it.");
204 if (it->second->validIds())
212 uint64_t esId,
const iris::IrisValueMap &fields, uint64_t time,
213 uint64_t sInstId,
bool syncEc, std::string &error_message_out)
215 const std::string &
event = fields.at(
"EVENT").getString();
216 const iris::InstanceId
id = fields.at(
"INST_ID").getU64();
217 const std::string &
name = fields.at(
"INST_NAME").getString();
222 if (
event ==
"added")
224 else if (
event ==
"removed")
225 _instId = iris::IRIS_UINT64_MAX;
234 uint64_t esId,
const iris::IrisValueMap &fields, uint64_t time,
235 uint64_t sInstId,
bool syncEc, std::string &error_message_out)
240 std::map<iris::ResourceId, const iris::ResourceInfo *>
242 for (
const auto &resource: resources) {
243 idToResource[resource.rscId] = &resource;
246 for (
const auto &resource: resources) {
247 std::string
name = resource.name;
248 iris::ResourceId parentId = resource.parentRscId;
249 while (parentId != iris::IRIS_UINT64_MAX) {
250 const auto *parent = idToResource[parentId];
252 parentId = parent->parentRscId;
254 resourceMap[
name] = resource;
264 uint64_t esId,
const iris::IrisValueMap &fields, uint64_t time,
265 uint64_t sInstId,
bool syncEc, std::string &error_message_out)
267 if (fields.at(
"RUNNING").getAsBool()) {
276 std::shared_ptr<BpInfo::EventList> events = it->second->events;
277 auto e_it = events->begin();
278 while (e_it != events->end()) {
295 call().simulationTime_run(iris::IrisInstIdSimulationEngine);
302 uint64_t esId,
const iris::IrisValueMap &fields, uint64_t time,
303 uint64_t sInstId,
bool syncEc, std::string &error_message_out)
307 Addr pc = fields.at(
"PC").getU64();
314 uint64_t esId,
const iris::IrisValueMap &fields, uint64_t time,
315 uint64_t sInstId,
bool syncEc, std::string &error_message_out)
320 call().perInstanceExecution_setState(
_instId,
false);
336 BaseISA *isa, iris::IrisConnectionInterface *iris_if,
337 const std::string &iris_path) :
338 _cpu(cpu), _threadId(
id), _system(
system), _mmu(mmu), _isa(isa),
339 _irisPath(iris_path), vecRegs(ArmISA::
NumVecRegs),
341 comInstEventQueue(
"instruction-based event queue"),
342 client(iris_if,
"client." + iris_path)
344 iris::InstanceInfo info;
345 auto ret_code =
noThrow().instanceRegistry_getInstanceInfoByName(
346 info,
"component." + iris_path);
347 if (ret_code == iris::E_ok) {
352 _instId = iris::IRIS_UINT64_MAX;
356 iris::EventSourceInfo evSrcInfo;
358 client.registerEventCallback<Self, &Self::instanceRegistryChanged>(
359 this,
"ec_IRIS_INSTANCE_REGISTRY_CHANGED",
360 "Install the iris instance ID",
"Iris::ThreadContext");
361 call().event_getEventSource(iris::IrisInstIdGlobalInstance, evSrcInfo,
362 "IRIS_INSTANCE_REGISTRY_CHANGED");
365 {
"EVENT",
"INST_ID",
"INST_NAME" };
367 evSrcInfo.evSrcId,
client.getInstId(), &fields);
369 client.registerEventCallback<Self, &Self::phaseInitLeave>(
370 this,
"ec_IRIS_SIM_PHASE_INIT_LEAVE",
371 "Initialize register contexts",
"Iris::ThreadContext");
372 call().event_getEventSource(iris::IrisInstIdSimulationEngine, evSrcInfo,
373 "IRIS_SIM_PHASE_INIT_LEAVE");
375 call().eventStream_create(
377 evSrcInfo.evSrcId,
client.getInstId());
379 client.registerEventCallback<Self, &Self::simulationTimeEvent>(
380 this,
"ec_IRIS_SIMULATION_TIME_EVENT",
381 "Handle simulation time stopping for breakpoints or stepping",
382 "Iris::ThreadContext");
383 call().event_getEventSource(iris::IrisInstIdSimulationEngine, evSrcInfo,
384 "IRIS_SIMULATION_TIME_EVENT");
386 call().eventStream_create(
388 evSrcInfo.evSrcId,
client.getInstId());
393 auto enable_lambda = [
this]{
394 call().perInstanceExecution_setState(
_instId,
true);
397 enable_lambda,
"resume after pseudo inst",
403 call().eventStream_destroy(
406 client.unregisterEventCallback(
"ec_IRIS_SIM_PHASE_INIT_LEAVE");
408 call().eventStream_destroy(
411 client.unregisterEventCallback(
"ec_IRIS_INSTANCE_REGISTRY_CHANGED");
413 call().eventStream_destroy(
416 client.unregisterEventCallback(
"ec_IRIS_SIMULATION_TIME_EVENT");
427 it->second->events->push_back(
e);
429 if (
_instId != iris::IRIS_UINT64_MAX && !it->second->validIds())
439 it->second->events->remove(
e);
441 if (it->second->empty())
449 iris::MemorySpaceId space,
Addr addr,
void *
p,
size_t size)
451 iris::MemoryReadResult
r;
454 std::memcpy(
p,
r.data.data(), size);
459 iris::MemorySpaceId space,
Addr addr,
const void *
p,
size_t size)
462 std::memcpy(
data.data(),
p, size);
463 iris::MemoryWriteResult
r;
472 iris::MemoryAddressTranslationResult result;
473 auto ret =
noThrow().memory_translateAddress(
476 if (ret != iris::E_ok) {
480 if (trans.inSpaceId == v_space && trans.outSpaceId == p_space)
483 panic(
"No legal translation IRIS address translation found.");
486 if (result.address.empty())
489 if (result.address.size() > 1) {
490 warn(
"Multiple mappings for address %#x.",
vaddr);
494 paddr = result.address[0];
504 call().simulationTime_stop(iris::IrisInstIdSimulationEngine);
521 panic_if(ret != iris::E_ok,
"Failed to get instruction count.");
567 if (new_status ==
Active) {
569 call().perInstanceExecution_setState(
_instId,
true);
572 call().perInstanceExecution_setState(
_instId,
false);
583 pc.nextThumb(
pc.thumb());
584 pc.aarch64(!cpsr.width);
585 pc.nextAArch64(!cpsr.width);
586 pc.illegalExec(
false);
590 iris::ResourceReadResult result;
593 if (cpsr.width && cpsr.t)
605 if (cpsr.width && cpsr.t)
608 iris::ResourceWriteResult result;
615 iris::ResourceId rsc_id = iris::IRIS_UINT64_MAX;
619 panic_if(rsc_id == iris::IRIS_UINT64_MAX,
620 "Misc reg %s is not supported by fast model.",
628 iris::ResourceReadResult result;
630 return result.data.at(0);
636 iris::ResourceWriteResult result;
658 const bool flat =
reg.regClass().isFlat();
678 panic(
"MiscRegs should not be read with getReg.");
680 panic(
"Unrecognized register class type %d.",
type);
700 panic(
"MiscRegs should not be read with getReg.");
702 panic(
"Unrecognized register class type %d.",
type);
711 const bool flat =
reg.regClass().isFlat();
731 panic(
"MiscRegs should not be read with getReg.");
733 panic(
"Unrecognized register class type %d.",
type);
753 panic(
"MiscRegs should not be read with getReg.");
755 panic(
"Unrecognized register class type %d.",
type);
764 const bool flat =
reg.regClass().isFlat();
773 panic(
"Unrecognized register class type %d.",
type);
782 panic(
"Unrecognized register class type %d.",
type);
792 iris::ResourceId rsc_id = iris::IRIS_UINT64_MAX;
793 if (int_reg < regIds.size())
794 rsc_id = regIds.at(int_reg);
796 panic_if(rsc_id == iris::IRIS_UINT64_MAX,
797 "Int reg %s is not supported by fast model.",
805 iris::ResourceReadResult result;
807 return result.data.at(0);
813 iris::ResourceWriteResult result;
820 iris::ResourceId rsc_id = iris::IRIS_UINT64_MAX;
834 if (rsc_id == iris::IRIS_UINT64_MAX)
836 iris::ResourceReadResult result;
838 return result.data.at(0);
845 panic_if(rsc_id == iris::IRIS_UINT64_MAX,
846 "Int reg %s is not supported by fast model.",
848 iris::ResourceWriteResult result;
855 iris::ResourceId rsc_id = iris::IRIS_UINT64_MAX;
865 if (rsc_id == iris::IRIS_UINT64_MAX)
867 iris::ResourceReadResult result;
869 return result.data.at(0);
876 panic_if(rsc_id == iris::IRIS_UINT64_MAX,
877 "CC reg %s is not supported by fast model.",
879 iris::ResourceWriteResult result;
886 iris::ResourceId rsc_id = iris::IRIS_UINT64_MAX;
903 if (rsc_id == iris::IRIS_UINT64_MAX)
906 iris::ResourceReadResult result;
908 size_t data_size = result.data.size() * (
sizeof(*result.data.data()));
909 size_t size = std::min(data_size,
reg.size());
910 memcpy(
reg.as<uint8_t>(), (
void *)result.data.data(), size);
924 iris::ResourceId rsc_id = iris::IRIS_UINT64_MAX;
939 if (rsc_id == iris::IRIS_UINT64_MAX)
942 iris::ResourceReadResult result;
946 size_t num_bits =
reg.NUM_BITS;
947 uint8_t *bytes = (uint8_t *)result.data.data();
948 while (num_bits > 8) {
static bool callSemihosting(ThreadContext *tc, bool gem5_ops=false)
Make a Semihosting call from either aarch64 or aarch32.
EventQueue comInstEventQueue
virtual void initFromIrisInstance(const ResourceMap &resources)
virtual void setVecPredReg(const RegId ®, const ArmISA::VecPredRegContainer &val)
void * getWritableReg(const RegId ®) override
ThreadContext(gem5::BaseCPU *cpu, int id, System *system, gem5::BaseMMU *mmu, gem5::BaseISA *isa, iris::IrisConnectionInterface *iris_if, const std::string &iris_path)
iris::ResourceId getMiscRegRscId(RegIndex misc_reg) const
bool remove(PCEvent *e) override
void uninstallBp(BpInfoIt it)
void setStatus(Status new_status) override
void readMemWithCurrentMsn(Addr vaddr, size_t size, char *data)
virtual RegVal readVecElemFlat(RegIndex idx) const
virtual void setCCReg(RegIndex reg_idx, RegVal val)
virtual void setVecReg(const RegId ®, const ArmISA::VecRegContainer &val)
MemorySpaceMap memorySpaceIds
std::vector< iris::MemorySupportedAddressTranslationResult > translations
ResourceIds vecPredRegIds
virtual ArmISA::VecRegContainer & getWritableVecReg(const RegId ®)
virtual RegVal readCCRegFlat(RegIndex idx) const
void installBp(BpInfoIt it)
iris::ResourceId getIntRegFlatRscId(RegIndex int_reg) const
Flat register interfaces.
ResourceIds flattenedIntIds
void descheduleInstCountEvent(Event *event) override
virtual RegVal readCCReg(RegIndex reg_idx) const
Status status() const override
virtual ArmISA::VecRegContainer & getWritableVecRegFlat(RegIndex idx)
void sendFunctional(PacketPtr pkt) override
void extractResourceMap(ResourceIds &ids, const ResourceMap &resources, const IdxNameMap &idx_names)
iris::ResourceId getVecPredRegRscId(RegIndex vec_reg) const
bool translateAddress(Addr &paddr, iris::MemorySpaceId p_space, Addr vaddr, iris::MemorySpaceId v_space)
iris::ResourceId getVecRegRscId(RegIndex vec_reg) const
void writeMem(iris::MemorySpaceId space, Addr addr, const void *p, size_t size)
iris::IrisErrorCode phaseInitLeave(uint64_t esId, const iris::IrisValueMap &fields, uint64_t time, uint64_t sInstId, bool syncEc, std::string &error_message_out)
virtual RegVal readIntRegFlat(RegIndex idx) const
Tick getCurrentInstCount() override
const PCStateBase & pcState() const override
virtual const ArmISA::VecPredRegContainer & readVecPredReg(const RegId ®) const
virtual void setVecPredRegFlat(RegIndex idx, const ArmISA::VecPredRegContainer &val)
iris::IrisErrorCode semihostingEvent(uint64_t esId, const iris::IrisValueMap &fields, uint64_t time, uint64_t sInstId, bool syncEc, std::string &error_message_out)
virtual RegVal readVecElem(const RegId ®) const
iris::IrisErrorCode simulationTimeEvent(uint64_t esId, const iris::IrisValueMap &fields, uint64_t time, uint64_t sInstId, bool syncEc, std::string &error_message_out)
iris::IrisCppAdapter & noThrow() const
virtual const std::vector< iris::MemorySpaceId > & getBpSpaceIds() const =0
virtual const ArmISA::VecRegContainer & readVecReg(const RegId ®) const
iris::ResourceId getCCRegFlatRscId(RegIndex cc_reg) const
RegVal getReg(const RegId ®) const override
iris::EventStreamId regEventStreamId
virtual void setVecRegFlat(RegIndex idx, const ArmISA::VecRegContainer &val)
iris::EventStreamId initEventStreamId
iris::EventStreamId semihostingEventStreamId
void readMem(iris::MemorySpaceId space, Addr addr, void *p, size_t size)
BpInfoIt getOrAllocBp(Addr pc)
gem5::BaseCPU * getCpuPtr() override
std::vector< ArmISA::VecRegContainer > vecRegs
std::map< std::string, iris::ResourceInfo > ResourceMap
std::map< int, std::string > IdxNameMap
virtual void setVecElemFlat(RegIndex idx, RegVal val)
iris::MemorySpaceId getMemorySpaceId(const Iris::CanonicalMsn &msn) const
RegVal readMiscRegNoEffect(RegIndex misc_reg) const override
void suspend() override
Set the status to Suspended.
iris::IrisErrorCode breakpointHit(uint64_t esId, const iris::IrisValueMap &fields, uint64_t time, uint64_t sInstId, bool syncEc, std::string &error_message_out)
virtual ArmISA::VecPredRegContainer & getWritableVecPredRegFlat(RegIndex idx)
virtual ArmISA::VecPredRegContainer & getWritableVecPredReg(const RegId ®)
std::vector< ArmISA::VecPredRegContainer > vecPredRegs
virtual void setIntRegFlat(RegIndex idx, uint64_t val)
iris::IrisCppAdapter & call() const
virtual ArmISA::VecPredRegContainer readVecPredRegFlat(RegIndex idx) const
BpInfoMap::iterator BpInfoIt
iris::ResourceId extractResourceId(const ResourceMap &resources, const std::string &name)
void writeMemWithCurrentMsn(Addr vaddr, size_t size, const char *data)
virtual RegVal readIntReg(RegIndex reg_idx) const
std::vector< iris::MemorySpaceInfo > memorySpaces
virtual void setVecElem(const RegId ®, RegVal val)
virtual void setIntReg(RegIndex reg_idx, RegVal val)
iris::EventStreamId timeEventStreamId
bool schedule(PCEvent *e) override
iris::ResourceId getIntRegRscId(RegIndex int_reg) const
iris::EventStreamId breakpointEventStreamId
virtual void setCCRegFlat(RegIndex idx, RegVal val)
void scheduleInstCountEvent(Event *event, Tick count) override
virtual const ArmISA::VecRegContainer & readVecRegFlat(RegIndex idx) const
iris::IrisErrorCode instanceRegistryChanged(uint64_t esId, const iris::IrisValueMap &fields, uint64_t time, uint64_t sInstId, bool syncEc, std::string &error_message_out)
void setReg(const RegId ®, RegVal val) override
iris::IrisInstance client
std::optional< Addr > bpAddr
void setMiscRegNoEffect(RegIndex misc_reg, const RegVal val) override
Event * enableAfterPseudoEvent
virtual void process(ThreadContext *tc)=0
Addr instAddr() const
Returns the memory address of the instruction this PC points to.
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
void makeResponse()
Take a request packet and modify it in place to be suitable for returning as a response to that reque...
T * getPtr()
get a pointer to the data ptr.
Register ID: describe an architectural register with its class and index.
constexpr RegIndex index() const
Index accessors.
@ Suspended
Temporarily inactive.
Vector Register Abstraction This generic class is the model in a particularization of MVC,...
void zero()
Zero the container.
void schedule(Event *event, Tick when, bool global=false)
Schedule the given event on this queue.
void deschedule(Event *event)
Deschedule the specified event.
void deschedule(Event &event)
void serviceEvents(Tick when)
process all events up to the given timestamp.
bool scheduled() const
Determine if the current event is scheduled.
void schedule(Event &event, Tick when)
static const Priority Sim_Exit_Pri
If we want to exit on this cycle, it's the very last thing we do.
bool empty() const
Returns true if no events are queued.
#define panic(...)
This implements a cprintf based panic() function.
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
bool isSecure(ThreadContext *tc)
VecPredReg::Container VecPredRegContainer
constexpr RegClass intRegClass
constexpr RegClass vecPredRegClass
constexpr RegClass ccRegClass
constexpr RegClass miscRegClass
static uint8_t itState(CPSR psr)
constexpr RegClass vecRegClass
@ PhysicalMemorySecureMsn
@ PhysicalMemoryNonSecureMsn
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Tick curTick()
The universal simulation clock.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
uint64_t Tick
Tick count type.
RegClassType
Enumerate the classes of registers.
@ CCRegClass
Condition-code register.
@ VecRegClass
Vector Register.
@ IntRegClass
Integer register.
@ MiscRegClass
Control (misc) register.
@ VecElemClass
Vector Register Native Elem lane.
const std::string & name()