This patch allows mutliple device tree binaries to be appended to zImage. A
device tree binary is selected when the 'machine_type' property in the root
node in the dtb matches the machine type passed in by the boot loader.

If the device tree binary does not have the 'machine_type' property, the device
tree is assumed to match the machine type. If no device tree binary matches,
the kernel attempts to boot with out a device tree.

Signed-off-by: John Bonesio <[email protected]>
---

 arch/arm/boot/compressed/head.S |   30 ++++++++++++++++++++++-
 arch/arm/boot/compressed/misc.c |   51 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 80 insertions(+), 1 deletions(-)

diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index c2cdc5f..f743431 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -229,7 +229,7 @@ restart:    adr     r0, LC0
  * if there are device trees (dtb) appended to zImage, advance r10 so that the
  * dtb data will get relocated along with the kernel if necessary.
  */
-
+1:
                ldr     r12, [r6, #0]
                ldr     r1, =0xedfe0dd0         @ sig is 0xdoodfeed big endian
                cmp     r12, r1
@@ -248,6 +248,7 @@ restart:    adr     r0, LC0
 
                add     r10, r10, r12
                add     r6, r6, r12
+               b       1b
 
 dtb_check_done:
                adr     r1, LC0
@@ -396,11 +397,34 @@ wont_overwrite:
  *
  * if there is a device tree (dtb) appended to zImage, set up to use this dtb.
  */
+               mvn     r9, #0                  @ r9 dtb search result
+                                               @ ... -1 = no appended dtb
+dt_search:
                ldr     r0, [r6, #0]
                ldr     r1, =0xedfe0dd0         @ sig is 0xdoodfeed big endian
                cmp     r0, r1
                bne     keep_atags
 
+               /* Get the dtb's size */
+               ldr     r5, [r6, #4]            @ device tree size
+
+               /* convert dtb size to little endian */
+               eor     r1, r5, r5, ror #16
+               bic     r1, r1, #0x00ff0000
+               mov     r5, r5, ror #8
+               eor     r5, r5, r1, lsr #8
+
+               mov     r0, r6
+               mov     r1, r7
+               bl      match_dt_machine_type
+               mov     r9, r0                  @ save result
+               cmp     r0, #0
+               bne     dt_found
+
+               add     r6, r5
+               b       dt_search
+
+dt_found:
 #ifndef CONFIG_ZBOOT_ROM
                ldr     r0, [r6, #4]
                add     r0, r0, #MERGE_SPACE    
@@ -413,6 +437,10 @@ wont_overwrite:
 #endif
                mov     r8, r6                  @ use the appended device tree
 keep_atags:
+
+               mov     r0, r9
+               mov     r1, r7
+               bl      put_dt_match_str
 #endif
 /*
  * Set up some pointers, and start decompressing.
diff --git a/arch/arm/boot/compressed/misc.c b/arch/arm/boot/compressed/misc.c
index 9af05ed..f16ca6a 100644
--- a/arch/arm/boot/compressed/misc.c
+++ b/arch/arm/boot/compressed/misc.c
@@ -25,6 +25,8 @@ unsigned int __machine_arch_type;
 #include <linux/stddef.h>      /* for NULL */
 #include <linux/linkage.h>
 #include <asm/string.h>
+#include <fdt.h>
+#include <libfdt.h>
 
 #include <asm/unaligned.h>
 
@@ -227,6 +229,55 @@ void *memcpy(void *__dest, __const void *__src, size_t __n)
        return __dest;
 }
 
+int match_dt_machine_type(void *fdt, unsigned int mach_type)
+{
+       int offset;
+       unsigned dt_mach_type;
+       unsigned *prop;
+       int match;
+
+       offset = fdt_path_offset(fdt, "/");
+       if (offset < 0)
+               return offset;
+
+       prop = fdt_getprop(fdt, offset, "machine-type", NULL);
+
+       if (! prop)
+               return 2;
+
+       dt_mach_type = fdt32_to_cpu(*prop);
+
+       return mach_type == dt_mach_type;
+}
+
+void put_dt_match_str(int match, unsigned int mach_type)
+{
+       switch (match) {
+       case 2:
+               putstr("'machine-type' property not found.");
+               putstr(" Device tree matched by default\n");
+               break;
+       case 1:
+               putstr("Device tree matched (machine type: ");
+               puthex(mach_type);
+               putstr(")\n");
+               break;
+       case 0:
+               putstr("Device tree not matched (machine type: ");
+               puthex(mach_type);
+               putstr(")\n");
+               break;
+       case -1:
+               /*
+                * -1 means 'no device tree appended' so don't display any
+                * message
+                */
+               break;
+       default:
+               putstr("Unknown device tree match type.\n");
+       }
+}
+
 /*
  * gzip delarations
  */

_______________________________________________
devicetree-discuss mailing list
[email protected]
https://lists.ozlabs.org/listinfo/devicetree-discuss

Reply via email to