[U-Boot] RFC: Aligning arch initialisation sequences

Graeme Russ graeme.russ at gmail.com
Sun Nov 14 06:10:06 CET 2010


On 13/11/10 22:18, Graeme Russ wrote:
> On 13/11/10 19:20, Albert ARIBAUD wrote:
>> Le 13/11/2010 05:16, Graeme Russ a écrit :
>>
>>> I essence, the gd pointer is a unique global variable available prior to
>>> relocation. On all other arches, this is achieved by using a reserved
>>> register which I do not have the luxury of on x86 :(
>>
>> Dusting off ooooold knowledge of x86 and without even a glance at x86 
>> u-boot... Since GD is the only global used pre-reloc, can you not ensure 
>> it always ends up first in the data segment, and then manage two values 
>> for the DS segment reg, one pre-reloc where only gd can be used, and one 
>> post-reloc where gd and all the other globals can be accessed?
> 
> I had though of something similar to that by using GS (which is not
> generally used by u-boot) but it is very messy
> 
> All segments are currently setup to be full 4GB with the initial descriptor
> table hard-coded in flash and then reloaded after relocation (it needs to
> be reloaded so it does not get clobbered when erasing flash or relocating
> from RAM). I did have a dynamic GTD calculated in asm using self modifying
> code but changed that out to use the same 'C' methodology as Linux. I would
> prefer not to go back there...
> 
> So yes, it is possible, but quite frankly, I would rather leave the init
> functions post relocation than mess around with the GTS pre-relocation
> 

OK, I've had a good hard look at this, and setting aside a segment is the
only way that I can think of. I'll need to revisit the self-modifying code
I threw out, but I can live with that small ugliness to bring x86
board_init_f() in line with the other (relocating) arches.

For some bizarre reason, the BIOS emulation layer *yuck* uses GS *double
yuck*. FS is available though

So, I can set aside FS to store the global data pointer, but this
introduces a new problem. To get the pointer, I cannot simply use gd->, I
will need to write a function to retrieve the pointer, so I need gd()->

So I'm thinking of a #define GLOBAL_DATA which all existing arches can
define simply as gd and x86 can define as get_gd_ptr() and I write the
get_gd_ptr() function to extract the pointer using FS


static inline void *get_gd_ptr(void)
{
	void *gd_ptr;

	asm volatile("gs mov 0, %0\n" : "=r" (gd_ptr));
	return gd_ptr;
}

Now I hope the compiler will optimise this down very well. For example,
accessing gd results in the following asm:

	/* gd->baudrate =  CONFIG_BAUDRATE; */
	mov    0x602917c,%eax
 	movl   $0x2580,0x8(%eax)

I would expect using FS to result in something like:

	/* gd->baudrate =  CONFIG_BAUDRATE; */
	mov    fs:0x00000000,%eax
 	movl   $0x2580,0x8(%eax)

So no speed or size penalty :)

Does this sound like a plan?

Regards,

Graeme


More information about the U-Boot mailing list