13d8536b4Sopenharmony_ci/* 23d8536b4Sopenharmony_ci * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. 33d8536b4Sopenharmony_ci * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. 43d8536b4Sopenharmony_ci * 53d8536b4Sopenharmony_ci * Redistribution and use in source and binary forms, with or without modification, 63d8536b4Sopenharmony_ci * are permitted provided that the following conditions are met: 73d8536b4Sopenharmony_ci * 83d8536b4Sopenharmony_ci * 1. Redistributions of source code must retain the above copyright notice, this list of 93d8536b4Sopenharmony_ci * conditions and the following disclaimer. 103d8536b4Sopenharmony_ci * 113d8536b4Sopenharmony_ci * 2. Redistributions in binary form must reproduce the above copyright notice, this list 123d8536b4Sopenharmony_ci * of conditions and the following disclaimer in the documentation and/or other materials 133d8536b4Sopenharmony_ci * provided with the distribution. 143d8536b4Sopenharmony_ci * 153d8536b4Sopenharmony_ci * 3. Neither the name of the copyright holder nor the names of its contributors may be used 163d8536b4Sopenharmony_ci * to endorse or promote products derived from this software without specific prior written 173d8536b4Sopenharmony_ci * permission. 183d8536b4Sopenharmony_ci * 193d8536b4Sopenharmony_ci * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 203d8536b4Sopenharmony_ci * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 213d8536b4Sopenharmony_ci * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 223d8536b4Sopenharmony_ci * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 233d8536b4Sopenharmony_ci * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 243d8536b4Sopenharmony_ci * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 253d8536b4Sopenharmony_ci * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 263d8536b4Sopenharmony_ci * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 273d8536b4Sopenharmony_ci * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 283d8536b4Sopenharmony_ci * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 293d8536b4Sopenharmony_ci * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 303d8536b4Sopenharmony_ci */ 313d8536b4Sopenharmony_ci 323d8536b4Sopenharmony_ci#include "los_lmk.h" 333d8536b4Sopenharmony_ci#include "los_interrupt.h" 343d8536b4Sopenharmony_ci#if (LOSCFG_KERNEL_LMK_DEBUG == 1) 353d8536b4Sopenharmony_ci#include "los_debug.h" 363d8536b4Sopenharmony_ci#endif 373d8536b4Sopenharmony_ci 383d8536b4Sopenharmony_ci#if (LOSCFG_KERNEL_LMK == 1) 393d8536b4Sopenharmony_ciSTATIC LosLmkOps g_losLmkOps; 403d8536b4Sopenharmony_ci 413d8536b4Sopenharmony_ciSTATIC BOOL OsIsLmkOpsNodeRegistered(LosLmkOpsNode *lmkNode) 423d8536b4Sopenharmony_ci{ 433d8536b4Sopenharmony_ci LosLmkOpsNode *opsNode = NULL; 443d8536b4Sopenharmony_ci 453d8536b4Sopenharmony_ci if (LOS_ListEmpty(&g_losLmkOps.lmkOpsList)) { 463d8536b4Sopenharmony_ci return FALSE; 473d8536b4Sopenharmony_ci } 483d8536b4Sopenharmony_ci LOS_DL_LIST_FOR_EACH_ENTRY(opsNode, &g_losLmkOps.lmkOpsList, LosLmkOpsNode, node) { 493d8536b4Sopenharmony_ci if (lmkNode == opsNode) { 503d8536b4Sopenharmony_ci return TRUE; 513d8536b4Sopenharmony_ci } 523d8536b4Sopenharmony_ci } 533d8536b4Sopenharmony_ci return FALSE; 543d8536b4Sopenharmony_ci} 553d8536b4Sopenharmony_ci 563d8536b4Sopenharmony_ciUINT32 LOS_LmkOpsNodeRegister(LosLmkOpsNode *lmkNode) 573d8536b4Sopenharmony_ci{ 583d8536b4Sopenharmony_ci UINT32 intSave; 593d8536b4Sopenharmony_ci LosLmkOpsNode *opsNode = NULL; 603d8536b4Sopenharmony_ci 613d8536b4Sopenharmony_ci if (lmkNode == NULL) { 623d8536b4Sopenharmony_ci return LOS_ERRNO_LMK_INVALID_PARAMETER; 633d8536b4Sopenharmony_ci } 643d8536b4Sopenharmony_ci 653d8536b4Sopenharmony_ci intSave = LOS_IntLock(); 663d8536b4Sopenharmony_ci if (OsIsLmkOpsNodeRegistered(lmkNode)) { 673d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 683d8536b4Sopenharmony_ci return LOS_ERRNO_LMK_ALREADY_REGISTERED; 693d8536b4Sopenharmony_ci } 703d8536b4Sopenharmony_ci if (LOS_ListEmpty(&g_losLmkOps.lmkOpsList)) { 713d8536b4Sopenharmony_ci LOS_ListHeadInsert(&g_losLmkOps.lmkOpsList, &lmkNode->node); 723d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 733d8536b4Sopenharmony_ci return LOS_OK; 743d8536b4Sopenharmony_ci } 753d8536b4Sopenharmony_ci 763d8536b4Sopenharmony_ci // the priority of registered node <= the first node 773d8536b4Sopenharmony_ci opsNode = LOS_DL_LIST_ENTRY(g_losLmkOps.lmkOpsList.pstNext, LosLmkOpsNode, node); 783d8536b4Sopenharmony_ci if (lmkNode->priority <= opsNode->priority) { 793d8536b4Sopenharmony_ci LOS_ListHeadInsert(&g_losLmkOps.lmkOpsList, &lmkNode->node); 803d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 813d8536b4Sopenharmony_ci return LOS_OK; 823d8536b4Sopenharmony_ci } 833d8536b4Sopenharmony_ci 843d8536b4Sopenharmony_ci // the priority of registered node > the last node 853d8536b4Sopenharmony_ci opsNode = LOS_DL_LIST_ENTRY(g_losLmkOps.lmkOpsList.pstPrev, LosLmkOpsNode, node); 863d8536b4Sopenharmony_ci if (lmkNode->priority >= opsNode->priority) { 873d8536b4Sopenharmony_ci LOS_ListTailInsert(&g_losLmkOps.lmkOpsList, &lmkNode->node); 883d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 893d8536b4Sopenharmony_ci return LOS_OK; 903d8536b4Sopenharmony_ci } 913d8536b4Sopenharmony_ci 923d8536b4Sopenharmony_ci // the priority of registered node > the first node and < the last node 933d8536b4Sopenharmony_ci LOS_DL_LIST_FOR_EACH_ENTRY(opsNode, &g_losLmkOps.lmkOpsList, LosLmkOpsNode, node) { 943d8536b4Sopenharmony_ci if (lmkNode->priority < opsNode->priority) { 953d8536b4Sopenharmony_ci LOS_ListHeadInsert((&opsNode->node)->pstPrev, &lmkNode->node); 963d8536b4Sopenharmony_ci break; 973d8536b4Sopenharmony_ci } 983d8536b4Sopenharmony_ci } 993d8536b4Sopenharmony_ci 1003d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 1013d8536b4Sopenharmony_ci return LOS_OK; 1023d8536b4Sopenharmony_ci} 1033d8536b4Sopenharmony_ci 1043d8536b4Sopenharmony_ciUINT32 LOS_LmkOpsNodeUnregister(LosLmkOpsNode *lmkNode) 1053d8536b4Sopenharmony_ci{ 1063d8536b4Sopenharmony_ci UINT32 intSave; 1073d8536b4Sopenharmony_ci 1083d8536b4Sopenharmony_ci if (lmkNode == NULL) { 1093d8536b4Sopenharmony_ci return LOS_ERRNO_LMK_INVALID_PARAMETER; 1103d8536b4Sopenharmony_ci } 1113d8536b4Sopenharmony_ci 1123d8536b4Sopenharmony_ci intSave = LOS_IntLock(); 1133d8536b4Sopenharmony_ci if (LOS_ListEmpty(&g_losLmkOps.lmkOpsList) || !OsIsLmkOpsNodeRegistered(lmkNode)) { 1143d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 1153d8536b4Sopenharmony_ci return LOS_ERRNO_LMK_NOT_REGISTERED; 1163d8536b4Sopenharmony_ci } 1173d8536b4Sopenharmony_ci LOS_ListDelete(&lmkNode->node); 1183d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 1193d8536b4Sopenharmony_ci return LOS_OK; 1203d8536b4Sopenharmony_ci} 1213d8536b4Sopenharmony_ci 1223d8536b4Sopenharmony_ciUINT32 LOS_LmkTasksKill(VOID) 1233d8536b4Sopenharmony_ci{ 1243d8536b4Sopenharmony_ci UINT32 intSave; 1253d8536b4Sopenharmony_ci UINT32 ret; 1263d8536b4Sopenharmony_ci LosLmkOpsNode *opsNode = NULL; 1273d8536b4Sopenharmony_ci FreeMemByKillingTask freeMem = NULL; 1283d8536b4Sopenharmony_ci 1293d8536b4Sopenharmony_ci intSave = LOS_IntLock(); 1303d8536b4Sopenharmony_ci 1313d8536b4Sopenharmony_ci // if tasks already killed, no need to do it again. 1323d8536b4Sopenharmony_ci if (g_losLmkOps.isMemFreed) { 1333d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 1343d8536b4Sopenharmony_ci return LOS_ERRNO_LMK_MEMORY_ALREADY_FREED; 1353d8536b4Sopenharmony_ci } else { 1363d8536b4Sopenharmony_ci g_losLmkOps.isMemFreed = TRUE; 1373d8536b4Sopenharmony_ci } 1383d8536b4Sopenharmony_ci LOS_DL_LIST_FOR_EACH_ENTRY(opsNode, &g_losLmkOps.lmkOpsList, LosLmkOpsNode, node) { 1393d8536b4Sopenharmony_ci freeMem = opsNode->freeMem; 1403d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 1413d8536b4Sopenharmony_ci if (freeMem != NULL) { 1423d8536b4Sopenharmony_ci ret = freeMem(); 1433d8536b4Sopenharmony_ci if (ret != LOS_OK) { 1443d8536b4Sopenharmony_ci return LOS_ERRNO_LMK_FREE_MEMORY_FAILURE; 1453d8536b4Sopenharmony_ci } 1463d8536b4Sopenharmony_ci } 1473d8536b4Sopenharmony_ci intSave = LOS_IntLock(); 1483d8536b4Sopenharmony_ci } 1493d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 1503d8536b4Sopenharmony_ci 1513d8536b4Sopenharmony_ci return LOS_OK; 1523d8536b4Sopenharmony_ci} 1533d8536b4Sopenharmony_ci 1543d8536b4Sopenharmony_ciUINT32 LOS_LmkTasksRestore(VOID) 1553d8536b4Sopenharmony_ci{ 1563d8536b4Sopenharmony_ci UINT32 intSave; 1573d8536b4Sopenharmony_ci UINT32 ret; 1583d8536b4Sopenharmony_ci LosLmkOpsNode *opsNode = NULL; 1593d8536b4Sopenharmony_ci RestoreKilledTask restore = NULL; 1603d8536b4Sopenharmony_ci 1613d8536b4Sopenharmony_ci intSave = LOS_IntLock(); 1623d8536b4Sopenharmony_ci 1633d8536b4Sopenharmony_ci // if no tasks killed, no need to restore. 1643d8536b4Sopenharmony_ci if (!g_losLmkOps.isMemFreed) { 1653d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 1663d8536b4Sopenharmony_ci return LOS_ERRNO_LMK_RESTORE_NOT_NEEDED; 1673d8536b4Sopenharmony_ci } else { 1683d8536b4Sopenharmony_ci g_losLmkOps.isMemFreed = FALSE; 1693d8536b4Sopenharmony_ci } 1703d8536b4Sopenharmony_ci LOS_DL_LIST_FOR_EACH_ENTRY(opsNode, &g_losLmkOps.lmkOpsList, LosLmkOpsNode, node) { 1713d8536b4Sopenharmony_ci restore = opsNode->restoreTask; 1723d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 1733d8536b4Sopenharmony_ci if (restore != NULL) { 1743d8536b4Sopenharmony_ci ret = restore(); 1753d8536b4Sopenharmony_ci if (ret != LOS_OK) { 1763d8536b4Sopenharmony_ci return LOS_ERRNO_LMK_RESTORE_TASKS_FAILURE; 1773d8536b4Sopenharmony_ci } 1783d8536b4Sopenharmony_ci } 1793d8536b4Sopenharmony_ci intSave = LOS_IntLock(); 1803d8536b4Sopenharmony_ci } 1813d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 1823d8536b4Sopenharmony_ci 1833d8536b4Sopenharmony_ci return LOS_OK; 1843d8536b4Sopenharmony_ci} 1853d8536b4Sopenharmony_ci 1863d8536b4Sopenharmony_ci#if (LOSCFG_KERNEL_LMK_DEBUG == 1) 1873d8536b4Sopenharmony_ciVOID LOS_LmkOpsNodeInfoShow(VOID) 1883d8536b4Sopenharmony_ci{ 1893d8536b4Sopenharmony_ci UINT32 intSave; 1903d8536b4Sopenharmony_ci LosLmkOpsNode *opsNode = NULL; 1913d8536b4Sopenharmony_ci 1923d8536b4Sopenharmony_ci intSave = LOS_IntLock(); 1933d8536b4Sopenharmony_ci LOS_DL_LIST_FOR_EACH_ENTRY(opsNode, &g_losLmkOps.lmkOpsList, LosLmkOpsNode, node) { 1943d8536b4Sopenharmony_ci PRINTK("Priority: %-4u Free:0x%-8x Restore:0x%-8x\n", opsNode->priority, 1953d8536b4Sopenharmony_ci (UINT32)(UINTPTR)opsNode->freeMem, (UINT32)(UINTPTR)opsNode->restoreTask); 1963d8536b4Sopenharmony_ci } 1973d8536b4Sopenharmony_ci LOS_IntRestore(intSave); 1983d8536b4Sopenharmony_ci} 1993d8536b4Sopenharmony_ci#endif 2003d8536b4Sopenharmony_ci 2013d8536b4Sopenharmony_ciVOID OsLmkInit(VOID) 2023d8536b4Sopenharmony_ci{ 2033d8536b4Sopenharmony_ci g_losLmkOps.isMemFreed = FALSE; 2043d8536b4Sopenharmony_ci LOS_ListInit(&g_losLmkOps.lmkOpsList); 2053d8536b4Sopenharmony_ci} 2063d8536b4Sopenharmony_ci#endif 207