sim-se: Add default to SyscallDesc constructor
[gem5.git] / src / sim / system.cc
index d0418d99b0d28aa791640a4ca27c62aa3249ac1d..e720db07a4f960a062bd9ed0cbda04af1380d2f1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2014 ARM Limited
+ * Copyright (c) 2011-2014,2017 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
  *          Rick Strong
  */
 
+#include "sim/system.hh"
+
 #include "arch/remote_gdb.hh"
 #include "arch/utility.hh"
 #include "base/loader/object_file.hh"
 #include "base/loader/symtab.hh"
 #include "base/str.hh"
 #include "base/trace.hh"
+#include "config/use_kvm.hh"
+#if USE_KVM
+#include "cpu/kvm/base.hh"
+#include "cpu/kvm/vm.hh"
+#endif
+#include "cpu/base.hh"
 #include "cpu/thread_context.hh"
 #include "debug/Loader.hh"
 #include "debug/WorkItems.hh"
@@ -60,7 +68,6 @@
 #include "sim/byteswap.hh"
 #include "sim/debug.hh"
 #include "sim/full_system.hh"
-#include "sim/system.hh"
 
 /**
  * To avoid linking errors with LTO, only include the header if we
@@ -68,6 +75,7 @@
  */
 #if THE_ISA != NULL_ISA
 #include "kern/kernel_stats.hh"
+
 #endif
 
 using namespace std;
@@ -80,6 +88,7 @@ int System::numSystemsRunning = 0;
 System::System(Params *p)
     : MemObject(p), _systemPort("system_port", this),
       _numContexts(0),
+      multiThread(p->multi_thread),
       pagePtr(0),
       init_param(p->init_param),
       physProxy(_systemPort, p->cache_line_size),
@@ -87,13 +96,18 @@ System::System(Params *p)
       kernel(nullptr),
       loadAddrMask(p->load_addr_mask),
       loadAddrOffset(p->load_offset),
-      nextPID(0),
+#if USE_KVM
+      kvmVM(p->kvm_vm),
+#else
+      kvmVM(nullptr),
+#endif
       physmem(name() + ".physmem", p->memories, p->mmap_using_noreserve),
       memoryMode(p->mem_mode),
       _cacheLineSize(p->cache_line_size),
       workItemsBegin(0),
       workItemsEnd(0),
       numWorkIds(p->num_work_ids),
+      thermalModel(p->thermal_model),
       _params(p),
       totalNumInsts(0),
       instEventQueue("system instruction-based event queue")
@@ -101,6 +115,12 @@ System::System(Params *p)
     // add self to global system list
     systemList.push_back(this);
 
+#if USE_KVM
+    if (kvmVM) {
+        kvmVM->setSystem(this);
+    }
+#endif
+
     if (FullSystem) {
         kernelSymtab = new SymbolTable;
         if (!debugSymbolTable)
@@ -138,6 +158,14 @@ System::System(Params *p)
             kernelEnd = kernel->bssBase() + kernel->bssSize();
             kernelEntry = kernel->entryPoint();
 
+            // If load_addr_mask is set to 0x0, then auto-calculate
+            // the smallest mask to cover all kernel addresses so gem5
+            // can relocate the kernel to a new offset.
+            if (loadAddrMask == 0) {
+                Addr shift_amt = findMsbSet(kernelEnd - kernelStart) + 1;
+                loadAddrMask = ((Addr)1 << shift_amt) - 1;
+            }
+
             // load symbols
             if (!kernel->loadGlobalSymbols(kernelSymtab))
                 fatal("could not load kernel symbols\n");
@@ -154,9 +182,17 @@ System::System(Params *p)
             // Loading only needs to happen once and after memory system is
             // connected so it will happen in initState()
         }
+
+        for (const auto &obj_name : p->kernel_extras) {
+            inform("Loading additional kernel object: %s", obj_name);
+            ObjectFile *obj = createObjectFile(obj_name);
+            fatal_if(!obj, "Failed to additional kernel object '%s'.\n",
+                     obj_name);
+            kernelExtras.push_back(obj);
+        }
     }
 
-    // increment the number of running systms
+    // increment the number of running systems
     numSystemsRunning++;
 
     // Set back pointers to the system in all memories
@@ -202,13 +238,6 @@ bool System::breakpoint()
     return false;
 }
 
-/**
- * Setting rgdb_wait to a positive integer waits for a remote debugger to
- * connect to that context ID before continuing.  This should really
-   be a parameter on the CPU object or something...
- */
-int rgdb_wait = -1;
-
 ContextID
 System::registerThreadContext(ThreadContext *tc, ContextID assigned)
 {
@@ -240,9 +269,13 @@ System::registerThreadContext(ThreadContext *tc, ContextID assigned)
         GDBListener *gdbl = new GDBListener(rgdb, port + id);
         gdbl->listen();
 
-        if (rgdb_wait != -1 && rgdb_wait == id)
-            gdbl->accept();
+        BaseCPU *cpu = tc->getCpuPtr();
+        if (cpu->waitForRemoteGDB()) {
+            inform("%s: Waiting for a remote GDB connection on port %d.\n",
+                   cpu->name(), gdbl->getPort());
 
+            gdbl->accept();
+        }
         if (remoteGDB.size() <= id) {
             remoteGDB.resize(id + 1);
         }
@@ -295,6 +328,10 @@ System::initState()
             }
             // Load program sections into memory
             kernel->loadSections(physProxy, loadAddrMask, loadAddrOffset);
+            for (const auto &extra_kernel : kernelExtras) {
+                extra_kernel->loadSections(physProxy, loadAddrMask,
+                                           loadAddrOffset);
+            }
 
             DPRINTF(Loader, "Kernel start = %#x\n", kernelStart);
             DPRINTF(Loader, "Kernel end   = %#x\n", kernelEnd);
@@ -317,6 +354,24 @@ System::replaceThreadContext(ThreadContext *tc, ContextID context_id)
         remoteGDB[context_id]->replaceThreadContext(tc);
 }
 
+bool
+System::validKvmEnvironment() const
+{
+#if USE_KVM
+    if (threadContexts.empty())
+        return false;
+
+    for (auto tc : threadContexts) {
+        if (dynamic_cast<BaseKvmCPU*>(tc->getCpuPtr()) == nullptr) {
+            return false;
+        }
+    }
+    return true;
+#else
+    return false;
+#endif
+}
+
 Addr
 System::allocPhysPages(int npages)
 {
@@ -367,7 +422,6 @@ System::serialize(CheckpointOut &cp) const
     if (FullSystem)
         kernelSymtab->serialize("kernel_symtab", cp);
     SERIALIZE_SCALAR(pagePtr);
-    SERIALIZE_SCALAR(nextPID);
     serializeSymtab(cp);
 
     // also serialize the memories in the system
@@ -381,7 +435,6 @@ System::unserialize(CheckpointIn &cp)
     if (FullSystem)
         kernelSymtab->unserialize("kernel_symtab", cp);
     UNSERIALIZE_SCALAR(pagePtr);
-    UNSERIALIZE_SCALAR(nextPID);
     unserializeSymtab(cp);
 
     // also unserialize the memories in the system
@@ -391,6 +444,8 @@ System::unserialize(CheckpointIn &cp)
 void
 System::regStats()
 {
+    MemObject::regStats();
+
     for (uint32_t j = 0; j < numWorkIds ; j++) {
         workItemStats[j] = new Stats::Histogram();
         stringstream namestr;