gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
system.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011-2014 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  * Authors: Steve Reinhardt
42  * Lisa Hsu
43  * Nathan Binkert
44  * Ali Saidi
45  * Rick Strong
46  */
47 
48 #include "sim/system.hh"
49 
50 #include "arch/remote_gdb.hh"
51 #include "arch/utility.hh"
53 #include "base/loader/symtab.hh"
54 #include "base/str.hh"
55 #include "base/trace.hh"
56 #include "config/use_kvm.hh"
57 #if USE_KVM
58 #include "cpu/kvm/vm.hh"
59 #endif
60 #include "cpu/thread_context.hh"
61 #include "debug/Loader.hh"
62 #include "debug/WorkItems.hh"
63 #include "mem/abstract_mem.hh"
64 #include "mem/physical.hh"
65 #include "params/System.hh"
66 #include "sim/byteswap.hh"
67 #include "sim/debug.hh"
68 #include "sim/full_system.hh"
69 
74 #if THE_ISA != NULL_ISA
75 #include "kern/kernel_stats.hh"
76 
77 #endif
78 
79 using namespace std;
80 using namespace TheISA;
81 
83 
85 
87  : MemObject(p), _systemPort("system_port", this),
88  _numContexts(0),
89  multiThread(p->multi_thread),
90  pagePtr(0),
91  init_param(p->init_param),
92  physProxy(_systemPort, p->cache_line_size),
93  kernelSymtab(nullptr),
94  kernel(nullptr),
95  loadAddrMask(p->load_addr_mask),
96  loadAddrOffset(p->load_offset),
97 #if USE_KVM
98  kvmVM(p->kvm_vm),
99 #else
100  kvmVM(nullptr),
101 #endif
102  physmem(name() + ".physmem", p->memories, p->mmap_using_noreserve),
103  memoryMode(p->mem_mode),
104  _cacheLineSize(p->cache_line_size),
105  workItemsBegin(0),
106  workItemsEnd(0),
107  numWorkIds(p->num_work_ids),
108  thermalModel(p->thermal_model),
109  _params(p),
110  totalNumInsts(0),
111  instEventQueue("system instruction-based event queue")
112 {
113  // add self to global system list
114  systemList.push_back(this);
115 
116 #if USE_KVM
117  if (kvmVM) {
118  kvmVM->setSystem(this);
119  }
120 #endif
121 
122  if (FullSystem) {
124  if (!debugSymbolTable)
126  }
127 
128  // check if the cache line size is a value known to work
129  if (!(_cacheLineSize == 16 || _cacheLineSize == 32 ||
130  _cacheLineSize == 64 || _cacheLineSize == 128))
131  warn_once("Cache line size is neither 16, 32, 64 nor 128 bytes.\n");
132 
133  // Get the generic system master IDs
134  MasterID tmp_id M5_VAR_USED;
135  tmp_id = getMasterId("writebacks");
136  assert(tmp_id == Request::wbMasterId);
137  tmp_id = getMasterId("functional");
138  assert(tmp_id == Request::funcMasterId);
139  tmp_id = getMasterId("interrupt");
140  assert(tmp_id == Request::intMasterId);
141 
142  if (FullSystem) {
143  if (params()->kernel == "") {
144  inform("No kernel set for full system simulation. "
145  "Assuming you know what you're doing\n");
146  } else {
147  // Get the kernel code
149  inform("kernel located at: %s", params()->kernel);
150 
151  if (kernel == NULL)
152  fatal("Could not load kernel file %s", params()->kernel);
153 
154  // setup entry points
158 
159  // load symbols
161  fatal("could not load kernel symbols\n");
162 
164  fatal("could not load kernel local symbols\n");
165 
167  fatal("could not load kernel symbols\n");
168 
170  fatal("could not load kernel local symbols\n");
171 
172  // Loading only needs to happen once and after memory system is
173  // connected so it will happen in initState()
174  }
175  }
176 
177  // increment the number of running systems
179 
180  // Set back pointers to the system in all memories
181  for (int x = 0; x < params()->memories.size(); x++)
182  params()->memories[x]->system(this);
183 }
184 
186 {
187  delete kernelSymtab;
188  delete kernel;
189 
190  for (uint32_t j = 0; j < numWorkIds; j++)
191  delete workItemStats[j];
192 }
193 
194 void
196 {
197  // check that the system port is connected
198  if (!_systemPort.isConnected())
199  panic("System port on %s is not connected.\n", name());
200 }
201 
203 System::getMasterPort(const std::string &if_name, PortID idx)
204 {
205  // no need to distinguish at the moment (besides checking)
206  return _systemPort;
207 }
208 
209 void
210 System::setMemoryMode(Enums::MemoryMode mode)
211 {
212  assert(drainState() == DrainState::Drained);
213  memoryMode = mode;
214 }
215 
217 {
218  if (remoteGDB.size())
219  return remoteGDB[0]->breakpoint();
220  return false;
221 }
222 
228 int rgdb_wait = -1;
229 
230 ContextID
232 {
233  int id;
234  if (assigned == InvalidContextID) {
235  for (id = 0; id < threadContexts.size(); id++) {
236  if (!threadContexts[id])
237  break;
238  }
239 
240  if (threadContexts.size() <= id)
241  threadContexts.resize(id + 1);
242  } else {
243  if (threadContexts.size() <= assigned)
244  threadContexts.resize(assigned + 1);
245  id = assigned;
246  }
247 
248  if (threadContexts[id])
249  fatal("Cannot have two CPUs with the same id (%d)\n", id);
250 
251  threadContexts[id] = tc;
252  _numContexts++;
253 
254 #if THE_ISA != NULL_ISA
255  int port = getRemoteGDBPort();
256  if (port) {
257  RemoteGDB *rgdb = new RemoteGDB(this, tc);
258  GDBListener *gdbl = new GDBListener(rgdb, port + id);
259  gdbl->listen();
260 
261  if (rgdb_wait != -1 && rgdb_wait == id)
262  gdbl->accept();
263 
264  if (remoteGDB.size() <= id) {
265  remoteGDB.resize(id + 1);
266  }
267 
268  remoteGDB[id] = rgdb;
269  }
270 #endif
271 
272  activeCpus.push_back(false);
273 
274  return id;
275 }
276 
277 int
279 {
280  int running = 0;
281  for (int i = 0; i < _numContexts; ++i) {
283  ++running;
284  }
285  return running;
286 }
287 
288 void
290 {
291  if (FullSystem) {
292  for (int i = 0; i < threadContexts.size(); i++)
294  // Moved from the constructor to here since it relies on the
295  // address map being resolved in the interconnect
299  if (params()->kernel != "") {
300  if (params()->kernel_addr_check) {
301  // Validate kernel mapping before loading binary
303  loadAddrOffset) &&
304  isMemAddr((kernelEnd & loadAddrMask) +
305  loadAddrOffset))) {
306  fatal("Kernel is mapped to invalid location (not memory). "
307  "kernelStart 0x(%x) - kernelEnd 0x(%x) %#x:%#x\n",
308  kernelStart,
309  kernelEnd, (kernelStart & loadAddrMask) +
311  (kernelEnd & loadAddrMask) + loadAddrOffset);
312  }
313  }
314  // Load program sections into memory
316 
317  DPRINTF(Loader, "Kernel start = %#x\n", kernelStart);
318  DPRINTF(Loader, "Kernel end = %#x\n", kernelEnd);
319  DPRINTF(Loader, "Kernel entry = %#x\n", kernelEntry);
320  DPRINTF(Loader, "Kernel loaded...\n");
321  }
322  }
323 }
324 
325 void
327 {
328  if (context_id >= threadContexts.size()) {
329  panic("replaceThreadContext: bad id, %d >= %d\n",
330  context_id, threadContexts.size());
331  }
332 
333  threadContexts[context_id] = tc;
334  if (context_id < remoteGDB.size())
335  remoteGDB[context_id]->replaceThreadContext(tc);
336 }
337 
338 Addr
340 {
341  Addr return_addr = pagePtr << PageShift;
342  pagePtr += npages;
343 
344  Addr next_return_addr = pagePtr << PageShift;
345 
346  AddrRange m5opRange(0xffff0000, 0xffffffff);
347  if (m5opRange.contains(next_return_addr)) {
348  warn("Reached m5ops MMIO region\n");
349  return_addr = 0xffffffff;
350  pagePtr = 0xffffffff >> PageShift;
351  }
352 
353  if ((pagePtr << PageShift) > physmem.totalSize())
354  fatal("Out of memory, please increase size of physical memory.");
355  return return_addr;
356 }
357 
358 Addr
360 {
361  return physmem.totalSize();
362 }
363 
364 Addr
366 {
367  return physmem.totalSize() - (pagePtr << PageShift);
368 }
369 
370 bool
372 {
373  return physmem.isMemAddr(addr);
374 }
375 
376 void
378 {
379  totalNumInsts = 0;
380 }
381 
382 void
384 {
385  if (FullSystem)
386  kernelSymtab->serialize("kernel_symtab", cp);
388  serializeSymtab(cp);
389 
390  // also serialize the memories in the system
391  physmem.serializeSection(cp, "physmem");
392 }
393 
394 
395 void
397 {
398  if (FullSystem)
399  kernelSymtab->unserialize("kernel_symtab", cp);
401  unserializeSymtab(cp);
402 
403  // also unserialize the memories in the system
404  physmem.unserializeSection(cp, "physmem");
405 }
406 
407 void
409 {
411 
412  for (uint32_t j = 0; j < numWorkIds ; j++) {
414  stringstream namestr;
415  ccprintf(namestr, "work_item_type%d", j);
416  workItemStats[j]->init(20)
417  .name(name() + "." + namestr.str())
418  .desc("Run time stat for" + namestr.str())
419  .prereq(*workItemStats[j]);
420  }
421 }
422 
423 void
424 System::workItemEnd(uint32_t tid, uint32_t workid)
425 {
426  std::pair<uint32_t,uint32_t> p(tid, workid);
427  if (!lastWorkItemStarted.count(p))
428  return;
429 
430  Tick samp = curTick() - lastWorkItemStarted[p];
431  DPRINTF(WorkItems, "Work item end: %d\t%d\t%lld\n", tid, workid, samp);
432 
433  if (workid >= numWorkIds)
434  fatal("Got workid greater than specified in system configuration\n");
435 
436  workItemStats[workid]->sample(samp);
437  lastWorkItemStarted.erase(p);
438 }
439 
440 void
442 {
443  ios::fmtflags flags(cerr.flags());
444 
447  for (; i != end; ++i) {
448  System *sys = *i;
449  cerr << "System " << sys->name() << ": " << hex << sys << endl;
450  }
451 
452  cerr.flags(flags);
453 }
454 
455 void
457 {
459 }
460 
461 MasterID
462 System::getMasterId(std::string master_name)
463 {
464  // strip off system name if the string starts with it
465  if (startswith(master_name, name()))
466  master_name = master_name.erase(0, name().size() + 1);
467 
468  // CPUs in switch_cpus ask for ids again after switching
469  for (int i = 0; i < masterIds.size(); i++) {
470  if (masterIds[i] == master_name) {
471  return i;
472  }
473  }
474 
475  // Verify that the statistics haven't been enabled yet
476  // Otherwise objects will have sized their stat buckets and
477  // they will be too small
478 
479  if (Stats::enabled()) {
480  fatal("Can't request a masterId after regStats(). "
481  "You must do so in init().\n");
482  }
483 
484  masterIds.push_back(master_name);
485 
486  return masterIds.size() - 1;
487 }
488 
489 std::string
491 {
492  if (master_id >= masterIds.size())
493  fatal("Invalid master_id passed to getMasterName()\n");
494 
495  return masterIds[master_id];
496 }
497 
498 System *
499 SystemParams::create()
500 {
501  return new System(this);
502 }
void ccprintf(cp::Print &print)
Definition: cprintf.hh:130
#define DPRINTF(x,...)
Definition: trace.hh:212
This master id is used for functional requests that don't come from a particular device.
Definition: request.hh:201
void listen()
Definition: remote_gdb.cc:208
virtual void unserializeSymtab(CheckpointIn &cp)
If needed, unserialize additional symbol table entries for a specific subclass of this system...
Definition: system.hh:584
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:371
const std::string & name()
Definition: trace.cc:49
Bitfield< 7 > i
Definition: miscregs.hh:1378
std::string getMasterName(MasterID master_id)
Get the name of an object for a given request id.
Definition: system.cc:490
Enums::MemoryMode memoryMode
Definition: system.hh:309
ContextID registerThreadContext(ThreadContext *tc, ContextID assigned=InvalidContextID)
Definition: system.cc:231
#define panic(...)
Definition: misc.hh:153
virtual bool loadGlobalSymbols(SymbolTable *symtab, Addr base=0, Addr offset=0, Addr mask=maxAddr)=0
System(Params *p)
Definition: system.cc:86
else
Definition: isa.cc:236
void unserializeSection(CheckpointIn &cp, const char *name)
Unserialize an a child object.
Definition: serialize.cc:585
const Addr PageShift
Definition: isa_traits.hh:51
int _numContexts
Definition: system.hh:200
const Params * params() const
Definition: system.hh:503
static void printSystems()
Definition: system.cc:441
ip6_addr_t addr
Definition: inet.hh:335
uint64_t totalSize() const
Get the total physical memory size.
Definition: physical.hh:204
int getRemoteGDBPort()
Definition: debug.cc:129
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition: root.cc:146
PhysicalMemory physmem
Definition: system.hh:307
Addr freeMemSize() const
Amount of physical memory that is still free.
Definition: system.cc:365
Addr allocPhysPages(int npages)
Allocate npages contiguous unused physical pages.
Definition: system.cc:339
#define warn_once(...)
Definition: misc.hh:226
void workItemEnd(uint32_t tid, uint32_t workid)
Definition: system.cc:424
SymbolTable * debugSymbolTable
Global unified debugging symbol table (for target).
Definition: symtab.cc:45
Definition: system.hh:83
bool contains(const Addr &a) const
Determine if the range contains an address.
Definition: addr_range.hh:328
SystemPort _systemPort
Definition: system.hh:108
virtual bool loadLocalSymbols(SymbolTable *symtab, Addr base=0, Addr offset=0, Addr mask=maxAddr)=0
Bitfield< 4, 0 > mode
Definition: miscregs.hh:1385
This master id is used for writeback requests by the caches.
Definition: request.hh:196
void printSystems()
Definition: system.cc:456
ThreadContext is the external interface to all thread state for anything outside of the CPU...
void init() override
After all objects have been created and all ports are connected, check that the system port is connec...
Definition: system.cc:195
int numRunningContexts()
Return number of running (non-halted) thread contexts in system.
Definition: system.cc:278
void setSystem(System *s)
Initialize system pointer.
Definition: vm.cc:532
#define warn(...)
Definition: misc.hh:219
Bitfield< 5, 0 > status
Definition: miscregs.hh:1604
AbstractMemory declaration.
Addr kernelStart
Beginning of kernel code.
Definition: system.hh:233
void startupCPU(ThreadContext *tc, int cpuId)
Definition: utility.hh:70
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: system.cc:396
BaseMasterPort & getMasterPort(const std::string &if_name, PortID idx=InvalidPortID) override
Additional function to return the Port of a memory object.
Definition: system.cc:203
PortProxy physProxy
Port to physical memory used for writing object files into ram at boot.
Definition: system.hh:224
The AddrRange class encapsulates an address range, and supports a number of tests to check if two ran...
Definition: addr_range.hh:72
void regStats() override
Register statistics for this object.
Definition: system.cc:408
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:145
void initState() override
initState() is called on each SimObject when not restoring from a checkpoint.
Definition: system.cc:289
Tick curTick()
The current simulated tick.
Definition: core.hh:47
void serialize(const std::string &base, CheckpointOut &cp) const
Definition: symtab.cc:113
Addr textBase() const
Definition: object_file.hh:138
Addr loadAddrMask
Mask that should be anded for binary/symbol loading.
Definition: system.hh:247
void drainResume() override
Resume execution after a successful drain.
Definition: system.cc:377
uint64_t Tick
Tick count type.
Definition: types.hh:63
const unsigned int _cacheLineSize
Definition: system.hh:311
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: system.cc:383
void serializeSection(CheckpointOut &cp, const char *name) const
Serialize an object into a new section.
Definition: serialize.cc:578
Addr pagePtr
Definition: system.hh:218
std::vector< ThreadContext * > threadContexts
Definition: system.hh:199
#define fatal(...)
Definition: misc.hh:163
A simple histogram stat.
Definition: statistics.hh:2551
Addr kernelEntry
Entry point in the kernel to start at.
Definition: system.hh:239
MemObjectParams Params
Definition: mem_object.hh:63
std::map< uint32_t, Stats::Histogram * > workItemStats
Definition: system.hh:542
Addr entryPoint() const
Definition: object_file.hh:134
Addr bssBase() const
Definition: object_file.hh:140
~System()
Definition: system.cc:185
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
uint16_t MasterID
Definition: request.hh:85
Draining buffers pending serialization/handover.
virtual bool loadSections(PortProxy &mem_proxy, Addr mask=maxAddr, Addr offset=0)
Definition: object_file.cc:93
std::vector< bool > activeCpus
Definition: system.hh:316
bool enabled()
Definition: statistics.cc:502
SymbolTable * kernelSymtab
kernel symbol table
Definition: system.hh:227
bool startswith(const char *s, const char *prefix)
Return true if 's' starts with the prefix string 'prefix'.
Definition: str.hh:205
uint32_t numWorkIds
Definition: system.hh:315
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:143
Bitfield< 24 > j
Definition: miscregs.hh:1369
static const int NumArgumentRegs M5_VAR_USED
Definition: process.cc:83
Addr memSize() const
Amount of physical memory that exists.
Definition: system.cc:359
ObjectFile * kernel
Object pointer for the kernel code.
Definition: system.hh:230
void accept()
Definition: remote_gdb.cc:238
bool isConnected() const
Definition: port.cc:84
int size()
Definition: pagetable.hh:146
virtual const std::string name() const
Definition: sim_object.hh:117
std::vector< std::string > masterIds
This array is a per-system list of all devices capable of issuing a memory system request and an asso...
Definition: system.hh:323
virtual void serializeSymtab(CheckpointOut &os) const
If needed, serialize additional symbol table entries for a specific subclass of this system...
Definition: system.hh:575
std::ostream CheckpointOut
Definition: serialize.hh:67
static int numSystemsRunning
Definition: system.hh:551
Permanently shut down.
ObjectFile * createObjectFile(const string &fname, bool raw)
Definition: object_file.cc:157
The MemObject class extends the ClockedObject with accessor functions to get its master and slave por...
Definition: mem_object.hh:60
A BaseMasterPort is a protocol-agnostic master port, responsible only for the structural connection t...
Definition: port.hh:115
size_t bssSize() const
Definition: object_file.hh:144
const ContextID InvalidContextID
Definition: types.hh:176
void replaceThreadContext(ThreadContext *tc, ContextID context_id)
Definition: system.cc:326
MasterID getMasterId(std::string req_name)
Request an id used to create a request object in the system.
Definition: system.cc:462
void unserialize(const std::string &base, CheckpointIn &cp)
Definition: symtab.cc:127
DrainState drainState() const
Return the current drain state of an object.
Definition: drain.hh:282
std::map< std::pair< uint32_t, uint32_t >, Tick > lastWorkItemStarted
Definition: system.hh:541
std::vector< BaseRemoteGDB * > remoteGDB
Definition: system.hh:487
int16_t PortID
Port index/ID type, and a symbolic name for an invalid port id.
Definition: types.hh:181
bool breakpoint()
Definition: system.cc:216
Addr loadAddrOffset
Offset that should be used for binary/symbol loading.
Definition: system.hh:254
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:237
Bitfield< 11 > id
Definition: miscregs.hh:124
KvmVM *const kvmVM
Definition: system.hh:305
#define inform(...)
Definition: misc.hh:221
Bitfield< 0 > p
int rgdb_wait
Setting rgdb_wait to a positive integer waits for a remote debugger to connect to that context ID bef...
Definition: system.cc:228
Bitfield< 1 > x
Definition: types.hh:105
void regStats() override
Register statistics for this object.
int ContextID
Globally unique thread context ID.
Definition: types.hh:175
if(it_gpu==gpuTypeMap.end())
Definition: gpu_nomali.cc:75
Addr kernelEnd
End of kernel code.
Definition: system.hh:236
Counter totalNumInsts
Definition: system.hh:539
This master id is used for message signaled interrupts.
Definition: request.hh:203
void setMemoryMode(Enums::MemoryMode mode)
Change the memory mode of the system.
Definition: system.cc:210
static std::vector< System * > systemList
Definition: system.hh:550

Generated on Fri Jun 9 2017 13:03:34 for gem5 by doxygen 1.8.6