[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