84d1f79fde87c8b1dbb5d196cd5bc22af083a39a
[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 * Authors: Gabe Black
28 */
29
30 #ifndef __ARCH_ARM_FASTMODEL_IRIS_THREAD_CONTEXT_HH__
31 #define __ARCH_ARM_FASTMODEL_IRIS_THREAD_CONTEXT_HH__
32
33 #include <list>
34 #include <map>
35 #include <memory>
36
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"
43
44 namespace Iris
45 {
46
47 // This class is the base for ThreadContexts which read and write state using
48 // the Iris API.
49 class ThreadContext : public ::ThreadContext
50 {
51 public:
52 typedef std::map<std::string, iris::ResourceInfo> ResourceMap;
53
54 typedef std::vector<iris::ResourceId> ResourceIds;
55 typedef std::map<int, std::string> IdxNameMap;
56
57 protected:
58 ::BaseCPU *_cpu;
59 int _threadId;
60 ContextID _contextId;
61 System *_system;
62 ::BaseTLB *_dtb;
63 ::BaseTLB *_itb;
64
65 std::string _irisPath;
66 iris::InstanceId _instId = iris::IRIS_UINT64_MAX;
67
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;
72
73 Status _status = Active;
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 BpId id;
115 std::list<PCEvent *> events;
116
117 BpInfo(Addr _pc) : pc(_pc), id(iris::IRIS_UINT64_MAX) {}
118
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; }
122 };
123
124 using BpInfoPtr = std::unique_ptr<BpInfo>;
125 using BpInfoMap = std::map<Addr, BpInfoPtr>;
126 using BpInfoIt = BpInfoMap::iterator;
127
128 BpInfoMap bps;
129
130 BpInfoIt getOrAllocBp(Addr pc);
131
132 void installBp(BpInfoIt it);
133 void uninstallBp(BpInfoIt it);
134 void delBp(BpInfoIt it);
135
136 virtual iris::MemorySpaceId getBpSpaceId(Addr pc) const = 0;
137
138
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);
151
152 iris::EventStreamId regEventStreamId;
153 iris::EventStreamId initEventStreamId;
154 iris::EventStreamId timeEventStreamId;
155 iris::EventStreamId breakpointEventStreamId;
156
157 mutable iris::IrisInstance client;
158 iris::IrisCppAdapter &call() const { return client.irisCall(); }
159 iris::IrisCppAdapter &noThrow() const { return client.irisCallNoThrow(); }
160
161 bool translateAddress(Addr &paddr, iris::MemorySpaceId p_space,
162 Addr vaddr, iris::MemorySpaceId v_space);
163
164 public:
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();
170
171 virtual bool translateAddress(Addr &paddr, Addr vaddr) = 0;
172
173 bool schedule(PCEvent *e) override;
174 bool remove(PCEvent *e) override;
175
176 void scheduleInstCountEvent(Event *event, Tick count) override;
177 void descheduleInstCountEvent(Event *event) override;
178 Tick getCurrentInstCount() override;
179
180 ::BaseCPU *getCpuPtr() override { return _cpu; }
181 int cpuId() const override { return _cpu->cpuId(); }
182 uint32_t socketId() const override { return _cpu->socketId(); }
183
184 int threadId() const override { return _threadId; }
185 void setThreadId(int id) override { _threadId = id; }
186
187 int contextId() const override { return _contextId; }
188 void setContextId(int id) override { _contextId = id; }
189
190 BaseTLB *
191 getITBPtr() override
192 {
193 return _itb;
194 }
195 BaseTLB *
196 getDTBPtr() override
197 {
198 return _dtb;
199 }
200 CheckerCPU *
201 getCheckerCpuPtr() override
202 {
203 panic("%s not implemented.", __FUNCTION__);
204 }
205 ArmISA::Decoder *
206 getDecoderPtr() override
207 {
208 panic("%s not implemented.", __FUNCTION__);
209 }
210
211 System *getSystemPtr() override { return _cpu->system; }
212
213 BaseISA *
214 getIsaPtr() override
215 {
216 panic("%s not implemented.", __FUNCTION__);
217 }
218
219 Kernel::Statistics *
220 getKernelStats() override
221 {
222 panic("%s not implemented.", __FUNCTION__);
223 }
224
225 PortProxy &getPhysProxy() override { return *physProxy; }
226 PortProxy &getVirtProxy() override { return *virtProxy; }
227 void initMemProxies(::ThreadContext *tc) override;
228
229 Process *
230 getProcessPtr() override
231 {
232 panic("%s not implemented.", __FUNCTION__);
233 }
234 void
235 setProcessPtr(Process *p) override
236 {
237 panic("%s not implemented.", __FUNCTION__);
238 }
239
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); }
245
246 void
247 dumpFuncProfile() override
248 {
249 panic("%s not implemented.", __FUNCTION__);
250 }
251
252 void
253 takeOverFrom(::ThreadContext *old_context) override
254 {
255 panic("%s not implemented.", __FUNCTION__);
256 }
257
258 void regStats(const std::string &name) override {}
259
260 EndQuiesceEvent *
261 getQuiesceEvent() override
262 {
263 panic("%s not implemented.", __FUNCTION__);
264 }
265
266 // Not necessarily the best location for these...
267 // Having an extra function just to read these is obnoxious
268 Tick
269 readLastActivate() override
270 {
271 panic("%s not implemented.", __FUNCTION__);
272 }
273 Tick readLastSuspend() override
274 {
275 panic("%s not implemented.", __FUNCTION__);
276 }
277
278 void
279 profileClear() override
280 {
281 panic("%s not implemented.", __FUNCTION__);
282 }
283 void
284 profileSample() override
285 {
286 panic("%s not implemented.", __FUNCTION__);
287 }
288
289 void
290 copyArchRegs(::ThreadContext *tc) override
291 {
292 panic("%s not implemented.", __FUNCTION__);
293 }
294
295 void
296 clearArchRegs() override
297 {
298 panic("%s not implemented.", __FUNCTION__);
299 }
300
301 //
302 // New accessors for new decoder.
303 //
304 RegVal readIntReg(RegIndex reg_idx) const override;
305
306 RegVal
307 readFloatReg(RegIndex reg_idx) const override
308 {
309 panic("%s not implemented.", __FUNCTION__);
310 }
311
312 const VecRegContainer &readVecReg(const RegId &reg) const override;
313 VecRegContainer &
314 getWritableVecReg(const RegId &reg) override
315 {
316 panic("%s not implemented.", __FUNCTION__);
317 }
318
319 /** Vector Register Lane Interfaces. */
320 /** @{ */
321 /** Reads source vector 8bit operand. */
322 ConstVecLane8
323 readVec8BitLaneReg(const RegId &reg) const override
324 {
325 panic("%s not implemented.", __FUNCTION__);
326 }
327
328 /** Reads source vector 16bit operand. */
329 ConstVecLane16
330 readVec16BitLaneReg(const RegId &reg) const override
331 {
332 panic("%s not implemented.", __FUNCTION__);
333 }
334
335 /** Reads source vector 32bit operand. */
336 ConstVecLane32
337 readVec32BitLaneReg(const RegId &reg) const override
338 {
339 panic("%s not implemented.", __FUNCTION__);
340 }
341
342 /** Reads source vector 64bit operand. */
343 ConstVecLane64
344 readVec64BitLaneReg(const RegId &reg) const override
345 {
346 panic("%s not implemented.", __FUNCTION__);
347 }
348
349 /** Write a lane of the destination vector register. */
350 void
351 setVecLane(const RegId &reg, const LaneData<LaneSize::Byte> &val) override
352 {
353 panic("%s not implemented.", __FUNCTION__);
354 }
355 void
356 setVecLane(const RegId &reg,
357 const LaneData<LaneSize::TwoByte> &val) override
358 {
359 panic("%s not implemented.", __FUNCTION__);
360 }
361 void
362 setVecLane(const RegId &reg,
363 const LaneData<LaneSize::FourByte> &val) override
364 {
365 panic("%s not implemented.", __FUNCTION__);
366 }
367 void
368 setVecLane(const RegId &reg,
369 const LaneData<LaneSize::EightByte> &val) override
370 {
371 panic("%s not implemented.", __FUNCTION__);
372 }
373 /** @} */
374
375 const VecElem &
376 readVecElem(const RegId &reg) const override
377 {
378 panic("%s not implemented.", __FUNCTION__);
379 }
380
381 const VecPredRegContainer &readVecPredReg(const RegId &reg) const override;
382 VecPredRegContainer &
383 getWritableVecPredReg(const RegId &reg) override
384 {
385 panic("%s not implemented.", __FUNCTION__);
386 }
387
388 RegVal
389 readCCReg(RegIndex reg_idx) const override
390 {
391 return readCCRegFlat(reg_idx);
392 }
393
394 void setIntReg(RegIndex reg_idx, RegVal val) override;
395
396 void
397 setFloatReg(RegIndex reg_idx, RegVal val) override
398 {
399 panic("%s not implemented.", __FUNCTION__);
400 }
401
402 void
403 setVecReg(const RegId &reg, const VecRegContainer &val) override
404 {
405 panic("%s not implemented.", __FUNCTION__);
406 }
407
408 void
409 setVecElem(const RegId& reg, const VecElem& val) override
410 {
411 panic("%s not implemented.", __FUNCTION__);
412 }
413
414 void
415 setVecPredReg(const RegId &reg,
416 const VecPredRegContainer &val) override
417 {
418 panic("%s not implemented.", __FUNCTION__);
419 }
420
421 void
422 setCCReg(RegIndex reg_idx, RegVal val) override
423 {
424 setCCRegFlat(reg_idx, val);
425 }
426
427 void pcStateNoRecord(const ArmISA::PCState &val) override { pcState(val); }
428 MicroPC microPC() const override { return 0; }
429
430 ArmISA::PCState pcState() const override;
431 void pcState(const ArmISA::PCState &val) override;
432 Addr instAddr() const override;
433 Addr nextInstAddr() const override;
434
435 RegVal readMiscRegNoEffect(RegIndex misc_reg) const override;
436 RegVal
437 readMiscReg(RegIndex misc_reg) override
438 {
439 return readMiscRegNoEffect(misc_reg);
440 }
441
442 void setMiscRegNoEffect(RegIndex misc_reg, const RegVal val) override;
443 void
444 setMiscReg(RegIndex misc_reg, const RegVal val) override
445 {
446 setMiscRegNoEffect(misc_reg, val);
447 }
448
449 RegId
450 flattenRegId(const RegId& regId) const override
451 {
452 panic("%s not implemented.", __FUNCTION__);
453 }
454
455 // Also not necessarily the best location for these two. Hopefully will go
456 // away once we decide upon where st cond failures goes.
457 unsigned
458 readStCondFailures() const override
459 {
460 panic("%s not implemented.", __FUNCTION__);
461 }
462
463 void
464 setStCondFailures(unsigned sc_failures) override
465 {
466 panic("%s not implemented.", __FUNCTION__);
467 }
468
469 // Same with st cond failures.
470 Counter
471 readFuncExeInst() const override
472 {
473 panic("%s not implemented.", __FUNCTION__);
474 }
475
476 void
477 syscall(Fault *fault) override
478 {
479 panic("%s not implemented.", __FUNCTION__);
480 }
481
482 /** @{ */
483 /**
484 * Flat register interfaces
485 *
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.
492 */
493
494 RegVal readIntRegFlat(RegIndex idx) const override;
495 void setIntRegFlat(RegIndex idx, uint64_t val) override;
496
497 RegVal
498 readFloatRegFlat(RegIndex idx) const override
499 {
500 panic("%s not implemented.", __FUNCTION__);
501 }
502 void
503 setFloatRegFlat(RegIndex idx, RegVal val) override
504 {
505 panic("%s not implemented.", __FUNCTION__);
506 }
507
508 const VecRegContainer &readVecRegFlat(RegIndex idx) const override;
509 VecRegContainer &
510 getWritableVecRegFlat(RegIndex idx) override
511 {
512 panic("%s not implemented.", __FUNCTION__);
513 }
514 void
515 setVecRegFlat(RegIndex idx, const VecRegContainer &val) override
516 {
517 panic("%s not implemented.", __FUNCTION__);
518 }
519
520 const VecElem&
521 readVecElemFlat(RegIndex idx, const ElemIndex& elemIdx) const override
522 {
523 panic("%s not implemented.", __FUNCTION__);
524 }
525 void
526 setVecElemFlat(RegIndex idx, const ElemIndex &elemIdx,
527 const VecElem &val) override
528 {
529 panic("%s not implemented.", __FUNCTION__);
530 }
531
532 const VecPredRegContainer &readVecPredRegFlat(RegIndex idx) const override;
533 VecPredRegContainer &
534 getWritableVecPredRegFlat(RegIndex idx) override
535 {
536 panic("%s not implemented.", __FUNCTION__);
537 }
538 void
539 setVecPredRegFlat(RegIndex idx, const VecPredRegContainer &val) override
540 {
541 panic("%s not implemented.", __FUNCTION__);
542 }
543
544 RegVal readCCRegFlat(RegIndex idx) const override;
545 void setCCRegFlat(RegIndex idx, RegVal val) override;
546 /** @} */
547
548 };
549
550 } // namespace Iris
551
552 #endif // __ARCH_ARM_FASTMODEL_IRIS_THREAD_CONTEXT_HH__