EngineerZone
All Places
Processors and DSP
Software and Development Tools
Das U-Boot for Blackfin
Discussions
I'm trying to bring up U-Boot on a very simple board of mine: a BF532 with 32 MB SDRAM. Initially I couldn't get any SDRAM functionality to work but with the help of the BfSdcCalculation spreadsheet posted here I was able to get my SDGCTL/SDRRC/SDBCTL registers configured properly such that I can do an exhaustive test of all 32 MB of memory by adding the following code to the end of initcode.c and loading/running it via gnICE JTAG:
/ * ... */
serial_putc('>');
serial_putc('\n');
/* Full memory coverage */
volatile unsigned short *mem_test_16;
volatile unsigned char *mem_test_8;
unsigned short patterns[] = { 0x5555, 0xAAAA, 0xFFFF, 0x0000 };
int patt_ndx;
for (patt_ndx = 0; patt_ndx < 4; ++patt_ndx)
{
mem_test_16 = (unsigned short *)(0x02000000);
unsigned short pattern = patterns[patt_ndx];
serial_putc('\n');
serial_putc('T');
serial_putc(':');
serial_put_word16(pattern);
serial_putc('\n');
serial_put_word32((unsigned int)mem_test_16);
while (mem_test_16 > 2)
{
--mem_test_16;
*mem_test_16 = pattern;
__builtin_bfin_ssync();
if (*mem_test_16 != pattern)
{
serial_put_word16(pattern);
serial_putc(':');
serial_put_word32((unsigned int)mem_test_16);
serial_putc(':');
serial_put_word16(*mem_test_16);
serial_putc('\n');
}
}
}
serial_deinit();
}
GNU gdb 6.6
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "--host=x86_64-unknown-linux-gnu --target=bfin-elf"...
(gdb) target remote :2000
Remote debugging using :2000
0xef000000 in ?? ()
(gdb) load init.elf
Loading section .text, size 0xca8 lma 0xffa08000
Start address 0xffa08000, load size 3240
Transfer rate: 143204 bits/sec, 3240 bytes/write.
(gdb) c
Continuing.
Program received signal SIGTRAP, Trace/breakpoint trap.
bfin_reset () at reset.c:45
45 asm(
(gdb) load u-boot
Loading section .text.pre, size 0x1f8 lma 0x1fc0000
Loading section .text.init, size 0xc98 lma 0x1fc01f8
Loading section .text, size 0xad50 lma 0x1fc0e90
Loading section .rodata, size 0x4a5c lma 0x1fcbbe0
Loading section .data, size 0x9ca lma 0x1fd063c
Loading section .u_boot_cmd, size 0x408 lma 0x1fd1008
Loading section .text_l1, size 0x28 lma 0x1fd1410
Start address 0x1fc0000, load size 70710
Transfer rate: 1484724 bits/sec, 7071 bytes/write.
(gdb) call memset(&_bss_vma, 0, &_bss_len)
Program received signal SIGTRAP, Trace/breakpoint trap.
0x01fc15aa in memset ()
The program being debugged was signaled while in a function called from GDB.
GDB remains in the frame where the signal was received.
To change this behavior use "set unwindonsignal on"
Evaluation of the expression containing the function (memset) will be abandoned.
(gdb) c
I tried changing the unwindonsignal behaviour, but get this error:
I should note that I can build, JTAG-load, and run U-Boot on my BF533-STAMP board using the same procedure.
I'm running with the following environment:
U-Boot-2010.06-2010R1-RC2
bfin-elf-gcc (ADI-2010R1-RC4) 4.3.5
BF532-0.6
Micron MT48LC16M16A2-7E SDRAM chip
CLKIN = 12.00 MHz
VCO_MULT = 28
CCLK_DIV = 1 (CCLK = 336 MHz)
SCLK_DIV = 4 (SCLK = 84 MHz)
EBIU_SDGCTL = 0x80911109
EBIU_SDRRC = 0x028A
I've attached the u-boot board config file I'm using. Any suggestions?
I saw you are using CONFIG_MEM_ADD_WDTH 11, should it be 9 since you are using 32MB memory.
Thanks for the reply, but when compiled with "#define CONFIG_MEM_ADD_WDTH 9" I'm still experiencing the same failure when I get to the BSS memset step (though my exhaustive write/read test still succeeds).
From the output of your memory test looks like your DRAM is working fine, could you boot your board up if flash the u-boot directly as mentioned in http://docs.blackfin.uclinux.org/doku.php?id=bootloaders:u-boot:loading?
I'd like to be able to try that route, but my board only has SPI flash. To my knowledge, UrJTAG (bfin-jtag) does not yet support writing images to SPI flash chips. Is there some other way I can do it?
Then I think you may try to lower your cclk and sclk and try again.
Sorry, I forgot to mention that in my original post - I have tried lowering both CCLK and SCLK to the lowest possible: 12 MHz (my CLKIN frequency). The results were the same: my memory test passed (ran much slower) while the call to memset from a GDB JTAG session failed. You can actually see the SDC configuration values I used in the polycam-bf532.h file I posted:
I should also note that I have made two prototypes of this board - both exhibit the same behavior.
Thanks for the information.
Then could you check the physicall address for _bss_vma and _bss_len? grep the u-boot source and check, it's in the map file. check if it's within the valid DRAM address space.
Ya, I made sure to check those values. They look reasonable for a 32MB memory: &_bss_vma = 0x1fd1438 and &_bss_len = 0x5e88 (so a range of 0x1fd1438 - 0x1fd72c0). I also tried memset()ing a small range that is definitely in the 0-0x02000000 valid DRAM memory space:
Please
(gdb) disas memset
And post the result here. Thank you.
Thanks for the tip. That seems to have identified the problem:
(gdb) target remote :2000
Remote debugging using :2000
0xef000000 in ?? ()
(gdb) load init.elf
Loading section .text, size 0x804 lma 0xffa08000
Start address 0xffa08000, load size 2052
Transfer rate: 147891 bits/sec, 2052 bytes/write.
(gdb) c
Continuing.
Program received signal SIGTRAP, Trace/breakpoint trap.
0xffa087d0 in ?? ()
(gdb) load u-boot
Loading section .text.pre, size 0x1f8 lma 0x1fc0000
Loading section .text.init, size 0x7ec lma 0x1fc01f8
Loading section .text, size 0xad50 lma 0x1fc09e4
Loading section .rodata, size 0x4a5c lma 0x1fcb734
Loading section .data, size 0x9ca lma 0x1fd0190
Loading section .u_boot_cmd, size 0x408 lma 0x1fd0b5c
Loading section .text_l1, size 0x28 lma 0x1fd0f64
Start address 0x1fc0000, load size 69514
Transfer rate: 1494924 bits/sec, 6951 bytes/write.
(gdb) disassemble memset
Dump of assembler code for function memset:
0x01fc10fc ;
0x01fc1100 <memset4>: JUMP.S 0x0x1fc10fe <memset2>;
0x01fc1102 <memset6>: JUMP.S 0x0x1fc1100 <memset4>;
0x01fc1104 <memset8>: JUMP.S 0x0x1fc1102 <memset6>;
0x01fc1106 <memset10>: JUMP.S 0x0x1fc1104 <memset8>;
0x01fc1108 <memset12>: JUMP.S 0x0x1fc1106 <memset10>;
0x01fc110a <memset14>: JUMP.S 0x0x1fc1108 <memset12>;
0x01fc110c <memset16>: JUMP.S 0x0x1fc110a <memset14>;
0x01fc110e <memset18>: JUMP.S 0x0x1fc110c <memset16>;
0x01fc1110 <memset20>: JUMP.S 0x0x1fc110e <memset18>;
0x01fc1112 <memset22>: JUMP.S 0x0x1fc1110 <memset20>;
0x01fc1114 <memset24>: JUMP.S 0x0x1fc1112 <memset22>;
0x01fc1116 <memset26>: JUMP.S 0x0x1fc1114 <memset24>;
0x01fc1118 <memset28>: JUMP.S 0x0x1fc1116 <memset26>;
0x01fc111a <memset30>: JUMP.S 0x0x1fc1118 <memset28>;
0x01fc111c <memset32>: JUMP.S 0x0x1fc111a <memset30>;
0x01fc111e <memset34>: JUMP.S 0x0x1fc111c <memset32>;
0x01fc1120 <memset36>: JUMP.S 0x0x1fc111e <memset34>;
0x01fc1122 <memset38>: JUMP.S 0x0x1fc1120 <memset36>;
0x01fc1124 <memset40>: JUMP.S 0x0x1fc1122 <memset38>;
0x01fc1126 <memset42>: JUMP.S 0x0x1fc1124 <memset40>;
0x01fc1128 <memset44>: JUMP.S 0x0x1fc1126 <memset42>;
0x01fc112a <memset46>: JUMP.S 0x0x1fc1128 <memset44>;
0x01fc112c <memset48>: JUMP.S 0x0x1fc112a <memset46>;
0x01fc112e <memset50>: JUMP.S 0x0x1fc112c <memset48>;
0x01fc1130 <memset52>: JUMP.S 0x0x1fc112e <memset50>;
0x01fc1132 <memset54>: JUMP.S 0x0x1fc1130 <memset52>;
0x01fc1134 <memset56>: JUMP.S 0x0x1fc1132 <memset54>;
0x01fc1136 <memset58>: JUMP.S 0x0x1fc1134 <memset56>;
0x01fc1138 <memset60>: JUMP.S 0x0x1fc1136 <memset58>;
0x01fc113a <memset62>: JUMP.S 0x0x1fc1138 <memset60>;
0x01fc113c <memset64>: JUMP.S 0x0x1fc113a <memset62>;
0x01fc113e <memset66>: JUMP.S 0x0x1fc113c <memset64>;
0x01fc1140 <memset68>: JUMP.S 0x0x1fc113e <memset66>;
0x01fc1142 <memset70>: JUMP.S 0x0x1fc1140 <memset68>;
0x01fc1144 <memset72>: JUMP.S 0x0x1fc1142 <memset70>;
0x01fc1146 <memset74>: JUMP.S 0x0x1fc1144 <memset72>;
0x01fc1148 <memset76>: JUMP.S 0x0x1fc1146 <memset74>;
0x01fc114a <memset78>: JUMP.S 0x0x1fc1148 <memset76>;
0x01fc114c <memset80>: JUMP.S 0x0x1fc114a <memset78>;
0x01fc114e <memset82>: JUMP.S 0x0x1fc114c <memset80>;
0x01fc1150 <memset84>: JUMP.S 0x0x1fc114e <memset82>;
0x01fc1152 <memset86>: JUMP.S 0x0x1fc1150 <memset84>;
0x01fc1154 <memset88>: JUMP.S 0x0x1fc1152 <memset86>;
0x01fc1156 <memset90>: JUMP.S 0x0x1fc1154 <memset88>;
0x01fc1158 <memset92>: JUMP.S 0x0x1fc1156 <memset90>;
End of assembler dump.
However, it's not clear to me how those JUMP instructions got there.
Hunting...
You can take a look at other functions in u-boot to see if they has the same issue. You can also try to write someting at 0x01fc1100 and readback to see if you can really write in SDRAM.
I've further characterized the problem but I'm still completely stuck on this. Any SDRAM address I read from returns the last value written to - something that my previous memory tests didn't uncover because I did a write, read, write, read pattern instead of write, write, read, read.
So, for example, with test code like this at the end of initcode():
...
serial_putc('>');
serial_putc('\n');
#ifdef MEM_TEST
serial_put_word32(bfin_read_EBIU_SDGCTL());
serial_putc('\n');
serial_put_word32(bfin_read_EBIU_SDRRC());
serial_putc('\n');
serial_put_word32(bfin_read_EBIU_SDBCTL());
serial_putc('\n');
serial_put_word16(bfin_read_PLL_CTL());
serial_putc('\n');
serial_putc('\n');
/*
* Abreviated memory test
*/
volatile unsigned char *test_addr_8;
volatile unsigned short *test_addr = (unsigned short *)0x00000000;
int cnt;
/* write/read of the alphabet in uppercase ascii 0x1000 = "AB", 0x2000
* = "CD", ...*/
for (cnt = 0; cnt < 10; ++cnt)
{
test_addr = ((unsigned short *)0x00000000) + cnt * 0x1000;
test_addr_8 = (unsigned char *)test_addr;
/* write */
*test_addr = ('B' << 8) + 'A' + (cnt * 0x0202);
__builtin_bfin_ssync(); /* make sure memory controller is done */
/* read and display */
serial_putc(test_addr_8[0]);
serial_putc(test_addr_8[1]);
}
serial_putc('\n');
/* read back the memory locations written by the previous write/read
* test */
for (cnt = 0; cnt < 10; ++cnt)
{
test_addr = ((unsigned short *)0x00000000) + cnt * 0x1000;
test_addr_8 = (unsigned char *)test_addr;
/* read and display */
serial_putc(test_addr_8[0]);
serial_putc(test_addr_8[1]);
}
serial_putc('\n');
/*
* Exhaustive memory test
*/
/* (attempt to) set all ext memory to known pattern */
for (test_addr = (unsigned short *)0x00000000;
test_addr <= (((unsigned short *)0x02000000) - 1);
++test_addr)
{
*test_addr = 0x1234;
}
/* write _one_ word to _one_ ext memory address */
*((unsigned short *)0x00010000) = 0xDEAD;
__builtin_bfin_ssync();
unsigned int anomaly_cnt = 0;
for (test_addr = (unsigned short *)0x00000000;
test_addr <= (((unsigned short *)0x02000000) - 1);
++test_addr)
{
unsigned short current_val = *test_addr;
if (current_val == 0xDEAD)
{
++anomaly_cnt;
}
else
{
serial_put_word32((unsigned int)test_addr);
serial_putc(':');
serial_put_word16(current_val);
serial_putc('\n');
asm("emuexcpt");
}
}
serial_putc('C');
serial_putc(':');
serial_put_word32(anomaly_cnt);
serial_putc('\n');
__builtin_bfin_ssync();
I get the following output:
ABabCabcdghijDabchijklmnoEadFabcdeGabdeHI>
8010884D
0000005B
00000013
8200
ABCDEFGHIJKLMNOPQRST
STSTSTSTSTSTSTSTSTST
C:01000000
I'm wondering if "CLKIN = CCLK = SCLK = 12MHz" is a good setting. Please verify it with the hardware reference manual.
Yes, I wondered about that too, but didn't find anything in the hardware
reference manual. But just to be sure I have just tried with:
CLKIN = 12 MHz
VCO = CCLK = 48 MHz
SCLK = 24 MHz
And I see the same problem.
I have finally been able to get SPI flash support working in urjtag which
allowed me to program my flash and boot via SPI Flash boot mode (as Aaron
suggested originally). Same problem, unfortunately, but at least I can rule
out any JTAG emulation issues.