From patchwork Mon Nov 15 11:08:48 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Graeme Russ X-Patchwork-Id: 71208 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id ABE63B7109 for ; Mon, 15 Nov 2010 22:09:05 +1100 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 43994283D6; Mon, 15 Nov 2010 12:09:04 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ANQ6IjmURvfT; Mon, 15 Nov 2010 12:09:04 +0100 (CET) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 05834283DF; Mon, 15 Nov 2010 12:09:02 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 1A04F283DF for ; Mon, 15 Nov 2010 12:08:59 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id KTjNB4TMML8p for ; Mon, 15 Nov 2010 12:08:57 +0100 (CET) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from mail-gw0-f44.google.com (mail-gw0-f44.google.com [74.125.83.44]) by theia.denx.de (Postfix) with ESMTP id 06132283D6 for ; Mon, 15 Nov 2010 12:08:55 +0100 (CET) Received: by gwb10 with SMTP id 10so2572550gwb.3 for ; Mon, 15 Nov 2010 03:08:54 -0800 (PST) Received: by 10.151.7.8 with SMTP id k8mr2024335ybi.290.1289819334526; Mon, 15 Nov 2010 03:08:54 -0800 (PST) Received: from [10.1.1.14] (d122-104-33-199.sbr6.nsw.optusnet.com.au [122.104.33.199]) by mx.google.com with ESMTPS id p1sm3009883ybn.5.2010.11.15.03.08.51 (version=TLSv1/SSLv3 cipher=RC4-MD5); Mon, 15 Nov 2010 03:08:53 -0800 (PST) Message-ID: <4CE114C0.2000201@gmail.com> Date: Mon, 15 Nov 2010 22:08:48 +1100 From: Graeme Russ User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.12) Gecko/20101027 Thunderbird/3.1.6 MIME-Version: 1.0 To: Albert ARIBAUD References: <4CD67A22.9040802@gmail.com> <201011091835.38581.vapier@gentoo.org> <4CDE1107.80108@gmail.com> <4CDE4A53.4070106@free.fr> <4CDE741C.1020507@gmail.com> <4CDF6F2E.9040900@gmail.com> <4CDF7821.4080300@gmail.com> <4CDFA8E9.3050803@free.fr> <20101114103001.7EE2014EA7E@gemini.denx.de> <4CDFD1AE.1070409@free.fr> <20101114150102.DAAF914EA7E@gemini.denx.de> <4CE0221A.7030502@free.fr> <20101114192331.62ECA134F54@gemini.denx.de> <4CE039CD.90706@gmail.com> <4CE04107.7050004@free.fr> In-Reply-To: <4CE04107.7050004@free.fr> Cc: "u-boot@lists.denx.de" Subject: Re: [U-Boot] RFC: Aligning arch initialisation sequences X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.9 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de 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<4CE0221A.7030502@free.fr> 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 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 #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