[U-Boot] questions about get_ram_size usage in U-Boot = DDR modification during code execution

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
participants (1)
-
Patrick DELAUNAY