diff mbox

[U-Boot,v2,22/22] omap: spl: add more debug traces

Message ID 4DF617C2.6070100@ti.com
State Not Applicable
Headers show

Commit Message

Aneesh V June 13, 2011, 1:59 p.m. UTC
Dear Wolfgang,

I just realized that I had not responded to this message.

On Monday 16 May 2011 01:51 AM, Wolfgang Denk wrote:
> Dear Aneesh V,
>
> In message<1305472900-4004-23-git-send-email-aneesh@ti.com>  you wrote:
>> In SPL console is enabled very early where as in U-Boot
>> it's not. So, SPL can have traces in early init code
>
> Console should _always_ be enabled as early as possible,

Unfortunately this is not the case with U-Boot today. Console
initialization happens in board_init_f(). Before board_init_f()
typically a lot of(in fact most of) low level initialization happens
through the lowlevel_init() function called from start.S and the
initial part of init_sequence()

>
>> while U-Boot can not have it in the same shared code.
>>
>> Adding a debug print macro that will be defined in SPL
>> but compiled out in U-Boot.
>
> Can we not rather change the code so both configurations behave the
> same?

In SPL I had more flexibility, so I do a simplified init of console
right at the beginning of lowlevel_init(), so I can use debug prints in
lowlevel_init(). Some part of our lowlevel_init() that is executed in
SPL path may also be executed by U-Boot if it runs from NOR flash, but
in this case console wouldn't be ready. That's why I made the macro.

>
>> --- a/arch/arm/cpu/armv7/omap4/clocks.c
>> +++ b/arch/arm/cpu/armv7/omap4/clocks.c
>> @@ -379,7 +379,7 @@ u32 omap4_ddr_clk(void)
>>
>>   	core_dpll_params = get_core_dpll_params();
>>
>> -	debug("sys_clk %d\n ", sys_clk_khz * 1000);
>> +	spl_debug("sys_clk %d\n ", sys_clk_khz * 1000);
>
> Do we really need a new macro name?  Can this not be the same debug()
> macro, just generating different code (if really needed) when building
> the SPL code?

No. That wouldn't serve the purpose. I need two macros to distinguish
between the two cases.
1. 'debug()' - can be used in all places at which console is guaranteed
to be initialized whether executed as part of U-Boot or SPL.
2. 'spl_debug()' to be used at places where console is initialized for
SPL but not for U-Boot (eg. lowlevel_init()) - so emit no code for
U-Boot.

>
>> @@ -1318,4 +1328,13 @@ void sdram_init(void)
>>
>>   	/* for the shadow registers to take effect */
>>   	freq_update_core();
>> +
>> +	/* Do some basic testing */
>> +	writel(0xDEADBEEF, CONFIG_SYS_SDRAM_BASE);
>> +	if (readl(CONFIG_SYS_SDRAM_BASE) == 0xDEADBEEF)
>> +		spl_debug("SDRAM Init success!\n");
>> +	else
>> +		printf("SDRAM Init failed!!\n");
>> +
>> +	spl_debug("<<sdram_init()\n");
>
> This is beyond the scope of "adding debug traces".  it must be split
> into separate patch.

will do.

>
> Also, please do not mess witrhout need with the RAM content - at the
> very least, restore the previous values.

Will do.

>
> But then - I wonder why this is needed at all. Are you not using
> get_ram_size()?  Maybe you should fix your code to using it!

It may make sense for us to do this as a memory test. For discovering
the amount of memory installed we are using a technique based on
reading of LPDDR2 mode registers.

The above was intended as a simple sanity testing.

>
>> diff --git a/arch/arm/include/asm/utils.h b/arch/arm/include/asm/utils.h
>> index d581539..3e847c1 100644
>> --- a/arch/arm/include/asm/utils.h
>> +++ b/arch/arm/include/asm/utils.h
>> @@ -25,6 +25,12 @@
>>   #ifndef	_UTILS_H_
>>   #define	_UTILS_H_
>>
>> +#if defined(DEBUG)&&  defined(CONFIG_PRELOADER)
>> +#define spl_debug(fmt, args...)	printf(fmt, ##args)
>> +#else
>> +#define spl_debug(fmt, args...)
>> +#endif
>
> NAK.  This is neither the right place for such a definition, nor do I
> want to see this addressed like that.
>
> I recommend to unify the code, so both SPL and non-SPL configurations
> can use teh same early console behaviour.

