Skip to content

[libcpu][aarch64]memory setup using memblock #9092

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions bsp/qemu-virt64-aarch64/drivers/board.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,5 @@ extern size_t MMUTable[];

void rt_hw_board_init(void)
{
rt_fdt_commit_memregion_early(&(rt_region_t)
{
.name = "memheap",
.start = (rt_size_t)rt_kmem_v2p(HEAP_BEGIN),
.end = (rt_size_t)rt_kmem_v2p(HEAP_END),
}, RT_TRUE);

rt_hw_common_setup();
}
21 changes: 7 additions & 14 deletions components/drivers/core/mnt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
}
}

Expand Down
1 change: 1 addition & 0 deletions components/drivers/ofw/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
196 changes: 9 additions & 187 deletions components/drivers/ofw/fdt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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");
}
}
}
Expand All @@ -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;

Expand All @@ -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;
Expand Down Expand Up @@ -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)
{
Expand All @@ -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;
}
}

Expand All @@ -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;
}

Expand Down Expand Up @@ -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)
Expand Down
Loading
Loading