[U-Boot] questions about get_ram_size usage in U-Boot = DDR modification during code execution
Patrick DELAUNAY
patrick.delaunay at st.com
Mon Apr 24 16:11:41 UTC 2017
Hi,
Today, I found a issue with get_ram_size() usage in U-Boot, when U-Boot is executed in the tested memory.
I have a platform with ARM Cortex and I implemented the dram_init() as it is preconized
in ./doc/README.arm-relocation:26
dram_init(): bd pointer is now at this point not accessible, so only
detect the real dramsize, and store it in gd->ram_size. Bst detected
with get_ram_size().
So my code is
#define DDR_BASE 0xC0000000
#define DDR_SIZE 0x40000000
int dram_init(void)
{
gd->ram_size= get_ram_size(DDR_BASE, DDR_SIZE);
}
? I detect 64MB memory on my device
Until now I have no issue with this code but after the last week
(because myU-Boot size increased a little) the get_ram_size cause execution error.
After investigation I found the root issue :
before relocation the code of the function dram_init() is location in DDR near of address
ower of 2 (get_ram_size address = 0xc001ffd6), this code is modified in DDR by the test before
to be executed (and before to be loaded in cache instruction) and that cause crash.
I don't see any warning for usage of get_ram_size() on DDR in U-Boot
documentation when it is executed in DDR.
Today I have no simple way to force location of get_ram_size to avoid alignment
with power of 2 address so for my board I just workaround the issue
by hard coding the DDR size.
Question 1: Anyone already have the same issue with this function ?
I could to propose a modified version for get_ram_size to avoid this issue....
By preserving some memory at the beginning of the DDR during the test
Question 2: it is a good idea to solve this issue like that ?
I can propose directly this patch ?
My idea is :
./include/common.h:
/* common/memsize.c */
long get_ram_size_with_min (long *, long, long);
long get_ram_size (long *, long);
./common/memsize.c:
/*
* Check memory range for valid RAM. A simple memory test determines
* the actually available RAM size between addresses `base' and
* `base + maxsize'.
*/
long get_ram_size(long *base, long maxsize)
{
get_ram_size_with_min(lbase, maxsize, 0x0);
}
/*
* Check memory range for valid RAM. A simple memory test determines
* the actually available RAM size between addresses `base + minsize' and
* `base + maxsize'
* *base is modified but memory beween base and base + minsize is
* preserved (usefull to test the size of DDR when it is used)
* minsize need to be a power of 2
*/
long get_ram_size_with_min(long *base, long maxsize, long minsize)
{
.....
for (cnt = (maxsize / sizeof(long)) >> 1; cnt > minsize; cnt >>= 1) {
.....
}
So the init function become:
int dram_init(void)
{
gd->ram_size= get_ram_size_with_min(DDR_BASE, DDR_SIZE, SZ_1MB);
}
? I preserved the first 1MB of DDR, used to execute U-Boot in DDR before relocation.
Regards
Patrick
More information about the U-Boot
mailing list