I always thought this is a serious issue with U-Boot. I gave it a quick
shot like below:

---
---


But this didn't work. It crashes at the first printf(). The reason is
init_baudrate() needs global data and global data is initialized in
board_init_f(). Further, we can not move global data initialization
earlier because for global data we reuse low level stack used by
lowlevel_init().

	gd = (gd_t *) ((CONFIG_SYS_INIT_SP_ADDR) & ~0x07);

So, we have an egg-and-chicken problem unless we find different spaces
for low-level stack and global data(that should not be a problem for
our board, but I am not sure of other boards).

Also, perhaps this needs to be done for all CPUs/archs.

IMHO, this will need a major overhaul and is not in the scope of my
current activity. Please suggest how to go about this.

Do you think re-naming spl_debug to omap_spl_debug() and putting it in
an OMAP header will help?:-) I am not sure if everybody has the same
situation as we have(that is, U-Boot and SPL sharing low-level init
code and console being initialized in one case while not in the other)

best regards,
Aneesh

Comments

Aneesh V June 14, 2011, 4:17 a.m. UTC | #1
Dear Wolfgang, Heiko,

On Monday 13 June 2011 07:29 PM, Aneesh V wrote:
> Dear Wolfgang,
[snip ...]
> But this didn't work. It crashes at the first printf(). The reason is
> init_baudrate() needs global data and global data is initialized in
> board_init_f(). Further, we can not move global data initialization
> earlier because for global data we reuse low level stack used by
> lowlevel_init().
>
> gd = (gd_t *) ((CONFIG_SYS_INIT_SP_ADDR) & ~0x07);

On second thoughts I realize that the stack in internal RAM is still in
use in board_init_f(). So, how does this work at all? The global data
and the stack seems to be overlapping!

Please note the register dump after the above instruction. Note that
R8(gd) and R13(sp) are very close.

N _  R0          0  R8   4030DF80  SP> 12345678
Z Z  R1         0A  R9   12345678  -04 80E80078
C C  R2   4030DED4  R10  40304350  FP> D78772CA
V _  R3       5555  R11  0002FE40  +04 4049A39E
I I  R4          0  R12  80E80068  +08 F5A73CF4
F F  R5         10  R13  4030DF78  +0C 7B317D39
T _  R6   12345678  R14  80E80078  +10 ED3CFCF0
J _  R7   12345678  PC   80E80880  +14 FEECEC6A
svc  SPSR        0  CPSR 600001D3  +18 6DB22EB2

Am I missing something?

best regards,
Aneesh
Wolfgang Denk June 15, 2011, 10:18 a.m. UTC | #2
Dear Aneesh V,

In message <4DF617C2.6070100@ti.com> you wrote:
> 
> > Console should _always_ be enabled as early as possible,
> 
> Unfortunately this is not the case with U-Boot today. Console
> initialization happens in board_init_f(). Before board_init_f()
> typically a lot of(in fact most of) low level initialization happens
> through the lowlevel_init() function called from start.S and the
> initial part of init_sequence()

As the name LOWLEVEL_init() suggests, this is suppoed to contain
always only the bare minimum of initialization that is necessary to
get the CPU running.  All more complex initializations should be
delayed and only be run when we have a proper environment, including
debug output on the console.

> > Can we not rather change the code so both configurations behave the
> > same?
> 
> In SPL I had more flexibility, so I do a simplified init of console
> right at the beginning of lowlevel_init(), so I can use debug prints in
> lowlevel_init(). Some part of our lowlevel_init() that is executed in
> SPL path may also be executed by U-Boot if it runs from NOR flash, but
> in this case console wouldn't be ready. That's why I made the macro.

I do not understand this.  How can you have more flexibility in the
more restricted environment?

We definitely should unify this.

> No. That wouldn't serve the purpose. I need two macros to distinguish
> between the two cases.
> 1. 'debug()' - can be used in all places at which console is guaranteed
> to be initialized whether executed as part of U-Boot or SPL.
> 2. 'spl_debug()' to be used at places where console is initialized for
> SPL but not for U-Boot (eg. lowlevel_init()) - so emit no code for
> U-Boot.

You see - this distinction is becoming a mess.  Let's get rid of this
and use common code for both cases.

Best regards,

Wolfgang Denk
Aneesh V July 3, 2011, 9:35 a.m. UTC | #3
Dear Wolfgang,

