changeset f795ce1feb5b in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=f795ce1feb5b
description:
        ARM: added support for flattened device tree blobs

        Newer Linux kernels require DTB (device tree blobs) to specify platform
        configurations. The input DTB filename can be specified through gem5 
parameters
        in LinuxArmSystem.

diffstat:

 src/arch/arm/ArmSystem.py      |   8 ++-
 src/arch/arm/linux/system.cc   |  97 ++++++++++++++++++++++++++++-------------
 src/base/loader/object_file.hh |   5 ++
 3 files changed, 76 insertions(+), 34 deletions(-)

diffs (139 lines):

diff -r 9ca8345d24c4 -r f795ce1feb5b src/arch/arm/ArmSystem.py
--- a/src/arch/arm/ArmSystem.py Tue Sep 25 11:49:40 2012 -0500
+++ b/src/arch/arm/ArmSystem.py Tue Sep 25 11:49:41 2012 -0500
@@ -65,5 +65,9 @@
     load_addr_mask = 0x0fffffff
     machine_type = Param.ArmMachineType('RealView_PBX',
         "Machine id from http://www.arm.linux.org.uk/developer/machines/";)
-    atags_addr = Param.Addr(0x100, "Address where default atags structure 
should be written")
-    early_kernel_symbols = Param.Bool(False, "enable early kernel symbol 
tables before MMU")
+    atags_addr = Param.Addr(0x100,
+        "Address where default atags structure should be written")
+    dtb_filename = Param.String("",
+        "File that contains the Device Tree Blob. Don't use DTB if empty.")
+    early_kernel_symbols = Param.Bool(False,
+        "enable early kernel symbol tables before MMU")
diff -r 9ca8345d24c4 -r f795ce1feb5b src/arch/arm/linux/system.cc
--- a/src/arch/arm/linux/system.cc      Tue Sep 25 11:49:40 2012 -0500
+++ b/src/arch/arm/linux/system.cc      Tue Sep 25 11:49:41 2012 -0500
@@ -122,40 +122,73 @@
     }
 
     // Setup boot data structure
-    AtagCore *ac = new AtagCore;
-    ac->flags(1); // read-only
-    ac->pagesize(8192);
-    ac->rootdev(0);
+    Addr addr = 0;
+    // Check if the kernel image has a symbol that tells us it supports
+    // device trees.
+    bool kernel_has_fdt_support =
+        kernelSymtab->findAddress("unflatten_device_tree", addr);
+    bool dtb_file_specified = params()->dtb_filename != "";
 
-    AddrRangeList atagRanges = physmem.getConfAddrRanges();
-    if (atagRanges.size() != 1) {
-        fatal("Expected a single ATAG memory entry but got %d\n",
-              atagRanges.size());
+    if (kernel_has_fdt_support && dtb_file_specified) {
+        // Kernel supports flattened device tree and dtb file specified.
+        // Using Device Tree Blob to describe system configuration.
+        inform("Loading DTB file: %s\n", params()->dtb_filename);
+
+        ObjectFile *dtb_file = createObjectFile(params()->dtb_filename, true);
+        if (!dtb_file) {
+            fatal("couldn't load DTB file: %s\n", params()->dtb_filename);
+        }
+        dtb_file->setTextBase(params()->atags_addr);
+        dtb_file->loadSections(physProxy);
+        delete dtb_file;
+    } else {
+        // Using ATAGS
+        // Warn if the kernel supports FDT and we haven't specified one
+        if (kernel_has_fdt_support) {
+            assert(!dtb_file_specified);
+            warn("Kernel supports device tree, but no DTB file specified\n");
+        }
+        // Warn if the kernel doesn't support FDT and we have specified one
+        if (dtb_file_specified) {
+            assert(!kernel_has_fdt_support);
+            warn("DTB file specified, but no device tree support in kernel\n");
+        }
+
+        AtagCore *ac = new AtagCore;
+        ac->flags(1); // read-only
+        ac->pagesize(8192);
+        ac->rootdev(0);
+
+        AddrRangeList atagRanges = physmem.getConfAddrRanges();
+        if (atagRanges.size() != 1) {
+            fatal("Expected a single ATAG memory entry but got %d\n",
+                  atagRanges.size());
+        }
+        AtagMem *am = new AtagMem;
+        am->memSize(atagRanges.begin()->size());
+        am->memStart(atagRanges.begin()->start);
+
+        AtagCmdline *ad = new AtagCmdline;
+        ad->cmdline(params()->boot_osflags);
+
+        DPRINTF(Loader, "boot command line %d bytes: %s\n", ad->size() <<2, 
params()->boot_osflags.c_str());
+
+        AtagNone *an = new AtagNone;
+
+        uint32_t size = ac->size() + am->size() + ad->size() + an->size();
+        uint32_t offset = 0;
+        uint8_t *boot_data = new uint8_t[size << 2];
+
+        offset += ac->copyOut(boot_data + offset);
+        offset += am->copyOut(boot_data + offset);
+        offset += ad->copyOut(boot_data + offset);
+        offset += an->copyOut(boot_data + offset);
+
+        DPRINTF(Loader, "Boot atags was %d bytes in total\n", size << 2);
+        DDUMP(Loader, boot_data, size << 2);
+
+        physProxy.writeBlob(params()->atags_addr, boot_data, size << 2);
     }
-    AtagMem *am = new AtagMem;
-    am->memSize(atagRanges.begin()->size());
-    am->memStart(atagRanges.begin()->start);
-
-    AtagCmdline *ad = new AtagCmdline;
-    ad->cmdline(params()->boot_osflags);
-
-    DPRINTF(Loader, "boot command line %d bytes: %s\n", ad->size() <<2, 
params()->boot_osflags.c_str());
-
-    AtagNone *an = new AtagNone;
-
-    uint32_t size = ac->size() + am->size() + ad->size() + an->size();
-    uint32_t offset = 0;
-    uint8_t *boot_data = new uint8_t[size << 2];
-
-    offset += ac->copyOut(boot_data + offset);
-    offset += am->copyOut(boot_data + offset);
-    offset += ad->copyOut(boot_data + offset);
-    offset += an->copyOut(boot_data + offset);
-
-    DPRINTF(Loader, "Boot atags was %d bytes in total\n", size << 2);
-    DDUMP(Loader, boot_data, size << 2);
-
-    physProxy.writeBlob(params()->atags_addr, boot_data, size << 2);
 
     for (int i = 0; i < threadContexts.size(); i++) {
         threadContexts[i]->setIntReg(0, 0);
diff -r 9ca8345d24c4 -r f795ce1feb5b src/base/loader/object_file.hh
--- a/src/base/loader/object_file.hh    Tue Sep 25 11:49:40 2012 -0500
+++ b/src/base/loader/object_file.hh    Tue Sep 25 11:49:41 2012 -0500
@@ -127,6 +127,11 @@
     size_t dataSize() const { return data.size; }
     size_t bssSize() const { return bss.size; }
 
+    /* This function allows you to override the base address where
+     * a binary is going to be loaded or set it if the binary is just a
+     * blob that doesn't include an object header.
+     * @param a address to load the binary/text section at
+     */
     void setTextBase(Addr a) { text.baseAddr = a; }
 };
 
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to