diff mbox

[v4,2/6] hw/arm/boot: dtb start and limit moved in arm_boot_info

Message ID 1414763612-4939-3-git-send-email-eric.auger@linaro.org
State New
Headers show

Commit Message

Auger Eric Oct. 31, 2014, 1:53 p.m. UTC
Two fields are added in arm_boot_info (dtb_start and dtb_limit). The
prototype of arm_load_kernel is changed to only use arm_boot_info.

The rationale behind introducing that change is when dealing with
dynamic sysbus devices, we need to upgrade the device tree with dynamic
device nodes after the dtb is already loaded. Storing those parameters
in arm_boot_info allows to avoid computing again dtb_start and
dtb_load, as done in arm_load_kernel.

Signed-off-by: Eric Auger <eric.auger@linaro.org>
---
 hw/arm/boot.c        | 38 +++++++++++++++++++++-----------------
 include/hw/arm/arm.h |  5 +++--
 2 files changed, 24 insertions(+), 19 deletions(-)
diff mbox

Patch

diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index f5714ea..9f0662e 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -314,24 +314,21 @@  static void set_kernel_args_old(const struct arm_boot_info *info)
 
 /**
  * arm_load_dtb() - load a device tree binary image into memory
- * @addr:       the address to load the image at
  * @binfo:      struct describing the boot environment
- * @addr_limit: upper limit of the available memory area at @addr
  *
  * Load a device tree supplied by the machine or by the user  with the
- * '-dtb' command line option, and put it at offset @addr in target
- * memory.
+ * '-dtb' command line option, and put it at offset binfo->dtb_start in
+ * target memory.
  *
- * If @addr_limit contains a meaningful value (i.e., it is strictly greater
- * than @addr), the device tree is only loaded if its size does not exceed
- * the limit.
+ * If binfo->dtb_limit contains a meaningful value (i.e., it is strictly
+ * greater binfo->dtb_start, the device tree is only loaded if its size does
+ * not exceed this upper limit.
  *
  * Returns: the size of the device tree image on success,
  *          0 if the image size exceeds the limit,
  *          -1 on errors.
  */
-int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
-                 hwaddr addr_limit)
+int arm_load_dtb(const struct arm_boot_info *binfo)
 {
     void *fdt = NULL;
     int size, rc;
@@ -360,7 +357,8 @@  int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
         }
     }
 
-    if (addr_limit > addr && size > (addr_limit - addr)) {
+    if (binfo->dtb_limit > binfo->dtb_start &&
+            size > (binfo->dtb_limit - binfo->dtb_start)) {
         /* Installing the device tree blob at addr would exceed addr_limit.
          * Whether this constitutes failure is up to the caller to decide,
          * so just return 0 as size, i.e., no error.
@@ -427,7 +425,7 @@  int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
     /* Put the DTB into the memory map as a ROM image: this will ensure
      * the DTB is copied again upon reset, even if addr points into RAM.
      */
-    rom_add_blob_fixed("dtb", fdt, size, addr);
+    rom_add_blob_fixed("dtb", fdt, size, binfo->dtb_start);
 
     g_free(fdt);
 
@@ -504,7 +502,10 @@  void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
             /* If we have a device tree blob, but no kernel to supply it to,
              * copy it to the base of RAM for a bootloader to pick up.
              */
-            if (arm_load_dtb(info->loader_start, info, 0) < 0) {
+            info->dtb_start = info->loader_start;
+            info->dtb_limit = 0;
+
+            if (arm_load_dtb(info) < 0) {
                 exit(1);
             }
         }
@@ -572,7 +573,9 @@  void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
             if (elf_low_addr < info->loader_start) {
                 elf_low_addr = 0;
             }
-            if (arm_load_dtb(info->loader_start, info, elf_low_addr) < 0) {
+            info->dtb_start = info->loader_start;
+            info->dtb_limit = elf_low_addr;
+            if (arm_load_dtb(info) < 0) {
                 exit(1);
             }
         }
@@ -635,12 +638,13 @@  void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
              * kernels will trash anything in the 4K page the initrd
              * ends in, so make sure the DTB isn't caught up in that.
              */
-            hwaddr dtb_start = QEMU_ALIGN_UP(info->initrd_start + initrd_size,
-                                             4096);
-            if (arm_load_dtb(dtb_start, info, 0) < 0) {
+            info->dtb_start = QEMU_ALIGN_UP(info->initrd_start + initrd_size,
+                                            4096);
+            info->dtb_limit = 0;
+            if (arm_load_dtb(info) < 0) {
                 exit(1);
             }
-            fixupcontext[FIXUP_ARGPTR] = dtb_start;
+            fixupcontext[FIXUP_ARGPTR] = info->dtb_start;
         } else {
             fixupcontext[FIXUP_ARGPTR] = info->loader_start + KERNEL_ARGS_ADDR;
             if (info->ram_size >= (1ULL << 32)) {
diff --git a/include/hw/arm/arm.h b/include/hw/arm/arm.h
index 5fdae7b..5f1ecb7 100644
--- a/include/hw/arm/arm.h
+++ b/include/hw/arm/arm.h
@@ -65,11 +65,12 @@  struct arm_boot_info {
     int is_linux;
     hwaddr initrd_start;
     hwaddr initrd_size;
+    hwaddr dtb_start; /* start address of the dtb */
+    hwaddr dtb_limit; /* upper RAM limit the dtb cannot overshoot */
     hwaddr entry;
 };
 void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info);
-int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo,
-                 hwaddr addr_limit);
+int arm_load_dtb(const struct arm_boot_info *binfo);
 
 /* Multiplication factor to convert from system clock ticks to qemu timer
    ticks.  */