[U-Boot] OMAP3/devkit8000 division/multiplication function problems

Hi List,
as some may know I'am working on an SPL for the devkit8000. Now I have a problem with the UART init where I hope someone on the list can help.
My problem is in drivers/serial/serial.c with the function calc_divisor. With my defines this function is essentially just this: return (CONFIG_SYS_NS16550_CLK + (gd->baudrate * (MODE_X_DIV / 2))) / (MODE_X_DIV * gd->baudrate);
(Where MODE_X_DIV=16)
If i try to execute this line (with the step instruction of gdb/openOCD) the debugger just does not return and I have to use Strg+c to get a prompt.
Then the PC is 0x4020ffd4 (upper region of SRAM) and the CPSR is 0x600001d7
I think I have some problem with the division/multiplication functions as there is nothing else in this line which may cause trouble (returns and function calls worked before).
U-boot is running in SRAM no SDRAM init yet.
Has someone an idea where I can start looking? Maybe a known pitfall for beginners? More information needed?
Thanks! Simon

Hi Simon,
On 14/06/11 18:52, Simon Schwarz wrote:
Hi List,
as some may know I'am working on an SPL for the devkit8000. Now I have a problem with the UART init where I hope someone on the list can help.
Are you working with a latest version of U-Boot? Do you have additional modifications not yet posted/committed?
My problem is in drivers/serial/serial.c with the function calc_divisor. With my defines this function is essentially just this: return (CONFIG_SYS_NS16550_CLK + (gd->baudrate * (MODE_X_DIV / 2))) / (MODE_X_DIV * gd->baudrate);
(Where MODE_X_DIV=16)
If i try to execute this line (with the step instruction of gdb/openOCD) the debugger just does not return and I have to use Strg+c to get a prompt.
Have you tried returning a hard-coded value?
Then the PC is 0x4020ffd4 (upper region of SRAM) and the CPSR is 0x600001d7
I think I have some problem with the division/multiplication functions as there is nothing else in this line which may cause trouble (returns and function calls worked before).
The problem may actually be related to gd access. I have had a heap (no pun intended) of trouble getting gd access right in the past. Is this the first access to gd?
U-boot is running in SRAM no SDRAM init yet.
If this is indeed the first access to gd, you need to look at the location of gd in SRAM and make sure it not being clobbered
Has someone an idea where I can start looking? Maybe a known pitfall for beginners? More information needed?
Try adding another temporary variable to gd (ulong temp for example) and in calc_divisor do:
ulong temp = gd->temp; gd->temp = 1;
and step through
I'm sure that if I am wrong, somebody else here will be of further assistance
Regards,
Graeme

(Sorry forgot the ML on CC - resend) Hi Graeme,
2011/6/14 Graeme Russ graeme.russ@gmail.com:
Hi Simon,
On 14/06/11 18:52, Simon Schwarz wrote:
Hi List,
as some may know I'am working on an SPL for the devkit8000. Now I have a problem with the UART init where I hope someone on the list can help.
Are you working with a latest version of U-Boot? Do you have additional modifications not yet posted/committed?
I based my modifications on commit 5d1ee00b1fe1180503f6dfc10e87a6c6e74778f3. Its about a month old. I have some modifications - as it is a SPL it's mainly the Makefile which is pulling all the parts from the main u-boot together. I also modified the SDRC but this code isn't executed at the stage where the problem happens. I adapted also some code from http://patchwork.ozlabs.org/patch/95641/ (Mostly this was: void preloader_console_init(void)).
My problem is in drivers/serial/serial.c with the function calc_divisor. With my defines this function is essentially just this: return (CONFIG_SYS_NS16550_CLK + (gd->baudrate * (MODE_X_DIV / 2))) / (MODE_X_DIV * gd->baudrate);
(Where MODE_X_DIV=16)
If i try to execute this line (with the step instruction of gdb/openOCD) the debugger just does not return and I have to use Strg+c to get a prompt.
Have you tried returning a hard-coded value?
yep, a hard-coded value works. It then has the same problem at: serial_out(CONFIG_SYS_NS16550_IER, &com_port->ier); (drivers/serial/ns16550.c:33)
Then the PC is 0x4020ffd4 (upper region of SRAM) and the CPSR is 0x600001d7
I think I have some problem with the division/multiplication functions as there is nothing else in this line which may cause trouble (returns and function calls worked before).
The problem may actually be related to gd access. I have had a heap (no pun intended) of trouble getting gd access right in the past. Is this the first access to gd?
It's the first (read-)access to gd but...
U-boot is running in SRAM no SDRAM init yet.
If this is indeed the first access to gd, you need to look at the location of gd in SRAM and make sure it not being clobbered
... I already did this and gd seems to be ok - I can't see any problems with gdb.
Has someone an idea where I can start looking? Maybe a known pitfall for beginners? More information needed?
Try adding another temporary variable to gd (ulong temp for example) and in calc_divisor do:
ulong temp = gd->temp; gd->temp = 1;
and step through
I will try that.
I'm sure that if I am wrong, somebody else here will be of further assistance
Regards,
Graeme
Thank you Graeme! I have some starting points now - but i don't think the problem is with gd (was also my first suggestion here).
Regards Simon

