128 lines
4.3 KiB
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);
|
|
}
|