-# Copyright (c) 2009, 2012-2013 ARM Limited
+# Copyright (c) 2009, 2012-2013, 2015 ARM Limited
# All rights reserved.
#
# The license below extends only to copyright in the software and shall
cxx_header = "arch/arm/system.hh"
load_addr_mask = 0xffffffff
multi_proc = Param.Bool(True, "Multiprocessor system?")
- boot_loader = Param.String("", "File that contains the boot loader code if any")
+ boot_loader = VectorParam.String([],
+ "File that contains the boot loader code. Zero or more files may be "
+ "specified. The first boot loader that matches the kernel's "
+ "architecture will be used.")
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")
have_security = Param.Bool(False,
/*
- * Copyright (c) 2010, 2012-2013 ARM Limited
+ * Copyright (c) 2010, 2012-2013, 2015 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
using namespace Linux;
ArmSystem::ArmSystem(Params *p)
- : System(p), bootldr(NULL), _haveSecurity(p->have_security),
+ : System(p),
+ bootLoaders(), bootldr(nullptr),
+ _haveSecurity(p->have_security),
_haveLPAE(p->have_lpae),
_haveVirtualization(p->have_virtualization),
_genericTimer(nullptr),
fatal("Invalid physical address range (%d)\n", _physAddrRange64);
}
- if (p->boot_loader != "") {
- bootldr = createObjectFile(p->boot_loader);
+ bootLoaders.reserve(p->boot_loader.size());
+ for (const auto &bl : p->boot_loader) {
+ std::unique_ptr<ObjectFile> obj;
+ obj.reset(createObjectFile(bl));
- if (!bootldr)
- fatal("Could not read bootloader: %s\n", p->boot_loader);
+ fatal_if(!obj, "Could not read bootloader: %s\n", bl);
+ bootLoaders.emplace_back(std::move(obj));
+ }
+
+ if (kernel) {
+ bootldr = getBootLoader(kernel);
+ } else if (!bootLoaders.empty()) {
+ // No kernel specified, default to the first boot loader
+ bootldr = bootLoaders[0].get();
+ }
+
+ if (!bootLoaders.empty() && !bootldr)
+ fatal("Can't find a matching boot loader / kernel combination!");
+ if (bootldr) {
+ bootldr->loadGlobalSymbols(debugSymbolTable);
if ((bootldr->getArch() == ObjectFile::Arm64) && !_highestELIs64) {
warn("Highest ARM exception-level set to AArch32 but bootloader "
"is for AArch64. Assuming you wanted these to match.\n");
"is for AArch32. Assuming you wanted these to match.\n");
_highestELIs64 = false;
}
-
- bootldr->loadGlobalSymbols(debugSymbolTable);
-
}
+
debugPrintkEvent = addKernelFuncEvent<DebugPrintkEvent>("dprintk");
}
delete debugPrintkEvent;
}
+ObjectFile *
+ArmSystem::getBootLoader(ObjectFile *const obj)
+{
+ for (auto &bl : bootLoaders) {
+ if (bl->getArch() == obj->getArch())
+ return bl.get();
+ }
+
+ return nullptr;
+}
+
bool
ArmSystem::haveLPAE(ThreadContext *tc)
{
/*
- * Copyright (c) 2010, 2012-2013 ARM Limited
+ * Copyright (c) 2010, 2012-2013, 2015 ARM Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
#ifndef __ARCH_ARM_SYSTEM_HH__
#define __ARCH_ARM_SYSTEM_HH__
+#include <memory>
#include <string>
#include <vector>
*/
Linux::DebugPrintkEvent *debugPrintkEvent;
+ /** Bootloaders */
+ std::vector<std::unique_ptr<ObjectFile>> bootLoaders;
+
/**
* Pointer to the bootloader object
*/
*/
const bool _haveLargeAsid64;
+ protected:
+ /**
+ * Get a boot loader that matches the kernel.
+ *
+ * @param obj Kernel binary
+ * @return Pointer to boot loader ObjectFile or nullptr if there
+ * is no matching boot loader.
+ */
+ ObjectFile *getBootLoader(ObjectFile *const obj);
+
public:
typedef ArmSystemParams Params;
const Params *