1/*
2 * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification,
5 * are permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 *    conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 *    of conditions and the following disclaimer in the documentation and/or other materials
12 *    provided with the distribution.
13 *
14 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
15 *    to endorse or promote products derived from this software without specific prior written
16 *    permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include "los_box.h"
32#include "los_task.h"
33#include "los_context.h"
34#include "los_arch_context.h"
35#include "los_debug.h"
36
37static UserTaskCB g_UserTaskCBArray[LOSCFG_BASE_CORE_TSK_LIMIT] = { 0 };
38static LosBoxCB g_boxCB[1];
39
40VOID OsUserTaskInit(UINT32 taskID, UINTPTR entry, UINTPTR userArea, UINTPTR userSp)
41{
42    LosTaskCB *taskCB = OS_TCB_FROM_TID(taskID);
43    taskCB->taskStatus |= OS_TASK_FLAG_USER_TASK;
44    HalUserTaskStackInit(taskCB->stackPointer, entry, userSp);
45
46    g_UserTaskCBArray[taskID].userArea = userArea;
47    g_UserTaskCBArray[taskID].userSp = userSp;
48    g_UserTaskCBArray[taskID].boxID = g_UserTaskCBArray[g_losTask.runTask->taskID].boxID;
49}
50
51VOID OsUserTaskDelete(UINT32 taskID)
52{
53    (VOID)memset_s(&g_UserTaskCBArray[taskID], sizeof(UserTaskCB), 0, sizeof(UserTaskCB));
54}
55
56UserTaskCB *OsGetUserTaskCB(UINT32 taskID)
57{
58    return &g_UserTaskCBArray[taskID];
59}
60
61static UINT32 BoxInit(VOID)
62{
63    UINT32 count = sizeof(g_boxCB) / sizeof(LosBoxCB);
64    for (UINT32 i = 0; i < count; i++) {
65        LosBoxCB *box = &g_boxCB[i];
66        box->boxStackAddr = box->boxStartAddr + box->boxSize - box->boxStackSize;
67    }
68
69    return LOS_OK;
70}
71
72VOID OsBoxStart(VOID)
73{
74    UINT32 ret, taskID;
75    UINT32 count = sizeof(g_boxCB) / sizeof(LosBoxCB);
76    TSK_INIT_PARAM_S taskInitParam = { 0 };
77
78    for (UINT32 i = 0; i < count; i++) {
79        LosBoxCB *box = &g_boxCB[i];
80        taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)box->boxStartAddr;
81        taskInitParam.uwStackSize = 0x1000;
82        taskInitParam.pcName = "BoxMainTask";
83        taskInitParam.usTaskPrio = LOSCFG_BOX_PRIO;
84        taskInitParam.uwResved = LOS_TASK_ATTR_JOINABLE;
85        ret = LOS_TaskCreateOnly(&taskID, &taskInitParam);
86        if (ret != LOS_OK) {
87            PRINT_ERR("Create box %u main task failed, Error 0x%x\n", i, ret);
88            return;
89        }
90
91        OsUserTaskInit(taskID, (UINTPTR)_ulibc_start, 0, box->boxStackAddr + box->boxStackSize);
92        g_UserTaskCBArray[taskID].boxID = i;
93
94        ret = LOS_TaskResume(taskID);
95        if (ret != LOS_OK) {
96            PRINT_ERR("Box(%u) resume task %u failed, Error 0x%x\n", i, taskID, ret);
97            return;
98        }
99    }
100}
101
102UINT32 LOS_BoxStart(VOID)
103{
104    UINT32 ret, taskID;
105    TSK_INIT_PARAM_S taskInitParam = { 0 };
106
107    ret = BoxInit();
108    if (ret != LOS_OK) {
109        PRINT_ERR("Box init failed! Error 0x%x\n", ret);
110        return ret;
111    }
112
113    taskInitParam.pfnTaskEntry = (TSK_ENTRY_FUNC)OsBoxStart;
114    taskInitParam.uwStackSize = 0x1000;
115    taskInitParam.pcName = "BoxStart";
116    taskInitParam.usTaskPrio = LOSCFG_BOX_START_PRIO;
117    taskInitParam.uwResved = 0;
118    return LOS_TaskCreate(&taskID, &taskInitParam);
119}
120