changeset abc8ab4ddd93 in /z/repo/m5
details: http://repo.m5sim.org/m5?cmd=changeset;node=abc8ab4ddd93
description:
        ARM: Add support for loading the a bootloader and configuring 
parameters for it

diffstat:

 src/arch/arm/ArmSystem.py    |   7 +++++
 src/arch/arm/linux/system.cc |  13 +++------
 src/arch/arm/system.cc       |  57 ++++++++++++++++++++++++++++++++++++++++++-
 src/arch/arm/system.hh       |  15 ++++++++++-
 src/arch/arm/utility.cc      |   3 +-
 5 files changed, 82 insertions(+), 13 deletions(-)

diffs (165 lines):

diff -r c38905a6fa32 -r abc8ab4ddd93 src/arch/arm/ArmSystem.py
--- a/src/arch/arm/ArmSystem.py Wed May 04 20:38:28 2011 -0500
+++ b/src/arch/arm/ArmSystem.py Wed May 04 20:38:28 2011 -0500
@@ -46,9 +46,16 @@
 class ArmSystem(System):
     type = 'ArmSystem'
     load_addr_mask = 0xffffffff
+    boot_loader = Param.String("", "File that contains the boot loader code if 
any")
+    boot_loader_mem = Param.PhysicalMemory(NULL,
+                          "Memory object that boot loader is to be loaded 
into")
+    gic_cpu_addr = Param.Addr(0, "Addres of the GIC CPU interface")
+    flags_addr = Param.Addr(0, "Address of the flags register for MP booting")
 
 class LinuxArmSystem(ArmSystem):
     type = 'LinuxArmSystem'
     load_addr_mask = 0x0fffffff
     machine_type = Param.ArmMachineType('RealView_PBX',
         "Machine id from http://www.arm.linux.org.uk/developer/machines/";)
+
+
diff -r c38905a6fa32 -r abc8ab4ddd93 src/arch/arm/linux/system.cc
--- a/src/arch/arm/linux/system.cc      Wed May 04 20:38:28 2011 -0500
+++ b/src/arch/arm/linux/system.cc      Wed May 04 20:38:28 2011 -0500
@@ -123,15 +123,12 @@
 LinuxArmSystem::initState()
 {
     ArmSystem::initState();
-    ThreadContext *tc = threadContexts[0];
 
-    // Set the initial PC to be at start of the kernel code
-    tc->pcState(tc->getSystemPtr()->kernelEntry & loadAddrMask);
-
-    // Setup the machine type
-    tc->setIntReg(0, 0);
-    tc->setIntReg(1, params()->machine_type);
-    tc->setIntReg(2, ParamsList);
+    for (int i = 0; i < threadContexts.size(); i++) {
+        threadContexts[i]->setIntReg(0, 0);
+        threadContexts[i]->setIntReg(1, params()->machine_type);
+        threadContexts[i]->setIntReg(2, ParamsList);
+    }
 }
 
 LinuxArmSystem::~LinuxArmSystem()
diff -r c38905a6fa32 -r abc8ab4ddd93 src/arch/arm/system.cc
--- a/src/arch/arm/system.cc    Wed May 04 20:38:28 2011 -0500
+++ b/src/arch/arm/system.cc    Wed May 04 20:38:28 2011 -0500
@@ -43,20 +43,73 @@
 #include <iostream>
 
 #include "arch/arm/system.hh"
+#include "base/loader/object_file.hh"
+#include "base/loader/symtab.hh"
+#include "cpu/thread_context.hh"
+#include "mem/physical.hh"
 
 using namespace std;
 using namespace Linux;
 
 ArmSystem::ArmSystem(Params *p)
-    : System(p)
+    : System(p), bootldr(NULL)
 {
     debugPrintkEvent = addKernelFuncEvent<DebugPrintkEvent>("dprintk");
 
+    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);
+
+        Port *mem_port;
+        FunctionalPort fp(name() + "-fport");
+        mem_port = p->boot_loader_mem->getPort("functional");
+        fp.setPeer(mem_port);
+        mem_port->setPeer(&fp);
+
+        bootldr->loadSections(&fp);
+        bootldr->loadGlobalSymbols(debugSymbolTable);
+
+        uint8_t jump_to_bl[] =
+        {
+            0x07, 0xf0, 0xa0, 0xe1  // branch to r7
+        };
+        functionalPort->writeBlob(0x0, jump_to_bl, sizeof(jump_to_bl));
+
+        inform("Using bootloader at address %#x\n", bootldr->entryPoint());
+    }
+}
+
+void
+ArmSystem::initState()
+{
+    System::initState();
+    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
+        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 (!params()->gic_cpu_addr || !params()->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);
+    }
 }
 
 ArmSystem::~ArmSystem()
 {
-    delete debugPrintkEvent;
+    if (debugPrintkEvent)
+        delete debugPrintkEvent;
 }
 
 
diff -r c38905a6fa32 -r abc8ab4ddd93 src/arch/arm/system.hh
--- a/src/arch/arm/system.hh    Wed May 04 20:38:28 2011 -0500
+++ b/src/arch/arm/system.hh    Wed May 04 20:38:28 2011 -0500
@@ -60,11 +60,24 @@
      */
     Linux::DebugPrintkEvent *debugPrintkEvent;
 
+    /**
+     * Pointer to the bootloader object
+     */
+    ObjectFile *bootldr;
+
   public:
     typedef ArmSystemParams Params;
+    const Params *
+    params() const
+    {
+        return dynamic_cast<const Params *>(_params);
+    }
+
     ArmSystem(Params *p);
     ~ArmSystem();
-    
+
+    void initState();
+
     virtual Addr fixFuncEventAddr(Addr addr)
     {
         // Remove the low bit that thumb symbols have set
diff -r c38905a6fa32 -r abc8ab4ddd93 src/arch/arm/utility.cc
--- a/src/arch/arm/utility.cc   Wed May 04 20:38:28 2011 -0500
+++ b/src/arch/arm/utility.cc   Wed May 04 20:38:28 2011 -0500
@@ -60,8 +60,7 @@
     // FPEXC.EN = 0
     
     static Fault reset = new Reset;
-    if (cpuId == 0)
-        reset->invoke(tc);
+    reset->invoke(tc);
 }
 
 uint64_t
_______________________________________________
m5-dev mailing list
m5-dev@m5sim.org
http://m5sim.org/mailman/listinfo/m5-dev

Reply via email to