From 2e2613d2c4755426cb6bfddf1ca7714b0deec177 Mon Sep 17 00:00:00 2001 From: Graeme Russ Date: Sat, 12 Feb 2011 15:11:50 +1100 Subject: [PATCH] x86: Move initial gd to fixed location --- arch/i386/cpu/start.S | 12 ++++++------ arch/i386/include/asm/global_data.h | 7 ++++++- arch/i386/lib/board.c | 36 ++++++++++++++++++++++++------------ include/configs/eNET.h | 3 +++ 4 files changed, 39 insertions(+), 19 deletions(-) diff --git a/arch/i386/cpu/start.S b/arch/i386/cpu/start.S index 97bac8f..0ce9713 100644 --- a/arch/i386/cpu/start.S +++ b/arch/i386/cpu/start.S @@ -127,13 +127,13 @@ mem_ok: /* Set the upper memory limit parameter */ subl $CONFIG_SYS_STACK_SIZE, %eax - /* Reserve space for global data */ - subl $(GD_SIZE * 4), %eax + /* Pointer to temporary global data */ + movl $CONFIG_SYS_INIT_GD_ADDR, %edx - /* %eax points to the global data structure */ - movl %esp, (GD_RAM_SIZE * 4)(%eax) - movl %ebx, (GD_FLAGS * 4)(%eax) - movl %ecx, (GD_LOAD_OFF * 4)(%eax) + /* %edx points to the global data structure */ + movl %esp, (GD_RAM_SIZE * 4)(%edx) + movl %ebx, (GD_FLAGS * 4)(%edx) + movl %ecx, (GD_LOAD_OFF * 4)(%edx) call board_init_f /* Enter, U-boot! */ diff --git a/arch/i386/include/asm/global_data.h b/arch/i386/include/asm/global_data.h index e9000c3..cd067f5 100644 --- a/arch/i386/include/asm/global_data.h +++ b/arch/i386/include/asm/global_data.h @@ -87,7 +87,12 @@ extern gd_t *gd; #define GD_FLG_COLD_BOOT 0x00100 /* Cold Boot */ #define GD_FLG_WARM_BOOT 0x00200 /* Warm Boot */ - +#if 0 #define DECLARE_GLOBAL_DATA_PTR +#else +#define XTRN_DECLARE_GLOBAL_DATA_PTR extern +#define DECLARE_GLOBAL_DATA_PTR XTRN_DECLARE_GLOBAL_DATA_PTR \ +gd_t *gd +#endif #endif /* __ASM_GBL_DATA_H */ diff --git a/arch/i386/lib/board.c b/arch/i386/lib/board.c index 2cadce8..4227312 100644 --- a/arch/i386/lib/board.c +++ b/arch/i386/lib/board.c @@ -45,7 +45,15 @@ #include #endif -DECLARE_GLOBAL_DATA_PTR; +/* + * Pointer to initial global data area + * + * Here we initialize it. + */ +#undef XTRN_DECLARE_GLOBAL_DATA_PTR +#define XTRN_DECLARE_GLOBAL_DATA_PTR /* empty = allocate here */ +DECLARE_GLOBAL_DATA_PTR = (gd_t *) (CONFIG_SYS_INIT_GD_ADDR); + /* Exports from the Linker Script */ extern ulong __text_start; @@ -168,7 +176,7 @@ gd_t *gd; /* * Load U-Boot into RAM, initialize BSS, perform relocation adjustments */ -void board_init_f (ulong gdp) +void board_init_f(ulong mem_top) { void *text_start = &__text_start; void *data_end = &__data_end; @@ -187,11 +195,11 @@ void board_init_f (ulong gdp) Elf32_Rel *re_end; /* Calculate destination RAM Address and relocation offset */ - dest_addr = (void *)gdp - (bss_end - text_start); + dest_addr = (void *)mem_top - (bss_end - text_start); rel_offset = text_start - dest_addr; /* Perform low-level initialization only when cold booted */ - if (((gd_t *)gdp)->flags & GD_FLG_COLD_BOOT) { + if (gd->flags & GD_FLG_COLD_BOOT) { /* First stage CPU initialization */ if (cpu_init_f() != 0) hang(); @@ -203,8 +211,8 @@ void board_init_f (ulong gdp) /* Copy U-Boot into RAM */ dst_addr = (ulong *)dest_addr; - src_addr = (ulong *)(text_start + ((gd_t *)gdp)->load_off); - end_addr = (ulong *)(data_end + ((gd_t *)gdp)->load_off); + 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++; @@ -217,8 +225,8 @@ void board_init_f (ulong gdp) *dst_addr++ = 0x00000000; /* Perform relocation adjustments */ - re_src = (Elf32_Rel *)(rel_dyn_start + ((gd_t *)gdp)->load_off); - re_end = (Elf32_Rel *)(rel_dyn_end + ((gd_t *)gdp)->load_off); + 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) @@ -226,11 +234,11 @@ void board_init_f (ulong gdp) *(Elf32_Addr *)(re_src->r_offset - rel_offset) -= rel_offset; } while (re_src++ < re_end); - ((gd_t *)gdp)->reloc_off = rel_offset; - ((gd_t *)gdp)->flags |= GD_FLG_RELOC; + gd->reloc_off = rel_offset; + gd->flags |= GD_FLG_RELOC; /* Enter the relocated U-Boot! */ - (board_init_r - rel_offset)((gd_t *)gdp, (ulong)dest_addr); + (board_init_r - rel_offset)(gd, (ulong)dest_addr); /* NOTREACHED - board_init_f() does not return */ while(1); @@ -242,11 +250,15 @@ void board_init_r(gd_t *id, ulong dest_addr) int i; ulong size; static bd_t bd_data; + static gd_t gd_data; init_fnc_t **init_fnc_ptr; show_boot_progress(0x21); - gd = id; + /* Global data pointer is now writable */ + gd = &gd_data; + memcpy(gd, id, sizeof(gd_t)); + /* compiler optimization barrier needed for GCC >= 3.4 */ __asm__ __volatile__("": : :"memory"); diff --git a/include/configs/eNET.h b/include/configs/eNET.h index 506f4c1..8b55cd3 100644 --- a/include/configs/eNET.h +++ b/include/configs/eNET.h @@ -164,6 +164,9 @@ #define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE #define CONFIG_SYS_MONITOR_LEN (256 * 1024) #define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 128*1024) +/* Address of temporary Global Data */ +#define CONFIG_SYS_INIT_GD_ADDR 0x19040000 + /* allow to overwrite serial and ethaddr */ #define CONFIG_ENV_OVERWRITE -- 2.7.4