aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/hw/arm/arm.h9
-rw-r--r--include/hw/arm/virt.h1
-rw-r--r--include/hw/elf_ops.h22
-rw-r--r--include/hw/loader.h59
4 files changed, 87 insertions, 4 deletions
diff --git a/include/hw/arm/arm.h b/include/hw/arm/arm.h
index 52ecf4aa8f..b2517f9a43 100644
--- a/include/hw/arm/arm.h
+++ b/include/hw/arm/arm.h
@@ -16,6 +16,13 @@
#include "qemu/notify.h"
#include "cpu.h"
+typedef enum {
+ ARM_ENDIANNESS_UNKNOWN = 0,
+ ARM_ENDIANNESS_LE,
+ ARM_ENDIANNESS_BE8,
+ ARM_ENDIANNESS_BE32,
+} arm_endianness;
+
/* armv7m.c */
DeviceState *armv7m_init(MemoryRegion *system_memory, int mem_size, int num_irq,
const char *kernel_filename, const char *cpu_model);
@@ -103,6 +110,8 @@ struct arm_boot_info {
* changing to non-secure state if implementing a non-secure boot
*/
bool secure_board_setup;
+
+ arm_endianness endianness;
};
/**
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index 1ce7847ae6..ecd8589603 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -61,6 +61,7 @@ enum {
VIRT_PCIE_MMIO_HIGH,
VIRT_GPIO,
VIRT_SECURE_UART,
+ VIRT_SECURE_MEM,
};
typedef struct MemMapEntry {
diff --git a/include/hw/elf_ops.h b/include/hw/elf_ops.h
index 0010c441d9..f510e7ec2a 100644
--- a/include/hw/elf_ops.h
+++ b/include/hw/elf_ops.h
@@ -263,7 +263,7 @@ static int glue(load_elf, SZ)(const char *name, int fd,
void *translate_opaque,
int must_swab, uint64_t *pentry,
uint64_t *lowaddr, uint64_t *highaddr,
- int elf_machine, int clear_lsb)
+ int elf_machine, int clear_lsb, int data_swab)
{
struct elfhdr ehdr;
struct elf_phdr *phdr = NULL, *ph;
@@ -366,6 +366,26 @@ static int glue(load_elf, SZ)(const char *name, int fd,
addr = ph->p_paddr;
}
+ if (data_swab) {
+ int j;
+ for (j = 0; j < file_size; j += (1 << data_swab)) {
+ uint8_t *dp = data + j;
+ switch (data_swab) {
+ case (1):
+ *(uint16_t *)dp = bswap16(*(uint16_t *)dp);
+ break;
+ case (2):
+ *(uint32_t *)dp = bswap32(*(uint32_t *)dp);
+ break;
+ case (3):
+ *(uint64_t *)dp = bswap64(*(uint64_t *)dp);
+ break;
+ default:
+ g_assert_not_reached();
+ }
+ }
+ }
+
/* the entry pointer in the ELF header is a virtual
* address, if the text segments paddr and vaddr differ
* we need to adjust the entry */
diff --git a/include/hw/loader.h b/include/hw/loader.h
index f7b43ab62f..0ba780852c 100644
--- a/include/hw/loader.h
+++ b/include/hw/loader.h
@@ -16,6 +16,18 @@ int load_image(const char *filename, uint8_t *addr); /* deprecated */
ssize_t load_image_size(const char *filename, void *addr, size_t size);
int load_image_targphys(const char *filename, hwaddr,
uint64_t max_sz);
+/**
+ * load_image_mr: load an image into a memory region
+ * @filename: Path to the image file
+ * @mr: Memory Region to load into
+ *
+ * Load the specified file into the memory region.
+ * The file loaded is registered as a ROM, so its contents will be
+ * reinstated whenever the system is reset.
+ * If the file is larger than the memory region's size the call will fail.
+ * Returns -1 on failure, or the size of the file.
+ */
+int load_image_mr(const char *filename, MemoryRegion *mr);
/* This is the limit on the maximum uncompressed image size that
* load_image_gzipped_buffer() and load_image_gzipped() will read. It prevents
@@ -32,10 +44,49 @@ int load_image_gzipped(const char *filename, hwaddr addr, uint64_t max_sz);
#define ELF_LOAD_WRONG_ARCH -3
#define ELF_LOAD_WRONG_ENDIAN -4
const char *load_elf_strerror(int error);
+
+/** load_elf:
+ * @filename: Path of ELF file
+ * @translate_fn: optional function to translate load addresses
+ * @translate_opaque: opaque data passed to @translate_fn
+ * @pentry: Populated with program entry point. Ignored if NULL.
+ * @lowaddr: Populated with lowest loaded address. Ignored if NULL.
+ * @highaddr: Populated with highest loaded address. Ignored if NULL.
+ * @bigendian: Expected ELF endianness. 0 for LE otherwise BE
+ * @elf_machine: Expected ELF machine type
+ * @clear_lsb: Set to mask off LSB of addresses (Some architectures use
+ * this for non-address data)
+ * @data_swab: Set to order of byte swapping for data. 0 for no swap, 1
+ * for swapping bytes within halfwords, 2 for bytes within
+ * words and 3 for within doublewords.
+ *
+ * Load an ELF file's contents to the emulated system's address space.
+ * Clients may optionally specify a callback to perform address
+ * translations. @pentry, @lowaddr and @highaddr are optional pointers
+ * which will be populated with various load information. @bigendian and
+ * @elf_machine give the expected endianness and machine for the ELF the
+ * load will fail if the target ELF does not match. Some architectures
+ * have some architecture-specific behaviours that come into effect when
+ * their particular values for @elf_machine are set.
+ */
+
int load_elf(const char *filename, uint64_t (*translate_fn)(void *, uint64_t),
void *translate_opaque, uint64_t *pentry, uint64_t *lowaddr,
uint64_t *highaddr, int big_endian, int elf_machine,
- int clear_lsb);
+ int clear_lsb, int data_swab);
+
+/** load_elf_hdr:
+ * @filename: Path of ELF file
+ * @hdr: Buffer to populate with header data. Header data will not be
+ * filled if set to NULL.
+ * @is64: Set to true if the ELF is 64bit. Ignored if set to NULL
+ * @errp: Populated with an error in failure cases
+ *
+ * Inspect an ELF file's header. Read its full header contents into a
+ * buffer and/or determine if the ELF is 64bit.
+ */
+void load_elf_hdr(const char *filename, void *hdr, bool *is64, Error **errp);
+
int load_aout(const char *filename, hwaddr addr, int max_sz,
int bswap_needed, hwaddr target_page_size);
int load_uimage(const char *filename, hwaddr *ep,
@@ -67,7 +118,7 @@ extern bool rom_file_has_mr;
int rom_add_file(const char *file, const char *fw_dir,
hwaddr addr, int32_t bootindex,
- bool option_rom);
+ bool option_rom, MemoryRegion *mr);
MemoryRegion *rom_add_blob(const char *name, const void *blob, size_t len,
size_t max_len, hwaddr addr,
const char *fw_file_name,
@@ -82,9 +133,11 @@ void *rom_ptr(hwaddr addr);
void hmp_info_roms(Monitor *mon, const QDict *qdict);
#define rom_add_file_fixed(_f, _a, _i) \
- rom_add_file(_f, NULL, _a, _i, false)
+ rom_add_file(_f, NULL, _a, _i, false, NULL)
#define rom_add_blob_fixed(_f, _b, _l, _a) \
rom_add_blob(_f, _b, _l, _l, _a, NULL, NULL, NULL)
+#define rom_add_file_mr(_f, _mr, _i) \
+ rom_add_file(_f, NULL, 0, _i, false, mr)
#define PC_ROM_MIN_VGA 0xc0000
#define PC_ROM_MIN_OPTION 0xc8000