On 15/11/10 07:05, Albert ARIBAUD wrote: > Le 14/11/2010 20:34, Graeme Russ a écrit : >> On 15/11/10 06:23, Wolfgang Denk wrote: >>> Dear Albert ARIBAUD, >>> >>> In message<[email protected]> you wrote: >>>> >>>> Alright, then I think we should document how we comply, or do not >>>> comply, with GNU EABI / AAPCS (maybe a README.arm that people could read >>>> up) -- and I think if there is a way to access GD both before and after >>>> relocation without making a register unavailable to the whole u-boot >>>> code, then we should use it. >>> >>> By the way - it should be not difficult to use a normal extern pointer >>> to reference the global data; see >>> "arch/powerpc/include/asm/global_data.h": >>> >>> 194 #if 1 >>> 195 #define DECLARE_GLOBAL_DATA_PTR register volatile gd_t *gd asm >>> ("r2") >>> 196 #else /* We could use plain global data, but the resulting code is >>> bigger */ >>> 197 #define XTRN_DECLARE_GLOBAL_DATA_PTR extern >>> 198 #define DECLARE_GLOBAL_DATA_PTR XTRN_DECLARE_GLOBAL_DATA_PTR \ >>> 199 gd_t *gd >>> 200 #endif >> >> I think you will find this peculiar to PowerPC > > I don't think Wolfgang's idea is actually processor-specific. > > Each processor has a way to define globals, which end up in the initialized > data or bss area. BSS is not available before relocation, but initialized > data is, and remains so after relocation. > > So if we define gd as an initialized pointer (residing in the initialized > data area), it will be available both before and after relocation. > > Before relocation, this pointer will be read-only. We can set it at compile > time if we know for each arch (or board) a good address in RAM or IRAM > where gd can exist. > > After relocation, the pointer becomes read-write: we can copy gd content > from (I)RAM to RAM if necessary and then update the gd pointer. > >> What you are talking about is exactly how x86 defines gd, but for x86, gd >> is not accessible until after relocation > > Could it become accessible with the idea I expose above? >
Yes - The following patch uses CONFIG_SYS_INIT_SP_ADDR as a temporary global data area which is copied to a permanent global data structure located in the data section. I honestly don't know where I stand on this solution though. By using FS, I can emulate the 'global register variable' and the initial global data structure can end up anywhere it needs to be without needing to define CONFIG_SYS_INIT_SP_ADDR but it will involve self-modifying code I would prefer not to re-introduce. However, this method requires CONFIG_SYS_INIT_SP_ADDR which is casting a certain memory location (in RAM) in stone. Now the eNET has some battery backed SRAM on board which I can point CONFIG_SYS_INIT_SP_ADDR. So I could move SDRAM initialisation into C code, but this is not guaranteed for every x86 board (and for the eNET, it reduces the amount of battery-backed configuration memory available). I am looking to port U-Boot to a VIA EPIA EN15000 single board computer. This has no SRAM. The VIA board has a C7 processor which coreboot has a 'Cache-as-RAM' (CAR) implementation for, and the SC520 might support CAR (still looking). If this is the case, I think I can unequivocally support the solution based on CONFIG_SYS_INIT_SP_ADDR and move low-level init into board_init_f() in line with the other arches. For now, consider it a +0.5 vote for the patch below :) Regards, Graeme commit e38af43f0246335578b8c207e8097fd0c5fca520 Author: Graeme Russ <[email protected]> Date: Mon Nov 15 21:15:52 2010 +1100 x86 Global Data Mods diff --git a/arch/i386/cpu/start.S b/arch/i386/cpu/start.S index aaf9dba..4c04a5a 100644 --- a/arch/i386/cpu/start.S +++ b/arch/i386/cpu/start.S @@ -127,14 +127,14 @@ mem_ok: /* Set the upper memory limit parameter */ subl $CONFIG_SYS_STACK_SIZE, %eax - /* Reserve space for global data */ - subl $(GD_SIZE * 4), %eax - - /* %eax points to the global data structure */ + /* Load some required values into the global data structure */ + movl $CONFIG_SYS_INIT_SP_ADDR, %eax movl %esp, (GD_RAM_SIZE * 4)(%eax) - movl %ebx, (GD_FLAGS * 4)(%eax) movl %ecx, (GD_LOAD_OFF * 4)(%eax) + /* Setup bootflags parameter to board_init_f() */ + movl %ebx, %eax + call board_init_f /* Enter, U-boot! */ /* indicate (lack of) progress */ diff --git a/arch/i386/include/asm/global_data.h b/arch/i386/include/asm/global_data.h index e9000c3..03ecc3c 100644 --- a/arch/i386/include/asm/global_data.h +++ b/arch/i386/include/asm/global_data.h @@ -88,6 +88,12 @@ extern gd_t *gd; #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 1a962d3..11e6569 100644 --- a/arch/i386/lib/board.c +++ b/arch/i386/lib/board.c @@ -45,7 +45,24 @@ #include <miiphy.h> #endif -DECLARE_GLOBAL_DATA_PTR; +#if 1 /* We could use plain global data, but the resulting code is bigger */ +/* + * 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_SP_ADDR); +#endif /* 0 */ + +static inline gd_t *get_gd_ptr(void) +{ + gd_t *gd_ptr; + + asm volatile("gs mov 0, %0\n" : "=r" (gd_ptr)); + return gd_ptr; +} /* Exports from the Linker Script */ extern ulong __text_start; @@ -163,12 +180,10 @@ init_fnc_t *init_sequence[] = { NULL, }; -gd_t *gd; - /* * Load U-Boot into RAM, initialize BSS, perform relocation adjustments */ -void board_init_f (ulong gdp) +void board_init_f (ulong bootflag) { void *text_start = &__text_start; void *data_end = &__data_end; @@ -186,12 +201,14 @@ void board_init_f (ulong gdp) Elf32_Rel *re_src; Elf32_Rel *re_end; + gd->flags = bootflag; + /* Calculate destination RAM Address and relocation offset */ - dest_addr = (void *)gdp - (bss_end - text_start); + dest_addr = (void *)gd->ram_size - (bss_end - text_start); rel_offset = dest_addr - text_start; /* 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 +220,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 +234,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 +243,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 +259,15 @@ void board_init_r(gd_t *id, ulong dest_addr) int i; ulong size; static bd_t bd_data; + static gd_t static_gd; + init_fnc_t **init_fnc_ptr; show_boot_progress(0x21); - gd = id; + memcpy (&static_gd, id, sizeof static_gd); + gd = &static_gd; + /* compiler optimization barrier needed for GCC >= 3.4 */ __asm__ __volatile__("": : :"memory"); diff --git a/include/configs/eNET.h b/include/configs/eNET.h index a04cc9a..b821e2d 100644 --- a/include/configs/eNET.h +++ b/include/configs/eNET.h @@ -172,6 +172,7 @@ * Memory organization */ #define CONFIG_SYS_STACK_SIZE 0x8000 /* Size of bootloader stack */ +#define CONFIG_SYS_INIT_SP_ADDR 0x1000000 #define CONFIG_SYS_BL_START_FLASH 0x38040000 /* Address of relocated code */ #define CONFIG_SYS_BL_START_RAM 0x03fd0000 /* Address of relocated code */ #define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_TEXT_BASE _______________________________________________ U-Boot mailing list [email protected] http://lists.denx.de/mailman/listinfo/u-boot

