diff options
| author | zms123456 <[email protected]> | 2024-06-26 14:36:49 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-06-26 14:36:49 +0800 |
| commit | b785ef9ed76fcf97d3f2d59e02bfaa8b5f6cc74e (patch) | |
| tree | 30056616a80720abecb7186ed1ac4a585f4674d3 /components | |
| parent | ac2664438d0d1048be46cb110549b90213a0e57a (diff) | |
[libcpu][aarch64]memory setup using memblock (#9092)
* memory setup using memblock
* map pages later
Diffstat (limited to 'components')
| -rw-r--r-- | components/drivers/core/mnt.c | 21 | ||||
| -rwxr-xr-x | components/drivers/ofw/Kconfig | 1 | ||||
| -rw-r--r-- | components/drivers/ofw/fdt.c | 196 | ||||
| -rw-r--r-- | components/mm/mm_memblock.c | 79 | ||||
| -rw-r--r-- | components/mm/mm_memblock.h | 4 |
5 files changed, 68 insertions, 233 deletions
diff --git a/components/drivers/core/mnt.c b/components/drivers/core/mnt.c index cca6d1c944..c59fcd8b89 100644 --- a/components/drivers/core/mnt.c +++ b/components/drivers/core/mnt.c @@ -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; } } diff --git a/components/drivers/ofw/Kconfig b/components/drivers/ofw/Kconfig index 3f6735e604..5d6f12bf9f 100755 --- a/components/drivers/ofw/Kconfig +++ b/components/drivers/ofw/Kconfig @@ -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 diff --git a/components/drivers/ofw/fdt.c b/components/drivers/ofw/fdt.c index ce80c3d194..45c73fff0c 100644 --- a/components/drivers/ofw/fdt.c +++ b/components/drivers/ofw/fdt.c @@ -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) diff --git a/components/mm/mm_memblock.c b/components/mm/mm_memblock.c index 8ec0867942..77ef4ddbe0 100644 --- a/components/mm/mm_memblock.c +++ b/components/mm/mm_memblock.c @@ -112,9 +112,9 @@ rt_inline void _reg_remove_after(struct rt_mmblk_reg *prev) /* adding overlapped regions is banned */ static rt_err_t _memblock_add_range(struct rt_memblock *memblock, - char *name, rt_size_t start, rt_size_t end, mm_flag_t flag) + const char *name, rt_size_t start, rt_size_t end, mm_flag_t flag) { - struct rt_mmblk_reg *reg, *reg_next; + struct rt_mmblk_reg *reg = RT_NULL, *reg_next = RT_NULL; rt_slist_t sentinel; rt_region_t new_region; @@ -153,7 +153,7 @@ static rt_err_t _memblock_add_range(struct rt_memblock *memblock, return _reg_insert_after(reg, &new_region, flag); } -rt_err_t rt_memblock_add_memory(char *name, rt_size_t start, rt_size_t end, mmblk_flag_t flags) +rt_err_t rt_memblock_add_memory(const char *name, rt_size_t start, rt_size_t end, mmblk_flag_t flags) { LOG_D("add physical address range [%p-%p) with flag 0x%x" \ " to overall memory regions\n", base, base + size, flag); @@ -161,7 +161,7 @@ rt_err_t rt_memblock_add_memory(char *name, rt_size_t start, rt_size_t end, mmbl return _memblock_add_range(&mmblk_memory, name, start, end, flags); } -rt_err_t rt_memblock_reserve_memory(char *name, rt_size_t start, rt_size_t end, mmblk_flag_t flags) +rt_err_t rt_memblock_reserve_memory(const char *name, rt_size_t start, rt_size_t end, mmblk_flag_t flags) { LOG_D("add physical address range [%p-%p) to reserved memory regions\n",\ base, base + size); @@ -319,7 +319,7 @@ static void _next_free_region(struct rt_mmblk_reg **m, struct rt_mmblk_reg **r, /* merge normal memory regions */ static void _memblock_merge_memory(void) { - struct rt_mmblk_reg *reg; + struct rt_mmblk_reg *reg = RT_NULL; rt_slist_for_each_entry(reg, &(mmblk_memory.reg_list), node) { @@ -333,43 +333,62 @@ static void _memblock_merge_memory(void) } } -/* free all available memory to buddy system */ -static void _memblock_free_all(void) +void rt_memblock_setup_memory_environment(void) { - rt_region_t reg; + struct rt_mmblk_reg *iter = RT_NULL, *start_reg = RT_NULL, *end_reg = RT_NULL; + rt_region_t reg = {0}; rt_size_t mem = 0; struct rt_mmblk_reg *m, *r; + void *err; - for_each_free_region(m, r, MEMBLOCK_NONE, ®.start, ®.end) - { - reg.start -= PV_OFFSET; - reg.end -= PV_OFFSET; - rt_page_install(reg); + _memblock_merge_memory(); - LOG_D("region [%p-%p) added to buddy system\n", reg.start, reg.end); - mem += reg.end - reg.start; - } + LOG_I("System memory:"); - LOG_D("0x%lx(%ld) bytes memory added to buddy system\n", mem, mem); -} + rt_slist_for_each_entry(iter, &(mmblk_memory.reg_list), node) + { + LOG_I(" %-*.s [%p, %p]", RT_NAME_MAX, iter->memreg.name, iter->memreg.start, iter->memreg.end); + } -void rt_memblock_setup_memory_environment(void) -{ - struct rt_mmblk_reg *reg, *start_reg, *end_reg; - rt_err_t err = RT_EOK; + LOG_I("Reserved memory:"); - _memblock_merge_memory(); - rt_slist_for_each_entry(reg, &(mmblk_reserved.reg_list), node) + rt_slist_for_each_entry(iter, &(mmblk_reserved.reg_list), node) { - if (reg->flags != MEMBLOCK_NONE) - { - err = _memblock_separate_range(&mmblk_memory, reg->memreg.start, reg->memreg.end, &start_reg, &end_reg); - RT_ASSERT(err == RT_EOK); + LOG_I(" %-*.s [%p, %p]", RT_NAME_MAX, iter->memreg.name, iter->memreg.start, iter->memreg.end); - _memblock_set_flag(start_reg, end_reg, reg->flags); + if (iter->flags != MEMBLOCK_NONE) + { + _memblock_separate_range(&mmblk_memory, iter->memreg.start, iter->memreg.end, &start_reg, &end_reg); + _memblock_set_flag(start_reg, end_reg, iter->flags); } } - _memblock_free_all(); + + /* install usable memory to system page */ + for_each_free_region(m, r, MEMBLOCK_NONE, ®.start, ®.end) + { + reg.start = RT_ALIGN(reg.start, ARCH_PAGE_SIZE); + reg.end = RT_ALIGN_DOWN(reg.end, ARCH_PAGE_SIZE); + + if (reg.start >= reg.end) + continue; + + LOG_I("physical memory region [%p-%p] installed to system page", reg.start, reg.end); + + reg.start -= PV_OFFSET; + reg.end -= PV_OFFSET; + + struct rt_mm_va_hint hint = {.flags = MMF_MAP_FIXED, + .limit_start = rt_kernel_space.start, + .limit_range_size = rt_kernel_space.size, + .map_size = reg.end - reg.start, + .prefer = (void *)reg.start}; + + rt_aspace_map_phy(&rt_kernel_space, &hint, MMU_MAP_K_RWCB, (reg.start + PV_OFFSET) >> MM_PAGE_SHIFT, &err); + rt_page_install(reg); + mem += reg.end - reg.start; + } + + LOG_I("%ld MB memory installed to system page", mem/1000000); } #ifdef UTEST_MM_API_TC diff --git a/components/mm/mm_memblock.h b/components/mm/mm_memblock.h index da9c7a679b..cb2185d866 100644 --- a/components/mm/mm_memblock.h +++ b/components/mm/mm_memblock.h @@ -56,7 +56,7 @@ struct rt_memblock * @param end the size of the physical address range * @param flags the flags of the region */ -rt_err_t rt_memblock_add_memory(char *name, rt_size_t start, rt_size_t end, mmblk_flag_t flags); +rt_err_t rt_memblock_add_memory(const char *name, rt_size_t start, rt_size_t end, mmblk_flag_t flags); /** * @brief Add a physical address range to the reserved memory region @@ -68,7 +68,7 @@ rt_err_t rt_memblock_add_memory(char *name, rt_size_t start, rt_size_t end, mmbl * @param end the size of the physical address range * @param flags the flags of the region */ -rt_err_t rt_memblock_reserve_memory(char *name, rt_size_t start, rt_size_t end, mmblk_flag_t flags); +rt_err_t rt_memblock_reserve_memory(const char *name, rt_size_t start, rt_size_t end, mmblk_flag_t flags); /** * @brief To conclude the management of memory by the memblock. |
