kernel_liteos_a/kernel/common/los_init.c

128 lines
4.3 KiB
C

/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "los_init_pri.h"
#include "los_atomic.h"
#include "los_config.h"
#include "los_hw.h"
#include "los_printf.h"
#include "los_spinlock.h"
#include "los_typedef.h"
#ifdef LOS_INIT_DEBUG
#include "los_sys_pri.h"
#include "los_tick.h"
#endif
/**
* Register kernel init level labels.
*/
OS_INIT_LEVEL_REG(kernel, 10, g_kernInitLevelList);
STATIC volatile UINT32 g_initCurrentLevel = OS_INVALID_VALUE;
STATIC volatile struct ModuleInitInfo *g_initCurrentModule = 0;
STATIC Atomic g_initCount = 0;
STATIC SPIN_LOCK_INIT(g_initLock);
/**
* It is recommended that each startup framework encapsulate a layer of its own calling interface.
*/
STATIC VOID InitLevelCall(const CHAR *name, const UINT32 level, struct ModuleInitInfo *initLevelList[])
{
struct ModuleInitInfo *module = NULL;
#ifdef LOS_INIT_DEBUG
UINT64 startNsec, endNsec;
UINT64 totalTime = 0;
UINT64 singleTime = 0;
UINT32 ret = LOS_OK;
#endif
if (ArchCurrCpuid() == 0) {
#ifdef LOS_INIT_DEBUG
PRINTK("-------- %s Module Init... level = %u --------\n", name, level);
#endif
g_initCurrentLevel = level;
g_initCurrentModule = initLevelList[level];
} else {
while (g_initCurrentLevel < level) {
}
}
do {
LOS_SpinLock(&g_initLock);
if (g_initCurrentModule >= initLevelList[level + 1]) {
LOS_SpinUnlock(&g_initLock);
break;
}
module = (struct ModuleInitInfo *)g_initCurrentModule;
g_initCurrentModule++;
LOS_SpinUnlock(&g_initLock);
if (module->hook != NULL) {
#ifdef LOS_INIT_DEBUG
ret = LOS_OK;
startNsec = LOS_CurrNanosec();
ret = (UINT32)module->hook();
endNsec = LOS_CurrNanosec();
singleTime = endNsec - startNsec;
totalTime += singleTime;
PRINTK("Starting %s module consumes %llu ns. Run on cpu %u\n", module->name, singleTime, ArchCurrCpuid());
#else
module->hook();
#endif
}
#ifdef LOS_INIT_DEBUG
if (ret != LOS_OK) {
PRINT_ERR("%s initialization failed at module %s, function addr at 0x%x, ret code is %u\n",
name, module->name, module->hook, ret);
}
#endif
} while (1);
if (level >= LOS_INIT_LEVEL_KMOD_TASK) {
LOS_AtomicInc(&g_initCount);
while ((LOS_AtomicRead(&g_initCount) % LOSCFG_KERNEL_CORE_NUM) != 0) {
}
}
#ifdef LOS_INIT_DEBUG
PRINTK("%s initialization at level %u consumes %lluns on cpu %u.\n", name, level, totalTime, ArchCurrCpuid());
#endif
}
VOID OsInitCall(const UINT32 level)
{
if (level >= LOS_INIT_LEVEL_FINISH) {
return;
}
InitLevelCall("Kernel", level, g_kernInitLevelList);
}