On Wednesday 15 June 2011 03:48 PM, Wolfgang Denk wrote:
> Dear Aneesh V,
>

[snip ..]

>> No. That wouldn't serve the purpose. I need two macros to distinguish
>> between the two cases.
>> 1. 'debug()' - can be used in all places at which console is guaranteed
>> to be initialized whether executed as part of U-Boot or SPL.
>> 2. 'spl_debug()' to be used at places where console is initialized for
>> SPL but not for U-Boot (eg. lowlevel_init()) - so emit no code for
>> U-Boot.
>
> You see - this distinction is becoming a mess.  Let's get rid of this
> and use common code for both cases.

I replaced spl_debug() with debug() now. I moved sdram_init() out of
lowlevel_init() for u-boot so that console is available by the time
sdram_init() runs.

However, clock init needs to remain in lowlevel_init() and I still feel
that some debug traces from this module will be a good debugging tool
for SPL, so I retained the traces and added something like this in
arch/arm/cpu/armv7/omap4/clocks.c:


/*
  * printing to console doesn't work unless
  * this code is executed from SPL
  */
#ifndef CONFIG_PRELOADER
#define printf(fmt, args...)
#define puts(s)
#endif

Is that fine?

best regards,
Aneesh
diff mbox

Patch

diff --git a/arch/arm/cpu/armv7/omap4/board.c 
b/arch/arm/cpu/armv7/omap4/board.c
index fcd29a7..56902e3 100644
--- a/arch/arm/cpu/armv7/omap4/board.c
+++ b/arch/arm/cpu/armv7/omap4/board.c
@@ -41,6 +41,7 @@  DECLARE_GLOBAL_DATA_PTR;
   */
  void s_init(void)
  {
+	printf("Hello World!!\n");
  	watchdog_init();
  }

diff --git a/arch/arm/cpu/armv7/omap4/lowlevel_init.S 
b/arch/arm/cpu/armv7/omap4/lowlevel_init.S
index 026dfa4..42264b2 100644
--- a/arch/arm/cpu/armv7/omap4/lowlevel_init.S
+++ b/arch/arm/cpu/armv7/omap4/lowlevel_init.S
@@ -31,17 +31,6 @@ 
  .globl lowlevel_init
  lowlevel_init:
  	/*
-	 * Setup a temporary stack
-	 */
-	ldr	sp, =LOW_LEVEL_SRAM_STACK
-
-	/*
-	 * Save the old lr(passed in ip) and the current lr to stack
-	 */
-	push	{ip, lr}
-
-	/*
  	 * go setup pll, mux, memory
  	 */
-	bl	s_init
-	pop	{ip, pc}
+	b	s_init
diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S
index d91ae12..4a9251f 100644
--- a/arch/arm/cpu/armv7/start.S
+++ b/arch/arm/cpu/armv7/start.S
@@ -307,10 +307,11 @@  cpu_init_crit:
  	 * basic memory. Go here to bump up clock rate and handle
  	 * wake up conditions.
  	 */
-	mov	ip, lr			@ persevere link reg across call
+	ldr	sp, =CONFIG_SYS_INIT_SP_ADDR
+	push	{lr}
+	bl	early_console_init
  	bl	lowlevel_init		@ go setup pll,mux,memory
-	mov	lr, ip			@ restore link
-	mov	pc, lr			@ back to my caller
+	pop	{pc}
  /*
   *************************************************************************
   *
diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c
index 1a784a1..0c696c2 100644
--- a/arch/arm/lib/board.c
+++ b/arch/arm/lib/board.c
@@ -248,9 +248,6 @@  init_fnc_t *init_sequence[] = {
  	get_clocks,
  #endif
  	env_init,		/* initialize environment */
-	init_baudrate,		/* initialze baudrate settings */
-	serial_init,		/* serial communications setup */
-	console_init_f,		/* stage 1 init of console */
  	display_banner,		/* say that we are here */
  #if defined(CONFIG_DISPLAY_CPUINFO)
  	print_cpuinfo,		/* display cpu info (and speed) */
@@ -268,6 +265,13 @@  init_fnc_t *init_sequence[] = {
  	NULL,
  };

+void early_console_init(void)
+{
+	init_baudrate();	/* initialze baudrate settings */
+	serial_init();		/* serial communications setup */
+	console_init_f();	/* stage 1 init of console */
+}
+
  void board_init_f (ulong bootflag)
  {
  	bd_t *bd;