From a8f6e6ceec37d96a1a5cc58e1304d3d1c11bc144 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Fri, 4 Oct 2019 02:08:13 -0700 Subject: [PATCH] sparc: Create a helper functions to install firmware images. 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 Maintainer: Gabe Black Tested-by: kokoro --- src/arch/sparc/system.cc | 95 +++++++++++++++++++++------------------- 1 file changed, 51 insertions(+), 44 deletions(-) diff --git a/src/arch/sparc/system.cc b/src/arch/sparc/system.cc index 255cc1453..2d79ab4c3 100644 --- a/src/arch/sparc/system.cc +++ b/src/arch/sparc/system.cc @@ -40,6 +40,19 @@ 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() -- 2.30.2