# configuration information about the physical memory layout to
# the kernel, e.g. using ATAG or ACPI
conf_table_reported = Param.Bool(True, "Report to configuration table")
+
+ # Image file to load into this memory as its initial contents. This is
+ # particularly useful for ROMs.
+ image_file = Param.String('',
+ "Image to load into memory as its initial contents")
#include <vector>
#include "arch/locked_mem.hh"
+#include "base/loader/memory_image.hh"
+#include "base/loader/object_file.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
#include "debug/LLSC.hh"
range.to_string());
}
+void
+AbstractMemory::initState()
+{
+ ClockedObject::initState();
+
+ const auto &file = params()->image_file;
+ if (file == "")
+ return;
+
+ auto *object = createObjectFile(file, true);
+ fatal_if(!object, "%s: Could not load %s.", name(), file);
+
+ panic_if(!object->loadGlobalSymbols(debugSymbolTable),
+ "%s: Could not load symbols from %s.", name(), file);
+
+ MemoryImage image = object->buildImage();
+
+ AddrRange image_range(image.minAddr(), image.maxAddr());
+ if (!range.contains(image_range.start())) {
+ warn("%s: Moving image from %s to memory address range %s.",
+ name(), image_range.to_string(), range.to_string());
+ image = image.offset(range.start());
+ image_range = AddrRange(image.minAddr(), image.maxAddr());
+ }
+ panic_if(!image_range.isSubset(range), "%s: memory image %s doesn't fit.",
+ name(), file);
+
+ PortProxy proxy([this](PacketPtr pkt) { functionalAccess(pkt); }, size());
+
+ panic_if(!image.write(proxy), "%s: Unable to write image.");
+}
+
void
AbstractMemory::setBackingStore(uint8_t* pmem_addr)
{