gem5 v23.0.0.1
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
511{
514}
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
545{
547}
548
549void
551 const char *data)
552{
554}
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.jazelle(cpsr.j);
585 pc.nextJazelle(cpsr.j);
586 pc.aarch64(!cpsr.width);
587 pc.nextAArch64(!cpsr.width);
588 pc.illegalExec(false);
589 pc.itstate(ArmISA::itState(cpsr));
590 pc.nextItstate(0);
591
592 iris::ResourceReadResult result;
593 call().resource_read(_instId, result, pcRscId);
594 Addr addr = result.data.at(0);
595 if (cpsr.width && cpsr.t)
596 addr = addr & ~0x1;
597 pc.set(addr);
598
599 return pc;
600}
601void
603{
604 Addr pc = val.instAddr();
605
606 ArmISA::CPSR cpsr = readMiscRegNoEffect(ArmISA::MISCREG_CPSR);
607 if (cpsr.width && cpsr.t)
608 pc = pc | 0x1;
609
610 iris::ResourceWriteResult result;
611 call().resource_write(_instId, result, pcRscId, pc);
612}
613
614iris::ResourceId
616{
617 iris::ResourceId rsc_id = iris::IRIS_UINT64_MAX;
618 if (misc_reg < miscRegIds.size())
619 rsc_id = miscRegIds.at(misc_reg);
620
621 panic_if(rsc_id == iris::IRIS_UINT64_MAX,
622 "Misc reg %s is not supported by fast model.",
623 ArmISA::miscRegClass[misc_reg]);
624 return rsc_id;
625}
626
627RegVal
629{
630 iris::ResourceReadResult result;
631 call().resource_read(_instId, result, getMiscRegRscId(misc_reg));
632 return result.data.at(0);
633}
634
635void
637{
638 iris::ResourceWriteResult result;
639 call().resource_write(_instId, result, getMiscRegRscId(misc_reg), val);
640}
641
642RegVal
644{
645 RegVal val;
646 getReg(reg, &val);
647 return val;
648}
649
650void
652{
653 setReg(reg, &val);
654}
655
656void
657ThreadContext::getReg(const RegId &reg, void *val) const
658{
659 const RegIndex idx = reg.index();
660 const bool flat = reg.regClass().isFlat();
661 const RegClassType type = reg.classValue();
662 if (flat) {
663 switch (type) {
664 case IntRegClass:
665 *(RegVal *)val = readIntRegFlat(idx);
666 break;
667 case VecRegClass:
669 break;
670 case VecElemClass:
671 *(RegVal *)val = readVecElemFlat(idx);
672 break;
673 case VecPredRegClass:
675 break;
676 case CCRegClass:
677 *(RegVal *)val = readCCRegFlat(idx);
678 break;
679 case MiscRegClass:
680 panic("MiscRegs should not be read with getReg.");
681 default:
682 panic("Unrecognized register class type %d.", type);
683 }
684 } else {
685 switch (type) {
686 case IntRegClass:
687 *(RegVal *)val = readIntReg(idx);
688 break;
689 case VecRegClass:
691 break;
692 case VecElemClass:
693 *(RegVal *)val = readVecElem(reg);
694 break;
695 case VecPredRegClass:
697 break;
698 case CCRegClass:
699 *(RegVal *)val = readCCReg(idx);
700 break;
701 case MiscRegClass:
702 panic("MiscRegs should not be read with getReg.");
703 default:
704 panic("Unrecognized register class type %d.", type);
705 }
706 }
707}
708
709void
710ThreadContext::setReg(const RegId &reg, const void *val)
711{
712 const RegIndex idx = reg.index();
713 const bool flat = reg.regClass().isFlat();
714 const RegClassType type = reg.classValue();
715 if (flat) {
716 switch (type) {
717 case IntRegClass:
718 setIntRegFlat(idx, *(RegVal *)val);
719 break;
720 case VecRegClass:
722 break;
723 case VecElemClass:
724 setVecElemFlat(idx, *(RegVal *)val);
725 break;
726 case VecPredRegClass:
728 break;
729 case CCRegClass:
730 setCCRegFlat(idx, *(RegVal *)val);
731 break;
732 case MiscRegClass:
733 panic("MiscRegs should not be read with getReg.");
734 default:
735 panic("Unrecognized register class type %d.", type);
736 }
737 } else {
738 switch (type) {
739 case IntRegClass:
740 setIntReg(idx, *(RegVal *)val);
741 break;
742 case VecRegClass:
744 break;
745 case VecElemClass:
746 setVecElem(reg, *(RegVal *)val);
747 break;
748 case VecPredRegClass:
750 break;
751 case CCRegClass:
752 setCCReg(idx, *(RegVal *)val);
753 break;
754 case MiscRegClass:
755 panic("MiscRegs should not be read with getReg.");
756 default:
757 panic("Unrecognized register class type %d.", type);
758 }
759 }
760}
761
762void *
764{
765 const RegIndex idx = reg.index();
766 const bool flat = reg.regClass().isFlat();
767 const RegClassType type = reg.classValue();
768 if (flat) {
769 switch (type) {
770 case VecRegClass:
771 return &getWritableVecRegFlat(idx);
772 case VecPredRegClass:
773 return &getWritableVecPredRegFlat(idx);
774 default:
775 panic("Unrecognized register class type %d.", type);
776 }
777 } else {
778 switch (type) {
779 case VecRegClass:
780 return &getWritableVecReg(reg);
781 case VecPredRegClass:
782 return &getWritableVecPredReg(reg);
783 default:
784 panic("Unrecognized register class type %d.", type);
785 }
786 }
787}
788
789iris::ResourceId
791{
792 ArmISA::CPSR cpsr = readMiscRegNoEffect(ArmISA::MISCREG_CPSR);
793 auto &regIds = cpsr.width ? intReg32Ids : intReg64Ids;
794 iris::ResourceId rsc_id = iris::IRIS_UINT64_MAX;
795 if (int_reg < regIds.size())
796 rsc_id = regIds.at(int_reg);
797
798 panic_if(rsc_id == iris::IRIS_UINT64_MAX,
799 "Int reg %s is not supported by fast model.",
800 ArmISA::intRegClass[int_reg]);
801 return rsc_id;
802}
803
804RegVal
806{
807 iris::ResourceReadResult result;
808 call().resource_read(_instId, result, getIntRegRscId(reg_idx));
809 return result.data.at(0);
810}
811
812void
814{
815 iris::ResourceWriteResult result;
816 call().resource_write(_instId, result, getIntRegRscId(reg_idx), val);
817}
818
819iris::ResourceId
821{
822 iris::ResourceId rsc_id = iris::IRIS_UINT64_MAX;
823 if (int_reg < flattenedIntIds.size())
824 rsc_id = flattenedIntIds.at(int_reg);
825 return rsc_id;
826}
827
828/*
829 * The 64 bit version of registers gives us a pre-flattened view of the reg
830 * file, no matter what mode we're in or if we're currently 32 or 64 bit.
831 */
832RegVal
834{
835 auto rsc_id = getIntRegFlatRscId(idx);
836 if (rsc_id == iris::IRIS_UINT64_MAX)
837 return 0;
838 iris::ResourceReadResult result;
839 call().resource_read(_instId, result, rsc_id);
840 return result.data.at(0);
841}
842
843void
845{
846 auto rsc_id = getIntRegFlatRscId(idx);
847 panic_if(rsc_id == iris::IRIS_UINT64_MAX,
848 "Int reg %s is not supported by fast model.",
850 iris::ResourceWriteResult result;
851 call().resource_write(_instId, result, rsc_id, val);
852}
853
854iris::ResourceId
856{
857 iris::ResourceId rsc_id = iris::IRIS_UINT64_MAX;
858 if (cc_reg < ccRegIds.size())
859 rsc_id = ccRegIds.at(cc_reg);
860 return rsc_id;
861}
862
863RegVal
865{
866 auto rsc_id = getCCRegFlatRscId(idx);
867 if (rsc_id == iris::IRIS_UINT64_MAX)
868 return 0;
869 iris::ResourceReadResult result;
870 call().resource_read(_instId, result, rsc_id);
871 return result.data.at(0);
872}
873
874void
876{
877 auto rsc_id = getCCRegFlatRscId(idx);
878 panic_if(rsc_id == iris::IRIS_UINT64_MAX,
879 "CC reg %s is not supported by fast model.",
880 ArmISA::ccRegClass[idx]);
881 iris::ResourceWriteResult result;
882 call().resource_write(_instId, result, rsc_id, val);
883}
884
885iris::ResourceId
887{
888 iris::ResourceId rsc_id = iris::IRIS_UINT64_MAX;
889 if (vec_reg < vecRegIds.size())
890 rsc_id = vecRegIds.at(vec_reg);
891 return rsc_id;
892}
893
896{
897 const RegIndex idx = reg_id.index();
899 reg.zero();
900
901 // Ignore accesses to registers which aren't architected. gem5 defines a
902 // few extra registers which it uses internally in the implementation of
903 // some instructions.
904 auto rsc_id = getVecRegRscId(reg_id);
905 if (rsc_id == iris::IRIS_UINT64_MAX)
906 return reg;
907
908 iris::ResourceReadResult result;
909 call().resource_read(_instId, result, rsc_id);
910 size_t data_size = result.data.size() * (sizeof(*result.data.data()));
911 size_t size = std::min(data_size, reg.size());
912 memcpy(reg.as<uint8_t>(), (void *)result.data.data(), size);
913
914 return reg;
915}
916
919{
920 return readVecReg(ArmISA::vecRegClass[idx]);
921}
922
923iris::ResourceId
925{
926 iris::ResourceId rsc_id = iris::IRIS_UINT64_MAX;
927 if (vec_reg < vecPredRegIds.size())
928 rsc_id = vecPredRegIds.at(vec_reg);
929 return rsc_id;
930}
931
934{
935 RegIndex idx = reg_id.index();
936
938 reg.reset();
939
940 auto rsc_id = getVecPredRegRscId(reg_id);
941 if (rsc_id == iris::IRIS_UINT64_MAX)
942 return reg;
943
944 iris::ResourceReadResult result;
945 call().resource_read(_instId, result, rsc_id);
946
947 size_t offset = 0;
948 size_t num_bits = reg.NUM_BITS;
949 uint8_t *bytes = (uint8_t *)result.data.data();
950 while (num_bits > 8) {
951 reg.setBits(offset, 8, *bytes);
952 offset += 8;
953 num_bits -= 8;
954 bytes++;
955 }
956 if (num_bits)
957 reg.setBits(offset, num_bits, *bytes);
958
959 return reg;
960}
961
964{
966}
967
968} // namespace Iris
969} // 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
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:93
constexpr RegIndex index() const
Index accessors.
Definition reg_class.hh:150
@ Suspended
Temporarily inactive.
Vector Register Abstraction This generic class is the model in a particularization of MVC,...
Definition vec_reg.hh:124
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
VecPredReg::Container VecPredRegContainer
Definition vec.hh:71
Bitfield< 6 > err
Bitfield< 23, 0 > offset
Definition types.hh:144
Bitfield< 9 > e
Definition misc_types.hh:65
Bitfield< 33 > id
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:66
constexpr RegClass miscRegClass
Definition misc.hh:2810
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:1004
Bitfield< 63 > val
Definition misc.hh:776
Bitfield< 3 > addr
Definition types.hh:84
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
uint16_t RegIndex
Definition types.hh:176
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
uint64_t RegVal
Definition types.hh:173
RegClassType
Enumerate the classes of registers.
Definition reg_class.hh:59
@ VecPredRegClass
Definition reg_class.hh:66
@ CCRegClass
Condition-code register.
Definition reg_class.hh:68
@ VecRegClass
Vector Register.
Definition reg_class.hh:63
@ IntRegClass
Integer register.
Definition reg_class.hh:60
@ MiscRegClass
Control (misc) register.
Definition reg_class.hh:69
@ VecElemClass
Vector Register Native Elem lane.
Definition reg_class.hh:65
const std::string & name()
Definition trace.cc:48

Generated on Mon Jul 10 2023 15:32:01 for gem5 by doxygen 1.9.7