mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-09-21 18:57:16 +08:00
[libcpu][aarch64]memory setup using memblock (#9092)
* memory setup using memblock * map pages later
This commit is contained in:
@@ -21,10 +21,10 @@
|
||||
#include <msh.h>
|
||||
#endif
|
||||
#include <ioremap.h>
|
||||
#include <mm_memblock.h>
|
||||
|
||||
#ifdef RT_USING_OFW
|
||||
#define bootargs_select rt_ofw_bootargs_select
|
||||
#define memregion_request rt_fdt_commit_memregion_request
|
||||
#else
|
||||
#error Platform have not kernel parameters select interfaces!
|
||||
#endif
|
||||
@@ -41,23 +41,16 @@ static int rootfs_mnt_init(void)
|
||||
if (!dev || !fstype)
|
||||
{
|
||||
const char *name = "initrd";
|
||||
rt_size_t mem_region_nr;
|
||||
rt_region_t *mem_region;
|
||||
rt_uint64_t initrd_start = 0, initrd_end = 0;
|
||||
struct rt_mmblk_reg *iter = RT_NULL;
|
||||
|
||||
if (!memregion_request(&mem_region, &mem_region_nr, RT_TRUE))
|
||||
rt_slist_for_each_entry(iter, &(rt_memblock_get_reserved()->reg_list), node)
|
||||
{
|
||||
while (mem_region_nr-- > 0)
|
||||
if (rt_strcmp(iter->memreg.name, name) == 0)
|
||||
{
|
||||
if (mem_region->name == name || !rt_strcmp(mem_region->name, name))
|
||||
{
|
||||
initrd_start = mem_region->start;
|
||||
initrd_end = mem_region->end;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
mem_region++;
|
||||
initrd_start = iter->memreg.start;
|
||||
initrd_end = iter->memreg.end;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ menuconfig RT_USING_OFW
|
||||
select RT_USING_ADT
|
||||
select RT_USING_ADT_REF
|
||||
select RT_USING_ADT_BITMAP
|
||||
select RT_USING_MEMBLOCK
|
||||
depends on RT_USING_DM
|
||||
default n
|
||||
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
#include <drivers/ofw_raw.h>
|
||||
#include <drivers/core/dm.h>
|
||||
|
||||
#include <mm_memblock.h>
|
||||
|
||||
#define DBG_TAG "rtdm.ofw"
|
||||
#define DBG_LVL DBG_INFO
|
||||
#include <rtdbg.h>
|
||||
@@ -29,9 +31,6 @@ RT_OFW_SYMBOL_TYPE_RANGE(earlycon, struct rt_fdt_earlycon_id, _earlycon_start =
|
||||
#define ARCH_INIT_MEMREGION_NR 128
|
||||
#endif
|
||||
|
||||
static rt_region_t _memregion[ARCH_INIT_MEMREGION_NR] rt_section(".bss.noclean.memregion");
|
||||
static int _memregion_front_idx = 0, _memregion_last_idx = RT_ARRAY_SIZE(_memregion) - 1;
|
||||
|
||||
static void *_fdt = RT_NULL;
|
||||
static rt_phandle _phandle_min;
|
||||
static rt_phandle _phandle_max;
|
||||
@@ -140,71 +139,6 @@ rt_bool_t rt_fdt_device_is_available(void *fdt, int nodeoffset)
|
||||
return ret;
|
||||
}
|
||||
|
||||
rt_err_t rt_fdt_commit_memregion_early(rt_region_t *region, rt_bool_t is_reserved)
|
||||
{
|
||||
rt_err_t err = RT_EOK;
|
||||
|
||||
if (region && region->name)
|
||||
{
|
||||
if (_memregion_front_idx < _memregion_last_idx)
|
||||
{
|
||||
int idx;
|
||||
|
||||
if (!_memregion_front_idx && _memregion_last_idx == RT_ARRAY_SIZE(_memregion) - 1)
|
||||
{
|
||||
for (int i = 0; i < RT_ARRAY_SIZE(_memregion); ++i)
|
||||
{
|
||||
_memregion[i].name = RT_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
idx = is_reserved ? _memregion_last_idx-- : _memregion_front_idx++;
|
||||
|
||||
rt_memcpy(&_memregion[idx], region, sizeof(*region));
|
||||
}
|
||||
else
|
||||
{
|
||||
err = -RT_EEMPTY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
err = -RT_EINVAL;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
rt_err_t rt_fdt_commit_memregion_request(rt_region_t **out_region, rt_size_t *out_nr, rt_bool_t is_reserved)
|
||||
{
|
||||
rt_err_t err = RT_EOK;
|
||||
|
||||
if (out_region && out_nr)
|
||||
{
|
||||
if (is_reserved)
|
||||
{
|
||||
*out_region = &_memregion[_memregion_last_idx + 1];
|
||||
*out_nr = RT_ARRAY_SIZE(_memregion) - 1 - _memregion_last_idx;
|
||||
}
|
||||
else
|
||||
{
|
||||
*out_region = &_memregion[0];
|
||||
*out_nr = _memregion_front_idx;
|
||||
}
|
||||
|
||||
if (*out_nr == 0)
|
||||
{
|
||||
err = -RT_EEMPTY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
err = -RT_EINVAL;
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
rt_err_t rt_fdt_prefetch(void *fdt)
|
||||
{
|
||||
rt_err_t err = -RT_ERROR;
|
||||
@@ -256,26 +190,6 @@ rt_err_t rt_fdt_scan_root(void)
|
||||
return err;
|
||||
}
|
||||
|
||||
rt_inline rt_err_t commit_memregion(const char *name, rt_uint64_t base, rt_uint64_t size, rt_bool_t is_reserved)
|
||||
{
|
||||
return rt_fdt_commit_memregion_early(&(rt_region_t)
|
||||
{
|
||||
.name = name,
|
||||
.start = (rt_size_t)base,
|
||||
.end = (rt_size_t)(base + size),
|
||||
}, is_reserved);
|
||||
}
|
||||
|
||||
static rt_err_t reserve_memregion(const char *name, rt_uint64_t base, rt_uint64_t size)
|
||||
{
|
||||
if (commit_memregion(name, base, size, RT_TRUE) == -RT_EEMPTY)
|
||||
{
|
||||
LOG_W("Reserved memory: %p - %p%s", base, base + size, " unable to record");
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t fdt_reserved_mem_check_root(int nodeoffset)
|
||||
{
|
||||
rt_err_t err = RT_EOK;
|
||||
@@ -331,8 +245,9 @@ static rt_err_t fdt_reserved_memory_reg(int nodeoffset, const char *uname)
|
||||
continue;
|
||||
}
|
||||
|
||||
rt_bool_t is_nomap = fdt_getprop(_fdt, nodeoffset, "no-map", RT_NULL) ? RT_TRUE : RT_FALSE;
|
||||
base = rt_fdt_translate_address(_fdt, nodeoffset, base);
|
||||
reserve_memregion(fdt_get_name(_fdt, nodeoffset, RT_NULL), base, size);
|
||||
rt_memblock_reserve_memory(uname, base, base + size, is_nomap);
|
||||
|
||||
len -= t_len;
|
||||
}
|
||||
@@ -371,7 +286,7 @@ static void fdt_scan_reserved_memory(void)
|
||||
|
||||
if (err == -RT_EEMPTY && fdt_getprop(_fdt, child, "size", RT_NULL))
|
||||
{
|
||||
reserve_memregion(fdt_get_name(_fdt, child, RT_NULL), 0, 0);
|
||||
LOG_E("Allocating reserved memory in setup is not yet supported");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -385,7 +300,6 @@ static void fdt_scan_reserved_memory(void)
|
||||
static rt_err_t fdt_scan_memory(void)
|
||||
{
|
||||
int nodeoffset, no;
|
||||
rt_region_t *region;
|
||||
rt_uint64_t base, size;
|
||||
rt_err_t err = -RT_EEMPTY;
|
||||
|
||||
@@ -399,11 +313,9 @@ static rt_err_t fdt_scan_memory(void)
|
||||
break;
|
||||
}
|
||||
|
||||
reserve_memregion("memreserve", base, size);
|
||||
rt_memblock_reserve_memory("memreserve", base, base + size, MEMBLOCK_NONE);
|
||||
}
|
||||
|
||||
no = 0;
|
||||
|
||||
fdt_for_each_subnode(nodeoffset, _fdt, 0)
|
||||
{
|
||||
int len;
|
||||
@@ -441,7 +353,8 @@ static rt_err_t fdt_scan_memory(void)
|
||||
continue;
|
||||
}
|
||||
|
||||
err = commit_memregion(name, base, size, RT_FALSE);
|
||||
bool is_hotpluggable = fdt_getprop(_fdt, nodeoffset, "hotpluggable", RT_NULL) ? RT_TRUE : RT_FALSE;
|
||||
err = rt_memblock_add_memory(name, base, base + size, is_hotpluggable);
|
||||
|
||||
if (!err)
|
||||
{
|
||||
@@ -451,8 +364,6 @@ static rt_err_t fdt_scan_memory(void)
|
||||
{
|
||||
LOG_W("Memory node(%d) ranges: %p - %p%s", no, base, base + size, " unable to record");
|
||||
}
|
||||
|
||||
++no;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -461,95 +372,6 @@ static rt_err_t fdt_scan_memory(void)
|
||||
fdt_scan_reserved_memory();
|
||||
}
|
||||
|
||||
region = &_memregion[0];
|
||||
|
||||
for (no = 0; region->name; ++region)
|
||||
{
|
||||
/* We need check the memory region now. */
|
||||
for (int i = RT_ARRAY_SIZE(_memregion) - 1; i > no; --i)
|
||||
{
|
||||
rt_region_t *res_region = &_memregion[i];
|
||||
|
||||
if (!res_region->name)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* +--------+ +--------+
|
||||
* | memory | | memory |
|
||||
* +--------+ +----------+ +----------+ +--------+
|
||||
* | reserved | | reserved |
|
||||
* +----------+ +----------+
|
||||
*/
|
||||
if (res_region->start >= region->end || res_region->end <= region->start)
|
||||
{
|
||||
/* No adjustments needed */
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* case 0: case 1:
|
||||
* +------------------+ +----------+
|
||||
* | memory | | memory |
|
||||
* +---+----------+---+ +---+----------+---+
|
||||
* | reserved | | reserved |
|
||||
* +----------+ +---+----------+---+
|
||||
*
|
||||
* case 2: case 3:
|
||||
* +------------------+ +------------------+
|
||||
* | memory | | memory |
|
||||
* +--------------+---+------+ +------+---+--------------+
|
||||
* | reserved | | reserved |
|
||||
* +----------+ +----------+
|
||||
*/
|
||||
if (res_region->start > region->start)
|
||||
{
|
||||
if (res_region->end < region->end)
|
||||
{
|
||||
/* case 0 */
|
||||
rt_size_t new_size = region->end - res_region->end;
|
||||
|
||||
region->end = res_region->start;
|
||||
|
||||
/* Commit part next block */
|
||||
err = commit_memregion(region->name, res_region->end, new_size, RT_FALSE);
|
||||
|
||||
if (!err)
|
||||
{
|
||||
++no;
|
||||
|
||||
/* Scan again */
|
||||
region = &_memregion[0];
|
||||
--region;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* case 2 */
|
||||
region->end = res_region->start;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (res_region->end < region->end)
|
||||
{
|
||||
/* case 3 */
|
||||
region->start = res_region->end;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* case 1 */
|
||||
region->name = RT_NULL;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
@@ -649,7 +471,7 @@ static rt_err_t fdt_scan_initrd(rt_uint64_t *ranges, const char *name, const cha
|
||||
|
||||
if (!err)
|
||||
{
|
||||
commit_memregion("initrd", ranges[0], ranges[1] - ranges[0], RT_TRUE);
|
||||
rt_memblock_reserve_memory("initrd", ranges[0], ranges[1], MEMBLOCK_NONE);
|
||||
}
|
||||
}
|
||||
else if (!ranges)
|
||||
|
||||
Reference in New Issue
Block a user