* [U-Boot] lib_arm global data pointer
@ 2009-07-10 12:52 Drasko DRASKOVIC
2009-07-13 13:38 ` Rabin Vincent
0 siblings, 1 reply; 7+ messages in thread
From: Drasko DRASKOVIC @ 2009-07-10 12:52 UTC (permalink / raw)
To: u-boot
Hi all,
in libarm/board.c, in function start_armboot(void) I found lines like these:
/* Pointer is writable since we allocated a register for it */
gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t));
/* compiler optimization barrier needed for GCC >= 3.4 */
__asm__ __volatile__("": : :"memory");
gd is defined as: register volatile gd_t *gd asm ("r8")
I have 3 questions:
1) Why is it necessary to allocate register? Don't we have stack at this
point (we already allocated stack in start.S).
2) One C question - are we sure that compiler will listen to our which and
really allocate register?
3) Why do we need this membar? To prevent compiler from touching our reg r8
or for some other reason?
Suppose that I allocated one register in start.S and put in it some data I
want to have later on C side. From start.S we enter to start_armboot(void)
function.
Would this work :
void start_armboot (void)
{
init_fnc_t **init_fnc_ptr;
char *s;
#ifndef CFG_NO_FLASH
ulong size;
#endif
#if defined(CONFIG_VFD) || defined(CONFIG_LCD)
unsigned long addr;
#endif
*#ifdef DATA_FROM_ASM_IN_R10
register volatile unsigned long tmp asm ("r10");
#endif*
/* Pointer is writable since we allocated a register for it */
gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t));
/* compiler optimization barrier needed for GCC >= 3.4 */
__asm__ __volatile__("": : :"memory");
memset ((void*)gd, 0, sizeof (gd_t));
gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));
memset (gd->bd, 0, sizeof (bd_t));
*#ifdef DATA_FROM_ASM_IN_R10
/* data will be passed to C from assembly start-up in reg r10 */
gd->bd->bi_my_data = tmp;
#endif*
monitor_flash_len = _bss_start - _armboot_start;
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
if ((*init_fnc_ptr)() != 0) {
hang ();
}
}
...
}
Would I from this point on really have on C stack what I had in r10 in
start.S?
If not, does anybody have idea how I can do it?
Thanks and best regards,
Drasko DRASKOVIC
^ permalink raw reply [flat|nested] 7+ messages in thread* [U-Boot] lib_arm global data pointer 2009-07-10 12:52 [U-Boot] lib_arm global data pointer Drasko DRASKOVIC @ 2009-07-13 13:38 ` Rabin Vincent 2009-07-13 14:00 ` Drasko DRASKOVIC 0 siblings, 1 reply; 7+ messages in thread From: Rabin Vincent @ 2009-07-13 13:38 UTC (permalink / raw) To: u-boot On Fri, Jul 10, 2009 at 02:52:32PM +0200, Drasko DRASKOVIC wrote: [...] > Suppose that I allocated one register in start.S and put in it some data I > want to have later on C side. From start.S we enter to start_armboot(void) > function. > Would this work : > > void start_armboot (void) > { > init_fnc_t **init_fnc_ptr; > char *s; > #ifndef CFG_NO_FLASH > ulong size; > #endif > #if defined(CONFIG_VFD) || defined(CONFIG_LCD) > unsigned long addr; > #endif > *#ifdef DATA_FROM_ASM_IN_R10 > register volatile unsigned long tmp asm ("r10"); > #endif* > > /* Pointer is writable since we allocated a register for it */ > gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t)); > /* compiler optimization barrier needed for GCC >= 3.4 */ > __asm__ __volatile__("": : :"memory"); > > memset ((void*)gd, 0, sizeof (gd_t)); > gd->bd = (bd_t*)((char*)gd - sizeof(bd_t)); > memset (gd->bd, 0, sizeof (bd_t)); > > *#ifdef DATA_FROM_ASM_IN_R10 > /* data will be passed to C from assembly start-up in reg r10 */ > gd->bd->bi_my_data = tmp; > #endif* > [...] > > Would I from this point on really have on C stack what I had in r10 in > start.S? > > If not, does anybody have idea how I can do it? While the above may work, why you don't just follow the procedure call standard instead? Place the value in r0 instead of r10, and you'll have it as the first argument to the function. Rabin ^ permalink raw reply [flat|nested] 7+ messages in thread
* [U-Boot] lib_arm global data pointer 2009-07-13 13:38 ` Rabin Vincent @ 2009-07-13 14:00 ` Drasko DRASKOVIC 2009-07-13 15:35 ` Wolfgang Denk 0 siblings, 1 reply; 7+ messages in thread From: Drasko DRASKOVIC @ 2009-07-13 14:00 UTC (permalink / raw) To: u-boot > > While the above may work, why you don't just follow the procedure call > standard instead? Place the value in r0 instead of r10, and you'll have > it as the first argument to the function. > there is a reason why I use r10 (and why somebody used r8, I suppose) - I search some address during start.S, and want to stock it in the place that will not be corrupted during continuation of the code in start.S. As you can see, start.S will heavily use r0, r1, probably other low-numbered regs. Yes, I can put r10 to r0 just before the call of the function (and change signature of start(void) to start(int my_var), is that rght?) but what would this change. If the thisngs work with r10, even better... And one thing I also noted that is strange a variable of "register volatile". I played around with arm gcc compiler - does this volatile stuff really have some effect? Compiler seems to produce asm code like it is not volatile (optimize by deleting conditions, assign values by add and not mov, etc...) BR, Drasko On Mon, Jul 13, 2009 at 3:38 PM, Rabin Vincent <rabin@rab.in> wrote: > On Fri, Jul 10, 2009 at 02:52:32PM +0200, Drasko DRASKOVIC wrote: > [...] > > Suppose that I allocated one register in start.S and put in it some data > I > > want to have later on C side. From start.S we enter to > start_armboot(void) > > function. > > Would this work : > > > > void start_armboot (void) > > { > > init_fnc_t **init_fnc_ptr; > > char *s; > > #ifndef CFG_NO_FLASH > > ulong size; > > #endif > > #if defined(CONFIG_VFD) || defined(CONFIG_LCD) > > unsigned long addr; > > #endif > > *#ifdef DATA_FROM_ASM_IN_R10 > > register volatile unsigned long tmp asm ("r10"); > > #endif* > > > > /* Pointer is writable since we allocated a register for it */ > > gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t)); > > /* compiler optimization barrier needed for GCC >= 3.4 */ > > __asm__ __volatile__("": : :"memory"); > > > > memset ((void*)gd, 0, sizeof (gd_t)); > > gd->bd = (bd_t*)((char*)gd - sizeof(bd_t)); > > memset (gd->bd, 0, sizeof (bd_t)); > > > > *#ifdef DATA_FROM_ASM_IN_R10 > > /* data will be passed to C from assembly start-up in reg r10 */ > > gd->bd->bi_my_data = tmp; > > #endif* > > > [...] > > > > Would I from this point on really have on C stack what I had in r10 in > > start.S? > > > > If not, does anybody have idea how I can do it? > > While the above may work, why you don't just follow the procedure call > standard instead? Place the value in r0 instead of r10, and you'll have > it as the first argument to the function. > > Rabin > ^ permalink raw reply [flat|nested] 7+ messages in thread
* [U-Boot] lib_arm global data pointer 2009-07-13 14:00 ` Drasko DRASKOVIC @ 2009-07-13 15:35 ` Wolfgang Denk 2009-07-13 16:00 ` Drasko DRASKOVIC 0 siblings, 1 reply; 7+ messages in thread From: Wolfgang Denk @ 2009-07-13 15:35 UTC (permalink / raw) To: u-boot Dear Drasko DRASKOVIC, In message <5ec3d7930907130700h24ab20c3t258e2c31e21bb71f@mail.gmail.com> you wrote: > > there is a reason why I use r10 (and why somebody used r8, I suppose) - I Well, that's easy - as the code has to interface with GCC generated code, you have to stick with GCC's register usage conventions. > And one thing I also noted that is strange a variable of "register > volatile". I played around with arm gcc compiler - does this volatile stuff > really have some effect? Compiler seems to produce asm code like it is not > volatile (optimize by deleting conditions, assign values by add and not mov, > etc...) "register volatile" makes sense only for the special case of global or local register variables. Whether or not it is implemented in a specific version of GCC for a specific architecture is another story; please ask this on the GCC mailing list. Best regards, Wolfgang Denk -- DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de One of the advantages of being a captain is being able to ask for ad- vice without necessarily having to take it. -- Kirk, "Dagger of the Mind", stardate 2715.2 ^ permalink raw reply [flat|nested] 7+ messages in thread
* [U-Boot] lib_arm global data pointer 2009-07-13 15:35 ` Wolfgang Denk @ 2009-07-13 16:00 ` Drasko DRASKOVIC 2009-07-13 19:34 ` Wolfgang Denk 0 siblings, 1 reply; 7+ messages in thread From: Drasko DRASKOVIC @ 2009-07-13 16:00 UTC (permalink / raw) To: u-boot > > Well, that's easy - as the code has to interface with GCC generated > code, you have to stick with GCC's register usage conventions. > I think we were refering here to ATPCS (ARM-THUMB Procedure Call Standard, i.e. ARM ABI), which tells that first 4 args of the calee are passed by the caller via r0-r3, and if calee takes more args, the rest is passed via stack. IMHO, GCC conventions has not much to do with this. I used r10 because there is small probability that it will be clobbered in start.S. "register volatile" makes sense only for the special case of global > or local register variables. Whether or not it is implemented in a > specific version of GCC for a specific architecture is another story; > please ask this on the GCC mailing list. > OK. But since it was implemented in U-Boot and for ARM, I thought that anybody who wrote this will be so kind to shread some light on this (I am guessing that that it has something to do with ISR, but in ISR we seem to preserve r8), and also on the membar two lines below, and spare me from subscribing to a huge volume gcc mailing lists for posting just one question. This rests for me one of the most obscure corners of U-Boot. Best regards, Drasko DRASKOVIC ^ permalink raw reply [flat|nested] 7+ messages in thread
* [U-Boot] lib_arm global data pointer 2009-07-13 16:00 ` Drasko DRASKOVIC @ 2009-07-13 19:34 ` Wolfgang Denk 2009-07-14 13:22 ` Drasko DRASKOVIC 0 siblings, 1 reply; 7+ messages in thread From: Wolfgang Denk @ 2009-07-13 19:34 UTC (permalink / raw) To: u-boot Dear Drasko DRASKOVIC, In message <5ec3d7930907130900l7e043b11lcf37a0d3e161f511@mail.gmail.com> you wrote: > > > Well, that's easy - as the code has to interface with GCC generated > > code, you have to stick with GCC's register usage conventions. > > > I think we were refering here to ATPCS (ARM-THUMB Procedure Call Standard, > i.e. ARM ABI), which tells that first 4 args of the calee are passed by the > caller via r0-r3, and if calee takes more args, the rest is passed via > stack. IMHO, GCC conventions has not much to do with this. I used r10 > because there is small probability that it will be clobbered in start.S. When I wrote "GCC's register usage conventions" I usually mean exactly that and not some completely different thing. You also might want to read the README. Search for "On ARM, the following registers are used"... > "register volatile" makes sense only for the special case of global > > or local register variables. Whether or not it is implemented in a > > specific version of GCC for a specific architecture is another story; > > please ask this on the GCC mailing list. > > > OK. But since it was implemented in U-Boot and for ARM, I thought that > anybody who wrote this will be so kind to shread some light on this (I am > guessing that that it has something to do with ISR, but in ISR we seem to This has nothing to do with ISRs at all. What makes you think so? > preserve r8), and also on the membar two lines below, and spare me from > subscribing to a huge volume gcc mailing lists for posting just one > question. This rests for me one of the most obscure corners of U-Boot. The GCC mailing list is where GCC experts can answer your questions. I'm not a GCC expert - just a happy user since version 1.35 or so... > --00151748e7286f26c8046e986b49 > Content-Type: text/html; charset=ISO-8859-1 > Content-Transfer-Encoding: quoted-printable And please don't post HTML. Best regards, Wolfgang Denk -- DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de You are only young once, but you can stay immature indefinitely. ^ permalink raw reply [flat|nested] 7+ messages in thread
* [U-Boot] lib_arm global data pointer 2009-07-13 19:34 ` Wolfgang Denk @ 2009-07-14 13:22 ` Drasko DRASKOVIC 0 siblings, 0 replies; 7+ messages in thread From: Drasko DRASKOVIC @ 2009-07-14 13:22 UTC (permalink / raw) To: u-boot Dear Wolfgang Denk. >On Mon, Jul 13, 2009 at 9:34 PM, Wolfgang Denk <wd@denx.de> wrote: > When I wrote "GCC's register usage conventions" I usually mean exactly > that and not some completely different thing. > > You also might want to read the README. Search for "On ARM, the > following registers are used"... On a first glance README actually tells that U-Boot will respect ATCPS (whith exception of r8, which it will reserve). So, actually, it can be that we were talking about the same thing, just that I used term ATPCS to underline that it is ARM (and not U-Boot or GCC) specific. http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ihi0042c/index.html (http://www.nabble.com/Register-Usage-td23279910.html) In any case, my code is working fine with r10 choice, which comes from the reasons I elaborated before (although maybe r10 would not be the happiest choice, but some of the regs r4-r9, r8 excluded). > This has nothing to do with ISRs at all. What makes you think so? This, for example: http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=64978&postdays=0&postorder=asc And this: http://www.nabble.com/bug-or-feature--CSE-optimizes-away-global,-fixed-register-td23909408.html This gave me a hint that people using "volatile register" vars mostly in these cases. And I was thinking myself: why claiming our local reg as volatile? Who can change it appart from us, if not some other thread (written in assembly most probably, because if it was a C call then GCC would introduce prologue and epilogue to preserve register that are guaranteed to be non clobbered by ATCPS). So what other thread do we have in non-multithreaded U-Boot? So, I grepped to see who the hell is touching r8, and all I could find was (in cpu/armXXX/start.S) : .macro irq_save_user_regs sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - r12} @ Calling r0-r12 @ !!!! R8 NEEDS to be saved !!!! a reserved stack spot would be good. add r8, sp, #S_PC stmdb r8, {sp, lr}^ @ Calling SP, LR str lr, [r8, #0] @ Save calling PC mrs r6, spsr str r6, [r8, #4] @ Save CPSR str r0, [r8, #8] @ Save OLD_R0 mov r0, sp .endm chunk of code in ISR. So, my suspicions comes from there. > The GCC mailing list is where GCC experts can answer your questions. > I'm not a GCC expert - just a happy user since version 1.35 or so... Thanks, I will investigate this interesting topic further and post on this thread if I come with reasonable solution. As I mentioned, my gcc was not working as I expected with "register volatile", as it was doing some optimization exibitions rather than plain register read/mov. Some questions are also worth mentioning: /* Pointer is writable since we allocated a register for it */ gd = (gd_t*)(_armboot_start - CONFIG_SYS_MALLOC_LEN - sizeof(gd_t)); Would not it be writable even if we did not allocated reg for it? We could have declared it as a global var without asm("r8") stuff and compiler would have put it on the stack - but I guess it would be writable. And then: /* compiler optimization barrier needed for GCC >= 3.4 */ __asm__ __volatile__("": : :"memory"); Why is order of ams instructions important here? (I did not had time yet to recompile without this membar before posting this question, so I will try to do it and reproduce the problem). Best regards, Drasko DRASKOVIC ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2009-07-14 13:22 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2009-07-10 12:52 [U-Boot] lib_arm global data pointer Drasko DRASKOVIC 2009-07-13 13:38 ` Rabin Vincent 2009-07-13 14:00 ` Drasko DRASKOVIC 2009-07-13 15:35 ` Wolfgang Denk 2009-07-13 16:00 ` Drasko DRASKOVIC 2009-07-13 19:34 ` Wolfgang Denk 2009-07-14 13:22 ` Drasko DRASKOVIC
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox