diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/imx6q-sabrelite/memlayout.h b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/imx6q-sabrelite/memlayout.h index eef60ffe4..b6ed98e68 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/imx6q-sabrelite/memlayout.h +++ b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/imx6q-sabrelite/memlayout.h @@ -60,6 +60,7 @@ Modification: #define USER_MEM_BASE (0x00000000) #define USER_MEM_TOP DEV_VRTMEM_BASE #define USER_IPC_SPACE_BASE (0x70000000) +#define USER_IPC_USE_ALLOCATOR_WATERMARK (0x70010000) #define USER_IPC_SPACE_TOP (USER_MEM_TOP - USER_STACK_SIZE) /* Deivce memory layout */ diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/zynq7000-zc702/memlayout.h b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/zynq7000-zc702/memlayout.h index f68861da0..855d27835 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/zynq7000-zc702/memlayout.h +++ b/Ubiquitous/XiZi_AIoT/hardkernel/mmu/arm/armv7-a/cortex-a9/zynq7000-zc702/memlayout.h @@ -53,13 +53,14 @@ Modification: #define NUM_TOPLEVEL_PDE NUM_LEVEL3_PDE #define PAGE_SIZE LEVEL4_PTE_SIZE -#define MAX_NR_FREE_PAGES ((PHY_MEM_STOP - PHY_MEM_BASE) >> LEVEL4_PTE_SHIFT) +#define MAX_NR_FREE_PAGES ((PHY_USER_FREEMEM_BASE - PHY_MEM_BASE) >> LEVEL4_PTE_SHIFT) /* User memory layout */ #define USER_STACK_SIZE PAGE_SIZE #define USER_MEM_BASE (0x00000000) #define USER_MEM_TOP DEV_VRTMEM_BASE #define USER_IPC_SPACE_BASE (0x70000000) +#define USER_IPC_USE_ALLOCATOR_WATERMARK (0x70010000) #define USER_IPC_SPACE_TOP (USER_MEM_TOP - USER_STACK_SIZE) /* Deivce memory layout */ diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/buddy.h b/Ubiquitous/XiZi_AIoT/softkernel/include/buddy.h index 6c890c840..d8a0354ca 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/include/buddy.h +++ b/Ubiquitous/XiZi_AIoT/softkernel/include/buddy.h @@ -68,7 +68,6 @@ struct KFreeList { struct double_list_node list_head; }; -#define MAX_NR_PAGES MAX_NR_FREE_PAGES struct KBuddy { uint32_t n_pages; uint32_t use_lock; @@ -77,7 +76,7 @@ struct KBuddy { struct KPage* first_page; uint32_t mem_start; uint32_t mem_end; - struct KPage pages[MAX_NR_PAGES]; + struct KPage* pages; }; /********************************************* @@ -89,6 +88,7 @@ struct KBuddy { * @param mem_end free memory region end * @return void */ +bool KBuddyInit(struct KBuddy* pbuddy, uint32_t mem_start, uint32_t mem_end); void KBuddySysInit(struct KBuddy* pbuddy, uint32_t mem_start, uint32_t mem_end); /* @@ -105,6 +105,8 @@ char* KBuddyAlloc(struct KBuddy* pbuddy, uint32_t size); */ bool KBuddyFree(struct KBuddy* pbuddy, char* vaddr); +void KBuddyDestory(struct KBuddy* pbuddy); + /* * Print current free pages for debug. */ diff --git a/Ubiquitous/XiZi_AIoT/softkernel/include/task.h b/Ubiquitous/XiZi_AIoT/softkernel/include/task.h index d79233c9c..2add2df49 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/include/task.h +++ b/Ubiquitous/XiZi_AIoT/softkernel/include/task.h @@ -31,6 +31,7 @@ Modification: #include "core.h" +#include "buddy.h" #include "list.h" #include "object_allocator.h" #include "pagetable.h" @@ -80,6 +81,7 @@ struct TaskMicroDescriptor { /* task communication resources */ struct double_list_node cli_sess_listhead; struct double_list_node svr_sess_listhead; + struct KBuddy* massive_ipc_allocator; struct TraceTag server_identifier; /* task schedule attributes */ @@ -98,6 +100,7 @@ struct SchedulerRightGroup { struct XiziTaskManager { struct double_list_node task_list_head[TASK_MAX_PRIORITY]; /* list of task control blocks that are allocated */ struct slab_allocator task_allocator; + struct slab_allocator task_buddy_allocator; uint32_t next_pid; /* init task manager */ diff --git a/Ubiquitous/XiZi_AIoT/softkernel/memory/buddy.c b/Ubiquitous/XiZi_AIoT/softkernel/memory/buddy.c index 7b263a625..702c0409e 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/memory/buddy.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/memory/buddy.c @@ -29,6 +29,7 @@ Modification: *************************************************/ #include "buddy.h" +#include "kalloc.h" #include "log.h" static void _buddy_split_page(struct KPage* page, uint32_t low_order, uint32_t high_order, struct KFreeList* list) @@ -138,8 +139,15 @@ static void KBuddyPagesFree(struct KBuddy* pbuddy, struct KPage* page) return; } -void KBuddySysInit(struct KBuddy* pbuddy, uint32_t mem_start, uint32_t mem_end) +bool KBuddyInit(struct KBuddy* pbuddy, uint32_t mem_start, uint32_t mem_end) { + if (pbuddy->pages == NULL) { + if ((pbuddy->pages = (struct KPage*)kalloc(((mem_end - mem_start) >> LEVEL4_PTE_SHIFT) * sizeof(struct KPage))) == NULL) { + ERROR("Not space to init a buddy object.\n"); + return false; + } + } + uint32_t i = 0; struct KPage* page = NULL; struct KFreeList* free_list = NULL; @@ -173,6 +181,16 @@ void KBuddySysInit(struct KBuddy* pbuddy, uint32_t mem_start, uint32_t mem_end) doubleListNodeInit(&page->node); KBuddyPagesFree(pbuddy, page); } + + return true; +} + +void KBuddySysInit(struct KBuddy* pbuddy, uint32_t mem_start, uint32_t mem_end) +{ +#define MAX_NR_PAGES MAX_NR_FREE_PAGES + static struct KPage kern_free_pages[MAX_NR_PAGES]; + pbuddy->pages = kern_free_pages; + KBuddyInit(pbuddy, mem_start, mem_end); } char* KBuddyAlloc(struct KBuddy* pbuddy, uint32_t size) @@ -211,6 +229,13 @@ bool KBuddyFree(struct KBuddy* pbuddy, char* vaddr) return true; } +void KBuddyDestory(struct KBuddy* pbuddy) +{ + if (pbuddy->pages) { + kfree((void*)pbuddy->pages); + } +} + void KFreePagesInfo(struct KBuddy* pbuddy) { DEBUG("Buddy structure:"); diff --git a/Ubiquitous/XiZi_AIoT/softkernel/memory/kalloc.c b/Ubiquitous/XiZi_AIoT/softkernel/memory/kalloc.c index 9ce64eaa3..1d7f272bc 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/memory/kalloc.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/memory/kalloc.c @@ -45,7 +45,7 @@ bool module_phymem_init() uint32_t user_freemem_start = PHY_USER_FREEMEM_BASE; uint32_t user_freemem_end = PHY_MEM_STOP; KBuddySysInit(&kern_virtmem_buddy, kern_freemem_start, kern_freemem_end); - KBuddySysInit(&user_phy_freemem_buddy, user_freemem_start, user_freemem_end); + KBuddyInit(&user_phy_freemem_buddy, user_freemem_start, user_freemem_end); LOG_PRINTF("Free memory organized done.\n"); return true; } diff --git a/Ubiquitous/XiZi_AIoT/softkernel/memory/share_page.c b/Ubiquitous/XiZi_AIoT/softkernel/memory/share_page.c index 1ea0713de..9a07aa676 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/memory/share_page.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/memory/share_page.c @@ -92,8 +92,23 @@ static uintptr_t map_task_share_page(struct TaskMicroDescriptor* task, const uin struct MmuCommonDone* p_mmu_driver = AchieveResource(&right_group.mmu_driver_tag); // map double vaddr page to support uniform ring buffer r/w - uintptr_t vaddr = alloc_share_page_addr(task, nr_pages * 2); - if (UNLIKELY(vaddr == 0)) { + uintptr_t vaddr = (uintptr_t)NULL; + if (task->massive_ipc_allocator != NULL) { + vaddr = (uintptr_t)KBuddyAlloc(task->massive_ipc_allocator, PAGE_SIZE * nr_pages * 2); + } else { + vaddr = alloc_share_page_addr(task, nr_pages * 2); + if (vaddr >= USER_IPC_USE_ALLOCATOR_WATERMARK) { + task->massive_ipc_allocator = (struct KBuddy*)slab_alloc(&xizi_task_manager.task_buddy_allocator); + KBuddyInit(task->massive_ipc_allocator, USER_IPC_USE_ALLOCATOR_WATERMARK, USER_IPC_SPACE_TOP); + if (!task->massive_ipc_allocator) { + ERROR("Alloc task buddy failed.\n"); + return (uintptr_t)NULL; + } + vaddr = (uintptr_t)KBuddyAlloc(task->massive_ipc_allocator, nr_pages * 2); + } + } + + if (UNLIKELY(vaddr == (uintptr_t)NULL)) { return (uintptr_t)NULL; } if (!xizi_pager.map_pages(task->pgdir.pd_addr, vaddr, paddr, nr_pages * PAGE_SIZE, false)) { @@ -149,6 +164,9 @@ void unmap_task_share_pages(struct TaskMicroDescriptor* task, const uintptr_t ta xizi_pager.unmap_pages(task->pgdir.pd_addr, task_vaddr, nr_pages * PAGE_SIZE); xizi_pager.unmap_pages(task->pgdir.pd_addr, task_vaddr + (nr_pages * PAGE_SIZE), nr_pages * PAGE_SIZE); + if (task_vaddr >= USER_IPC_USE_ALLOCATOR_WATERMARK) { + KBuddyFree(task->massive_ipc_allocator, (void*)task_vaddr); + } if (task == cur_cpu()->task) { p_mmu_driver->TlbFlush(task_vaddr, 2 * nr_pages * PAGE_SIZE); diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/task.c b/Ubiquitous/XiZi_AIoT/softkernel/task/task.c index 127a3ec9b..0299c4972 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/task/task.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/task/task.c @@ -49,6 +49,7 @@ static void _task_manager_init() } // init task (slab) allocator slab_init(&xizi_task_manager.task_allocator, sizeof(struct TaskMicroDescriptor)); + slab_init(&xizi_task_manager.task_buddy_allocator, sizeof(struct KBuddy)); // pid pool xizi_task_manager.next_pid = 0; @@ -95,6 +96,10 @@ static void _dealloc_task_cb(struct TaskMicroDescriptor* task) doubleListDel(cur_node); // free task back to allocator + if (task->massive_ipc_allocator != NULL) { + KBuddyDestory(task->massive_ipc_allocator); + slab_free(&xizi_task_manager.task_buddy_allocator, (void*)task->massive_ipc_allocator); + } slab_free(&xizi_task_manager.task_allocator, (void*)task); // remove priority