Hi again,
seems that there is a problem with gd - at least your test breaks...
I added unsigned long temp at the end of gd.
And added unsigned long a=0; a=gd->temp; gd->temp = 4;
to calc_divisor
Here is a part of the debugging session: Breakpoint 1, calc_divisor (port=<optimized out>) at serial.c:171 171 a = gd->temp; (gdb) p/x a $1 = 0x0 (gdb) s ^C Program received signal SIGINT, Interrupt. 0x00014010 in ?? ()
had to use Strg+C to get back a gdb prompt.
But if do: p *gd The output seems to be ok (for this stage of the SPL): $3 = {bd = 0x40203df0, flags = 1, baudrate = 115200, have_console = 0, env_addr = 0, env_valid = 0, fb_base = 0, timer_rate_hz = 0, tbl = 0, tbu = 0, timer_reset_value = 0, lastinc = 0, relocaddr = 0, ram_size = 0, mon_len = 0, irq_sp = 0, start_addr_sp = 0, reloc_off = 0, tlb_addr = 0, jt = 0x0, env_buf = '\000' <repeats 31 times>, temp = 0}
Ideas? A Problem with the linker script maybe?
Regards Simon

Ok. It seems I (or more precise a college) have a possible solution.
From the assembly one can see that r8 is used with a total ridiculus
value - and on ARM r8 is used to point to gd - tada.
I will test that and report back.
Regards Simon
2011/6/14 Simon Schwarz simonschwarzcor@googlemail.com:
Hi again,
seems that there is a problem with gd - at least your test breaks...
I added unsigned long temp at the end of gd.
And added unsigned long a=0; a=gd->temp; gd->temp = 4;
to calc_divisor
Here is a part of the debugging session: Breakpoint 1, calc_divisor (port=<optimized out>) at serial.c:171 171 a = gd->temp; (gdb) p/x a $1 = 0x0 (gdb) s ^C Program received signal SIGINT, Interrupt. 0x00014010 in ?? ()
had to use Strg+C to get back a gdb prompt.
But if do: p *gd The output seems to be ok (for this stage of the SPL): $3 = {bd = 0x40203df0, flags = 1, baudrate = 115200, have_console = 0, env_addr = 0, env_valid = 0, fb_base = 0, timer_rate_hz = 0, tbl = 0, tbu = 0, timer_reset_value = 0, lastinc = 0, relocaddr = 0, ram_size = 0, mon_len = 0, irq_sp = 0, start_addr_sp = 0, reloc_off = 0, tlb_addr = 0, jt = 0x0, env_buf = '\000' <repeats 31 times>, temp = 0}
Ideas? A Problem with the linker script maybe?
Regards Simon

Hi Graeme,
Setting r8 to gd was the solution. I now set it right before the first access to gd then it works like a charm: asm("ldr r8, [%[value]]"::[value] "r" (&gd):"r8"); /* Set r8 to gd */
Thanks for your help! Simon
2011/6/14 Simon Schwarz simonschwarzcor@googlemail.com:
Ok. It seems I (or more precise a college) have a possible solution.
From the assembly one can see that r8 is used with a total ridiculus value - and on ARM r8 is used to point to gd - tada.
I will test that and report back.
Regards Simon
2011/6/14 Simon Schwarz simonschwarzcor@googlemail.com:
Hi again,
seems that there is a problem with gd - at least your test breaks...
I added unsigned long temp at the end of gd.
And added unsigned long a=0; a=gd->temp; gd->temp = 4;
to calc_divisor
Here is a part of the debugging session: Breakpoint 1, calc_divisor (port=<optimized out>) at serial.c:171 171 a = gd->temp; (gdb) p/x a $1 = 0x0 (gdb) s ^C Program received signal SIGINT, Interrupt. 0x00014010 in ?? ()
had to use Strg+C to get back a gdb prompt.
But if do: p *gd The output seems to be ok (for this stage of the SPL): $3 = {bd = 0x40203df0, flags = 1, baudrate = 115200, have_console = 0, env_addr = 0, env_valid = 0, fb_base = 0, timer_rate_hz = 0, tbl = 0, tbu = 0, timer_reset_value = 0, lastinc = 0, relocaddr = 0, ram_size = 0, mon_len = 0, irq_sp = 0, start_addr_sp = 0, reloc_off = 0, tlb_addr = 0, jt = 0x0, env_buf = '\000' <repeats 31 times>, temp = 0}
Ideas? A Problem with the linker script maybe?
Regards Simon
participants (2)
-
Graeme Russ
-
Simon Schwarz