gem5  v20.0.0.3
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 "arch/remote_gdb.hh"
47 #include "arch/utility.hh"
49 #include "base/loader/symtab.hh"
50 #include "base/str.hh"
51 #include "base/trace.hh"
52 #include "config/use_kvm.hh"
53 #if USE_KVM
54 #include "cpu/kvm/base.hh"
55 #include "cpu/kvm/vm.hh"
56 #endif
57 #include "cpu/base.hh"
58 #include "cpu/thread_context.hh"
59 #include "debug/Loader.hh"
60 #include "debug/WorkItems.hh"
61 #include "mem/abstract_mem.hh"
62 #include "mem/physical.hh"
63 #include "params/System.hh"
64 #include "sim/byteswap.hh"
65 #include "sim/debug.hh"
66 #include "sim/full_system.hh"
67 #include "sim/redirect_path.hh"
68 
73 #if THE_ISA != NULL_ISA
74 #include "kern/kernel_stats.hh"
75 
76 #endif
77 
78 using namespace std;
79 using namespace TheISA;
80 
82 
84 
86  : SimObject(p), _systemPort("system_port", this),
87  multiThread(p->multi_thread),
88  pagePtr(0),
89  init_param(p->init_param),
90  physProxy(_systemPort, p->cache_line_size),
91  workload(p->workload),
92 #if USE_KVM
93  kvmVM(p->kvm_vm),
94 #else
95  kvmVM(nullptr),
96 #endif
97  physmem(name() + ".physmem", p->memories, p->mmap_using_noreserve),
98  memoryMode(p->mem_mode),
99  _cacheLineSize(p->cache_line_size),
100  workItemsBegin(0),
101  workItemsEnd(0),
102  numWorkIds(p->num_work_ids),
103  thermalModel(p->thermal_model),
104  _params(p),
105  _m5opRange(p->m5ops_base ?
106  RangeSize(p->m5ops_base, 0x10000) :
107  AddrRange(1, 0)), // Create an empty range if disabled
108  totalNumInsts(0),
109  redirectPaths(p->redirect_paths)
110 {
111  if (workload)
112  workload->system = this;
113 
114  // add self to global system list
115  systemList.push_back(this);
116 
117 #if USE_KVM
118  if (kvmVM) {
119  kvmVM->setSystem(this);
120  }
121 #endif
122 
123  // check if the cache line size is a value known to work
124  if (!(_cacheLineSize == 16 || _cacheLineSize == 32 ||
125  _cacheLineSize == 64 || _cacheLineSize == 128))
126  warn_once("Cache line size is neither 16, 32, 64 nor 128 bytes.\n");
127 
128  // Get the generic system master IDs
129  MasterID tmp_id M5_VAR_USED;
130  tmp_id = getMasterId(this, "writebacks");
131  assert(tmp_id == Request::wbMasterId);
132  tmp_id = getMasterId(this, "functional");
133  assert(tmp_id == Request::funcMasterId);
134  tmp_id = getMasterId(this, "interrupt");
135  assert(tmp_id == Request::intMasterId);
136 
137  // increment the number of running systems
139 
140  // Set back pointers to the system in all memories
141  for (int x = 0; x < params()->memories.size(); x++)
142  params()->memories[x]->system(this);
143 }
144 
146 {
147  for (uint32_t j = 0; j < numWorkIds; j++)
148  delete workItemStats[j];
149 }
150 
151 void
153 {
154  // check that the system port is connected
155  if (!_systemPort.isConnected())
156  panic("System port on %s is not connected.\n", name());
157 }
158 
159 void
161 {
163 
164  // Now that we're about to start simulation, wait for GDB connections if
165  // requested.
166 #if THE_ISA != NULL_ISA
167  for (auto *tc: threadContexts) {
168  auto *cpu = tc->getCpuPtr();
169  auto id = tc->contextId();
170  if (remoteGDB.size() <= id)
171  continue;
172  auto *rgdb = remoteGDB[id];
173 
174  if (cpu->waitForRemoteGDB()) {
175  inform("%s: Waiting for a remote GDB connection on port %d.\n",
176  cpu->name(), rgdb->port());
177 
178  rgdb->connect();
179  }
180  }
181 #endif
182 }
183 
184 Port &
185 System::getPort(const std::string &if_name, PortID idx)
186 {
187  // no need to distinguish at the moment (besides checking)
188  return _systemPort;
189 }
190 
191 void
192 System::setMemoryMode(Enums::MemoryMode mode)
193 {
194  assert(drainState() == DrainState::Drained);
195  memoryMode = mode;
196 }
197 
199 {
200  if (remoteGDB.size())
201  return remoteGDB[0]->breakpoint();
202  return false;
203 }
204 
205 ContextID
207 {
208  int id = assigned;
209  if (id == InvalidContextID) {
210  // Find an unused context ID for this thread.
211  id = 0;
212  while (id < threadContexts.size() && threadContexts[id])
213  id++;
214  }
215 
216  if (threadContexts.size() <= id)
217  threadContexts.resize(id + 1);
218 
220  "Cannot have two CPUs with the same id (%d)\n", id);
221 
222  threadContexts[id] = tc;
223  for (auto *e: liveEvents)
224  tc->schedule(e);
225 
226 #if THE_ISA != NULL_ISA
227  int port = getRemoteGDBPort();
228  if (port) {
229  RemoteGDB *rgdb = new RemoteGDB(this, tc, port + id);
230  rgdb->listen();
231 
232  if (remoteGDB.size() <= id)
233  remoteGDB.resize(id + 1);
234 
235  remoteGDB[id] = rgdb;
236  }
237 #endif
238 
239  activeCpus.push_back(false);
240 
241  return id;
242 }
243 
246 {
247  for (auto &it : threadContexts) {
248  if (ThreadContext::Halted == it->status())
249  return it;
250  }
251  return nullptr;
252 }
253 
254 bool
256 {
257  bool all = true;
258  liveEvents.push_back(event);
259  for (auto *tc: threadContexts)
260  all = tc->schedule(event) && all;
261  return all;
262 }
263 
264 bool
266 {
267  bool all = true;
268  liveEvents.remove(event);
269  for (auto *tc: threadContexts)
270  all = tc->remove(event) && all;
271  return all;
272 }
273 
274 int
276 {
277  return std::count_if(
278  threadContexts.cbegin(),
279  threadContexts.cend(),
280  [] (ThreadContext* tc) {
281  return ((tc->status() != ThreadContext::Halted) &&
282  (tc->status() != ThreadContext::Halting));
283  }
284  );
285 }
286 
287 void
289 {
290  if (context_id >= threadContexts.size()) {
291  panic("replaceThreadContext: bad id, %d >= %d\n",
292  context_id, threadContexts.size());
293  }
294 
295  for (auto *e: liveEvents) {
296  threadContexts[context_id]->remove(e);
297  tc->schedule(e);
298  }
299  threadContexts[context_id] = tc;
300  if (context_id < remoteGDB.size())
301  remoteGDB[context_id]->replaceThreadContext(tc);
302 }
303 
304 bool
306 {
307 #if USE_KVM
308  if (threadContexts.empty())
309  return false;
310 
311  for (auto tc : threadContexts) {
312  if (dynamic_cast<BaseKvmCPU*>(tc->getCpuPtr()) == nullptr) {
313  return false;
314  }
315  }
316  return true;
317 #else
318  return false;
319 #endif
320 }
321 
322 Addr
324 {
325  Addr return_addr = pagePtr << PageShift;
326  pagePtr += npages;
327 
328  Addr next_return_addr = pagePtr << PageShift;
329 
330  if (_m5opRange.contains(next_return_addr)) {
331  warn("Reached m5ops MMIO region\n");
332  return_addr = 0xffffffff;
333  pagePtr = 0xffffffff >> PageShift;
334  }
335 
336  if ((pagePtr << PageShift) > physmem.totalSize())
337  fatal("Out of memory, please increase size of physical memory.");
338  return return_addr;
339 }
340 
341 Addr
343 {
344  return physmem.totalSize();
345 }
346 
347 Addr
349 {
350  return physmem.totalSize() - (pagePtr << PageShift);
351 }
352 
353 bool
355 {
356  return physmem.isMemAddr(addr);
357 }
358 
359 void
361 {
362  totalNumInsts = 0;
363 }
364 
365 void
367 {
369 
370  // also serialize the memories in the system
371  physmem.serializeSection(cp, "physmem");
372 }
373 
374 
375 void
377 {
379 
380  // also unserialize the memories in the system
381  physmem.unserializeSection(cp, "physmem");
382 }
383 
384 void
386 {
388 
389  for (uint32_t j = 0; j < numWorkIds ; j++) {
391  stringstream namestr;
392  ccprintf(namestr, "work_item_type%d", j);
393  workItemStats[j]->init(20)
394  .name(name() + "." + namestr.str())
395  .desc("Run time stat for" + namestr.str())
396  .prereq(*workItemStats[j]);
397  }
398 }
399 
400 void
401 System::workItemEnd(uint32_t tid, uint32_t workid)
402 {
403  std::pair<uint32_t,uint32_t> p(tid, workid);
404  if (!lastWorkItemStarted.count(p))
405  return;
406 
407  Tick samp = curTick() - lastWorkItemStarted[p];
408  DPRINTF(WorkItems, "Work item end: %d\t%d\t%lld\n", tid, workid, samp);
409 
410  if (workid >= numWorkIds)
411  fatal("Got workid greater than specified in system configuration\n");
412 
413  workItemStats[workid]->sample(samp);
414  lastWorkItemStarted.erase(p);
415 }
416 
417 void
419 {
420  ios::fmtflags flags(cerr.flags());
421 
424  for (; i != end; ++i) {
425  System *sys = *i;
426  cerr << "System " << sys->name() << ": " << hex << sys << endl;
427  }
428 
429  cerr.flags(flags);
430 }
431 
432 void
434 {
436 }
437 
438 std::string
439 System::stripSystemName(const std::string& master_name) const
440 {
441  if (startswith(master_name, name())) {
442  return master_name.substr(name().size());
443  } else {
444  return master_name;
445  }
446 }
447 
448 MasterID
450 {
452 
453  // number of occurrences of the SimObject pointer
454  // in the master list.
455  auto obj_number = 0;
456 
457  for (int i = 0; i < masters.size(); i++) {
458  if (masters[i].obj == obj) {
459  id = i;
460  obj_number++;
461  }
462  }
463 
464  fatal_if(obj_number > 1,
465  "Cannot lookup MasterID by SimObject pointer: "
466  "More than one master is sharing the same SimObject\n");
467 
468  return id;
469 }
470 
471 MasterID
472 System::lookupMasterId(const std::string& master_name) const
473 {
474  std::string name = stripSystemName(master_name);
475 
476  for (int i = 0; i < masters.size(); i++) {
477  if (masters[i].masterName == name) {
478  return i;
479  }
480  }
481 
482  return Request::invldMasterId;
483 }
484 
485 MasterID
486 System::getGlobalMasterId(const std::string& master_name)
487 {
488  return _getMasterId(nullptr, master_name);
489 }
490 
491 MasterID
492 System::getMasterId(const SimObject* master, std::string submaster)
493 {
494  auto master_name = leafMasterName(master, submaster);
495  return _getMasterId(master, master_name);
496 }
497 
498 MasterID
499 System::_getMasterId(const SimObject* master, const std::string& master_name)
500 {
501  std::string name = stripSystemName(master_name);
502 
503  // CPUs in switch_cpus ask for ids again after switching
504  for (int i = 0; i < masters.size(); i++) {
505  if (masters[i].masterName == name) {
506  return i;
507  }
508  }
509 
510  // Verify that the statistics haven't been enabled yet
511  // Otherwise objects will have sized their stat buckets and
512  // they will be too small
513 
514  if (Stats::enabled()) {
515  fatal("Can't request a masterId after regStats(). "
516  "You must do so in init().\n");
517  }
518 
519  // Generate a new MasterID incrementally
520  MasterID master_id = masters.size();
521 
522  // Append the new Master metadata to the group of system Masters.
523  masters.emplace_back(master, name, master_id);
524 
525  return masters.back().masterId;
526 }
527 
528 std::string
529 System::leafMasterName(const SimObject* master, const std::string& submaster)
530 {
531  if (submaster.empty()) {
532  return master->name();
533  } else {
534  // Get the full master name by appending the submaster name to
535  // the root SimObject master name
536  return master->name() + "." + submaster;
537  }
538 }
539 
540 std::string
542 {
543  if (master_id >= masters.size())
544  fatal("Invalid master_id passed to getMasterName()\n");
545 
546  const auto& master_info = masters[master_id];
547  return master_info.masterName;
548 }
549 
550 System *
551 SystemParams::create()
552 {
553  return new System(this);
554 }
bool schedule(PCEvent *event) override
Definition: system.cc:255
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:163
void ccprintf(cp::Print &print)
Definition: cprintf.hh:127
#define DPRINTF(x,...)
Definition: trace.hh:225
AddrRange RangeSize(Addr start, Addr size)
Definition: addr_range.hh:580
Ports are used to interface objects to each other.
Definition: port.hh:56
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:171
const std::string & name()
Definition: trace.cc:50
Bitfield< 7 > i
std::string getMasterName(MasterID master_id)
Get the name of an object for a given request id.
Definition: system.cc:541
Enums::MemoryMode memoryMode
Definition: system.hh:284
ContextID registerThreadContext(ThreadContext *tc, ContextID assigned=InvalidContextID)
Definition: system.cc:206
const Addr PageShift
Definition: isa_traits.hh:55
Trying to exit and waiting for an event to completely exit.
SimObjectParams Params
Definition: sim_object.hh:114
System(Params *p)
Definition: system.cc:85
uint64_t totalSize() const
Get the total physical memory size.
Definition: physical.hh:198
const Params * params() const
Definition: system.hh:456
Addr freeMemSize() const
Amount of physical memory that is still free.
Definition: system.cc:348
bool contains(const Addr &a) const
Determine if the range contains an address.
Definition: addr_range.hh:402
static void printSystems()
Definition: system.cc:418
ip6_addr_t addr
Definition: inet.hh:330
int getRemoteGDBPort()
Definition: debug.cc:119
PhysicalMemory physmem
Definition: system.hh:282
Addr allocPhysPages(int npages)
Allocate npages contiguous unused physical pages.
Definition: system.cc:323
void workItemEnd(uint32_t tid, uint32_t workid)
Definition: system.cc:401
Definition: system.hh:72
Overload hash function for BasicBlockRange type.
Definition: vec_reg.hh:587
bool isConnected() const
Is this port currently connected to a peer?
Definition: port.hh:124
SystemPort _systemPort
Definition: system.hh:98
Definition: cprintf.cc:40
Bitfield< 4, 0 > mode
std::list< PCEvent * > liveEvents
Definition: system.hh:97
ThreadContext is the external interface to all thread state for anything outside of the CPU...
This master id is used for functional requests that don&#39;t come from a particular device.
Definition: request.hh:208
void serializeSection(CheckpointOut &cp, const char *name) const
Serialize an object into a new section.
Definition: serialize.cc:171
STL vector class.
Definition: stl.hh:37
Bitfield< 33 > id
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition: system.cc:152
virtual bool schedule(PCEvent *event)=0
int numRunningContexts()
Return number of running (non-halted) thread contexts in system.
Definition: system.cc:275
Bitfield< 3 > x
Definition: pagetable.hh:69
DrainState drainState() const
Return the current drain state of an object.
Definition: drain.hh:308
void setSystem(System *s)
Initialize system pointer.
Definition: vm.cc:530
AbstractMemory declaration.
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: system.cc:376
The AddrRange class encapsulates an address range, and supports a number of tests to check if two ran...
Definition: addr_range.hh:68
void regStats() override
Callback to set stat parameters.
Definition: system.cc:385
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:770
#define inform(...)
Definition: logging.hh:209
Draining buffers pending serialization/handover.
virtual void startup()
startup() is the final initialization call before simulation.
Definition: sim_object.cc:96
Tick curTick()
The current simulated tick.
Definition: core.hh:44
Addr memSize() const
Amount of physical memory that exists.
Definition: system.cc:342
This master id is used for message signaled interrupts.
Definition: request.hh:210
MasterID getGlobalMasterId(const std::string &master_name)
Registers a GLOBAL MasterID, which is a MasterID not related to any particular SimObject; since no Si...
Definition: system.cc:486
void drainResume() override
Resume execution after a successful drain.
Definition: system.cc:360
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:354
uint64_t Tick
Tick count type.
Definition: types.hh:61
const unsigned int _cacheLineSize
Definition: system.hh:286
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: system.cc:366
MasterID getMasterId(const SimObject *master, std::string submaster=std::string())
Request an id used to create a request object in the system.
Definition: system.cc:492
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:234
const AddrRange _m5opRange
Range for memory-mapped m5 pseudo ops.
Definition: system.hh:450
Addr pagePtr
Definition: system.hh:204
std::vector< ThreadContext * > threadContexts
Definition: system.hh:182
A simple histogram stat.
Definition: statistics.hh:2626
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition: logging.hh:199
ThreadContext * findFreeContext()
Definition: system.cc:245
std::map< uint32_t, Stats::Histogram * > workItemStats
Definition: system.hh:482
Workload * workload
OS kernel.
Definition: system.hh:213
~System()
Definition: system.cc:145
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:140
uint16_t MasterID
Definition: request.hh:84
Bitfield< 10, 5 > event
#define warn_once(...)
Definition: logging.hh:212
std::vector< bool > activeCpus
Definition: system.hh:291
bool enabled()
Definition: statistics.cc:545
bool startswith(const char *s, const char *prefix)
Return true if &#39;s&#39; starts with the prefix string &#39;prefix&#39;.
Definition: str.hh:224
uint32_t numWorkIds
Definition: system.hh:290
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:763
Bitfield< 24 > j
MasterID lookupMasterId(const SimObject *obj) const
Looks up the MasterID for a given SimObject returns an invalid MasterID (invldMasterId) if not found...
Definition: system.cc:449
Bitfield< 9 > e
std::vector< MasterInfo > masters
This array is a per-system list of all devices capable of issuing a memory system request and an asso...
Definition: system.hh:298
virtual const std::string name() const
Definition: sim_object.hh:129
bool validKvmEnvironment() const
Verify gem5 configuration will support KVM emulation.
Definition: system.cc:305
std::ostream CheckpointOut
Definition: serialize.hh:63
bool remove(PCEvent *event) override
Definition: system.cc:265
static int numSystemsRunning
Definition: system.hh:491
Permanently shut down.
MasterID _getMasterId(const SimObject *master, const std::string &master_name)
helper function for getMasterId
Definition: system.cc:499
const ContextID InvalidContextID
Definition: types.hh:230
void replaceThreadContext(ThreadContext *tc, ContextID context_id)
Definition: system.cc:288
std::map< std::pair< uint32_t, uint32_t >, Tick > lastWorkItemStarted
Definition: system.hh:481
std::vector< BaseRemoteGDB * > remoteGDB
Definition: system.hh:437
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
Definition: types.hh:235
std::string stripSystemName(const std::string &master_name) const
Strips off the system name from a master name.
Definition: system.cc:439
#define warn(...)
Definition: logging.hh:208
virtual void regStats()
Callback to set stat parameters.
Definition: group.cc:64
bool breakpoint()
Definition: system.cc:198
This master id is used for writeback requests by the caches.
Definition: request.hh:203
KvmVM *const kvmVM
Definition: system.hh:280
System * system
Definition: workload.hh:47
Bitfield< 0 > p
Abstract superclass for simulation objects.
Definition: sim_object.hh:93
int ContextID
Globally unique thread context ID.
Definition: types.hh:229
Invalid master id for assertion checking only.
Definition: request.hh:215
void startup() override
startup() is the final initialization call before simulation.
Definition: system.cc:160
Counter totalNumInsts
Definition: system.hh:480
Port & getPort(const std::string &if_name, PortID idx=InvalidPortID) override
Additional function to return the Port of a memory object.
Definition: system.cc:185
void unserializeSection(CheckpointIn &cp, const char *name)
Unserialize an a child object.
Definition: serialize.cc:178
std::string leafMasterName(const SimObject *master, const std::string &submaster)
Helper function for constructing the full (sub)master name by providing the root master and the relat...
Definition: system.cc:529
void setMemoryMode(Enums::MemoryMode mode)
Change the memory mode of the system.
Definition: system.cc:192
static std::vector< System * > systemList
Definition: system.hh:490

Generated on Fri Jul 3 2020 15:42:40 for gem5 by doxygen 1.8.13