Browse Source

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

* memory setup using memblock

* map pages later
zms123456 10 months ago
parent
commit
b785ef9ed7

+ 0 - 7
bsp/qemu-virt64-aarch64/drivers/board.c

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

+ 7 - 14
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;
             }
         }
 

+ 1 - 0
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
 

+ 9 - 187
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)

+ 49 - 30
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, &reg.start, &reg.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, &reg.start, &reg.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

+ 2 - 2
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.

+ 6 - 0
libcpu/Kconfig

@@ -17,6 +17,12 @@ if ARCH_ARMV8 && ARCH_CPU_64BIT
         select ARCH_USING_HW_THREAD_SELF
         default y if RT_USING_OFW
         default n
+    config ARCH_HEAP_SIZE
+        hex "Size of system heap"
+        default 0x4000000
+    config ARCH_INIT_PAGE_SIZE
+        hex "Size of init page region"
+        default 0x200000
     endmenu
 endif
 

+ 1 - 6
libcpu/aarch64/common/mmu.c

@@ -828,14 +828,9 @@ void rt_hw_mem_setup_early(unsigned long *tbl0, unsigned long *tbl1,
     int ret;
     unsigned long count = (size + ARCH_SECTION_MASK) >> ARCH_SECTION_SHIFT;
     unsigned long normal_attr = MMU_MAP_CUSTOM(MMU_AP_KAUN, NORMAL_MEM);
-
-#ifdef RT_USING_SMART
-    unsigned long va = KERNEL_VADDR_START;
-#else
     extern unsigned char _start;
-    unsigned long va = (unsigned long) &_start;
+    unsigned long va = (unsigned long) &_start - pv_off;
     va = RT_ALIGN_DOWN(va, 0x200000);
-#endif
 
     /* setup pv off */
     rt_kmem_pvoff_set(pv_off);

+ 37 - 212
libcpu/aarch64/common/setup.c

@@ -25,6 +25,7 @@
 #include <rtdevice.h>
 #include <gic.h>
 #include <gicv3.h>
+#include <mm_memblock.h>
 
 #define SIZE_KB  1024
 #define SIZE_MB (1024 * SIZE_KB)
@@ -198,38 +199,15 @@ rt_inline void cpu_info_init(void)
 #endif /* RT_USING_HWTIMER */
 }
 
