154568cb3Sopenharmony_ci/* 254568cb3Sopenharmony_ci * Copyright (c) 2009-2023 Huawei Technologies Co., Ltd. All rights reserved. 354568cb3Sopenharmony_ci * 454568cb3Sopenharmony_ci * UniProton is licensed under Mulan PSL v2. 554568cb3Sopenharmony_ci * You can use this software according to the terms and conditions of the Mulan PSL v2. 654568cb3Sopenharmony_ci * You may obtain a copy of Mulan PSL v2 at: 754568cb3Sopenharmony_ci * http://license.coscl.org.cn/MulanPSL2 854568cb3Sopenharmony_ci * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, 954568cb3Sopenharmony_ci * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, 1054568cb3Sopenharmony_ci * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. 1154568cb3Sopenharmony_ci * See the Mulan PSL v2 for more details. 1254568cb3Sopenharmony_ci * Create: 2009-12-22 1354568cb3Sopenharmony_ci * Description: Fsc 内存实现 1454568cb3Sopenharmony_ci */ 1554568cb3Sopenharmony_ci#include "prt_task_external.h" 1654568cb3Sopenharmony_ci#include "prt_fscmem_internal.h" 1754568cb3Sopenharmony_ci 1854568cb3Sopenharmony_ci/* 判断初始化内存地址和大小是否为4字节对齐 */ 1954568cb3Sopenharmony_ci#define OS_MEM_GETBIT(addr) (addr & (U32)(sizeof(U32) - 1)) 2054568cb3Sopenharmony_ci 2154568cb3Sopenharmony_ciOS_SEC_BSS struct TagMemFuncLib g_memArithAPI; /* 算法对应API */ 2254568cb3Sopenharmony_ciOS_SEC_BSS struct TagFscMemCtrl g_fscMemNodeList[OS_FSC_MEM_LAST_IDX]; 2354568cb3Sopenharmony_ciOS_SEC_BSS U32 g_fscMemBitMap = 1; 2454568cb3Sopenharmony_ci 2554568cb3Sopenharmony_ciOS_SEC_TEXT struct TagFscMemCtrl *OsFscMemSearch(U32 size, U32 *idx) 2654568cb3Sopenharmony_ci{ 2754568cb3Sopenharmony_ci U32 staIdx; 2854568cb3Sopenharmony_ci struct TagFscMemCtrl *currBlk = NULL; 2954568cb3Sopenharmony_ci struct TagFscMemCtrl *headBlk = NULL; 3054568cb3Sopenharmony_ci 3154568cb3Sopenharmony_ci staIdx = OS_FSC_MEM_SZ2IDX(size); 3254568cb3Sopenharmony_ci *idx = staIdx + 1; 3354568cb3Sopenharmony_ci 3454568cb3Sopenharmony_ci while (TRUE) { 3554568cb3Sopenharmony_ci *idx = OsGetLmb1((g_fscMemBitMap << *idx) >> *idx); 3654568cb3Sopenharmony_ci if (OS_FSC_MEM_LAST_IDX <= *idx) { 3754568cb3Sopenharmony_ci *idx = staIdx; 3854568cb3Sopenharmony_ci 3954568cb3Sopenharmony_ci headBlk = &g_fscMemNodeList[*idx]; 4054568cb3Sopenharmony_ci currBlk = headBlk->next; 4154568cb3Sopenharmony_ci 4254568cb3Sopenharmony_ci /* 空闲链表非空 */ 4354568cb3Sopenharmony_ci while (currBlk != headBlk) { 4454568cb3Sopenharmony_ci /* 找到可用的内存块 */ 4554568cb3Sopenharmony_ci if (OS_FSC_MEM_SZGET(currBlk) >= size) { 4654568cb3Sopenharmony_ci return currBlk; 4754568cb3Sopenharmony_ci } 4854568cb3Sopenharmony_ci 4954568cb3Sopenharmony_ci currBlk = currBlk->next; 5054568cb3Sopenharmony_ci } 5154568cb3Sopenharmony_ci 5254568cb3Sopenharmony_ci OS_REPORT_ERROR(OS_ERRNO_FSCMEM_ALLOC_NO_MEMORY); 5354568cb3Sopenharmony_ci return NULL; 5454568cb3Sopenharmony_ci } 5554568cb3Sopenharmony_ci 5654568cb3Sopenharmony_ci headBlk = &g_fscMemNodeList[*idx]; 5754568cb3Sopenharmony_ci /* 空闲链表为空,清除BitMap标志位 */ 5854568cb3Sopenharmony_ci if (headBlk->next == headBlk) { 5954568cb3Sopenharmony_ci g_fscMemBitMap &= ~(OS_FSC_MEM_IDX2BIT(*idx)); 6054568cb3Sopenharmony_ci } else { 6154568cb3Sopenharmony_ci break; 6254568cb3Sopenharmony_ci } 6354568cb3Sopenharmony_ci } 6454568cb3Sopenharmony_ci currBlk = headBlk->next; 6554568cb3Sopenharmony_ci 6654568cb3Sopenharmony_ci return currBlk; 6754568cb3Sopenharmony_ci} 6854568cb3Sopenharmony_ci 6954568cb3Sopenharmony_ciOS_SEC_TEXT void *OsFscMemAllocInner(U32 mid, U32 size, uintptr_t align) 7054568cb3Sopenharmony_ci{ 7154568cb3Sopenharmony_ci U32 idx; 7254568cb3Sopenharmony_ci U32 allocSize; 7354568cb3Sopenharmony_ci U32 *blkTailMagic = NULL; 7454568cb3Sopenharmony_ci uintptr_t usrAddr; 7554568cb3Sopenharmony_ci struct TagFscMemCtrl *plotBlk = NULL; 7654568cb3Sopenharmony_ci struct TagFscMemCtrl *currBlk = NULL; 7754568cb3Sopenharmony_ci struct TagFscMemCtrl *nextBlk = NULL; 7854568cb3Sopenharmony_ci 7954568cb3Sopenharmony_ci (void)mid; 8054568cb3Sopenharmony_ci if (size == 0) { 8154568cb3Sopenharmony_ci OS_REPORT_ERROR(OS_ERRNO_MEM_ALLOC_SIZE_ZERO); 8254568cb3Sopenharmony_ci return NULL; 8354568cb3Sopenharmony_ci } 8454568cb3Sopenharmony_ci 8554568cb3Sopenharmony_ci /* 由于已经按OS_FSC_MEM_SIZE_ALIGN字节对齐,最大可能补齐的大小是align - OS_FSC_MEM_SIZE_ALIGN */ 8654568cb3Sopenharmony_ci allocSize = ALIGN(size, OS_FSC_MEM_SIZE_ALIGN) + (align - OS_FSC_MEM_SIZE_ALIGN) + 8754568cb3Sopenharmony_ci OS_FSC_MEM_USED_HEAD_SIZE + OS_FSC_MEM_TAIL_SIZE; 8854568cb3Sopenharmony_ci if ((allocSize < size) || allocSize >= ((OS_FSC_MEM_MAXVAL - OS_FSC_MEM_USED_HEAD_SIZE) - OS_FSC_MEM_TAIL_SIZE)) { 8954568cb3Sopenharmony_ci OS_REPORT_ERROR(OS_ERRNO_MEM_ALLOC_SIZETOOLARGE); 9054568cb3Sopenharmony_ci return NULL; 9154568cb3Sopenharmony_ci } 9254568cb3Sopenharmony_ci 9354568cb3Sopenharmony_ci currBlk = OsFscMemSearch(allocSize, &idx); 9454568cb3Sopenharmony_ci if (currBlk == NULL) { 9554568cb3Sopenharmony_ci return NULL; 9654568cb3Sopenharmony_ci } 9754568cb3Sopenharmony_ci 9854568cb3Sopenharmony_ci /* 找到足够空间的空闲链表,并对其进行分割 */ 9954568cb3Sopenharmony_ci if (OS_FSC_MEM_SZGET(currBlk) >= (allocSize + OS_FSC_MEM_MIN_SIZE)) { 10054568cb3Sopenharmony_ci currBlk->size -= allocSize; 10154568cb3Sopenharmony_ci 10254568cb3Sopenharmony_ci /* 调整链表 */ 10354568cb3Sopenharmony_ci if (idx != OS_FSC_MEM_SZ2IDX(currBlk->size)) { 10454568cb3Sopenharmony_ci OsFscMemDelete(currBlk); 10554568cb3Sopenharmony_ci OsFscMemInsert(currBlk, g_fscMemNodeList, &g_fscMemBitMap); 10654568cb3Sopenharmony_ci } 10754568cb3Sopenharmony_ci 10854568cb3Sopenharmony_ci plotBlk = (struct TagFscMemCtrl *)((uintptr_t)currBlk + (uintptr_t)currBlk->size); 10954568cb3Sopenharmony_ci plotBlk->prevSize = currBlk->size; 11054568cb3Sopenharmony_ci plotBlk->size = allocSize; 11154568cb3Sopenharmony_ci 11254568cb3Sopenharmony_ci currBlk = plotBlk; 11354568cb3Sopenharmony_ci } else { 11454568cb3Sopenharmony_ci OsFscMemDelete(currBlk); 11554568cb3Sopenharmony_ci } 11654568cb3Sopenharmony_ci 11754568cb3Sopenharmony_ci nextBlk = (struct TagFscMemCtrl *)((uintptr_t)currBlk + (uintptr_t)currBlk->size); 11854568cb3Sopenharmony_ci nextBlk->prevSize = 0; 11954568cb3Sopenharmony_ci currBlk->next = OS_FSC_MEM_MAGIC_USED; 12054568cb3Sopenharmony_ci 12154568cb3Sopenharmony_ci /* 设置内存越界检查魔术字 */ 12254568cb3Sopenharmony_ci blkTailMagic = (U32 *)((uintptr_t)currBlk + (uintptr_t)currBlk->size - (uintptr_t)OS_FSC_MEM_TAIL_SIZE); 12354568cb3Sopenharmony_ci *blkTailMagic = OS_FSC_MEM_TAIL_MAGIC; 12454568cb3Sopenharmony_ci 12554568cb3Sopenharmony_ci // currBlk->prev 复用为内存对齐的偏移地址 12654568cb3Sopenharmony_ci currBlk->prev = 0; 12754568cb3Sopenharmony_ci usrAddr = (((uintptr_t)currBlk + OS_FSC_MEM_SLICE_HEAD_SIZE + align - 1) & ~(align - 1)); 12854568cb3Sopenharmony_ci OsMemSetHeadAddr(usrAddr, ((uintptr_t)currBlk + OS_FSC_MEM_SLICE_HEAD_SIZE)); 12954568cb3Sopenharmony_ci 13054568cb3Sopenharmony_ci return (void *)usrAddr; 13154568cb3Sopenharmony_ci} 13254568cb3Sopenharmony_ci 13354568cb3Sopenharmony_ciOS_SEC_TEXT U32 OsFscMemFree(void *addr) 13454568cb3Sopenharmony_ci{ 13554568cb3Sopenharmony_ci struct TagFscMemCtrl *prevBlk = NULL; /* 前一内存块指针 */ 13654568cb3Sopenharmony_ci struct TagFscMemCtrl *currBlk = NULL; /* 当前内存块指针 */ 13754568cb3Sopenharmony_ci struct TagFscMemCtrl *nextBlk = NULL; /* 后一内存块指针 */ 13854568cb3Sopenharmony_ci U32 *blkTailMagic = NULL; 13954568cb3Sopenharmony_ci uintptr_t blkSize; 14054568cb3Sopenharmony_ci 14154568cb3Sopenharmony_ci if (addr == NULL) { 14254568cb3Sopenharmony_ci return OS_ERRNO_MEM_FREE_ADDR_INVALID; 14354568cb3Sopenharmony_ci } 14454568cb3Sopenharmony_ci 14554568cb3Sopenharmony_ci currBlk = (struct TagFscMemCtrl *)OsMemGetHeadAddr((uintptr_t)addr); 14654568cb3Sopenharmony_ci blkSize = currBlk->size; 14754568cb3Sopenharmony_ci 14854568cb3Sopenharmony_ci if ((currBlk->next != OS_FSC_MEM_MAGIC_USED) || (currBlk->size == 0)) { 14954568cb3Sopenharmony_ci return OS_ERRNO_MEM_FREE_SH_DAMAGED; 15054568cb3Sopenharmony_ci } 15154568cb3Sopenharmony_ci 15254568cb3Sopenharmony_ci blkTailMagic = (U32 *)((uintptr_t)currBlk + blkSize - (uintptr_t)OS_FSC_MEM_TAIL_SIZE); 15354568cb3Sopenharmony_ci if (*blkTailMagic != OS_FSC_MEM_TAIL_MAGIC) { 15454568cb3Sopenharmony_ci return OS_ERRNO_MEM_OVERWRITE; 15554568cb3Sopenharmony_ci } 15654568cb3Sopenharmony_ci 15754568cb3Sopenharmony_ci nextBlk = (struct TagFscMemCtrl *)((uintptr_t)currBlk + blkSize); 15854568cb3Sopenharmony_ci 15954568cb3Sopenharmony_ci /* 后一内存块未使用,当前模块释放后与其合并 */ 16054568cb3Sopenharmony_ci if (nextBlk->next != OS_FSC_MEM_MAGIC_USED) { 16154568cb3Sopenharmony_ci OsFscMemDelete(nextBlk); 16254568cb3Sopenharmony_ci 16354568cb3Sopenharmony_ci currBlk->size += nextBlk->size; 16454568cb3Sopenharmony_ci 16554568cb3Sopenharmony_ci if (memset_s(nextBlk, sizeof(struct TagFscMemCtrl), 0, sizeof(struct TagFscMemCtrl)) != EOK) { 16654568cb3Sopenharmony_ci OS_GOTO_SYS_ERROR1(); 16754568cb3Sopenharmony_ci } 16854568cb3Sopenharmony_ci } 16954568cb3Sopenharmony_ci 17054568cb3Sopenharmony_ci /* 前一内存块未使用,当前内存模块与其合并 */ 17154568cb3Sopenharmony_ci if (currBlk->prevSize != 0) { 17254568cb3Sopenharmony_ci prevBlk = (struct TagFscMemCtrl *)((uintptr_t)currBlk - (uintptr_t)currBlk->prevSize); 17354568cb3Sopenharmony_ci prevBlk->size += currBlk->size; 17454568cb3Sopenharmony_ci 17554568cb3Sopenharmony_ci OsFscMemDelete(prevBlk); 17654568cb3Sopenharmony_ci 17754568cb3Sopenharmony_ci if (memset_s(currBlk, sizeof(struct TagFscMemCtrl), 0, sizeof(struct TagFscMemCtrl)) != EOK) { 17854568cb3Sopenharmony_ci OS_GOTO_SYS_ERROR1(); 17954568cb3Sopenharmony_ci } 18054568cb3Sopenharmony_ci currBlk = prevBlk; 18154568cb3Sopenharmony_ci } 18254568cb3Sopenharmony_ci 18354568cb3Sopenharmony_ci /* 合并后的总内存块插入链表 */ 18454568cb3Sopenharmony_ci OsFscMemInsert(currBlk, g_fscMemNodeList, &g_fscMemBitMap); 18554568cb3Sopenharmony_ci 18654568cb3Sopenharmony_ci nextBlk = (struct TagFscMemCtrl *)((uintptr_t)currBlk + (uintptr_t)currBlk->size); 18754568cb3Sopenharmony_ci nextBlk->prevSize = currBlk->size; 18854568cb3Sopenharmony_ci 18954568cb3Sopenharmony_ci return OS_OK; 19054568cb3Sopenharmony_ci} 19154568cb3Sopenharmony_ci 19254568cb3Sopenharmony_ciOS_SEC_TEXT void *OsMemAlloc(enum MoudleId mid, U8 ptNo, U32 size) 19354568cb3Sopenharmony_ci{ 19454568cb3Sopenharmony_ci (void)ptNo; 19554568cb3Sopenharmony_ci return OsFscMemAllocInner(mid, size, OS_FSC_MEM_SIZE_ALIGN); 19654568cb3Sopenharmony_ci} 19754568cb3Sopenharmony_ci 19854568cb3Sopenharmony_ciOS_SEC_TEXT void *OsMemAllocAlign(U32 mid, U8 ptNo, U32 size, enum MemAlign alignPow) 19954568cb3Sopenharmony_ci{ 20054568cb3Sopenharmony_ci (void)ptNo; 20154568cb3Sopenharmony_ci if (alignPow >= MEM_ADDR_BUTT || alignPow < MEM_ADDR_ALIGN_004) { 20254568cb3Sopenharmony_ci OS_REPORT_ERROR(OS_ERRNO_MEM_ALLOC_ALIGNPOW_INVALID); 20354568cb3Sopenharmony_ci return NULL; 20454568cb3Sopenharmony_ci } 20554568cb3Sopenharmony_ci return OsFscMemAllocInner(mid, size, (1U << (U32)alignPow)); 20654568cb3Sopenharmony_ci} 20754568cb3Sopenharmony_ci 20854568cb3Sopenharmony_ci/* 20954568cb3Sopenharmony_ci * 描述:初始化内存 21054568cb3Sopenharmony_ci */ 21154568cb3Sopenharmony_ciOS_SEC_TEXT U32 OsFscMemInit(U32 addr, U32 size) 21254568cb3Sopenharmony_ci{ 21354568cb3Sopenharmony_ci U32 idx; 21454568cb3Sopenharmony_ci struct TagFscMemCtrl *headBlk = NULL; 21554568cb3Sopenharmony_ci struct TagFscMemCtrl *currBlk = NULL; 21654568cb3Sopenharmony_ci struct TagFscMemCtrl *nextBlk = NULL; 21754568cb3Sopenharmony_ci 21854568cb3Sopenharmony_ci /* 异常判断 */ 21954568cb3Sopenharmony_ci if ((void *)(uintptr_t)addr == NULL) { 22054568cb3Sopenharmony_ci return OS_ERRNO_MEM_INITADDR_ISINVALID; 22154568cb3Sopenharmony_ci } 22254568cb3Sopenharmony_ci 22354568cb3Sopenharmony_ci if (OS_MEM_GETBIT(addr) != 0U) { 22454568cb3Sopenharmony_ci return OS_ERRNO_MEM_INITADDR_INVALID; 22554568cb3Sopenharmony_ci } 22654568cb3Sopenharmony_ci 22754568cb3Sopenharmony_ci if (OS_MEM_GETBIT(size) != 0U) { 22854568cb3Sopenharmony_ci return OS_ERRNO_MEM_INITSIZE_INVALID; 22954568cb3Sopenharmony_ci } 23054568cb3Sopenharmony_ci 23154568cb3Sopenharmony_ci if (size < OS_FSC_MEM_USED_HEAD_SIZE) { 23254568cb3Sopenharmony_ci return OS_ERRNO_MEM_PTCREATE_SIZE_ISTOOSMALL; 23354568cb3Sopenharmony_ci } 23454568cb3Sopenharmony_ci 23554568cb3Sopenharmony_ci if (size > OS_FSC_MEM_MAXVAL) { 23654568cb3Sopenharmony_ci return OS_ERRNO_MEM_PTCREATE_SIZE_ISTOOBIG; 23754568cb3Sopenharmony_ci } 23854568cb3Sopenharmony_ci 23954568cb3Sopenharmony_ci if (memset_s((void *)(uintptr_t)addr, size, 0, size) != EOK) { 24054568cb3Sopenharmony_ci OS_GOTO_SYS_ERROR1(); 24154568cb3Sopenharmony_ci } 24254568cb3Sopenharmony_ci 24354568cb3Sopenharmony_ci /* 链表初始化,指向自己 */ 24454568cb3Sopenharmony_ci headBlk = &g_fscMemNodeList[0]; 24554568cb3Sopenharmony_ci for (idx = 0; idx < OS_FSC_MEM_LAST_IDX; idx++, headBlk++) { 24654568cb3Sopenharmony_ci headBlk->prev = headBlk; 24754568cb3Sopenharmony_ci headBlk->next = headBlk; 24854568cb3Sopenharmony_ci } 24954568cb3Sopenharmony_ci 25054568cb3Sopenharmony_ci size -= OS_FSC_MEM_USED_HEAD_SIZE; 25154568cb3Sopenharmony_ci 25254568cb3Sopenharmony_ci g_fscMemBitMap |= 1U << (31 - OS_FSC_MEM_LAST_IDX); 25354568cb3Sopenharmony_ci 25454568cb3Sopenharmony_ci /* 获取索引号 */ 25554568cb3Sopenharmony_ci idx = OS_FSC_MEM_SZ2IDX(size); 25654568cb3Sopenharmony_ci g_fscMemBitMap |= OS_FSC_MEM_IDX2BIT(idx); 25754568cb3Sopenharmony_ci 25854568cb3Sopenharmony_ci /* 挂载链表初始化 */ 25954568cb3Sopenharmony_ci headBlk = &g_fscMemNodeList[idx]; 26054568cb3Sopenharmony_ci currBlk = (struct TagFscMemCtrl *)(uintptr_t)addr; 26154568cb3Sopenharmony_ci currBlk->next = headBlk; 26254568cb3Sopenharmony_ci currBlk->prevSize = 0; 26354568cb3Sopenharmony_ci currBlk->size = (U16)size; 26454568cb3Sopenharmony_ci currBlk->prev = headBlk; 26554568cb3Sopenharmony_ci headBlk->next = currBlk; 26654568cb3Sopenharmony_ci headBlk->prev = currBlk; 26754568cb3Sopenharmony_ci 26854568cb3Sopenharmony_ci nextBlk = (struct TagFscMemCtrl *)((uintptr_t)currBlk + (uintptr_t)currBlk->size); 26954568cb3Sopenharmony_ci nextBlk->next = OS_FSC_MEM_MAGIC_USED; 27054568cb3Sopenharmony_ci nextBlk->size = 0; 27154568cb3Sopenharmony_ci 27254568cb3Sopenharmony_ci g_memArithAPI.alloc = OsMemAlloc; 27354568cb3Sopenharmony_ci g_memArithAPI.allocAlign = OsMemAllocAlign; 27454568cb3Sopenharmony_ci g_memArithAPI.free = OsFscMemFree; 27554568cb3Sopenharmony_ci 27654568cb3Sopenharmony_ci g_osMemAlloc = OsMemAlloc; 27754568cb3Sopenharmony_ci 27854568cb3Sopenharmony_ci return OS_OK; 27954568cb3Sopenharmony_ci} 280