aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2019-07-26 16:23:07 +0100
committerPeter Maydell <peter.maydell@linaro.org>2019-07-26 16:23:07 +0100
commitfff3159900d2b95613a9cb75fc3703e67a674729 (patch)
treeea85ccdfd9d85e97ecd0ce33d4ac22a77ceaa0d9 /hw
parentc985266ea5b50e46e07b3568c1346e10064205c9 (diff)
parent67505c114e6acc26f3a1a2b74833c61b6a34ff95 (diff)
Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20190726' into staging
target-arm queue: * Fix broken migration on pl330 device * Fix broken migration on stellaris-input device * Add type checks to vmstate varry macros to avoid this class of bugs * hw/arm/boot: Fix some remaining cases where we would put the initrd on top of the kernel image # gpg: Signature made Fri 26 Jul 2019 16:19:17 BST # gpg: using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE # gpg: issuer "peter.maydell@linaro.org" # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [ultimate] # gpg: aka "Peter Maydell <pmaydell@gmail.com>" [ultimate] # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [ultimate] # Primary key fingerprint: E1A5 C593 CD41 9DE2 8E83 15CF 3C25 25ED 1436 0CDE * remotes/pmaydell/tags/pull-target-arm-20190726: hw/arm/boot: Further improve initrd positioning code hw/arm/boot: Rename elf_{low, high}_addr to image_{low, high}_addr vmstate.h: Type check VMSTATE_STRUCT_VARRAY macros stellaris_input: Fix vmstate description of buttons field pl330: fix vmstate description Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r--hw/arm/boot.c37
-rw-r--r--hw/dma/pl330.c17
-rw-r--r--hw/input/stellaris_input.c10
3 files changed, 42 insertions, 22 deletions
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 1fb24fbef2..c2b89b3bb9 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -986,7 +986,9 @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
int kernel_size;
int initrd_size;
int is_linux = 0;
- uint64_t elf_entry, elf_low_addr, elf_high_addr;
+ uint64_t elf_entry;
+ /* Addresses of first byte used and first byte not used by the image */
+ uint64_t image_low_addr = 0, image_high_addr = 0;
int elf_machine;
hwaddr entry;
static const ARMInsnFixup *primary_loader;
@@ -1014,24 +1016,24 @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
info->nb_cpus = 1;
/* Assume that raw images are linux kernels, and ELF images are not. */
- kernel_size = arm_load_elf(info, &elf_entry, &elf_low_addr,
- &elf_high_addr, elf_machine, as);
+ kernel_size = arm_load_elf(info, &elf_entry, &image_low_addr,
+ &image_high_addr, elf_machine, as);
if (kernel_size > 0 && have_dtb(info)) {
/*
* If there is still some room left at the base of RAM, try and put
* the DTB there like we do for images loaded with -bios or -pflash.
*/
- if (elf_low_addr > info->loader_start
- || elf_high_addr < info->loader_start) {
+ if (image_low_addr > info->loader_start
+ || image_high_addr < info->loader_start) {
/*
- * Set elf_low_addr as address limit for arm_load_dtb if it may be
+ * Set image_low_addr as address limit for arm_load_dtb if it may be
* pointing into RAM, otherwise pass '0' (no limit)
*/
- if (elf_low_addr < info->loader_start) {
- elf_low_addr = 0;
+ if (image_low_addr < info->loader_start) {
+ image_low_addr = 0;
}
info->dtb_start = info->loader_start;
- info->dtb_limit = elf_low_addr;
+ info->dtb_limit = image_low_addr;
}
}
entry = elf_entry;
@@ -1039,17 +1041,29 @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
uint64_t loadaddr = info->loader_start + KERNEL_NOLOAD_ADDR;
kernel_size = load_uimage_as(info->kernel_filename, &entry, &loadaddr,
&is_linux, NULL, NULL, as);
+ if (kernel_size >= 0) {
+ image_low_addr = loadaddr;
+ image_high_addr = image_low_addr + kernel_size;
+ }
}
if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64) && kernel_size < 0) {
kernel_size = load_aarch64_image(info->kernel_filename,
info->loader_start, &entry, as);
is_linux = 1;
+ if (kernel_size >= 0) {
+ image_low_addr = entry;
+ image_high_addr = image_low_addr + kernel_size;
+ }
} else if (kernel_size < 0) {
/* 32-bit ARM */
entry = info->loader_start + KERNEL_LOAD_ADDR;
kernel_size = load_image_targphys_as(info->kernel_filename, entry,
ram_end - KERNEL_LOAD_ADDR, as);
is_linux = 1;
+ if (kernel_size >= 0) {
+ image_low_addr = entry;
+ image_high_addr = image_low_addr + kernel_size;
+ }
}
if (kernel_size < 0) {
error_report("could not load kernel '%s'", info->kernel_filename);
@@ -1081,7 +1095,10 @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu,
* we might still make a bad choice here.
*/
info->initrd_start = info->loader_start +
- MAX(MIN(info->ram_size / 2, 128 * 1024 * 1024), kernel_size);
+ MIN(info->ram_size / 2, 128 * 1024 * 1024);
+ if (image_high_addr) {
+ info->initrd_start = MAX(info->initrd_start, image_high_addr);
+ }
info->initrd_start = TARGET_PAGE_ALIGN(info->initrd_start);
if (is_linux) {
diff --git a/hw/dma/pl330.c b/hw/dma/pl330.c
index 58df965a46..a56a3e7771 100644
--- a/hw/dma/pl330.c
+++ b/hw/dma/pl330.c
@@ -218,11 +218,12 @@ typedef struct PL330Queue {
static const VMStateDescription vmstate_pl330_queue = {
.name = "pl330_queue",
- .version_id = 1,
- .minimum_version_id = 1,
+ .version_id = 2,
+ .minimum_version_id = 2,
.fields = (VMStateField[]) {
- VMSTATE_STRUCT_VARRAY_UINT32(queue, PL330Queue, queue_size, 1,
- vmstate_pl330_queue_entry, PL330QueueEntry),
+ VMSTATE_STRUCT_VARRAY_POINTER_UINT32(queue, PL330Queue, queue_size,
+ vmstate_pl330_queue_entry,
+ PL330QueueEntry),
VMSTATE_END_OF_LIST()
}
};
@@ -278,12 +279,12 @@ struct PL330State {
static const VMStateDescription vmstate_pl330 = {
.name = "pl330",
- .version_id = 1,
- .minimum_version_id = 1,
+ .version_id = 2,
+ .minimum_version_id = 2,
.fields = (VMStateField[]) {
VMSTATE_STRUCT(manager, PL330State, 0, vmstate_pl330_chan, PL330Chan),
- VMSTATE_STRUCT_VARRAY_UINT32(chan, PL330State, num_chnls, 0,
- vmstate_pl330_chan, PL330Chan),
+ VMSTATE_STRUCT_VARRAY_POINTER_UINT32(chan, PL330State, num_chnls,
+ vmstate_pl330_chan, PL330Chan),
VMSTATE_VBUFFER_UINT32(lo_seqn, PL330State, 1, NULL, num_chnls),
VMSTATE_VBUFFER_UINT32(hi_seqn, PL330State, 1, NULL, num_chnls),
VMSTATE_STRUCT(fifo, PL330State, 0, vmstate_pl330_fifo, PL330Fifo),
diff --git a/hw/input/stellaris_input.c b/hw/input/stellaris_input.c
index 20c87d86f4..3a666d61d4 100644
--- a/hw/input/stellaris_input.c
+++ b/hw/input/stellaris_input.c
@@ -60,12 +60,14 @@ static const VMStateDescription vmstate_stellaris_button = {
static const VMStateDescription vmstate_stellaris_gamepad = {
.name = "stellaris_gamepad",
- .version_id = 1,
- .minimum_version_id = 1,
+ .version_id = 2,
+ .minimum_version_id = 2,
.fields = (VMStateField[]) {
VMSTATE_INT32(extension, gamepad_state),
- VMSTATE_STRUCT_VARRAY_INT32(buttons, gamepad_state, num_buttons, 0,
- vmstate_stellaris_button, gamepad_button),
+ VMSTATE_STRUCT_VARRAY_POINTER_INT32(buttons, gamepad_state,
+ num_buttons,
+ vmstate_stellaris_button,
+ gamepad_button),
VMSTATE_END_OF_LIST()
}
};