System: Move code in initState() back into constructor whenever possible.
authorAli Saidi <Ali.Saidi@ARM.com>
Fri, 9 Mar 2012 14:59:26 +0000 (09:59 -0500)
committerAli Saidi <Ali.Saidi@ARM.com>
Fri, 9 Mar 2012 14:59:26 +0000 (09:59 -0500)
The change to port proxies recently moved code out of the constructor into
initState(). This is needed for code that loads data into memory, however
for code that setups symbol tables, kernel based events, etc this is the wrong
thing to do as that code is only called when a checkpoint isn't being restored
from.

src/arch/alpha/linux/system.cc
src/arch/alpha/linux/system.hh
src/arch/alpha/system.cc
src/arch/alpha/system.hh
src/arch/arm/linux/system.cc
src/arch/arm/system.cc
src/arch/sparc/system.cc
src/sim/system.cc

index e42553b63477a433328f9d85c0e043849d80a6c7..db3c16d7e78925bfe027466e916e9a2bec803b73 100644 (file)
@@ -113,6 +113,12 @@ LinuxAlphaSystem::initState()
     else
         panic("could not find dp264_mv\n");
 
+}
+
+void
+LinuxAlphaSystem::setupFuncEvents()
+{
+    AlphaSystem::setupFuncEvents();
 #ifndef NDEBUG
     kernelPanicEvent = addKernelFuncEvent<BreakPCEvent>("panic");
     if (!kernelPanicEvent)
@@ -148,6 +154,7 @@ LinuxAlphaSystem::initState()
     // re-enable, but we should find a better way to turn it on than
     // using DTRACE(Thread), since looking at a trace flag at tick 0
     // leads to non-intuitive behavior with --trace-start.
+    Addr addr = 0;
     if (false && kernelSymtab->findAddress("alpha_switch_to", addr)) {
         printThreadEvent = new PrintThreadInfo(&pcEventQueue, "threadinfo",
                                                addr + sizeof(MachInst) * 6);
index 5436a27b2d7381098d76e14ce9f5bf817d2da0cc..345c17bb7d5d2ea07c0b01e04017d16b0b45aba3 100644 (file)
@@ -123,6 +123,12 @@ class LinuxAlphaSystem : public AlphaSystem
     /** Grab the PCBB of the idle process when it starts */
     IdleStartEvent *idleStartEvent;
 
+  protected:
+    /** Setup all the function events. Must be done after init() for Alpha since
+     * fixFuncEvent() requires a function port
+     */
+    virtual void setupFuncEvents();
+
   public:
     typedef LinuxAlphaSystemParams Params;
     LinuxAlphaSystem(Params *p);
index 8d6629169183859af61149979a34fad406f5da14..51e1d7e07883eeea4237fcd7c8033261cd948603 100644 (file)
@@ -63,6 +63,27 @@ AlphaSystem::AlphaSystem(Params *p)
     pal = createObjectFile(params()->pal);
     if (pal == NULL)
         fatal("Could not load PALcode file %s", params()->pal);
+
+    // load symbols
+    if (!console->loadGlobalSymbols(consoleSymtab))
+        panic("could not load console symbols\n");
+
+    if (!pal->loadGlobalSymbols(palSymtab))
+        panic("could not load pal symbols\n");
+
+    if (!pal->loadLocalSymbols(palSymtab))
+        panic("could not load pal symbols\n");
+
+    if (!console->loadGlobalSymbols(debugSymbolTable))
+        panic("could not load console symbols\n");
+
+    if (!pal->loadGlobalSymbols(debugSymbolTable))
+        panic("could not load pal symbols\n");
+
+    if (!pal->loadLocalSymbols(debugSymbolTable))
+        panic("could not load pal symbols\n");
+
+
 }
 
 AlphaSystem::~AlphaSystem()
@@ -78,6 +99,8 @@ AlphaSystem::~AlphaSystem()
 void
 AlphaSystem::initState()
 {
+     Addr addr = 0;
+
     // Moved from the constructor to here since it relies on the
     // address map being resolved in the interconnect
 
@@ -88,30 +111,6 @@ AlphaSystem::initState()
     pal->loadSections(physProxy, loadAddrMask);
     console->loadSections(physProxy, loadAddrMask);
 
-    // load symbols
-    if (!console->loadGlobalSymbols(consoleSymtab))
-        panic("could not load console symbols\n");
-
-    if (!pal->loadGlobalSymbols(palSymtab))
-        panic("could not load pal symbols\n");
-
-    if (!pal->loadLocalSymbols(palSymtab))
-        panic("could not load pal symbols\n");
-
-    if (!console->loadGlobalSymbols(debugSymbolTable))
-        panic("could not load console symbols\n");
-
-    if (!pal->loadGlobalSymbols(debugSymbolTable))
-        panic("could not load pal symbols\n");
-
-    if (!pal->loadLocalSymbols(debugSymbolTable))
-        panic("could not load pal symbols\n");
-
-     Addr addr = 0;
-#ifndef NDEBUG
-    consolePanicEvent = addConsoleFuncEvent<BreakPCEvent>("panic");
-#endif
-
     /**
      * Copy the osflags (kernel arguments) into the consoles
      * memory. (Presently Linux does not use the console service
@@ -135,6 +134,29 @@ AlphaSystem::initState()
         virtProxy.write(addr+0x58, data);
     } else
         panic("could not find hwrpb\n");
+
+    // Setup all the function events now that we have a system and a symbol
+    // table
+    setupFuncEvents();
+}
+
+void
+AlphaSystem::loadState(Checkpoint *cp)
+{
+    System::loadState(cp);
+
+    // Setup all the function events now that we have a system and a symbol
+    // table
+    setupFuncEvents();
+
+}
+
+void
+AlphaSystem::setupFuncEvents()
+{
+#ifndef NDEBUG
+    consolePanicEvent = addConsoleFuncEvent<BreakPCEvent>("panic");
+#endif
 }
 
 /**
index 0e809cb949ff576b796af4924beca1b850e7c8ff..d832dfe778935ad94663529249952f44790904a1 100644 (file)
@@ -62,6 +62,10 @@ class AlphaSystem : public System
     virtual void serialize(std::ostream &os);
     virtual void unserialize(Checkpoint *cp, const std::string &section);
 
+    /** Override loadState to provide a path to call setupFuncEvents()
+     */
+    virtual void loadState(Checkpoint *cp);
+
     /**
      * Set the m5AlphaAccess pointer in the console
      */
@@ -89,6 +93,12 @@ class AlphaSystem : public System
 
     const Params *params() const { return (const Params *)_params; }
 
+
+    /** Setup all the function events. Must be done after init() for Alpha since
+     * fixFuncEvent() requires a function port
+     */
+    virtual void setupFuncEvents();
+
     /** Add a function-based event to PALcode. */
     template <class T>
     T *
index 4e18a265d2d7e63ca4f8b5419e4c97ac4c847563..64bda4b4dc5b109068480b69237e0cae4cc1fc31 100644 (file)
@@ -58,6 +58,40 @@ using namespace Linux;
 LinuxArmSystem::LinuxArmSystem(Params *p)
     : ArmSystem(p)
 {
+#ifndef NDEBUG
+    kernelPanicEvent = addKernelFuncEvent<BreakPCEvent>("panic");
+    if (!kernelPanicEvent)
+        panic("could not find kernel symbol \'panic\'");
+#endif
+
+    // With ARM udelay() is #defined to __udelay
+    Addr addr = 0;
+    if (kernelSymtab->findAddress("__udelay", addr)) {
+        uDelaySkipEvent = new UDelayEvent(&pcEventQueue, "__udelay",
+                fixFuncEventAddr(addr), 1000, 0);
+    } else {
+        panic("couldn't find kernel symbol \'udelay\'");
+    }
+
+    // constant arguments to udelay() have some precomputation done ahead of
+    // time. Constant comes from code.
+    if (kernelSymtab->findAddress("__const_udelay", addr)) {
+        constUDelaySkipEvent = new UDelayEvent(&pcEventQueue, "__const_udelay",
+                fixFuncEventAddr(addr), 1000, 107374);
+    } else {
+        panic("couldn't find kernel symbol \'udelay\'");
+    }
+
+    secDataPtrAddr = 0;
+    secDataAddr = 0;
+    penReleaseAddr = 0;
+    kernelSymtab->findAddress("__secondary_data", secDataPtrAddr);
+    kernelSymtab->findAddress("secondary_data", secDataAddr);
+    kernelSymtab->findAddress("pen_release", penReleaseAddr);
+
+    secDataPtrAddr &= ~ULL(0x7F);
+    secDataAddr &= ~ULL(0x7F);
+    penReleaseAddr &= ~ULL(0x7F);
 }
 
 bool
@@ -116,41 +150,6 @@ LinuxArmSystem::initState()
 
     physProxy.writeBlob(params()->atags_addr, boot_data, size << 2);
 
-#ifndef NDEBUG
-    kernelPanicEvent = addKernelFuncEvent<BreakPCEvent>("panic");
-    if (!kernelPanicEvent)
-        panic("could not find kernel symbol \'panic\'");
-#endif
-
-    // With ARM udelay() is #defined to __udelay
-    Addr addr = 0;
-    if (kernelSymtab->findAddress("__udelay", addr)) {
-        uDelaySkipEvent = new UDelayEvent(&pcEventQueue, "__udelay",
-                fixFuncEventAddr(addr), 1000, 0);
-    } else {
-        panic("couldn't find kernel symbol \'udelay\'");
-    }
-
-    // constant arguments to udelay() have some precomputation done ahead of
-    // time. Constant comes from code.
-    if (kernelSymtab->findAddress("__const_udelay", addr)) {
-        constUDelaySkipEvent = new UDelayEvent(&pcEventQueue, "__const_udelay",
-                fixFuncEventAddr(addr), 1000, 107374);
-    } else {
-        panic("couldn't find kernel symbol \'udelay\'");
-    }
-
-    secDataPtrAddr = 0;
-    secDataAddr = 0;
-    penReleaseAddr = 0;
-    kernelSymtab->findAddress("__secondary_data", secDataPtrAddr);
-    kernelSymtab->findAddress("secondary_data", secDataAddr);
-    kernelSymtab->findAddress("pen_release", penReleaseAddr);
-
-    secDataPtrAddr &= ~ULL(0x7F);
-    secDataAddr &= ~ULL(0x7F);
-    penReleaseAddr &= ~ULL(0x7F);
-
     for (int i = 0; i < threadContexts.size(); i++) {
         threadContexts[i]->setIntReg(0, 0);
         threadContexts[i]->setIntReg(1, params()->machine_type);
index 8b85715cb51dc04aaef0a51296fd7fc4fa7db82e..7fbabafcb191c528af9d35b628f7bafdb7e54ae4 100644 (file)
@@ -55,6 +55,19 @@ using namespace Linux;
 ArmSystem::ArmSystem(Params *p)
     : System(p), bootldr(NULL)
 {
+    if ((p->boot_loader == "") != (p->boot_loader_mem == NULL))
+        fatal("If boot_loader is specifed, memory to load it must be also.\n");
+
+    if (p->boot_loader != "") {
+        bootldr = createObjectFile(p->boot_loader);
+
+        if (!bootldr)
+            fatal("Could not read bootloader: %s\n", p->boot_loader);
+
+        bootldr->loadGlobalSymbols(debugSymbolTable);
+
+    }
+    debugPrintkEvent = addKernelFuncEvent<DebugPrintkEvent>("dprintk");
 }
 
 void
@@ -68,17 +81,8 @@ ArmSystem::initState()
 
     const Params* p = params();
 
-    if ((p->boot_loader == "") != (p->boot_loader_mem == NULL))
-        fatal("If boot_loader is specifed, memory to load it must be also.\n");
-
-    if (p->boot_loader != "") {
-        bootldr = createObjectFile(p->boot_loader);
-
-        if (!bootldr)
-            fatal("Could not read bootloader: %s\n", p->boot_loader);
-
+    if (bootldr) {
         bootldr->loadSections(physProxy);
-        bootldr->loadGlobalSymbols(debugSymbolTable);
 
         uint8_t jump_to_bl[] =
         {
@@ -87,32 +91,30 @@ ArmSystem::initState()
         physProxy.writeBlob(0x0, jump_to_bl, sizeof(jump_to_bl));
 
         inform("Using bootloader at address %#x\n", bootldr->entryPoint());
-    }
 
-    if (bootldr) {
         // Put the address of the boot loader into r7 so we know
         // where to branch to after the reset fault
         // All other values needed by the boot loader to know what to do
+        if (!p->gic_cpu_addr || !p->flags_addr)
+            fatal("gic_cpu_addr && flags_addr must be set with bootloader\n");
+
         for (int i = 0; i < threadContexts.size(); i++) {
             threadContexts[i]->setIntReg(3, kernelEntry & loadAddrMask);
             threadContexts[i]->setIntReg(4, params()->gic_cpu_addr);
             threadContexts[i]->setIntReg(5, params()->flags_addr);
             threadContexts[i]->setIntReg(7, bootldr->entryPoint());
         }
-        if (!p->gic_cpu_addr || !p->flags_addr)
-            fatal("gic_cpu_addr && flags_addr must be set with bootloader\n");
     } else {
         // Set the initial PC to be at start of the kernel code
         threadContexts[0]->pcState(kernelEntry & loadAddrMask);
     }
+
     for (int i = 0; i < threadContexts.size(); i++) {
         if (p->midr_regval) {
             threadContexts[i]->setMiscReg(ArmISA::MISCREG_MIDR,
                                           p->midr_regval);
         }
     }
-
-    debugPrintkEvent = addKernelFuncEvent<DebugPrintkEvent>("dprintk");
 }
 
 ArmSystem::~ArmSystem()
index ab5f7432e4ffb5f5173d425119b77288113e5fa4..9ce0a90de3e66f85498a387e4f7272a03aea6fb7 100644 (file)
@@ -48,13 +48,6 @@ SparcSystem::SparcSystem(Params *p)
     nvramSymtab = new SymbolTable;
     hypervisorDescSymtab = new SymbolTable;
     partitionDescSymtab = new SymbolTable;
-}
-
-void
-SparcSystem::initState()
-{
-    // Call the initialisation of the super class
-    System::initState();
 
     /**
      * Load the boot code, and hypervisor into memory.
@@ -91,26 +84,6 @@ SparcSystem::initState()
         fatal("Could not load partition description image %s",
                 params()->partition_desc_bin);
 
-
-    // Load reset binary into memory
-    reset->setTextBase(params()->reset_addr);
-    reset->loadSections(physProxy);
-    // Load the openboot binary
-    openboot->setTextBase(params()->openboot_addr);
-    openboot->loadSections(physProxy);
-    // Load the hypervisor binary
-    hypervisor->setTextBase(params()->hypervisor_addr);
-    hypervisor->loadSections(physProxy);
-    // Load the nvram image
-    nvram->setTextBase(params()->nvram_addr);
-    nvram->loadSections(physProxy);
-    // Load the hypervisor description image
-    hypervisor_desc->setTextBase(params()->hypervisor_desc_addr);
-    hypervisor_desc->loadSections(physProxy);
-    // Load the partition description image
-    partition_desc->setTextBase(params()->partition_desc_addr);
-    partition_desc->loadSections(physProxy);
-
     // load symbols
     if (!reset->loadGlobalSymbols(resetSymtab))
         panic("could not load reset symbols\n");
@@ -154,6 +127,33 @@ SparcSystem::initState()
     if (!partition_desc->loadLocalSymbols(debugSymbolTable))
         panic("could not load partition description symbols\n");
 
+}
+
+void
+SparcSystem::initState()
+{
+    // Call the initialisation of the super class
+    System::initState();
+
+    // Load reset binary into memory
+    reset->setTextBase(params()->reset_addr);
+    reset->loadSections(physProxy);
+    // Load the openboot binary
+    openboot->setTextBase(params()->openboot_addr);
+    openboot->loadSections(physProxy);
+    // Load the hypervisor binary
+    hypervisor->setTextBase(params()->hypervisor_addr);
+    hypervisor->loadSections(physProxy);
+    // Load the nvram image
+    nvram->setTextBase(params()->nvram_addr);
+    nvram->loadSections(physProxy);
+    // Load the hypervisor description image
+    hypervisor_desc->setTextBase(params()->hypervisor_desc_addr);
+    hypervisor_desc->loadSections(physProxy);
+    // Load the partition description image
+    partition_desc->setTextBase(params()->partition_desc_addr);
+    partition_desc->loadSections(physProxy);
+
 
     // @todo any fixup code over writing data in binaries on setting break
     // events on functions should happen here.
index 36d4447ff0bae83566175fc768b544dd462928b4..4601d2d52f2ad34300136240246b56b62c67bdaf 100644 (file)
@@ -117,6 +117,44 @@ System::System(Params *p)
     tmp_id = getMasterId("interrupt");
     assert(tmp_id == Request::intMasterId);
 
+    if (FullSystem) {
+        if (params()->kernel == "") {
+            inform("No kernel set for full system simulation. "
+                    "Assuming you know what you're doing if not SPARC ISA\n");
+        } else {
+            // Get the kernel code
+            kernel = createObjectFile(params()->kernel);
+            inform("kernel located at: %s", params()->kernel);
+
+            if (kernel == NULL)
+                fatal("Could not load kernel file %s", params()->kernel);
+
+            // setup entry points
+            kernelStart = kernel->textBase();
+            kernelEnd = kernel->bssBase() + kernel->bssSize();
+            kernelEntry = kernel->entryPoint();
+
+            // load symbols
+            if (!kernel->loadGlobalSymbols(kernelSymtab))
+                fatal("could not load kernel symbols\n");
+
+            if (!kernel->loadLocalSymbols(kernelSymtab))
+                fatal("could not load kernel local symbols\n");
+
+            if (!kernel->loadGlobalSymbols(debugSymbolTable))
+                fatal("could not load kernel symbols\n");
+
+            if (!kernel->loadLocalSymbols(debugSymbolTable))
+                fatal("could not load kernel local symbols\n");
+
+            // Loading only needs to happen once and after memory system is
+            // connected so it will happen in initState()
+        }
+    }
+
+    // increment the number of running systms
+    numSystemsRunning++;
+
 }
 
 System::~System()
@@ -232,38 +270,10 @@ System::initState()
         /**
          * Load the kernel code into memory
          */
-        if (params()->kernel == "") {
-            inform("No kernel set for full system simulation. "
-                    "Assuming you know what you're doing...\n");
-        } else {
-            // Load kernel code
-            kernel = createObjectFile(params()->kernel);
-            inform("kernel located at: %s", params()->kernel);
-
-            if (kernel == NULL)
-                fatal("Could not load kernel file %s", params()->kernel);
-
+        if (params()->kernel != "")  {
             // Load program sections into memory
             kernel->loadSections(physProxy, loadAddrMask);
 
-            // setup entry points
-            kernelStart = kernel->textBase();
-            kernelEnd = kernel->bssBase() + kernel->bssSize();
-            kernelEntry = kernel->entryPoint();
-
-            // load symbols
-            if (!kernel->loadGlobalSymbols(kernelSymtab))
-                fatal("could not load kernel symbols\n");
-
-            if (!kernel->loadLocalSymbols(kernelSymtab))
-                fatal("could not load kernel local symbols\n");
-
-            if (!kernel->loadGlobalSymbols(debugSymbolTable))
-                fatal("could not load kernel symbols\n");
-
-            if (!kernel->loadLocalSymbols(debugSymbolTable))
-                fatal("could not load kernel local symbols\n");
-
             DPRINTF(Loader, "Kernel start = %#x\n", kernelStart);
             DPRINTF(Loader, "Kernel end   = %#x\n", kernelEnd);
             DPRINTF(Loader, "Kernel entry = %#x\n", kernelEntry);
@@ -271,9 +281,6 @@ System::initState()
         }
     }
 
-    // increment the number of running systms
-    numSystemsRunning++;
-
     activeCpus.clear();
 
     if (!FullSystem)