x86: Split board_init_f() into init_fnc_t compatible functions
authorGraeme Russ <graeme.russ@gmail.com>
Sat, 12 Feb 2011 04:12:06 +0000 (15:12 +1100)
committerGraeme Russ <graeme.russ@gmail.com>
Sat, 12 Feb 2011 04:12:06 +0000 (15:12 +1100)
arch/i386/include/asm/global_data.h
arch/i386/lib/board.c

index cd067f548661d7a377c6bf3d19ac1186df3cad71..f8a16d646fd41db195838a0c667d3de0c0679a96 100644 (file)
@@ -46,6 +46,8 @@ typedef       struct global_data {
        unsigned long   env_valid;      /* Checksum of Environment valid? */
        unsigned long   cpu_clk;        /* CPU clock in Hz!             */
        unsigned long   bus_clk;
+       unsigned long   relocaddr;      /* Start address of U-Boot in RAM */
+       unsigned long   start_addr_sp;  /* start_addr_stackpointer */
        phys_size_t     ram_size;       /* RAM size */
        unsigned long   reset_status;   /* reset status register at boot */
        void            **jt;           /* jump table */
@@ -67,11 +69,13 @@ extern gd_t *gd;
 #define GD_ENV_VALID   7
 #define GD_CPU_CLK     8
 #define GD_BUS_CLK     9
-#define GD_RAM_SIZE    10
-#define GD_RESET_STATUS        11
-#define GD_JT          12
+#define GD_RELOC_ADDR  10
+#define GD_START_ADDR_SP       11
+#define GD_RAM_SIZE    12
+#define GD_RESET_STATUS        13
+#define GD_JT          14
 
-#define GD_SIZE                13
+#define GD_SIZE                15
 
 /*
  * Global Data Flags
index 8ec04462b9197f0a8122c4b068a666021149032d..c13efc83f91c6a03bf3265f9d09ce28d3a597488 100644 (file)
@@ -170,30 +170,71 @@ init_fnc_t *init_sequence[] = {
 
 gd_t *gd;
 
-/*
- * Load U-Boot into RAM, initialize BSS, perform relocation adjustments
- */
-void board_init_f(ulong boot_flags)
+static int calculate_relocation_address(void)
 {
        void *text_start = &__text_start;
-       void *data_end = &__data_end;
-       void *rel_dyn_start = &__rel_dyn_start;
-       void *rel_dyn_end = &__rel_dyn_end;
+       void *bss_end = &__bss_end;
+       void *dest_addr;
+       ulong rel_offset;
+
+       /* Calculate destination RAM Address and relocation offset */
+       dest_addr = (void *)gd->ram_size;
+       dest_addr -= CONFIG_SYS_STACK_SIZE;
+       dest_addr -= (bss_end - text_start);
+       rel_offset = dest_addr - text_start;
+
+       gd->start_addr_sp = gd->ram_size;
+       gd->relocaddr = (ulong)dest_addr;
+       gd->reloc_off = rel_offset;
+
+       return 0;
+}
+
+static int copy_uboot_to_ram(void)
+{
+       ulong *dst_addr = (ulong *)gd->relocaddr;
+       ulong *src_addr = (ulong *)&__text_start;
+       ulong *end_addr = (ulong *)&__data_end;
+
+       while (src_addr < end_addr)
+               *dst_addr++ = *src_addr++;
+
+       return 0;
+}
+
+static int clear_bss(void)
+{
        void *bss_start = &__bss_start;
        void *bss_end = &__bss_end;
 
-       ulong *dst_addr;
-       ulong *src_addr;
-       ulong *end_addr;
+       ulong *dst_addr = (ulong *)(bss_start + gd->reloc_off);
+       ulong *end_addr = (ulong *)(bss_end + gd->reloc_off);;
 
-       void *addr_sp;
-       void *dest_addr;
-       ulong rel_offset;
-       Elf32_Rel *re_src;
-       Elf32_Rel *re_end;
+       while (dst_addr < end_addr)
+               *dst_addr++ = 0x00000000;
+
+       return 0;
+}
 
-       gd->flags = boot_flags;
+static int do_elf_reloc_fixups(void)
+{
+       Elf32_Rel *re_src = (Elf32_Rel *)(&__rel_dyn_start);
+       Elf32_Rel *re_end = (Elf32_Rel *)(&__rel_dyn_end);
+
+       do {
+               if (re_src->r_offset >= CONFIG_SYS_TEXT_BASE)
+                       if (*(Elf32_Addr *)(re_src->r_offset + gd->reloc_off) >= CONFIG_SYS_TEXT_BASE)
+                               *(Elf32_Addr *)(re_src->r_offset + gd->reloc_off) += gd->reloc_off;
+       } while (re_src++ < re_end);
+
+       return 0;
+}
 
+/*
+ * Load U-Boot into RAM, initialize BSS, perform relocation adjustments
+ */
+void board_init_f(ulong boot_flags)
+{
        if (env_init() != 0)
                hang();
 
@@ -209,12 +250,8 @@ void board_init_f(ulong boot_flags)
        if (dram_init_f() != 0)
                hang();
 
-       /* Calculate destination RAM Address and relocation offset */
-       dest_addr = (void *)gd->ram_size;
-       addr_sp = dest_addr;
-       dest_addr -= CONFIG_SYS_STACK_SIZE;
-       dest_addr -= (bss_end - text_start);
-       rel_offset = dest_addr - text_start;
+       if (calculate_relocation_address() != 0)
+               hang();
 
        /* First stage CPU initialization */
        if (cpu_init_f() != 0)
@@ -225,35 +262,19 @@ void board_init_f(ulong boot_flags)
                hang();
 
        /* Copy U-Boot into RAM */
-       dst_addr = (ulong *)dest_addr;
-       src_addr = (ulong *)(text_start + gd->load_off);
-       end_addr = (ulong *)(data_end  + gd->load_off);
-
-       while (src_addr < end_addr)
-               *dst_addr++ = *src_addr++;
-
-       /* Clear BSS */
-       dst_addr = (ulong *)(bss_start + rel_offset);
-       end_addr = (ulong *)(bss_end + rel_offset);
-
-       while (dst_addr < end_addr)
-               *dst_addr++ = 0x00000000;
+       if (copy_uboot_to_ram() != 0)
+               hang();
 
-       /* Perform relocation adjustments */
-       re_src = (Elf32_Rel *)(rel_dyn_start + gd->load_off);
-       re_end = (Elf32_Rel *)(rel_dyn_end + gd->load_off);
+       if (clear_bss() != 0)
+               hang();
 
-       do {
-               if (re_src->r_offset >= CONFIG_SYS_TEXT_BASE)
-                       if (*(Elf32_Addr *)(re_src->r_offset + rel_offset) >= CONFIG_SYS_TEXT_BASE)
-                               *(Elf32_Addr *)(re_src->r_offset + rel_offset) += rel_offset;
-       } while (re_src++ < re_end);
+       if (do_elf_reloc_fixups() != 0)
+               hang();
 
-       gd->reloc_off = rel_offset;
        gd->flags |= GD_FLG_RELOC;
 
        /* Enter the relocated U-Boot! */
-       relocate_code((ulong)addr_sp, gd, (ulong)dest_addr);
+       relocate_code(gd->start_addr_sp, gd, gd->relocaddr);
 
        /* NOTREACHED - relocate_code() does not return */
        while(1);