[U-Boot] valid RAM region on a 256MB fails occasionally

Hi !
I am trying to run a u-boot.bin from the RAM as a standalone application and occationally my board hangs and resets. i found the place it breaks but dont have any clue why..
After the u-boot.img is loaded, i get the cmd prompt and run run the u-boot.bin from by boot partition of emmc U-Boot# fatload mmc 1:1 0x84000000 u-boot.bin reading u-boot.bin 388959 bytes read in 44 ms (8.4 MiB/s) U-Boot# go 0x84000000 ## Starting application at 0x84000000 ...
Here the u-boot.bin starts and runs fine most of the time. occationally i get the following and system hangs and resets.
RAM Configuration: Bank #0: 80000000 DRAM: 1 GiB
I have a 256M lpDDR Ram on our custom board and for some reason u-boot calculates the wrong (1Gb) on the bad cases..
Here is the file it reports the calculated RAM size.. u-boot-2015.07/common/memsize.c.
I added some debug prints and here are the outputs for a valid case and occational bad reset..
function modified: ---------------------
long get_ram_size(long *base, long maxsize) { volatile long *addr; long save[32]; long cnt; long val; long size; int i = 0;
printf("The value of base is %ld and max value is %ld and size of long is %d \n", *base, maxsize, sizeof(long));
for (cnt = (maxsize / sizeof(long)) >> 1; cnt > 0; cnt >>= 1) { addr = base + cnt; /* pointer arith! */ printf("address= %ld ", *addr); sync(); save[i++] = *addr; printf("save[%d]=%ld \n", i, *addr); sync(); *addr = ~cnt; } printf("The address val is %ld ", *addr); addr = base; sync(); save[i] = *addr; sync(); *addr = 0; printf("save[%d]=%ld \n", i, *addr); sync(); if ((val = *addr) != 0) { /* Restore the original data before leaving the function. */ puts(" The value of addr is 0 \n"); sync(); *addr = save[i]; for (cnt = 1; cnt < maxsize / sizeof(long); cnt <<= 1) { addr = base + cnt; sync(); *addr = save[--i]; } puts("Returning zero size !!!"); return (0); }
for (cnt = 1; cnt < maxsize / sizeof(long); cnt <<= 1) { addr = base + cnt; /* pointer arith! */ val = *addr; *addr = save[--i];
printf("base=%ld , val=%ld , address,save[%d]=%ld, cnt=%ld and ~cnt=%ld \n",*base, val,i,*addr,cnt,~cnt);
if (val != ~cnt) { size = cnt * sizeof(long);
printf("calulated size is %ld \n!!!!", size); /* * Restore the original data * before leaving the function. */ for (cnt <<= 1; cnt < maxsize / sizeof(long); cnt <<= 1) { addr = base + cnt; *addr = save[--i]; }
printf("returning cal size %ld \n!!!!", size); return (size); } }
puts("returning max size!!!!"); return (maxsize); }
Bad Case: ---------------- http://u-boot.10912.n7.nabble.com/file/n226040/bad.jpg
Good Case: --------------
http://u-boot.10912.n7.nabble.com/file/n226040/good.jpg
I get a value even after the valid RAM range and this happens randomly.. I have caches enabled in both the u-boot.img and u-boot.bin. please let me know if i am missing anything..
Thanks, Harsha
-- View this message in context: http://u-boot.10912.n7.nabble.com/valid-RAM-region-on-a-256MB-fails-occasion... Sent from the U-Boot mailing list archive at Nabble.com.

i found the problem..
The first stage bootloader has initialized the mmu unit and since the second stage is running on an already initialized RAM, the RAM test still sees data outside physical address and hence thinks it to be 1GB.
When it tries to relocate itself into this address range, it fails and resets.
I dont see a problem if i hardcode my RAM size to 256 << 20 for the 2nd stage u-boot.bin. But I will try to read the value of the RAM from the chip itself..
-Harsha
-- View this message in context: http://u-boot.10912.n7.nabble.com/valid-RAM-region-on-a-256MB-fails-occasion... Sent from the U-Boot mailing list archive at Nabble.com.
participants (1)
-
harsha kiran