gem5 v24.0.0.0
Loading...
Searching...
No Matches
system.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2011-2014,2017-2019 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 (c) 2003-2006 The Regents of The University of Michigan
15 * Copyright (c) 2011 Regents of the University of California
16 * All rights reserved.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions are
20 * met: redistributions of source code must retain the above copyright
21 * notice, this list of conditions and the following disclaimer;
22 * redistributions in binary form must reproduce the above copyright
23 * notice, this list of conditions and the following disclaimer in the
24 * documentation and/or other materials provided with the distribution;
25 * neither the name of the copyright holders nor the names of its
26 * contributors may be used to endorse or promote products derived from
27 * this software without specific prior written permission.
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
32 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
33 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
34 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
35 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
36 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
37 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
38 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 */
41
42#include "sim/system.hh"
43
44#include <algorithm>
45
46#include "base/compiler.hh"
47#include "base/cprintf.hh"
49#include "base/loader/symtab.hh"
50#include "base/str.hh"
51#include "base/trace.hh"
52#include "cpu/base.hh"
53#include "cpu/thread_context.hh"
54#include "debug/Loader.hh"
55#include "debug/Quiesce.hh"
56#include "debug/WorkItems.hh"
57#include "mem/abstract_mem.hh"
58#include "mem/physical.hh"
59#include "params/System.hh"
60#include "sim/byteswap.hh"
61#include "sim/debug.hh"
62#include "sim/redirect_path.hh"
64
65namespace gem5
66{
67
69
70void
72{
73 DPRINTFS(Quiesce, context->getCpuPtr(), "activating\n");
75}
76
77std::string
79{
80 assert(context);
81 return csprintf("%s.threads[%d]", context->getSystemPtr()->name(),
82 context->contextId());
83}
84
85void
87{
88 context->suspend();
89 context->getSystemPtr()->workload->recordQuiesce();
90}
91
92void
94{
95 ContextID id = size();
96 tc->setContextId(id);
97
98 auto &t = threads.emplace_back();
99 t.context = tc;
100 // Look up this thread again on resume, in case the threads vector has
101 // been reallocated.
102 t.resumeEvent = new EventFunctionWrapper(
103 [this, id](){ thread(id).resume(); },
104 tc->getSystemPtr()->name());
105}
106
107void
109{
110 auto &t = thread(id);
111 panic_if(!t.context, "Can't replace a context which doesn't exist.");
112 if (t.resumeEvent->scheduled()) {
113 Tick when = t.resumeEvent->when();
114 t.context->getCpuPtr()->deschedule(t.resumeEvent);
115 tc->getCpuPtr()->schedule(t.resumeEvent, when);
116 }
117 t.context = tc;
118}
119
122{
123 for (auto &thread: threads) {
125 return thread.context;
126 }
127 return nullptr;
128}
129
130int
132{
133 int count = 0;
134 for (auto &thread: threads) {
135 auto status = thread.context->status();
138 count++;
139 }
140 }
141 return count;
142}
143
144void
146{
147 auto &t = thread(id);
148 [[maybe_unused]] BaseCPU *cpu = t.context->getCpuPtr();
149 DPRINTFS(Quiesce, cpu, "quiesce()\n");
150 t.quiesce();
151}
152
153void
155{
156 auto &t = thread(id);
157 BaseCPU *cpu = t.context->getCpuPtr();
158
159 DPRINTFS(Quiesce, cpu, "quiesceTick until %u\n", when);
160 t.quiesce();
161
162 cpu->reschedule(t.resumeEvent, when, true);
163}
164
166
168 : SimObject(p), _systemPort("system_port"),
169 multiThread(p.multi_thread),
171 physProxy(_systemPort, p.cache_line_size),
173 physmem(name() + ".physmem", p.memories, p.mmap_using_noreserve,
174 p.shared_backstore, p.auto_unlink_shared_backstore),
175 ShadowRomRanges(p.shadow_rom_ranges.begin(),
176 p.shadow_rom_ranges.end()),
177 memoryMode(p.mem_mode),
178 _cacheLineSize(p.cache_line_size),
179 numWorkIds(p.num_work_ids),
180 thermalModel(p.thermal_model),
181 _m5opRange(p.m5ops_base ?
182 RangeSize(p.m5ops_base, 0x10000) :
183 AddrRange(1, 0)), // Create an empty range if disabled
184 redirectPaths(p.redirect_paths)
185{
186 panic_if(!workload, "No workload set for system %s "
187 "(could use StubWorkload?).", name());
188 workload->setSystem(this);
189
190 // add self to global system list
191 systemList.push_back(this);
192
193 // check if the cache line size is a value known to work
194 if (_cacheLineSize != 16 && _cacheLineSize != 32 &&
195 _cacheLineSize != 64 && _cacheLineSize != 128) {
196 warn_once("Cache line size is neither 16, 32, 64 nor 128 bytes.\n");
197 }
198
199 // Get the generic system requestor IDs
200 [[maybe_unused]] RequestorID tmp_id;
201 tmp_id = getRequestorId(this, "writebacks");
202 assert(tmp_id == Request::wbRequestorId);
203 tmp_id = getRequestorId(this, "functional");
204 assert(tmp_id == Request::funcRequestorId);
205 tmp_id = getRequestorId(this, "interrupt");
206 assert(tmp_id == Request::intRequestorId);
207
208 // increment the number of running systems
210
211 // Set back pointers to the system in all memories
212 for (int x = 0; x < params().memories.size(); x++)
213 params().memories[x]->system(this);
214}
215
217{
218 for (uint32_t j = 0; j < numWorkIds; j++)
219 delete workItemStats[j];
220}
221
222Port &
223System::getPort(const std::string &if_name, PortID idx)
224{
225 // no need to distinguish at the moment (besides checking)
226 return _systemPort;
227}
228
229void
230System::setMemoryMode(enums::MemoryMode mode)
231{
232 assert(drainState() == DrainState::Drained);
234}
235
236void
238{
239 threads.insert(tc);
240
242
243 for (auto *e: liveEvents)
244 tc->schedule(e);
245}
246
247bool
249{
250 bool all = true;
251 liveEvents.push_back(event);
252 for (auto *tc: threads)
253 all = tc->schedule(event) && all;
254 return all;
255}
256
257bool
259{
260 bool all = true;
261 liveEvents.remove(event);
262 for (auto *tc: threads)
263 all = tc->remove(event) && all;
264 return all;
265}
266
267void
269{
270 auto *otc = threads[context_id];
271 threads.replace(tc, context_id);
272
274
275 for (auto *e: liveEvents) {
276 otc->remove(e);
277 tc->schedule(e);
278 }
279}
280
281Addr
283{
284 return physmem.totalSize();
285}
286
287bool
289{
290 return physmem.isMemAddr(addr);
291}
292
293void
295 memory::AbstractMemory *deviceMemory)
296{
297 deviceMemMap[requestor_id].push_back(deviceMemory);
298}
299
300bool
302{
303 if (!deviceMemMap.count(pkt->requestorId())) {
304 return false;
305 }
306
307 return (getDeviceMemory(pkt) != nullptr);
308}
309
312{
313 const RequestorID& rid = pkt->requestorId();
314
315 panic_if(!deviceMemMap.count(rid),
316 "No device memory found for Requestor %d\n", rid);
317
318 for (auto& mem : deviceMemMap.at(rid)) {
319 if (pkt->getAddrRange().isSubset(mem->getAddrRange())) {
320 return mem;
321 }
322 }
323
324 return nullptr;
325}
326
327void
329{
330 for (auto &t: threads.threads) {
331 Tick when = 0;
332 if (t.resumeEvent && t.resumeEvent->scheduled())
333 when = t.resumeEvent->when();
334 ContextID id = t.context->contextId();
335 paramOut(cp, csprintf("quiesceEndTick_%d", id), when);
336 }
337
338 // also serialize the memories in the system
339 physmem.serializeSection(cp, "physmem");
340}
341
342
343void
345{
346 for (auto &t: threads.threads) {
347 Tick when = 0;
348 ContextID id = t.context->contextId();
349 if (!optParamIn(cp, csprintf("quiesceEndTick_%d", id), when) ||
350 !when || !t.resumeEvent) {
351 continue;
352 }
353 t.context->getCpuPtr()->schedule(t.resumeEvent, when);
354 }
355
356 // also unserialize the memories in the system
357 physmem.unserializeSection(cp, "physmem");
358}
359
360void
362{
364
365 for (uint32_t j = 0; j < numWorkIds ; j++) {
367 std::stringstream namestr;
368 ccprintf(namestr, "work_item_type%d", j);
369 workItemStats[j]->init(20)
370 .name(namestr.str())
371 .desc("Run time stat for" + namestr.str())
372 .prereq(*workItemStats[j]);
373 }
374}
375
376void
377System::workItemEnd(uint32_t tid, uint32_t workid)
378{
379 std::pair<uint32_t,uint32_t> p(tid, workid);
380 if (!lastWorkItemStarted.count(p))
381 return;
382
383 Tick samp = curTick() - lastWorkItemStarted[p];
384 DPRINTF(WorkItems, "Work item end: %d\t%d\t%lld\n", tid, workid, samp);
385
386 if (workid >= numWorkIds)
387 fatal("Got workid greater than specified in system configuration\n");
388
389 workItemStats[workid]->sample(samp);
390 lastWorkItemStarted.erase(p);
391}
392
393bool
394System::trapToGdb(GDBSignal signal, ContextID ctx_id) const
395{
396 return workload->trapToGdb(signal, ctx_id);
397}
398
399void
401{
402 std::ios::fmtflags flags(std::cerr.flags());
403
406 for (; i != end; ++i) {
407 System *sys = *i;
408 std::cerr << "System " << sys->name() << ": " << std::hex << sys
409 << std::endl;
410 }
411
412 std::cerr.flags(flags);
413}
414
415void
420
421std::string
422System::stripSystemName(const std::string& requestor_name) const
423{
424 if (startswith(requestor_name, name())) {
425 return requestor_name.substr(name().size() + 1);
426 } else {
427 return requestor_name;
428 }
429}
430
433{
435
436 // number of occurrences of the SimObject pointer
437 // in the requestor list.
438 auto obj_number = 0;
439
440 for (int i = 0; i < requestors.size(); i++) {
441 if (requestors[i].obj == obj) {
442 id = i;
443 obj_number++;
444 }
445 }
446
447 fatal_if(obj_number > 1,
448 "Cannot lookup RequestorID by SimObject pointer: "
449 "More than one requestor is sharing the same SimObject\n");
450
451 return id;
452}
453
455System::lookupRequestorId(const std::string& requestor_name) const
456{
457 std::string name = stripSystemName(requestor_name);
458
459 for (int i = 0; i < requestors.size(); i++) {
460 if (requestors[i].req_name == name) {
461 return i;
462 }
463 }
464
466}
467
469System::getGlobalRequestorId(const std::string& requestor_name)
470{
471 return _getRequestorId(nullptr, requestor_name);
472}
473
475System::getRequestorId(const SimObject* requestor, std::string subrequestor)
476{
477 auto requestor_name = leafRequestorName(requestor, subrequestor);
478 return _getRequestorId(requestor, requestor_name);
479}
480
483 const std::string& requestor_name)
484{
485 std::string name = stripSystemName(requestor_name);
486
487 // CPUs in switch_cpus ask for ids again after switching
488 for (int i = 0; i < requestors.size(); i++) {
489 if (requestors[i].req_name == name) {
490 return i;
491 }
492 }
493
494 // Verify that the statistics haven't been enabled yet
495 // Otherwise objects will have sized their stat buckets and
496 // they will be too small
497
498 if (statistics::enabled()) {
499 fatal("Can't request a requestorId after regStats(). "
500 "You must do so in init().\n");
501 }
502
503 // Generate a new RequestorID incrementally
504 RequestorID requestor_id = requestors.size();
505
506 // Append the new Requestor metadata to the group of system Requestors.
507 requestors.emplace_back(requestor, name, requestor_id);
508
509 return requestors.back().id;
510}
511
512std::string
514 const std::string& subrequestor)
515{
516 if (subrequestor.empty()) {
517 return requestor->name();
518 } else {
519 // Get the full requestor name by appending the subrequestor name to
520 // the root SimObject requestor name
521 return requestor->name() + "." + subrequestor;
522 }
523}
524
525std::string
527{
528 if (requestor_id >= requestors.size())
529 fatal("Invalid requestor_id passed to getRequestorName()\n");
530
531 const auto& requestor_info = requestors[requestor_id];
532 return requestor_info.req_name;
533}
534
535} // namespace gem5
AbstractMemory declaration.
#define DPRINTFS(x, s,...)
Definition trace.hh:217
#define DPRINTF(x,...)
Definition trace.hh:210
The AddrRange class encapsulates an address range, and supports a number of tests to check if two ran...
Definition addr_range.hh:82
virtual std::string name() const
Definition named.hh:47
virtual bool schedule(PCEvent *event)=0
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition packet.hh:295
AddrRange getAddrRange() const
Get address range to which this packet belongs.
Definition packet.cc:243
RequestorID requestorId() const
Definition packet.hh:780
Ports are used to interface objects to each other.
Definition port.hh:62
@ funcRequestorId
This requestor id is used for functional requests that don't come from a particular device.
Definition request.hh:279
@ invldRequestorId
Invalid requestor id for assertion checking only.
Definition request.hh:286
@ wbRequestorId
This requestor id is used for writeback requests by the caches.
Definition request.hh:274
@ intRequestorId
This requestor id is used for message signaled interrupts.
Definition request.hh:281
Abstract superclass for simulation objects.
SimObjectParams Params
const_iterator end() const
Definition system.hh:228
void quiesceTick(ContextID id, Tick when)
Definition system.cc:154
const_iterator begin() const
Definition system.hh:227
void quiesce(ContextID id)
Definition system.cc:145
int size() const
Definition system.hh:210
Thread & thread(ContextID id)
Definition system.hh:133
int numRunning() const
Definition system.cc:131
void insert(ThreadContext *tc)
Definition system.cc:93
std::vector< Thread > threads
Definition system.hh:130
void replace(ThreadContext *tc, ContextID id)
Definition system.cc:108
ThreadContext * findFree()
Definition system.cc:121
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition system.cc:328
RequestorID lookupRequestorId(const SimObject *obj) const
Looks up the RequestorID for a given SimObject returns an invalid RequestorID (invldRequestorId) if n...
Definition system.cc:432
bool remove(PCEvent *event) override
Definition system.cc:258
uint32_t numWorkIds
Definition system.hh:412
RequestorID _getRequestorId(const SimObject *requestor, const std::string &requestor_name)
helper function for getRequestorId
Definition system.cc:482
static int numSystemsRunning
Definition system.hh:594
void registerThreadContext(ThreadContext *tc)
Definition system.cc:237
enums::MemoryMode memoryMode
Definition system.hh:406
std::string leafRequestorName(const SimObject *requestor, const std::string &subrequestor)
Helper function for constructing the full (sub)requestor name by providing the root requestor and the...
Definition system.cc:513
void addDeviceMemory(RequestorID requestorId, memory::AbstractMemory *deviceMemory)
Add a physical memory range for a device.
Definition system.cc:294
Addr memSize() const
Amount of physical memory that exists.
Definition system.cc:282
std::unordered_map< RequestorID, std::vector< memory::AbstractMemory * > > deviceMemMap
Definition system.hh:112
std::string getRequestorName(RequestorID requestor_id)
Get the name of an object for a given request id.
Definition system.cc:526
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition system.cc:344
bool isMemAddr(Addr addr) const
Check if a physical address is within a range of a memory that is part of the global address map.
Definition system.cc:288
RequestorID getRequestorId(const SimObject *requestor, std::string subrequestor={})
Request an id used to create a request object in the system.
Definition system.cc:475
bool schedule(PCEvent *event) override
Definition system.cc:248
SystemPort _systemPort
Definition system.hh:108
bool isDeviceMemAddr(const PacketPtr &pkt) const
Similar to isMemAddr but for devices.
Definition system.cc:301
System(const Params &p)
Definition system.cc:167
std::map< std::pair< uint32_t, uint32_t >, Tick > lastWorkItemStarted
Definition system.hh:584
memory::PhysicalMemory physmem
Definition system.hh:402
static void printSystems()
Definition system.cc:400
std::map< uint32_t, statistics::Histogram * > workItemStats
Definition system.hh:585
std::string stripSystemName(const std::string &requestor_name) const
Strips off the system name from a requestor name.
Definition system.cc:422
void setMemoryMode(enums::MemoryMode mode)
Change the memory mode of the system.
Definition system.cc:230
void workItemEnd(uint32_t tid, uint32_t workid)
Definition system.cc:377
Workload * workload
OS kernel.
Definition system.hh:326
std::vector< RedirectPath * > redirectPaths
Definition system.hh:612
uint64_t init_param
Definition system.hh:319
PortProxy physProxy
Port to physical memory used for writing object files into ram at boot.
Definition system.hh:323
const Addr _cacheLineSize
Definition system.hh:408
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Additional function to return the Port of a memory object.
Definition system.cc:223
const bool multiThread
Definition system.hh:312
ThermalModel * thermalModel
Definition system.hh:421
void regStats() override
Callback to set stat parameters.
Definition system.cc:361
RequestorID getGlobalRequestorId(const std::string &requestor_name)
Registers a GLOBAL RequestorID, which is a RequestorID not related to any particular SimObject; since...
Definition system.cc:469
memory::AbstractMemory * getDeviceMemory(const PacketPtr &pkt) const
Return a pointer to the device memory.
Definition system.cc:311
std::list< PCEvent * > liveEvents
Definition system.hh:107
std::vector< RequestorInfo > requestors
This array is a per-system list of all devices capable of issuing a memory system request and an asso...
Definition system.hh:419
static std::vector< System * > systemList
Definition system.hh:593
bool trapToGdb(GDBSignal signal, ContextID ctx_id) const
Definition system.cc:394
AddrRangeList ShadowRomRanges
Definition system.hh:404
void replaceThreadContext(ThreadContext *tc, ContextID context_id)
Definition system.cc:268
Threads threads
Definition system.hh:310
const AddrRange _m5opRange
Range for memory-mapped m5 pseudo ops.
Definition system.hh:561
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual void activate()=0
Set the status to Active.
virtual System * getSystemPtr()=0
virtual BaseCPU * getCpuPtr()=0
@ Halted
Permanently shut down.
@ Halting
Trying to exit and waiting for an event to completely exit.
virtual Status status() const =0
virtual void setContextId(ContextID id)=0
virtual void replaceThreadContext(ThreadContext *tc)
Definition workload.cc:51
virtual void registerThreadContext(ThreadContext *tc)
Definition workload.cc:38
bool trapToGdb(GDBSignal sig, ContextID ctx_id)
Definition workload.cc:75
virtual void setSystem(System *sys)
Definition workload.hh:88
An abstract memory represents a contiguous block of physical memory, with an associated address range...
bool isMemAddr(Addr addr) const
Check if a physical address is within a range of a memory that is part of the global address map.
Definition physical.cc:273
uint64_t totalSize() const
Get the total physical memory size.
Definition physical.hh:231
A simple histogram stat.
STL pair class.
Definition stl.hh:58
STL vector class.
Definition stl.hh:37
bool isSubset(const AddrRange &r) const
Determine if this range is a subset of another range, i.e.
AddrRange RangeSize(Addr start, Addr size)
DrainState drainState() const
Return the current drain state of an object.
Definition drain.hh:324
@ Drained
Buffers drained, ready for serialization/handover.
void schedule(Event &event, Tick when)
Definition eventq.hh:1012
void reschedule(Event &event, Tick when, bool always=false)
Definition eventq.hh:1030
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition logging.hh:236
#define fatal(...)
This implements a cprintf based fatal() function.
Definition logging.hh:200
#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
bool optParamIn(CheckpointIn &cp, const std::string &name, T &param, bool do_warn=true)
This function is used for restoring optional parameters from the checkpoint.
Definition serialize.hh:357
void serializeSection(CheckpointOut &cp, const char *name) const
Serialize an object into a new section.
Definition serialize.cc:74
void unserializeSection(CheckpointIn &cp, const char *name)
Unserialize an a child object.
Definition serialize.cc:81
const Params & params() const
virtual void regStats()
Callback to set stat parameters.
Definition group.cc:68
uint8_t flags
Definition helpers.cc:87
#define warn_once(...)
Definition logging.hh:260
Bitfield< 4, 0 > mode
Definition misc_types.hh:74
Bitfield< 5 > t
Definition misc_types.hh:71
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 9 > e
Definition misc_types.hh:65
Bitfield< 33 > id
Bitfield< 5, 0 > status
Bitfield< 10, 5 > event
Bitfield< 0 > p
Bitfield< 31, 0 > all
Definition types.hh:76
Bitfield< 3 > x
Definition pagetable.hh:73
Bitfield< 3 > addr
Definition types.hh:84
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
bool startswith(const char *s, const char *prefix)
Return true if 's' starts with the prefix string 'prefix'.
Definition str.hh:230
void printSystems()
Definition system.cc:416
Tick curTick()
The universal simulation clock.
Definition cur_tick.hh:46
std::ostream CheckpointOut
Definition serialize.hh:66
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition types.hh:147
void paramOut(CheckpointOut &cp, const std::string &name, ExtMachInst const &machInst)
Definition types.cc:40
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
Definition types.hh:245
uint64_t Tick
Tick count type.
Definition types.hh:58
uint16_t RequestorID
Definition request.hh:95
int ContextID
Globally unique thread context ID.
Definition types.hh:239
std::string csprintf(const char *format, const Args &...args)
Definition cprintf.hh:161
void ccprintf(cp::Print &print)
Definition cprintf.hh:130
std::string name() const
Definition system.cc:78
ThreadContext * context
Definition system.hh:121
bool_vector8 mem[]
Definition reset_stim.h:43

Generated on Tue Jun 18 2024 16:23:57 for gem5 by doxygen 1.11.0