sim-se: Add default to SyscallDesc constructor
[gem5.git] / src / sim / system.cc
index 9315882b7d776826f8b0e40d833b9026b560bcee..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
 #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"
@@ -156,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");
@@ -172,6 +182,14 @@ 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 systems
@@ -220,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)
 {
@@ -258,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);
         }
@@ -313,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);
@@ -335,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)
 {