-rt_inline rt_bool_t is_kernel_aspace(const char *name)
-{
-    static char * const names[] =
-    {
-        "kernel",
-        "memheap",
-    };
-
-    if (!name)
-    {
-        return RT_FALSE;
-    }
-
-    for (int i = 0; i < RT_ARRAY_SIZE(names); ++i)
-    {
-        if (!rt_strcmp(names[i], name))
-        {
-            return RT_TRUE;
-        }
-    }
-
-    return RT_FALSE;
-}
-
 void rt_hw_common_setup(void)
 {
-    rt_size_t mem_region_nr;
-    rt_region_t *mem_region;
-    rt_size_t page_best_start;
-    rt_region_t platform_mem_region;
+    rt_size_t kernel_start, kernel_end;
+    rt_size_t heap_start, heap_end;
+    rt_size_t init_page_start, init_page_end;
+    rt_size_t fdt_start, fdt_end;
+    rt_region_t init_page_region = { 0 };
+    rt_region_t platform_mem_region = { 0 };
     static struct mem_desc platform_mem_desc;
-    void *kernel_start, *kernel_end, *memheap_start = RT_NULL, *memheap_end = RT_NULL;
 
     system_vectors_init();
 
@@ -239,61 +217,42 @@ void rt_hw_common_setup(void)
     rt_hw_mmu_map_init(&rt_kernel_space, (void*)0xffffd0000000, 0x10000000, MMUTable, 0);
 #endif
 
-    kernel_start = rt_kmem_v2p((void *)&_start) - 64;
-    kernel_end   = rt_kmem_v2p((void *)&_end);
+    kernel_start    = RT_ALIGN_DOWN((rt_size_t)rt_kmem_v2p((void *)&_start) - 64, ARCH_PAGE_SIZE);
+    kernel_end      = RT_ALIGN((rt_size_t)rt_kmem_v2p((void *)&_end), ARCH_PAGE_SIZE);
+    heap_start      = kernel_end;
+    heap_end        = RT_ALIGN(heap_start + ARCH_HEAP_SIZE, ARCH_PAGE_SIZE);
+    init_page_start = heap_end;
+    init_page_end   = RT_ALIGN(init_page_start + ARCH_INIT_PAGE_SIZE, ARCH_PAGE_SIZE);
+    fdt_start       = init_page_end;
+    fdt_end         = RT_ALIGN(fdt_start + fdt_size, ARCH_PAGE_SIZE);
 
-    if (!rt_fdt_commit_memregion_request(&mem_region, &mem_region_nr, RT_TRUE))
-    {
-        const char *name = "memheap";
+    platform_mem_region.start = kernel_start;
+    platform_mem_region.end   = fdt_end;
 
-        while (mem_region_nr --> 0)
-        {
-            if (mem_region->name == name || !rt_strcmp(mem_region->name, name))
-            {
-                memheap_start = (void *)mem_region->start;
-                memheap_end = (void *)mem_region->end;
+    rt_memblock_reserve_memory("kernel", kernel_start, kernel_end, MEMBLOCK_NONE);
+    rt_memblock_reserve_memory("memheap", heap_start, heap_end, MEMBLOCK_NONE);
+    rt_memblock_reserve_memory("init-page", init_page_start, init_page_end, MEMBLOCK_NONE);
+    rt_memblock_reserve_memory("fdt", fdt_start, fdt_end, MEMBLOCK_NONE);
 
-                break;
-            }
-            mem_region++;
-        }
-    }
+    rt_memmove((void *)(fdt_start - PV_OFFSET), (void *)(fdt_ptr - PV_OFFSET), fdt_size);
+    fdt_ptr = (void *)fdt_start;
 
-    page_best_start = (rt_size_t)(memheap_end ? : kernel_end);
+    rt_system_heap_init((void *)(heap_start - PV_OFFSET), (void *)(heap_end - PV_OFFSET));
 
-    if (memheap_end && fdt_ptr > kernel_start)
-    {
-        rt_memmove(memheap_end - PV_OFFSET, fdt_ptr - PV_OFFSET, fdt_size);
+    init_page_region.start = init_page_start - PV_OFFSET;
+    init_page_region.end = init_page_end - PV_OFFSET;
+    rt_page_init(init_page_region);
 
-        fdt_ptr = memheap_end;
+    /* create MMU mapping of kernel memory */
+    platform_mem_region.start = RT_ALIGN_DOWN(platform_mem_region.start, ARCH_PAGE_SIZE);
+    platform_mem_region.end   = RT_ALIGN(platform_mem_region.end, ARCH_PAGE_SIZE);
 
-        page_best_start = (rt_size_t)fdt_ptr + fdt_size;
-    }
+    platform_mem_desc.paddr_start = platform_mem_region.start;
+    platform_mem_desc.vaddr_start = platform_mem_region.start - PV_OFFSET;
+    platform_mem_desc.vaddr_end = platform_mem_region.end - PV_OFFSET - 1;
+    platform_mem_desc.attr = NORMAL_MEM;
 
-    rt_fdt_commit_memregion_early(&(rt_region_t)
-    {
-        .name = "fdt",
-        .start = (rt_size_t)fdt_ptr,
-        .end = (rt_size_t)(fdt_ptr + fdt_size),
-    }, RT_TRUE);
-
-    fdt_ptr -= PV_OFFSET;
-
-    rt_fdt_commit_memregion_early(&(rt_region_t)
-    {
-        .name = "kernel",
-        .start = (rt_size_t)kernel_start,
-        .end = (rt_size_t)kernel_end,
-    }, RT_TRUE);
-
-#ifndef RT_USING_SMART
-    rt_fdt_commit_memregion_early(&(rt_region_t)
-    {
-        .name = "null",
-        .start = (rt_size_t)RT_NULL,
-        .end = (rt_size_t)RT_NULL + ARCH_PAGE_SIZE,
-    }, RT_TRUE);
-#endif /* !RT_USING_SMART */
+    rt_hw_mmu_setup(&rt_kernel_space, &platform_mem_desc, 1);
 
     if (rt_fdt_prefetch(fdt_ptr))
     {
@@ -307,143 +266,9 @@ void rt_hw_common_setup(void)
 
     rt_fdt_scan_memory();
 
-    if (memheap_start && memheap_end)
-    {
-        rt_system_heap_init(memheap_start - PV_OFFSET, memheap_end - PV_OFFSET);
-    }
-
-    platform_mem_region.start = ~0UL;
-    platform_mem_region.end = 0;
-
-    if (!rt_fdt_commit_memregion_request(&mem_region, &mem_region_nr, RT_TRUE))
-    {
-        LOG_I("Reserved memory:");
-
-        while (mem_region_nr --> 0)
-        {
-            if (is_kernel_aspace(mem_region->name))
-            {
-                if (platform_mem_region.start > mem_region->start)
-                {
-                    platform_mem_region.start = mem_region->start;
-                }
-
-                if (platform_mem_region.end < mem_region->end)
-                {
-                    platform_mem_region.end = mem_region->end;
-                }
-            }
-
-            LOG_I("  %-*.s [%p, %p]", RT_NAME_MAX, mem_region->name, mem_region->start, mem_region->end);
-
-            ++mem_region;
-        }
-    }
-
-    if (!rt_fdt_commit_memregion_request(&mem_region, &mem_region_nr, RT_FALSE))
-    {
-        rt_ubase_t best_offset = ~0UL;
-        rt_region_t *usable_mem_region = mem_region, *page_region = RT_NULL;
-        rt_region_t init_page_region = { 0 };
-        rt_region_t defer_hi = { 0 };
-        rt_err_t error;
+    rt_memblock_setup_memory_environment();
 
-        LOG_I("Usable memory:");
-
-        for (int i = 0; i < mem_region_nr; ++i, ++mem_region)
-        {
-            if (!mem_region->name)
-            {
-                continue;
-            }
-
-            if (platform_mem_region.start > mem_region->start)
-            {
-                platform_mem_region.start = mem_region->start;
-            }
-
-            if (platform_mem_region.end < mem_region->end)
-            {
-                platform_mem_region.end = mem_region->end;
-            }
-
-            if (mem_region->start >= page_best_start &&
-                mem_region->start - page_best_start < best_offset &&
-                /* MUST >= 1MB */
-                mem_region->end - mem_region->start >= SIZE_MB)
-            {
-                page_region = mem_region;
-
-                best_offset = page_region->start - page_best_start;
-            }
-
-            LOG_I("  %-*.s [%p, %p]", RT_NAME_MAX, mem_region->name, mem_region->start, mem_region->end);
-
-        }
-
-        RT_ASSERT(page_region != RT_NULL);
-
-        /* don't map more than ARCH_EARLY_MAP_SIZE */
-        if (page_region->end - page_region->start > ARCH_PAGE_INIT_THRESHOLD)
-        {
-            defer_hi.name = page_region->name;
-            defer_hi.end = page_region->end;
-            defer_hi.start = RT_ALIGN_DOWN(page_region->start + ARCH_PAGE_INIT_THRESHOLD,
-                                           ARCH_SECTION_SIZE);
-            page_region->end = defer_hi.start;
-        }
-
-        init_page_region.start = page_region->start - PV_OFFSET;
-        init_page_region.end = page_region->end - PV_OFFSET;
-
-        rt_page_init(init_page_region);
-
-        platform_mem_region.start = RT_ALIGN(platform_mem_region.start, ARCH_PAGE_SIZE);
-        platform_mem_region.end = RT_ALIGN_DOWN(platform_mem_region.end, ARCH_PAGE_SIZE);
-        RT_ASSERT(platform_mem_region.end - platform_mem_region.start != 0);
-
-        platform_mem_desc.paddr_start = platform_mem_region.start;
-        platform_mem_desc.vaddr_start = platform_mem_region.start - PV_OFFSET;
-        platform_mem_desc.vaddr_end = platform_mem_region.end - PV_OFFSET - 1;
-        platform_mem_desc.attr = NORMAL_MEM;
-
-        rt_hw_mmu_setup(&rt_kernel_space, &platform_mem_desc, 1);
-
-        rt_fdt_earlycon_kick(FDT_EARLYCON_KICK_UPDATE);
-
-        mem_region = usable_mem_region;
-
-        if (defer_hi.start)
-        {
-            /* to virt address */
-            init_page_region.start = defer_hi.start - PV_OFFSET;
-            init_page_region.end = defer_hi.end - PV_OFFSET;
-            error = rt_page_install(init_page_region);
-
-            if (error)
-            {
-                LOG_W("Deferred page installation FAILED:");
-                LOG_W("  %-*.s [%p, %p]", RT_NAME_MAX,
-                    defer_hi.name, defer_hi.start, defer_hi.end);
-            }
-            else
-            {
-                LOG_I("Deferred page installation SUCCEED:");
-                LOG_I("  %-*.s [%p, %p]", RT_NAME_MAX,
-                      defer_hi.name, defer_hi.start, defer_hi.end);
-            }
-        }
-
-        for (int i = 0; i < mem_region_nr; ++i, ++mem_region)
-        {
-            if (mem_region != page_region && mem_region->name)
-            {
-                init_page_region.start = mem_region->start - PV_OFFSET;
-                init_page_region.end = mem_region->end - PV_OFFSET;
-                rt_page_install(init_page_region);
-            }
-        }
-    }
+    rt_fdt_earlycon_kick(FDT_EARLYCON_KICK_UPDATE);
 
     rt_fdt_unflatten();