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