2 * Copyright 2019 Google, Inc.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met: redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer;
8 * redistributions in binary form must reproduce the above copyright
9 * notice, this list of conditions and the following disclaimer in the
10 * documentation and/or other materials provided with the distribution;
11 * neither the name of the copyright holders nor the names of its
12 * contributors may be used to endorse or promote products derived from
13 * this software without specific prior written permission.
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #ifndef __ARCH_ARM_FASTMODEL_IRIS_THREAD_CONTEXT_HH__
31 #define __ARCH_ARM_FASTMODEL_IRIS_THREAD_CONTEXT_HH__
37 #include "cpu/base.hh"
38 #include "cpu/thread_context.hh"
39 #include "iris/IrisInstance.h"
40 #include "iris/detail/IrisErrorCode.h"
41 #include "iris/detail/IrisObjects.h"
42 #include "sim/system.hh"
47 // This class is the base for ThreadContexts which read and write state using
49 class ThreadContext : public ::ThreadContext
52 typedef std::map<std::string, iris::ResourceInfo> ResourceMap;
54 typedef std::vector<iris::ResourceId> ResourceIds;
55 typedef std::map<int, std::string> IdxNameMap;
65 std::string _irisPath;
66 iris::InstanceId _instId = iris::IRIS_UINT64_MAX;
68 // Temporary holding places for the vector reg accessors to return.
69 // These are not updated live, only when requested.
70 mutable std::vector<ArmISA::VecRegContainer> vecRegs;
71 mutable std::vector<ArmISA::VecPredRegContainer> vecPredRegs;
73 Status _status = Active;
75 virtual void initFromIrisInstance(const ResourceMap &resources);
77 iris::ResourceId extractResourceId(
78 const ResourceMap &resources, const std::string &name);
79 void extractResourceMap(ResourceIds &ids,
80 const ResourceMap &resources, const IdxNameMap &idx_names);
83 ResourceIds miscRegIds;
84 ResourceIds intReg32Ids;
85 ResourceIds intReg64Ids;
86 ResourceIds flattenedIntIds;
89 iris::ResourceId pcRscId = iris::IRIS_UINT64_MAX;
90 iris::ResourceId icountRscId;
92 ResourceIds vecRegIds;
93 ResourceIds vecPredRegIds;
95 std::vector<iris::MemorySpaceInfo> memorySpaces;
96 std::vector<iris::MemorySupportedAddressTranslationResult> translations;
98 std::unique_ptr<PortProxy> virtProxy = nullptr;
99 std::unique_ptr<PortProxy> physProxy = nullptr;
102 // A queue to keep track of instruction count based events.
103 EventQueue comInstEventQueue;
104 // A helper function to maintain the IRIS step count. This makes sure the
105 // step count is correct even after IRIS resets it for us, and also handles
106 // events which are supposed to happen at the current instruction count.
107 void maintainStepping();
110 using BpId = uint64_t;
115 std::list<PCEvent *> events;
117 BpInfo(Addr _pc) : pc(_pc), id(iris::IRIS_UINT64_MAX) {}
119 bool empty() const { return events.empty(); }
120 bool validId() const { return id != iris::IRIS_UINT64_MAX; }
121 void clearId() { id = iris::IRIS_UINT64_MAX; }
124 using BpInfoPtr = std::unique_ptr<BpInfo>;
125 using BpInfoMap = std::map<Addr, BpInfoPtr>;
126 using BpInfoIt = BpInfoMap::iterator;
130 BpInfoIt getOrAllocBp(Addr pc);
132 void installBp(BpInfoIt it);
133 void uninstallBp(BpInfoIt it);
134 void delBp(BpInfoIt it);
136 virtual iris::MemorySpaceId getBpSpaceId(Addr pc) const = 0;
139 iris::IrisErrorCode instanceRegistryChanged(
140 uint64_t esId, const iris::IrisValueMap &fields, uint64_t time,
141 uint64_t sInstId, bool syncEc, std::string &error_message_out);
142 iris::IrisErrorCode phaseInitLeave(
143 uint64_t esId, const iris::IrisValueMap &fields, uint64_t time,
144 uint64_t sInstId, bool syncEc, std::string &error_message_out);
145 iris::IrisErrorCode simulationTimeEvent(
146 uint64_t esId, const iris::IrisValueMap &fields, uint64_t time,
147 uint64_t sInstId, bool syncEc, std::string &error_message_out);
148 iris::IrisErrorCode breakpointHit(
149 uint64_t esId, const iris::IrisValueMap &fields, uint64_t time,
150 uint64_t sInstId, bool syncEc, std::string &error_message_out);
152 iris::EventStreamId regEventStreamId;
153 iris::EventStreamId initEventStreamId;
154 iris::EventStreamId timeEventStreamId;
155 iris::EventStreamId breakpointEventStreamId;
157 mutable iris::IrisInstance client;
158 iris::IrisCppAdapter &call() const { return client.irisCall(); }
159 iris::IrisCppAdapter &noThrow() const { return client.irisCallNoThrow(); }
161 bool translateAddress(Addr &paddr, iris::MemorySpaceId p_space,
162 Addr vaddr, iris::MemorySpaceId v_space);
165 ThreadContext(::BaseCPU *cpu, int id, System *system,
166 ::BaseTLB *dtb, ::BaseTLB *itb,
167 iris::IrisConnectionInterface *iris_if,
168 const std::string &iris_path);
169 virtual ~ThreadContext();
171 virtual bool translateAddress(Addr &paddr, Addr vaddr) = 0;
173 bool schedule(PCEvent *e) override;
174 bool remove(PCEvent *e) override;
176 void scheduleInstCountEvent(Event *event, Tick count) override;
177 void descheduleInstCountEvent(Event *event) override;
178 Tick getCurrentInstCount() override;
180 ::BaseCPU *getCpuPtr() override { return _cpu; }
181 int cpuId() const override { return _cpu->cpuId(); }
182 uint32_t socketId() const override { return _cpu->socketId(); }
184 int threadId() const override { return _threadId; }
185 void setThreadId(int id) override { _threadId = id; }
187 int contextId() const override { return _contextId; }
188 void setContextId(int id) override { _contextId = id; }
201 getCheckerCpuPtr() override
203 panic("%s not implemented.", __FUNCTION__);
206 getDecoderPtr() override
208 panic("%s not implemented.", __FUNCTION__);
211 System *getSystemPtr() override { return _cpu->system; }
216 panic("%s not implemented.", __FUNCTION__);
220 getKernelStats() override
222 panic("%s not implemented.", __FUNCTION__);
225 PortProxy &getPhysProxy() override { return *physProxy; }
226 PortProxy &getVirtProxy() override { return *virtProxy; }
227 void initMemProxies(::ThreadContext *tc) override;
230 getProcessPtr() override
232 panic("%s not implemented.", __FUNCTION__);
235 setProcessPtr(Process *p) override
237 panic("%s not implemented.", __FUNCTION__);
240 Status status() const override;
241 void setStatus(Status new_status) override;
242 void activate() override { setStatus(Active); }
243 void suspend() override { setStatus(Suspended); }
244 void halt() override { setStatus(Halted); }
247 dumpFuncProfile() override
249 panic("%s not implemented.", __FUNCTION__);
253 takeOverFrom(::ThreadContext *old_context) override
255 panic("%s not implemented.", __FUNCTION__);
258 void regStats(const std::string &name) override {}
261 getQuiesceEvent() override
263 panic("%s not implemented.", __FUNCTION__);
266 // Not necessarily the best location for these...
267 // Having an extra function just to read these is obnoxious
269 readLastActivate() override
271 panic("%s not implemented.", __FUNCTION__);
273 Tick readLastSuspend() override
275 panic("%s not implemented.", __FUNCTION__);
279 profileClear() override
281 panic("%s not implemented.", __FUNCTION__);
284 profileSample() override
286 panic("%s not implemented.", __FUNCTION__);
290 copyArchRegs(::ThreadContext *tc) override
292 panic("%s not implemented.", __FUNCTION__);
296 clearArchRegs() override
298 panic("%s not implemented.", __FUNCTION__);
302 // New accessors for new decoder.
304 RegVal readIntReg(RegIndex reg_idx) const override;
307 readFloatReg(RegIndex reg_idx) const override
309 panic("%s not implemented.", __FUNCTION__);
312 const VecRegContainer &readVecReg(const RegId ®) const override;
314 getWritableVecReg(const RegId ®) override
316 panic("%s not implemented.", __FUNCTION__);
319 /** Vector Register Lane Interfaces. */
321 /** Reads source vector 8bit operand. */
323 readVec8BitLaneReg(const RegId ®) const override
325 panic("%s not implemented.", __FUNCTION__);
328 /** Reads source vector 16bit operand. */
330 readVec16BitLaneReg(const RegId ®) const override
332 panic("%s not implemented.", __FUNCTION__);
335 /** Reads source vector 32bit operand. */
337 readVec32BitLaneReg(const RegId ®) const override
339 panic("%s not implemented.", __FUNCTION__);
342 /** Reads source vector 64bit operand. */
344 readVec64BitLaneReg(const RegId ®) const override
346 panic("%s not implemented.", __FUNCTION__);
349 /** Write a lane of the destination vector register. */
351 setVecLane(const RegId ®, const LaneData<LaneSize::Byte> &val) override
353 panic("%s not implemented.", __FUNCTION__);
356 setVecLane(const RegId ®,
357 const LaneData<LaneSize::TwoByte> &val) override
359 panic("%s not implemented.", __FUNCTION__);
362 setVecLane(const RegId ®,
363 const LaneData<LaneSize::FourByte> &val) override
365 panic("%s not implemented.", __FUNCTION__);
368 setVecLane(const RegId ®,
369 const LaneData<LaneSize::EightByte> &val) override
371 panic("%s not implemented.", __FUNCTION__);
376 readVecElem(const RegId ®) const override
378 panic("%s not implemented.", __FUNCTION__);
381 const VecPredRegContainer &readVecPredReg(const RegId ®) const override;
382 VecPredRegContainer &
383 getWritableVecPredReg(const RegId ®) override
385 panic("%s not implemented.", __FUNCTION__);
389 readCCReg(RegIndex reg_idx) const override
391 return readCCRegFlat(reg_idx);
394 void setIntReg(RegIndex reg_idx, RegVal val) override;
397 setFloatReg(RegIndex reg_idx, RegVal val) override
399 panic("%s not implemented.", __FUNCTION__);
403 setVecReg(const RegId ®, const VecRegContainer &val) override
405 panic("%s not implemented.", __FUNCTION__);
409 setVecElem(const RegId& reg, const VecElem& val) override
411 panic("%s not implemented.", __FUNCTION__);
415 setVecPredReg(const RegId ®,
416 const VecPredRegContainer &val) override
418 panic("%s not implemented.", __FUNCTION__);
422 setCCReg(RegIndex reg_idx, RegVal val) override
424 setCCRegFlat(reg_idx, val);
427 void pcStateNoRecord(const ArmISA::PCState &val) override { pcState(val); }
428 MicroPC microPC() const override { return 0; }
430 ArmISA::PCState pcState() const override;
431 void pcState(const ArmISA::PCState &val) override;
432 Addr instAddr() const override;
433 Addr nextInstAddr() const override;
435 RegVal readMiscRegNoEffect(RegIndex misc_reg) const override;
437 readMiscReg(RegIndex misc_reg) override
439 return readMiscRegNoEffect(misc_reg);
442 void setMiscRegNoEffect(RegIndex misc_reg, const RegVal val) override;
444 setMiscReg(RegIndex misc_reg, const RegVal val) override
446 setMiscRegNoEffect(misc_reg, val);
450 flattenRegId(const RegId& regId) const override
452 panic("%s not implemented.", __FUNCTION__);
455 // Also not necessarily the best location for these two. Hopefully will go
456 // away once we decide upon where st cond failures goes.
458 readStCondFailures() const override
460 panic("%s not implemented.", __FUNCTION__);
464 setStCondFailures(unsigned sc_failures) override
466 panic("%s not implemented.", __FUNCTION__);
469 // Same with st cond failures.
471 readFuncExeInst() const override
473 panic("%s not implemented.", __FUNCTION__);
477 syscall(Fault *fault) override
479 panic("%s not implemented.", __FUNCTION__);
484 * Flat register interfaces
486 * Some architectures have different registers visible in
487 * different modes. Such architectures "flatten" a register (see
488 * flattenRegId()) to map it into the
489 * gem5 register file. This interface provides a flat interface to
490 * the underlying register file, which allows for example
491 * serialization code to access all registers.
494 RegVal readIntRegFlat(RegIndex idx) const override;
495 void setIntRegFlat(RegIndex idx, uint64_t val) override;
498 readFloatRegFlat(RegIndex idx) const override
500 panic("%s not implemented.", __FUNCTION__);
503 setFloatRegFlat(RegIndex idx, RegVal val) override
505 panic("%s not implemented.", __FUNCTION__);
508 const VecRegContainer &readVecRegFlat(RegIndex idx) const override;
510 getWritableVecRegFlat(RegIndex idx) override
512 panic("%s not implemented.", __FUNCTION__);
515 setVecRegFlat(RegIndex idx, const VecRegContainer &val) override
517 panic("%s not implemented.", __FUNCTION__);
521 readVecElemFlat(RegIndex idx, const ElemIndex& elemIdx) const override
523 panic("%s not implemented.", __FUNCTION__);
526 setVecElemFlat(RegIndex idx, const ElemIndex &elemIdx,
527 const VecElem &val) override
529 panic("%s not implemented.", __FUNCTION__);
532 const VecPredRegContainer &readVecPredRegFlat(RegIndex idx) const override;
533 VecPredRegContainer &
534 getWritableVecPredRegFlat(RegIndex idx) override
536 panic("%s not implemented.", __FUNCTION__);
539 setVecPredRegFlat(RegIndex idx, const VecPredRegContainer &val) override
541 panic("%s not implemented.", __FUNCTION__);
544 RegVal readCCRegFlat(RegIndex idx) const override;
545 void setCCRegFlat(RegIndex idx, RegVal val) override;
552 #endif // __ARCH_ARM_FASTMODEL_IRIS_THREAD_CONTEXT_HH__