init_raminfo()
Determine the location and size of available system RAM and initialize the asinfo structure in the system page.
Synopsis:
#include "elsinore_startup.h"
void init_raminfo (void)
Arguments:
None.
Description:
The init_raminfo() function specifies the CPU address range that
is allocated to RAM, and places this information in to the asinfo
structure in the system page (see
asinfo in the
System Page
chapter).
If you know the exact size and location of RAM in your system, you can replace this
library function with one that simply hard-codes the values via one or more
add_ram() calls. For example,
the following function call from inside
init_raminfo() specifies the starting physical address and
the size of RAM: add_ram(0, MEG(total_size))
. If you don't have
this information, your init_raminfo() must get this information
from the memory controller.
The amount of work you need to do yourself to write an init_raminfo() function for your platform depends largely on your hardware architecture:
- ARM
- There's no library default. You must supply your own init_raminfo() function. You can use the init_raminfo.c source code for boards similar to yours as a starting point.
- x86
- If the RAM configuration is known (e.g. set by the IPL code, or the multi-boot IPL code gets set by the gnu utility), then the library version of init_raminfo() will call the library routine find_startup_info() to fetch the information from a known location in memory.
Example:
The code below is from the init_raminfo.c file in the BSP for the fictitious ARM DK Elsinore Ghost 8 board:
#include "elsinore_startup.h"
extern int ddr_size;
void init_raminfo()
{
if(fdt) {
fdt_raminfo();
} else {
if (ddr_size) {
add_ram(0x80000000, ddr_size);
} else {
uintptr_t dmm_base = ELSINORE_DMM_BASE;
int i;
for (i = 0; i < 4; ++i) {
uint32_t lisa_map;
uint32_t mem_base;
uint32_t map_size;
int is_mapped;
lisa_map = in32(dmm_base + DMM_LISA_MAP_0 + (i * 4));
mem_base = (lisa_map & DMM_LISA_MAP_SYS_ADDR_MASK);
is_mapped = ((lisa_map & DMM_LISA_MAP_SDRC_MAP_MASK) >> DMM_LISA_MAP_SDRC_MAP_SHIFT)
!= DMM_LISA_MAP_SDRC_MAP_UNMAPPED;
// need to figure out what this mapped section is for
if (is_mapped && (mem_base != 0xff000000)) {
map_size = (lisa_map & DMM_LISA_MAP_SYS_SIZE_MASK) >> DMM_LISA_MAP_SYS_SIZE_SHIFT;
map_size = (1 << map_size) * MEG(16);
add_ram(mem_base, map_size);
} else if (mem_base == 0xff000000) {
alloc_ram(mem_base, MEG(16), 1);
}
}
}
}
}