init_raminfo()

Updated: May 06, 2022

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.
If the RAM configuration isn't known, then a RAM scan (via x86_scanmem()) is performed looking for valid memory between locations 0 and 0xFFFFFF, inclusive. (Note that the VGA aperture that usually starts at location 0xB0000 is specifically ignored.)

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);
                }
            }
        }
    }
}