x86: Split board_init_f() into init_fnc_t compatible functions

This commit is contained in:
Graeme Russ 2011-02-12 15:12:06 +11:00
parent 5fed82110d
commit 71a5404974
2 changed files with 77 additions and 52 deletions

View 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

View File

@ -170,30 +170,71 @@ init_fnc_t *init_sequence[] = {
gd_t *gd;
static int calculate_relocation_address(void)
{
void *text_start = &__text_start;
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 *)(bss_start + gd->reloc_off);
ulong *end_addr = (ulong *)(bss_end + gd->reloc_off);;
while (dst_addr < end_addr)
*dst_addr++ = 0x00000000;
return 0;
}
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)
{
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_start = &__bss_start;
void *bss_end = &__bss_end;
ulong *dst_addr;
ulong *src_addr;
ulong *end_addr;
void *addr_sp;
void *dest_addr;
ulong rel_offset;
Elf32_Rel *re_src;
Elf32_Rel *re_end;
gd->flags = 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);
if (copy_uboot_to_ram() != 0)
hang();
while (src_addr < end_addr)
*dst_addr++ = *src_addr++;
if (clear_bss() != 0)
hang();
/* Clear BSS */
dst_addr = (ulong *)(bss_start + rel_offset);
end_addr = (ulong *)(bss_end + rel_offset);
if (do_elf_reloc_fixups() != 0)
hang();
while (dst_addr < end_addr)
*dst_addr++ = 0x00000000;
/* Perform relocation adjustments */
re_src = (Elf32_Rel *)(rel_dyn_start + gd->load_off);
re_end = (Elf32_Rel *)(rel_dyn_end + gd->load_off);
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);
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);