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