fastmodel: Update the IRIS ThreadContext base class.
[gem5.git] / src / arch / arm / fastmodel / iris / thread_context.hh
1 /*
2 * Copyright 2019 Google, Inc.
3 *
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.
14 *
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.
26 */
27
28 #ifndef __ARCH_ARM_FASTMODEL_IRIS_THREAD_CONTEXT_HH__
29 #define __ARCH_ARM_FASTMODEL_IRIS_THREAD_CONTEXT_HH__
30
31 #include <list>
32 #include <map>
33 #include <memory>
34
35 #include "cpu/base.hh"
36 #include "cpu/thread_context.hh"
37 #include "iris/IrisInstance.h"
38 #include "iris/detail/IrisErrorCode.h"
39 #include "iris/detail/IrisObjects.h"
40 #include "sim/system.hh"
41
42 namespace Iris
43 {
44
45 // This class is the base for ThreadContexts which read and write state using
46 // the Iris API.
47 class ThreadContext : public ::ThreadContext
48 {
49 public:
50 typedef std::map<std::string, iris::ResourceInfo> ResourceMap;
51
52 typedef std::vector<iris::ResourceId> ResourceIds;
53 typedef std::map<int, std::string> IdxNameMap;
54
55 protected:
56 ::BaseCPU *_cpu;
57 int _threadId;
58 ContextID _contextId;
59 System *_system;
60 ::BaseTLB *_dtb;
61 ::BaseTLB *_itb;
62 ::BaseISA *_isa;
63
64 std::string _irisPath;
65 iris::InstanceId _instId = iris::IRIS_UINT64_MAX;
66
67 // Temporary holding places for the vector reg accessors to return.
68 // These are not updated live, only when requested.
69 mutable std::vector<ArmISA::VecRegContainer> vecRegs;
70 mutable std::vector<ArmISA::VecPredRegContainer> vecPredRegs;
71
72 Status _status = Active;
73 Event *enableAfterPseudoEvent;
74
75 virtual void initFromIrisInstance(const ResourceMap &resources);
76
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);
81
82
83 ResourceIds miscRegIds;
84 ResourceIds intReg32Ids;
85 ResourceIds intReg64Ids;
86 ResourceIds flattenedIntIds;
87 ResourceIds ccRegIds;
88
89 iris::ResourceId pcRscId = iris::IRIS_UINT64_MAX;
90 iris::ResourceId icountRscId;
91
92 ResourceIds vecRegIds;
93 ResourceIds vecPredRegIds;
94
95 std::vector<iris::MemorySpaceInfo> memorySpaces;
96 std::vector<iris::MemorySupportedAddressTranslationResult> translations;
97
98 std::unique_ptr<PortProxy> virtProxy = nullptr;
99 std::unique_ptr<PortProxy> physProxy = nullptr;
100
101
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();
108
109
110 using BpId = uint64_t;
111 struct BpInfo
112 {
113 Addr pc;
114 std::vector<BpId> ids;
115 using EventList = std::list<PCEvent *>;
116 std::shared_ptr<EventList> events;
117
118 BpInfo(Addr _pc) : pc(_pc), events(new EventList) {}
119
120 bool empty() const { return events->empty(); }
121 bool validIds() const { return !ids.empty(); }
122 void clearIds() { ids.clear(); }
123 };
124
125 using BpInfoPtr = std::unique_ptr<BpInfo>;
126 using BpInfoMap = std::map<Addr, BpInfoPtr>;
127 using BpInfoIt = BpInfoMap::iterator;
128
129 BpInfoMap bps;
130
131 BpInfoIt getOrAllocBp(Addr pc);
132
133 void installBp(BpInfoIt it);
134 void uninstallBp(BpInfoIt it);
135 void delBp(BpInfoIt it);
136
137 virtual const std::vector<iris::MemorySpaceId> &getBpSpaceIds() const = 0;
138
139
140 iris::IrisErrorCode instanceRegistryChanged(
141 uint64_t esId, const iris::IrisValueMap &fields, uint64_t time,
142 uint64_t sInstId, bool syncEc, std::string &error_message_out);
143 iris::IrisErrorCode phaseInitLeave(
144 uint64_t esId, const iris::IrisValueMap &fields, uint64_t time,
145 uint64_t sInstId, bool syncEc, std::string &error_message_out);
146 iris::IrisErrorCode simulationTimeEvent(
147 uint64_t esId, const iris::IrisValueMap &fields, uint64_t time,
148 uint64_t sInstId, bool syncEc, std::string &error_message_out);
149 iris::IrisErrorCode breakpointHit(
150 uint64_t esId, const iris::IrisValueMap &fields, uint64_t time,
151 uint64_t sInstId, bool syncEc, std::string &error_message_out);
152 iris::IrisErrorCode semihostingEvent(
153 uint64_t esId, const iris::IrisValueMap &fields, uint64_t time,
154 uint64_t sInstId, bool syncEc, std::string &error_message_out);
155
156 iris::EventStreamId regEventStreamId;
157 iris::EventStreamId initEventStreamId;
158 iris::EventStreamId timeEventStreamId;
159 iris::EventStreamId breakpointEventStreamId;
160 iris::EventStreamId semihostingEventStreamId;
161
162 mutable iris::IrisInstance client;
163 iris::IrisCppAdapter &call() const { return client.irisCall(); }
164 iris::IrisCppAdapter &noThrow() const { return client.irisCallNoThrow(); }
165
166 bool translateAddress(Addr &paddr, iris::MemorySpaceId p_space,
167 Addr vaddr, iris::MemorySpaceId v_space);
168
169 public:
170 ThreadContext(::BaseCPU *cpu, int id, System *system,
171 ::BaseTLB *dtb, ::BaseTLB *itb, ::BaseISA *isa,
172 iris::IrisConnectionInterface *iris_if,
173 const std::string &iris_path);
174 virtual ~ThreadContext();
175
176 virtual bool translateAddress(Addr &paddr, Addr vaddr) = 0;
177
178 bool schedule(PCEvent *e) override;
179 bool remove(PCEvent *e) override;
180
181 void scheduleInstCountEvent(Event *event, Tick count) override;
182 void descheduleInstCountEvent(Event *event) override;
183 Tick getCurrentInstCount() override;
184
185 ::BaseCPU *getCpuPtr() override { return _cpu; }
186 int cpuId() const override { return _cpu->cpuId(); }
187 uint32_t socketId() const override { return _cpu->socketId(); }
188
189 int threadId() const override { return _threadId; }
190 void setThreadId(int id) override { _threadId = id; }
191
192 int contextId() const override { return _contextId; }
193 void setContextId(int id) override { _contextId = id; }
194
195 BaseTLB *
196 getITBPtr() override
197 {
198 return _itb;
199 }
200 BaseTLB *
201 getDTBPtr() override
202 {
203 return _dtb;
204 }
205 CheckerCPU *getCheckerCpuPtr() override { return nullptr; }
206 ArmISA::Decoder *
207 getDecoderPtr() override
208 {
209 panic("%s not implemented.", __FUNCTION__);
210 }
211
212 System *getSystemPtr() override { return _cpu->system; }
213
214 BaseISA *
215 getIsaPtr() override
216 {
217 return _isa;
218 }
219
220 PortProxy &getPhysProxy() override { return *physProxy; }
221 PortProxy &getVirtProxy() override { return *virtProxy; }
222 void initMemProxies(::ThreadContext *tc) override;
223
224 Process *
225 getProcessPtr() override
226 {
227 panic("%s not implemented.", __FUNCTION__);
228 }
229 void
230 setProcessPtr(Process *p) override
231 {
232 panic("%s not implemented.", __FUNCTION__);
233 }
234
235 Status status() const override;
236 void setStatus(Status new_status) override;
237 void activate() override { setStatus(Active); }
238 void suspend() override { setStatus(Suspended); }
239 void halt() override { setStatus(Halted); }
240
241 void
242 takeOverFrom(::ThreadContext *old_context) override
243 {
244 panic("%s not implemented.", __FUNCTION__);
245 }
246
247 void regStats(const std::string &name) override {}
248
249 // Not necessarily the best location for these...
250 // Having an extra function just to read these is obnoxious
251 Tick
252 readLastActivate() override
253 {
254 panic("%s not implemented.", __FUNCTION__);
255 }
256 Tick readLastSuspend() override
257 {
258 panic("%s not implemented.", __FUNCTION__);
259 }
260
261 void
262 copyArchRegs(::ThreadContext *tc) override
263 {
264 panic("%s not implemented.", __FUNCTION__);
265 }
266
267 void
268 clearArchRegs() override
269 {
270 warn("Ignoring clearArchRegs()");
271 }
272
273 //
274 // New accessors for new decoder.
275 //
276 RegVal readIntReg(RegIndex reg_idx) const override;
277
278 RegVal
279 readFloatReg(RegIndex reg_idx) const override
280 {
281 panic("%s not implemented.", __FUNCTION__);
282 }
283
284 const VecRegContainer &readVecReg(const RegId &reg) const override;
285 VecRegContainer &
286 getWritableVecReg(const RegId &reg) override
287 {
288 panic("%s not implemented.", __FUNCTION__);
289 }
290
291 /** Vector Register Lane Interfaces. */
292 /** @{ */
293 /** Reads source vector 8bit operand. */
294 ConstVecLane8
295 readVec8BitLaneReg(const RegId &reg) const override
296 {
297 panic("%s not implemented.", __FUNCTION__);
298 }
299
300 /** Reads source vector 16bit operand. */
301 ConstVecLane16
302 readVec16BitLaneReg(const RegId &reg) const override
303 {
304 panic("%s not implemented.", __FUNCTION__);
305 }
306
307 /** Reads source vector 32bit operand. */
308 ConstVecLane32
309 readVec32BitLaneReg(const RegId &reg) const override
310 {
311 panic("%s not implemented.", __FUNCTION__);
312 }
313
314 /** Reads source vector 64bit operand. */
315 ConstVecLane64
316 readVec64BitLaneReg(const RegId &reg) const override
317 {
318 panic("%s not implemented.", __FUNCTION__);
319 }
320
321 /** Write a lane of the destination vector register. */
322 void
323 setVecLane(const RegId &reg, const LaneData<LaneSize::Byte> &val) override
324 {
325 panic("%s not implemented.", __FUNCTION__);
326 }
327 void
328 setVecLane(const RegId &reg,
329 const LaneData<LaneSize::TwoByte> &val) override
330 {
331 panic("%s not implemented.", __FUNCTION__);
332 }
333 void
334 setVecLane(const RegId &reg,
335 const LaneData<LaneSize::FourByte> &val) override
336 {
337 panic("%s not implemented.", __FUNCTION__);
338 }
339 void
340 setVecLane(const RegId &reg,
341 const LaneData<LaneSize::EightByte> &val) override
342 {
343 panic("%s not implemented.", __FUNCTION__);
344 }
345 /** @} */
346
347 const VecElem &
348 readVecElem(const RegId &reg) const override
349 {
350 panic("%s not implemented.", __FUNCTION__);
351 }
352
353 const VecPredRegContainer &readVecPredReg(const RegId &reg) const override;
354 VecPredRegContainer &
355 getWritableVecPredReg(const RegId &reg) override
356 {
357 panic("%s not implemented.", __FUNCTION__);
358 }
359
360 RegVal
361 readCCReg(RegIndex reg_idx) const override
362 {
363 return readCCRegFlat(reg_idx);
364 }
365
366 void setIntReg(RegIndex reg_idx, RegVal val) override;
367
368 void
369 setFloatReg(RegIndex reg_idx, RegVal val) override
370 {
371 panic("%s not implemented.", __FUNCTION__);
372 }
373
374 void
375 setVecReg(const RegId &reg, const VecRegContainer &val) override
376 {
377 panic("%s not implemented.", __FUNCTION__);
378 }
379
380 void
381 setVecElem(const RegId& reg, const VecElem& val) override
382 {
383 panic("%s not implemented.", __FUNCTION__);
384 }
385
386 void
387 setVecPredReg(const RegId &reg,
388 const VecPredRegContainer &val) override
389 {
390 panic("%s not implemented.", __FUNCTION__);
391 }
392
393 void
394 setCCReg(RegIndex reg_idx, RegVal val) override
395 {
396 setCCRegFlat(reg_idx, val);
397 }
398
399 void pcStateNoRecord(const ArmISA::PCState &val) override { pcState(val); }
400 MicroPC microPC() const override { return 0; }
401
402 ArmISA::PCState pcState() const override;
403 void pcState(const ArmISA::PCState &val) override;
404 Addr instAddr() const override;
405 Addr nextInstAddr() const override;
406
407 RegVal readMiscRegNoEffect(RegIndex misc_reg) const override;
408 RegVal
409 readMiscReg(RegIndex misc_reg) override
410 {
411 return readMiscRegNoEffect(misc_reg);
412 }
413
414 void setMiscRegNoEffect(RegIndex misc_reg, const RegVal val) override;
415 void
416 setMiscReg(RegIndex misc_reg, const RegVal val) override
417 {
418 setMiscRegNoEffect(misc_reg, val);
419 }
420
421 RegId
422 flattenRegId(const RegId& regId) const override
423 {
424 panic("%s not implemented.", __FUNCTION__);
425 }
426
427 // Also not necessarily the best location for these two. Hopefully will go
428 // away once we decide upon where st cond failures goes.
429 unsigned
430 readStCondFailures() const override
431 {
432 panic("%s not implemented.", __FUNCTION__);
433 }
434
435 void
436 setStCondFailures(unsigned sc_failures) override
437 {
438 panic("%s not implemented.", __FUNCTION__);
439 }
440
441 // Same with st cond failures.
442 Counter
443 readFuncExeInst() const override
444 {
445 panic("%s not implemented.", __FUNCTION__);
446 }
447
448 /** @{ */
449 /**
450 * Flat register interfaces
451 *
452 * Some architectures have different registers visible in
453 * different modes. Such architectures "flatten" a register (see
454 * flattenRegId()) to map it into the
455 * gem5 register file. This interface provides a flat interface to
456 * the underlying register file, which allows for example
457 * serialization code to access all registers.
458 */
459
460 RegVal readIntRegFlat(RegIndex idx) const override;
461 void setIntRegFlat(RegIndex idx, uint64_t val) override;
462
463 RegVal
464 readFloatRegFlat(RegIndex idx) const override
465 {
466 panic("%s not implemented.", __FUNCTION__);
467 }
468 void
469 setFloatRegFlat(RegIndex idx, RegVal val) override
470 {
471 panic("%s not implemented.", __FUNCTION__);
472 }
473
474 const VecRegContainer &readVecRegFlat(RegIndex idx) const override;
475 VecRegContainer &
476 getWritableVecRegFlat(RegIndex idx) override
477 {
478 panic("%s not implemented.", __FUNCTION__);
479 }
480 void
481 setVecRegFlat(RegIndex idx, const VecRegContainer &val) override
482 {
483 panic("%s not implemented.", __FUNCTION__);
484 }
485
486 const VecElem&
487 readVecElemFlat(RegIndex idx, const ElemIndex& elemIdx) const override
488 {
489 panic("%s not implemented.", __FUNCTION__);
490 }
491 void
492 setVecElemFlat(RegIndex idx, const ElemIndex &elemIdx,
493 const VecElem &val) override
494 {
495 panic("%s not implemented.", __FUNCTION__);
496 }
497
498 const VecPredRegContainer &readVecPredRegFlat(RegIndex idx) const override;
499 VecPredRegContainer &
500 getWritableVecPredRegFlat(RegIndex idx) override
501 {
502 panic("%s not implemented.", __FUNCTION__);
503 }
504 void
505 setVecPredRegFlat(RegIndex idx, const VecPredRegContainer &val) override
506 {
507 panic("%s not implemented.", __FUNCTION__);
508 }
509
510 RegVal readCCRegFlat(RegIndex idx) const override;
511 void setCCRegFlat(RegIndex idx, RegVal val) override;
512 /** @} */
513
514 // hardware transactional memory
515 void
516 htmAbortTransaction(uint64_t htm_uid, HtmFailureFaultCause cause) override
517 {
518 panic("%s not implemented.", __FUNCTION__);
519 }
520
521 BaseHTMCheckpointPtr &
522 getHtmCheckpointPtr() override
523 {
524 panic("%s not implemented.", __FUNCTION__);
525 }
526
527 void
528 setHtmCheckpointPtr(BaseHTMCheckpointPtr cpt) override
529 {
530 panic("%s not implemented.", __FUNCTION__);
531 }
532 };
533
534 } // namespace Iris
535
536 #endif // __ARCH_ARM_FASTMODEL_IRIS_THREAD_CONTEXT_HH__