gem5 v24.0.0.0
Loading...
Searching...
No Matches
thread_context.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2020 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright 2019 Google, Inc.
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions are
18 * met: redistributions of source code must retain the above copyright
19 * notice, this list of conditions and the following disclaimer;
20 * redistributions in binary form must reproduce the above copyright
21 * notice, this list of conditions and the following disclaimer in the
22 * documentation and/or other materials provided with the distribution;
23 * neither the name of the copyright holders nor the names of its
24 * contributors may be used to endorse or promote products derived from
25 * this software without specific prior written permission.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 */
39
41
42#include <cstdint>
43#include <cstring>
44#include <utility>
45#include <vector>
46
49#include "arch/arm/regs/vec.hh"
50#include "arch/arm/system.hh"
51#include "arch/arm/utility.hh"
52#include "base/logging.hh"
53#include "iris/detail/IrisCppAdapter.h"
54#include "iris/detail/IrisObjects.h"
57#include "sim/pseudo_inst.hh"
58
59namespace gem5
60{
61
62namespace Iris
63{
64
65void
67{
68 bool enabled = false;
69 call().perInstanceExecution_getState(_instId, enabled);
71
72 suspend();
73
74 call().memory_getMemorySpaces(_instId, memorySpaces);
75 for (const auto &space: memorySpaces) {
76 memorySpaceIds.emplace(
77 Iris::CanonicalMsn(space.canonicalMsn), space.spaceId);
78 }
79 call().memory_getUsefulAddressTranslations(_instId, translations);
80
81 typedef ThreadContext Self;
82 iris::EventSourceInfo evSrcInfo;
83
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");
88 call().eventStream_create(_instId, breakpointEventStreamId,
89 evSrcInfo.evSrcId, client.getInstId());
90
91 for (auto it = bps.begin(); it != bps.end(); it++)
92 installBp(it);
93
94 client.registerEventCallback<Self, &Self::semihostingEvent>(
95 this, "ec_IRIS_SEMIHOSTING_CALL_EXTENSION",
96 "Handle a semihosting call", "Iris::ThreadContext");
97 call().event_getEventSource(_instId, evSrcInfo,
98 "IRIS_SEMIHOSTING_CALL_EXTENSION");
99 call().eventStream_create(_instId, semihostingEventStreamId,
100 evSrcInfo.evSrcId, client.getInstId(),
101 // Set all arguments to their defaults, except syncEc which is
102 // changed to true.
103 nullptr, "", false, 0, nullptr, false, false, true);
104}
105
106iris::ResourceId
108 const ResourceMap &resources, const std::string &name)
109{
110 return resources.at(name).rscId;
111}
112
113void
115 ResourceIds &ids, const ResourceMap &resources,
116 const IdxNameMap &idx_names)
117{
118 for (const auto &idx_name: idx_names) {
119 int idx = idx_name.first;
120 const std::string &name = idx_name.second;
121
122 if (idx >= ids.size())
123 ids.resize(idx + 1, iris::IRIS_UINT64_MAX);
124
125 ids[idx] = extractResourceId(resources, name);
126 }
127}
128
129iris::MemorySpaceId
131{
132 auto it = memorySpaceIds.find(msn);
133 return it == memorySpaceIds.end() ? iris::IRIS_UINT64_MAX : it->second;
134}
135
136void
138{
139 Tick now = 0;
140
141 while (true) {
142 if (comInstEventQueue.empty()) {
143 // Set to 0 to deactivate stepping.
144 call().step_setup(_instId, 0, "instruction");
145 break;
146 }
147
149 if (!now)
150 now = getCurrentInstCount();
151
152 if (next <= now) {
154 // Start over now that comInstEventQueue has likely changed.
155 continue;
156 }
157
158 // Set to the number of instructions still to step through.
159 Tick remaining = next - now;
160 call().step_setup(_instId, remaining, "instruction");
161 break;
162 }
163}
164
167{
168 auto pc_it = bps.find(pc);
169
170 if (pc_it != bps.end())
171 return pc_it;
172
173 auto res = bps.emplace(std::make_pair(pc, new BpInfo(pc)));
174 panic_if(!res.second, "Inserting breakpoint failed.");
175 return res.first;
176}
177
178void
180{
181 Addr pc = it->second->pc;
182 const auto &space_ids = getBpSpaceIds();
183 for (auto sid: space_ids) {
184 BpId id;
185 call().breakpoint_set_code(_instId, id, pc, sid, 0);
186 it->second->ids.push_back(id);
187 }
188}
189
190void
192{
193 for (auto id: it->second->ids)
194 call().breakpoint_delete(_instId, id);
195 it->second->clearIds();
196}
197
198void
200{
201 panic_if(!it->second->empty(),
202 "BP info still had events associated with it.");
203
204 if (it->second->validIds())
205 uninstallBp(it);
206
207 bps.erase(it);
208}
209
210iris::IrisErrorCode
212 uint64_t esId, const iris::IrisValueMap &fields, uint64_t time,
213 uint64_t sInstId, bool syncEc, std::string &error_message_out)
214{
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();
218
219 if (name != "component." + _irisPath)
220 return iris::E_ok;
221
222 if (event == "added")
223 _instId = id;
224 else if (event == "removed")
225 _instId = iris::IRIS_UINT64_MAX;
226 else
227 panic("Unrecognized event type %s", event);
228
229 return iris::E_ok;
230}
231
232iris::IrisErrorCode
234 uint64_t esId, const iris::IrisValueMap &fields, uint64_t time,
235 uint64_t sInstId, bool syncEc, std::string &error_message_out)
236{
238 call().resource_getList(_instId, resources);
239
240 std::map<iris::ResourceId, const iris::ResourceInfo *>
241 idToResource;
242 for (const auto &resource: resources) {
243 idToResource[resource.rscId] = &resource;
244 }
245 ResourceMap resourceMap;
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];
251 name = parent->name + "." + name;
252 parentId = parent->parentRscId;
253 }
254 resourceMap[name] = resource;
255 }
256
257 initFromIrisInstance(resourceMap);
258
259 return iris::E_ok;
260}
261
262iris::IrisErrorCode
264 uint64_t esId, const iris::IrisValueMap &fields, uint64_t time,
265 uint64_t sInstId, bool syncEc, std::string &error_message_out)
266{
267 if (fields.at("RUNNING").getAsBool()) {
268 // If this is just simulation time starting up, don't do anything.
269 return iris::E_ok;
270 }
271
272 // Handle the breakpoint event at simulation is stopped if needed.
273 if (bpAddr.has_value()) {
274 auto it = getOrAllocBp(bpAddr.value());
275
276 std::shared_ptr<BpInfo::EventList> events = it->second->events;
277 auto e_it = events->begin();
278 while (e_it != events->end()) {
279 PCEvent *e = *e_it;
280 // Advance e_it here since e might remove itself from the list.
281 e_it++;
282 e->process(this);
283 }
284
285 bpAddr.reset();
286 }
287
288 // If simulation time has stopped for any reason, IRIS helpfully clears
289 // all stepping counters and we need to set them back. We might also need
290 // to service events based on the current number of executed instructions.
292
293 // Restart simulation time to make sure things progress once we give
294 // control back.
295 call().simulationTime_run(iris::IrisInstIdSimulationEngine);
296
297 return iris::E_ok;
298}
299
300iris::IrisErrorCode
302 uint64_t esId, const iris::IrisValueMap &fields, uint64_t time,
303 uint64_t sInstId, bool syncEc, std::string &error_message_out)
304{
305 // Handle the breakpoint event later when the fastmodel simulation is
306 // stopped.
307 Addr pc = fields.at("PC").getU64();
308 bpAddr = pc;
309 return iris::E_ok;
310}
311
312iris::IrisErrorCode
314 uint64_t esId, const iris::IrisValueMap &fields, uint64_t time,
315 uint64_t sInstId, bool syncEc, std::string &error_message_out)
316{
317 if (ArmSystem::callSemihosting(this, true)) {
318 // Stop execution in case an exit of the sim loop was scheduled. We
319 // don't want to keep executing instructions in the mean time.
320 call().perInstanceExecution_setState(_instId, false);
321
322 // Schedule an event to resume execution right after any exit has
323 // had a chance to happen.
326
327 call().semihosting_return(_instId, readIntReg(0));
328 } else {
329 call().semihosting_notImplemented(_instId);
330 }
331 return iris::E_ok;
332}
333
335 gem5::BaseCPU *cpu, int id, System *system, gem5::BaseMMU *mmu,
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),
340 vecPredRegs(ArmISA::NumVecPredRegs),
341 comInstEventQueue("instruction-based event queue"),
342 client(iris_if, "client." + iris_path)
343{
344 iris::InstanceInfo info;
345 auto ret_code = noThrow().instanceRegistry_getInstanceInfoByName(
346 info, "component." + iris_path);
347 if (ret_code == iris::E_ok) {
348 // The iris instance registry already new about this path.
349 _instId = info.instId;
350 } else {
351 // This path doesn't (yet) exist. Set the ID to something invalid.
352 _instId = iris::IRIS_UINT64_MAX;
353 }
354
355 typedef ThreadContext Self;
356 iris::EventSourceInfo evSrcInfo;
357
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");
363 regEventStreamId = iris::IRIS_UINT64_MAX;
364 static const std::vector<std::string> fields =
365 { "EVENT", "INST_ID", "INST_NAME" };
366 call().eventStream_create(iris::IrisInstIdGlobalInstance, regEventStreamId,
367 evSrcInfo.evSrcId, client.getInstId(), &fields);
368
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");
374 initEventStreamId = iris::IRIS_UINT64_MAX;
375 call().eventStream_create(
376 iris::IrisInstIdSimulationEngine, initEventStreamId,
377 evSrcInfo.evSrcId, client.getInstId());
378
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");
385 timeEventStreamId = iris::IRIS_UINT64_MAX;
386 call().eventStream_create(
387 iris::IrisInstIdSimulationEngine, timeEventStreamId,
388 evSrcInfo.evSrcId, client.getInstId());
389
390 breakpointEventStreamId = iris::IRIS_UINT64_MAX;
391 semihostingEventStreamId = iris::IRIS_UINT64_MAX;
392
393 auto enable_lambda = [this]{
394 call().perInstanceExecution_setState(_instId, true);
395 };
397 enable_lambda, "resume after pseudo inst",
398 false, Event::Sim_Exit_Pri + 1);
399}
400
402{
403 call().eventStream_destroy(
404 iris::IrisInstIdSimulationEngine, initEventStreamId);
405 initEventStreamId = iris::IRIS_UINT64_MAX;
406 client.unregisterEventCallback("ec_IRIS_SIM_PHASE_INIT_LEAVE");
407
408 call().eventStream_destroy(
409 iris::IrisInstIdGlobalInstance, regEventStreamId);
410 regEventStreamId = iris::IRIS_UINT64_MAX;
411 client.unregisterEventCallback("ec_IRIS_INSTANCE_REGISTRY_CHANGED");
412
413 call().eventStream_destroy(
414 iris::IrisInstIdGlobalInstance, timeEventStreamId);
415 timeEventStreamId = iris::IRIS_UINT64_MAX;
416 client.unregisterEventCallback("ec_IRIS_SIMULATION_TIME_EVENT");
417
421}
422
423bool
425{
426 auto it = getOrAllocBp(e->pc());
427 it->second->events->push_back(e);
428
429 if (_instId != iris::IRIS_UINT64_MAX && !it->second->validIds())
430 installBp(it);
431
432 return true;
433}
434
435bool
437{
438 auto it = getOrAllocBp(e->pc());
439 it->second->events->remove(e);
440
441 if (it->second->empty())
442 delBp(it);
443
444 return true;
445}
446
447void
449 iris::MemorySpaceId space, Addr addr, void *p, size_t size)
450{
451 iris::MemoryReadResult r;
452 auto err = call().memory_read(_instId, r, space, addr, 1, size);
453 panic_if(err != iris::E_ok, "readMem failed.");
454 std::memcpy(p, r.data.data(), size);
455}
456
457void
459 iris::MemorySpaceId space, Addr addr, const void *p, size_t size)
460{
461 std::vector<uint64_t> data((size + 7) / 8);
462 std::memcpy(data.data(), p, size);
463 iris::MemoryWriteResult r;
464 auto err = call().memory_write(_instId, r, space, addr, 1, size, data);
465 panic_if(err != iris::E_ok, "writeMem failed.");
466}
467
468bool
469ThreadContext::translateAddress(Addr &paddr, iris::MemorySpaceId p_space,
470 Addr vaddr, iris::MemorySpaceId v_space)
471{
472 iris::MemoryAddressTranslationResult result;
473 auto ret = noThrow().memory_translateAddress(
474 _instId, result, v_space, vaddr, p_space);
475
476 if (ret != iris::E_ok) {
477 // Check if there was a legal translation between these two spaces.
478 // If so, something else went wrong.
479 for (auto &trans: translations)
480 if (trans.inSpaceId == v_space && trans.outSpaceId == p_space)
481 return false;
482
483 panic("No legal translation IRIS address translation found.");
484 }
485
486 if (result.address.empty())
487 return false;
488
489 if (result.address.size() > 1) {
490 warn("Multiple mappings for address %#x.", vaddr);
491 return false;
492 }
493
494 paddr = result.address[0];
495 return true;
496}
497
498void
500{
503 if (count <= now)
504 call().simulationTime_stop(iris::IrisInstIdSimulationEngine);
505 else
507}
508
509void
515
516Tick
518{
519 uint64_t count;
520 auto ret = call().step_getStepCounterValue(_instId, count, "instruction");
521 panic_if(ret != iris::E_ok, "Failed to get instruction count.");
522 return count;
523}
524
525void
527{
528 auto msn = ArmISA::isSecure(this) ?
530 auto id = getMemorySpaceId(msn);
531
532 auto addr = pkt->getAddr();
533 auto size = pkt->getSize();
534 auto data = pkt->getPtr<uint8_t>();
535
536 pkt->makeResponse();
537 if (pkt->isRead())
538 readMem(id, addr, data, size);
539 else
540 writeMem(id, addr, data, size);
541}
542
543void
548
549void
555
558{
559 return _status;
560}
561
562void
564{
567 if (new_status == Active) {
568 if (_status != Active)
569 call().perInstanceExecution_setState(_instId, true);
570 } else {
571 if (_status == Active)
572 call().perInstanceExecution_setState(_instId, false);
573 }
574 _status = new_status;
575}
576
577const PCStateBase &
579{
580 ArmISA::CPSR cpsr = readMiscRegNoEffect(ArmISA::MISCREG_CPSR);
581
582 pc.thumb(cpsr.t);
583 pc.nextThumb(pc.thumb());
584 pc.aarch64(!cpsr.width);
585 pc.nextAArch64(!cpsr.width);
586 pc.illegalExec(false);
587 pc.itstate(ArmISA::itState(cpsr));
588 pc.nextItstate(0);
589
590 iris::ResourceReadResult result;
591 call().resource_read(_instId, result, pcRscId);
592 Addr addr = result.data.at(0);
593 if (cpsr.width && cpsr.t)
594 addr = addr & ~0x1;
595 pc.set(addr);
596
597 return pc;
598}
599void
601{
602 Addr pc = val.instAddr();
603
604 ArmISA::CPSR cpsr = readMiscRegNoEffect(ArmISA::MISCREG_CPSR);
605 if (cpsr.width && cpsr.t)
606 pc = pc | 0x1;
607
608 iris::ResourceWriteResult result;
609 call().resource_write(_instId, result, pcRscId, pc);
610}
611
612iris::ResourceId
614{
615 iris::ResourceId rsc_id = iris::IRIS_UINT64_MAX;
616 if (misc_reg < miscRegIds.size())
617 rsc_id = miscRegIds.at(misc_reg);
618
619 panic_if(rsc_id == iris::IRIS_UINT64_MAX,
620 "Misc reg %s is not supported by fast model.",
621 ArmISA::miscRegClass[misc_reg]);
622 return rsc_id;
623}
624
625RegVal
627{
628 iris::ResourceReadResult result;
629 call().resource_read(_instId, result, getMiscRegRscId(misc_reg));
630 return result.data.at(0);
631}
632
633void
635{
636 iris::ResourceWriteResult result;
637 call().resource_write(_instId, result, getMiscRegRscId(misc_reg), val);
638}
639
640RegVal
642{
643 RegVal val;
644 getReg(reg, &val);
645 return val;
646}
647
648void
653
654void
655ThreadContext::getReg(const RegId &reg, void *val) const
656{
657 const RegIndex idx = reg.index();
658 const bool flat = reg.regClass().isFlat();
659 const RegClassType type = reg.classValue();
660 if (flat) {
661 switch (type) {
662 case IntRegClass:
663 *(RegVal *)val = readIntRegFlat(idx);
664 break;
665 case VecRegClass:
667 break;
668 case VecElemClass:
669 *(RegVal *)val = readVecElemFlat(idx);
670 break;
671 case VecPredRegClass:
673 break;
674 case CCRegClass:
675 *(RegVal *)val = readCCRegFlat(idx);
676 break;
677 case MiscRegClass:
678 panic("MiscRegs should not be read with getReg.");
679 default:
680 panic("Unrecognized register class type %d.", type);
681 }
682 } else {
683 switch (type) {
684 case IntRegClass:
685 *(RegVal *)val = readIntReg(idx);
686 break;
687 case VecRegClass:
689 break;
690 case VecElemClass:
691 *(RegVal *)val = readVecElem(reg);
692 break;
693 case VecPredRegClass:
695 break;
696 case CCRegClass:
697 *(RegVal *)val = readCCReg(idx);
698 break;
699 case MiscRegClass:
700 panic("MiscRegs should not be read with getReg.");
701 default:
702 panic("Unrecognized register class type %d.", type);
703 }
704 }
705}
706
707void
708ThreadContext::setReg(const RegId &reg, const void *val)
709{
710 const RegIndex idx = reg.index();
711 const bool flat = reg.regClass().isFlat();
712 const RegClassType type = reg.classValue();
713 if (flat) {
714 switch (type) {
715 case IntRegClass:
716 setIntRegFlat(idx, *(RegVal *)val);
717 break;
718 case VecRegClass:
720 break;
721 case VecElemClass:
722 setVecElemFlat(idx, *(RegVal *)val);
723 break;
724 case VecPredRegClass:
726 break;
727 case CCRegClass:
728 setCCRegFlat(idx, *(RegVal *)val);
729 break;
730 case MiscRegClass:
731 panic("MiscRegs should not be read with getReg.");
732 default:
733 panic("Unrecognized register class type %d.", type);
734 }
735 } else {
736 switch (type) {
737 case IntRegClass:
738 setIntReg(idx, *(RegVal *)val);
739 break;
740 case VecRegClass:
742 break;
743 case VecElemClass:
744 setVecElem(reg, *(RegVal *)val);
745 break;
746 case VecPredRegClass:
748 break;
749 case CCRegClass:
750 setCCReg(idx, *(RegVal *)val);
751 break;
752 case MiscRegClass:
753 panic("MiscRegs should not be read with getReg.");
754 default:
755 panic("Unrecognized register class type %d.", type);
756 }
757 }
758}
759
760void *
762{
763 const RegIndex idx = reg.index();
764 const bool flat = reg.regClass().isFlat();
765 const RegClassType type = reg.classValue();
766 if (flat) {
767 switch (type) {
768 case VecRegClass:
769 return &getWritableVecRegFlat(idx);
770 case VecPredRegClass:
771 return &getWritableVecPredRegFlat(idx);
772 default:
773 panic("Unrecognized register class type %d.", type);
774 }
775 } else {
776 switch (type) {
777 case VecRegClass:
778 return &getWritableVecReg(reg);
779 case VecPredRegClass:
780 return &getWritableVecPredReg(reg);
781 default:
782 panic("Unrecognized register class type %d.", type);
783 }
784 }
785}
786
787iris::ResourceId
789{
790 ArmISA::CPSR cpsr = readMiscRegNoEffect(ArmISA::MISCREG_CPSR);
791 auto &regIds = cpsr.width ? intReg32Ids : intReg64Ids;
792 iris::ResourceId rsc_id = iris::IRIS_UINT64_MAX;
793 if (int_reg < regIds.size())
794 rsc_id = regIds.at(int_reg);
795
796 panic_if(rsc_id == iris::IRIS_UINT64_MAX,
797 "Int reg %s is not supported by fast model.",
798 ArmISA::intRegClass[int_reg]);
799 return rsc_id;
800}
801
802RegVal
804{
805 iris::ResourceReadResult result;
806 call().resource_read(_instId, result, getIntRegRscId(reg_idx));
807 return result.data.at(0);
808}
809
810void
812{
813 iris::ResourceWriteResult result;
814 call().resource_write(_instId, result, getIntRegRscId(reg_idx), val);
815}
816
817iris::ResourceId
819{
820 iris::ResourceId rsc_id = iris::IRIS_UINT64_MAX;
821 if (int_reg < flattenedIntIds.size())
822 rsc_id = flattenedIntIds.at(int_reg);
823 return rsc_id;
824}
825
826/*
827 * The 64 bit version of registers gives us a pre-flattened view of the reg
828 * file, no matter what mode we're in or if we're currently 32 or 64 bit.
829 */
830RegVal
832{
833 auto rsc_id = getIntRegFlatRscId(idx);
834 if (rsc_id == iris::IRIS_UINT64_MAX)
835 return 0;
836 iris::ResourceReadResult result;
837 call().resource_read(_instId, result, rsc_id);
838 return result.data.at(0);
839}
840
841void
843{
844 auto rsc_id = getIntRegFlatRscId(idx);
845 panic_if(rsc_id == iris::IRIS_UINT64_MAX,
846 "Int reg %s is not supported by fast model.",
848 iris::ResourceWriteResult result;
849 call().resource_write(_instId, result, rsc_id, val);
850}
851
852iris::ResourceId
854{
855 iris::ResourceId rsc_id = iris::IRIS_UINT64_MAX;
856 if (cc_reg < ccRegIds.size())
857 rsc_id = ccRegIds.at(cc_reg);
858 return rsc_id;
859}
860
861RegVal
863{
864 auto rsc_id = getCCRegFlatRscId(idx);
865 if (rsc_id == iris::IRIS_UINT64_MAX)
866 return 0;
867 iris::ResourceReadResult result;
868 call().resource_read(_instId, result, rsc_id);
869 return result.data.at(0);
870}
871
872void
874{
875 auto rsc_id = getCCRegFlatRscId(idx);
876 panic_if(rsc_id == iris::IRIS_UINT64_MAX,
877 "CC reg %s is not supported by fast model.",
878 ArmISA::ccRegClass[idx]);
879 iris::ResourceWriteResult result;
880 call().resource_write(_instId, result, rsc_id, val);
881}
882
883iris::ResourceId
885{
886 iris::ResourceId rsc_id = iris::IRIS_UINT64_MAX;
887 if (vec_reg < vecRegIds.size())
888 rsc_id = vecRegIds.at(vec_reg);
889 return rsc_id;
890}
891
894{
895 const RegIndex idx = reg_id.index();
897 reg.zero();
898
899 // Ignore accesses to registers which aren't architected. gem5 defines a
900 // few extra registers which it uses internally in the implementation of
901 // some instructions.
902 auto rsc_id = getVecRegRscId(reg_id);
903 if (rsc_id == iris::IRIS_UINT64_MAX)
904 return reg;
905
906 iris::ResourceReadResult result;
907 call().resource_read(_instId, result, rsc_id);
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);
911
912 return reg;
913}
914
920
921iris::ResourceId
923{
924 iris::ResourceId rsc_id = iris::IRIS_UINT64_MAX;
925 if (vec_reg < vecPredRegIds.size())
926 rsc_id = vecPredRegIds.at(vec_reg);
927 return rsc_id;
928}
929
932{
933 RegIndex idx = reg_id.index();
934
936 reg.reset();
937
938 auto rsc_id = getVecPredRegRscId(reg_id);
939 if (rsc_id == iris::IRIS_UINT64_MAX)
940 return reg;
941
942 iris::ResourceReadResult result;
943 call().resource_read(_instId, result, rsc_id);
944
945 size_t offset = 0;
946 size_t num_bits = reg.NUM_BITS;
947 uint8_t *bytes = (uint8_t *)result.data.data();
948 while (num_bits > 8) {
949 reg.setBits(offset, 8, *bytes);
950 offset += 8;
951 num_bits -= 8;
952 bytes++;
953 }
954 if (num_bits)
955 reg.setBits(offset, num_bits, *bytes);
956
957 return reg;
958}
959
965
966} // namespace Iris
967} // namespace gem5
const char data[]
static bool callSemihosting(ThreadContext *tc, bool gem5_ops=false)
Make a Semihosting call from either aarch64 or aarch32.
Definition system.cc:191
Tick nextTick() const
Definition eventq.hh:836
virtual void initFromIrisInstance(const ResourceMap &resources)
virtual void setVecPredReg(const RegId &reg, const ArmISA::VecPredRegContainer &val)
void * getWritableReg(const RegId &reg) 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 &reg, const ArmISA::VecRegContainer &val)
std::vector< iris::MemorySupportedAddressTranslationResult > translations
virtual ArmISA::VecRegContainer & getWritableVecReg(const RegId &reg)
virtual RegVal readCCRegFlat(RegIndex idx) const
void installBp(BpInfoIt it)
iris::ResourceId getIntRegFlatRscId(RegIndex int_reg) const
Flat register interfaces.
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 &reg) 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 &reg) 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 &reg) const
iris::ResourceId getCCRegFlatRscId(RegIndex cc_reg) const
RegVal getReg(const RegId &reg) 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 &reg)
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 &reg, 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 &reg, RegVal val) override
iris::IrisInstance client
std::optional< Addr > bpAddr
void setMiscRegNoEffect(RegIndex misc_reg, const RegVal val) override
virtual void process(ThreadContext *tc)=0
Addr instAddr() const
Returns the memory address of the instruction this PC points to.
Definition pcstate.hh:108
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition packet.hh:295
bool isRead() const
Definition packet.hh:593
Addr getAddr() const
Definition packet.hh:807
void makeResponse()
Take a request packet and modify it in place to be suitable for returning as a response to that reque...
Definition packet.hh:1062
T * getPtr()
get a pointer to the data ptr.
Definition packet.hh:1225
unsigned getSize() const
Definition packet.hh:817
Register ID: describe an architectural register with its class and index.
Definition reg_class.hh:94
constexpr RegIndex index() const
Index accessors.
Definition reg_class.hh:151
@ Suspended
Temporarily inactive.
Vector Register Abstraction This generic class is the model in a particularization of MVC,...
Definition vec_reg.hh:126
void zero()
Zero the container.
Definition vec_reg.hh:144
void schedule(Event *event, Tick when, bool global=false)
Schedule the given event on this queue.
Definition eventq.hh:757
void deschedule(Event *event)
Deschedule the specified event.
Definition eventq.hh:790
void deschedule(Event &event)
Definition eventq.hh:1021
void serviceEvents(Tick when)
process all events up to the given timestamp.
Definition eventq.hh:869
bool scheduled() const
Determine if the current event is scheduled.
Definition eventq.hh:458
void schedule(Event &event, Tick when)
Definition eventq.hh:1012
static const Priority Sim_Exit_Pri
If we want to exit on this cycle, it's the very last thing we do.
Definition eventq.hh:237
bool empty() const
Returns true if no events are queued.
Definition eventq.hh:891
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:188
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition logging.hh:214
#define warn(...)
Definition logging.hh:256
Bitfield< 39, 36 > ids
const int NumVecPredRegs
Definition vec.hh:84
bool isSecure(ThreadContext *tc)
Definition utility.cc:74
Bitfield< 6 > err
Bitfield< 23, 0 > offset
Definition types.hh:144
Bitfield< 9 > e
Definition misc_types.hh:65
Bitfield< 33 > id
VecPredReg::Container VecPredRegContainer
Definition vec.hh:71
const int NumVecRegs
Definition vec.hh:83
constexpr RegClass intRegClass
Definition int.hh:173
constexpr RegClass vecPredRegClass
Definition vec.hh:109
constexpr RegClass ccRegClass
Definition cc.hh:87
@ MISCREG_CPSR
Definition misc.hh:67
constexpr RegClass miscRegClass
Definition misc.hh:2937
static uint8_t itState(CPSR psr)
Definition utility.hh:191
constexpr RegClass vecRegClass
Definition vec.hh:101
@ PhysicalMemorySecureMsn
@ PhysicalMemoryNonSecureMsn
Bitfield< 4 > pc
Bitfield< 10, 5 > event
Bitfield< 0 > p
Bitfield< 5, 3 > reg
Definition types.hh:92
Bitfield< 15 > system
Definition misc.hh:1032
Bitfield< 63 > val
Definition misc.hh:804
Bitfield< 3 > addr
Definition types.hh:84
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
uint16_t RegIndex
Definition types.hh:176
uint64_t RegVal
Definition types.hh:173
Tick curTick()
The universal simulation clock.
Definition cur_tick.hh:46
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition types.hh:147
uint64_t Tick
Tick count type.
Definition types.hh:58
RegClassType
Enumerate the classes of registers.
Definition reg_class.hh:60
@ VecPredRegClass
Definition reg_class.hh:67
@ CCRegClass
Condition-code register.
Definition reg_class.hh:69
@ VecRegClass
Vector Register.
Definition reg_class.hh:64
@ IntRegClass
Integer register.
Definition reg_class.hh:61
@ MiscRegClass
Control (misc) register.
Definition reg_class.hh:70
@ VecElemClass
Vector Register Native Elem lane.
Definition reg_class.hh:66
const std::string & name()
Definition trace.cc:48

Generated on Tue Jun 18 2024 16:24:02 for gem5 by doxygen 1.11.0