sparc: Create a helper functions to install firmware images.
authorGabe Black <gabeblack@google.com>
Fri, 4 Oct 2019 09:08:13 +0000 (02:08 -0700)
committerGabe Black <gabeblack@google.com>
Wed, 30 Oct 2019 00:06:50 +0000 (00:06 +0000)
The first function handles the repetitive process of creating an
ObjectFile for a particular purpose and checking if that was
successful.
The second conditionally offsets the images in case they were, for
instance, loaded from an ELF file which already had them in the right
place. It offsets them so that their entry point (which will be zero
for raw images) lines up with the appropriate entry address (which will
be at the start of raw images).

This is more correct in more cases, and also removes a lot of
redundancy. There's still a lot of redundancy in the code which sets
up the symbol tables, but there are some irregularities which make that
harder to wrap in a helper function.

Change-Id: I2fee8b2175faff284ff9e007307f7769043497a1
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/21469
Reviewed-by: Brandon Potter <Brandon.Potter@amd.com>
Maintainer: Gabe Black <gabeblack@google.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/arch/sparc/system.cc

index 255cc145371f268398dca2fe53c0de31c68a2c9b..2d79ab4c3c0e1f633127768817d52dd8f2691518 100644 (file)
 
 using namespace BigEndianGuest;
 
+namespace
+{
+
+ObjectFile *
+loadFirmwareImage(const std::string &fname, const std::string &name)
+{
+    ObjectFile *obj = createObjectFile(fname, true);
+    fatal_if(!obj, "Could not load %s %s.", name, fname);
+    return obj;
+}
+
+} // anonymous namespace
+
 SparcSystem::SparcSystem(Params *p)
     : System(p), sysTick(0)
 {
@@ -50,40 +63,15 @@ SparcSystem::SparcSystem(Params *p)
     hypervisorDescSymtab = new SymbolTable;
     partitionDescSymtab = new SymbolTable;
 
-    /**
-     * Load the boot code, and hypervisor into memory.
-     */
-    // Read the reset binary
-    reset = createObjectFile(params()->reset_bin, true);
-    if (reset == NULL)
-        fatal("Could not load reset binary %s", params()->reset_bin);
-
-    // Read the openboot binary
-    openboot = createObjectFile(params()->openboot_bin, true);
-    if (openboot == NULL)
-        fatal("Could not load openboot bianry %s", params()->openboot_bin);
-
-    // Read the hypervisor binary
-    hypervisor = createObjectFile(params()->hypervisor_bin, true);
-    if (hypervisor == NULL)
-        fatal("Could not load hypervisor binary %s", params()->hypervisor_bin);
-
-    // Read the nvram image
-    nvram = createObjectFile(params()->nvram_bin, true);
-    if (nvram == NULL)
-        fatal("Could not load nvram image %s", params()->nvram_bin);
-
-    // Read the hypervisor description image
-    hypervisor_desc = createObjectFile(params()->hypervisor_desc_bin, true);
-    if (hypervisor_desc == NULL)
-        fatal("Could not load hypervisor description image %s",
-                params()->hypervisor_desc_bin);
-
-    // Read the partition description image
-    partition_desc = createObjectFile(params()->partition_desc_bin, true);
-    if (partition_desc == NULL)
-        fatal("Could not load partition description image %s",
-                params()->partition_desc_bin);
+    reset = loadFirmwareImage(params()->reset_bin, "reset binary");
+    openboot = loadFirmwareImage(params()->openboot_bin, "openboot binary");
+    hypervisor = loadFirmwareImage(
+            params()->hypervisor_bin, "hypervisor binary");
+    nvram = loadFirmwareImage(params()->nvram_bin, "nvram image");
+    hypervisor_desc = loadFirmwareImage(
+            params()->hypervisor_desc_bin, "hypervisor description image");
+    partition_desc = loadFirmwareImage(
+            params()->partition_desc_bin, "partition description image");
 
     // load symbols
     if (!reset->loadGlobalSymbols(resetSymtab))
@@ -130,25 +118,44 @@ SparcSystem::SparcSystem(Params *p)
 
 }
 
+namespace
+{
+
+void
+writeFirmwareImage(ObjectFile *obj, Addr addr, const PortProxy &proxy)
+{
+    MemoryImage image = obj->buildImage();
+
+    // If the entry point isn't somewhere in the image, we assume we need to
+    // move where it's loaded so that it is.
+    if (addr < image.minAddr() || addr >= image.maxAddr()) {
+        // Move the image by the difference between the expected entry address,
+        // and the entry point in the object file.
+        image.offset(addr - obj->entryPoint());
+    }
+
+    image.write(proxy);
+}
+
+} // anonymous namespace
+
 void
 SparcSystem::initState()
 {
     // Call the initialisation of the super class
     System::initState();
 
-    reset->buildImage().offset(params()->reset_addr).write(physProxy);
-    openboot->buildImage().offset(params()->openboot_addr).write(physProxy);
-    hypervisor->buildImage().
-        offset(params()->hypervisor_addr).write(physProxy);
-    nvram->buildImage().offset(params()->nvram_addr).write(physProxy);
-    hypervisor_desc->buildImage().
-        offset(params()->hypervisor_desc_addr).write(physProxy);
-    partition_desc->buildImage().
-        offset(params()->partition_desc_addr).write(physProxy);
+    writeFirmwareImage(reset, params()->reset_addr, physProxy);
+    writeFirmwareImage(openboot, params()->openboot_addr, physProxy);
+    writeFirmwareImage(hypervisor, params()->hypervisor_addr, physProxy);
+    writeFirmwareImage(nvram, params()->nvram_addr, physProxy);
+    writeFirmwareImage(
+            hypervisor_desc, params()->hypervisor_desc_addr, physProxy);
+    writeFirmwareImage(
+            partition_desc, params()->partition_desc_addr, physProxy);
 
     // @todo any fixup code over writing data in binaries on setting break
     // events on functions should happen here.
-
 }
 
 SparcSystem::~SparcSystem()