diff options
Diffstat (limited to 'arch/x86/lib')
-rw-r--r-- | arch/x86/lib/board.c | 3 | ||||
-rw-r--r-- | arch/x86/lib/init_helpers.c | 23 | ||||
-rw-r--r-- | arch/x86/lib/init_wrappers.c | 1 | ||||
-rw-r--r-- | arch/x86/lib/relocate.c | 17 |
4 files changed, 42 insertions, 2 deletions
diff --git a/arch/x86/lib/board.c b/arch/x86/lib/board.c index 22bc26d..2441a66 100644 --- a/arch/x86/lib/board.c +++ b/arch/x86/lib/board.c @@ -32,6 +32,7 @@ */ #include <common.h> +#include <fdtdec.h> #include <watchdog.h> #include <stdio_dev.h> #include <asm/u-boot-x86.h> @@ -131,6 +132,7 @@ init_fnc_t *init_sequence_f[] = { init_fnc_t *init_sequence_f_r[] = { init_cache_f_r, copy_uboot_to_ram, + copy_fdt_to_ram, clear_bss, do_elf_reloc_fixups, @@ -217,6 +219,7 @@ static void do_init_loop(init_fnc_t **init_fnc_ptr) void board_init_f(ulong boot_flags) { + gd->fdt_blob = gd->arch.new_fdt = NULL; gd->flags = boot_flags; do_init_loop(init_sequence_f); diff --git a/arch/x86/lib/init_helpers.c b/arch/x86/lib/init_helpers.c index ff2d21f..414fdcc 100644 --- a/arch/x86/lib/init_helpers.c +++ b/arch/x86/lib/init_helpers.c @@ -22,6 +22,7 @@ */ #include <common.h> #include <command.h> +#include <fdtdec.h> #include <stdio_dev.h> #include <version.h> #include <malloc.h> @@ -85,17 +86,35 @@ int calculate_relocation_address(void) (uintptr_t)&__text_start; ulong total_size; ulong dest_addr; + ulong fdt_size = 0; +#if defined(CONFIG_OF_SEPARATE) && defined(CONFIG_OF_CONTROL) + if (gd->fdt_blob) + fdt_size = ALIGN(fdt_totalsize(gd->fdt_blob) + 0x1000, 32); +#endif total_size = ALIGN(uboot_size, 1 << 12) + CONFIG_SYS_MALLOC_LEN + - CONFIG_SYS_STACK_SIZE; + CONFIG_SYS_STACK_SIZE + fdt_size; + dest_addr = board_get_usable_ram_top(total_size); /* * NOTE: All destination address are rounded down to 16-byte * boundary to satisfy various worst-case alignment * requirements */ - dest_addr = board_get_usable_ram_top(total_size); + dest_addr &= ~15; +#if defined(CONFIG_OF_SEPARATE) && defined(CONFIG_OF_CONTROL) + /* + * If the device tree is sitting immediate above our image then we + * must relocate it. If it is embedded in the data section, then it + * will be relocated with other data. + */ + if (gd->fdt_blob) { + dest_addr -= fdt_size; + gd->arch.new_fdt = (void *)dest_addr; + dest_addr &= ~15; + } +#endif /* U-Boot is below the FDT */ dest_addr -= uboot_size; dest_addr &= ~((1 << 12) - 1); diff --git a/arch/x86/lib/init_wrappers.c b/arch/x86/lib/init_wrappers.c index cca018f..19af875 100644 --- a/arch/x86/lib/init_wrappers.c +++ b/arch/x86/lib/init_wrappers.c @@ -22,6 +22,7 @@ */ #include <common.h> #include <environment.h> +#include <fdtdec.h> #include <serial.h> #include <kgdb.h> #include <scsi.h> diff --git a/arch/x86/lib/relocate.c b/arch/x86/lib/relocate.c index 23edca9..3a38e52 100644 --- a/arch/x86/lib/relocate.c +++ b/arch/x86/lib/relocate.c @@ -32,6 +32,7 @@ */ #include <common.h> +#include <libfdt.h> #include <malloc.h> #include <asm/u-boot-x86.h> #include <asm/relocate.h> @@ -46,6 +47,22 @@ int copy_uboot_to_ram(void) return 0; } +int copy_fdt_to_ram(void) +{ + if (gd->arch.new_fdt) { + ulong fdt_size; + + fdt_size = ALIGN(fdt_totalsize(gd->fdt_blob) + 0x1000, 32); + + memcpy(gd->arch.new_fdt, gd->fdt_blob, fdt_size); + debug("Relocated fdt from %p to %p, size %lx\n", + gd->fdt_blob, gd->arch.new_fdt, fdt_size); + gd->fdt_blob = gd->arch.new_fdt; + } + + return 0; +} + int clear_bss(void) { ulong dst_addr = (ulong)&__bss_start + gd->reloc_off; |