1.主从CPU是如何初始化的 2.搞明白了变量前缀 uc:UINT8 us:UINT16 uw:UINT32 代表的意思

搜索 @note_pic 方便理解画的字符图
搜索 @note_why 尚未看明白的地方,如果您看明白了,请告知完善
搜索 @note_thinking 一点思考和吐槽的地方
搜索 @note_#if0 由第三方项目提供不由内核源码中定义的极为重要的结构体,为方便理解而添加的
搜索 @note_good 给源码点赞
上级 6091ff0e
/*
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020, 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.
*/
/**
* @defgroup los_hw Hardware
* @ingroup kernel
*/
#ifndef _LOS_HW_CPU_H
#define _LOS_HW_CPU_H
#include "los_typedef.h"
#include "los_toolchain.h"
#include "los_hw_arch.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
/* ARM System Registers */
#define DSB __asm__ volatile("dsb" ::: "memory")
#define DMB __asm__ volatile("dmb" ::: "memory")
#define ISB __asm__ volatile("isb" ::: "memory")
#define BARRIER __asm__ volatile("":::"memory")
#define ARM_SYSREG_READ(REG) \
({ \
UINT32 _val; \
__asm__ volatile("mrc " REG : "=r" (_val)); \
_val; \
})
#define ARM_SYSREG_WRITE(REG, val) \
({ \
__asm__ volatile("mcr " REG :: "r" (val)); \
ISB; \
})
#define ARM_SYSREG64_READ(REG) \
({ \
UINT64 _val; \
__asm__ volatile("mrrc " REG : "=r" (_val)); \
_val; \
})
#define ARM_SYSREG64_WRITE(REG, val) \
({ \
__asm__ volatile("mcrr " REG :: "r" (val)); \
ISB; \
})
#define CP14_REG(CRn, Op1, CRm, Op2) "p14, "#Op1", %0, "#CRn","#CRm","#Op2
#define CP15_REG(CRn, Op1, CRm, Op2) "p15, "#Op1", %0, "#CRn","#CRm","#Op2
#define CP15_REG64(CRn, Op1) "p15, "#Op1", %0, %H0,"#CRn
//CP15 协处理器各寄存器信息
/*
* Identification registers (c0) //c0 - 身份寄存器
*/
#define MIDR CP15_REG(c0, 0, c0, 0) /* Main ID Register */ //主ID寄存器
#define MPIDR CP15_REG(c0, 0, c0, 5) /* Multiprocessor Affinity Register *///多处理器关联寄存器给每个CPU制定一个逻辑地址
#define CCSIDR CP15_REG(c0, 1, c0, 0) /* Cache Size ID Registers */ //缓存大小ID寄存器
#define CLIDR CP15_REG(c0, 1, c0, 1) /* Cache Level ID Register */ //缓存登记ID寄存器
#define VPIDR CP15_REG(c0, 4, c0, 0) /* Virtualization Processor ID Register */ //虚拟化处理器ID寄存器
#define VMPIDR CP15_REG(c0, 4, c0, 5) /* Virtualization Multiprocessor ID Register */ //虚拟化多处理器ID寄存器
/*
* System control registers (c1) //c1 - 系统控制寄存器 各种控制位(可读写)
*/
#define SCTLR CP15_REG(c1, 0, c0, 0) /* System Control Register */ //系统控制寄存器
#define ACTLR CP15_REG(c1, 0, c0, 1) /* Auxiliary Control Register */ //辅助控制寄存器
#define CPACR CP15_REG(c1, 0, c0, 2) /* Coprocessor Access Control Register */ //协处理器访问控制寄存器
/*
* Memory protection and control registers (c2 & c3) //c2 - 传说中的TTB寄存器,主要是给MMU使用 c3 - 域访问控制位
*/
#define TTBR0 CP15_REG(c2, 0, c0, 0) /* Translation Table Base Register 0 */ //转换表基地址寄存器0
#define TTBR1 CP15_REG(c2, 0, c0, 1) /* Translation Table Base Register 1 */ //转换表基地址寄存器1
#define TTBCR CP15_REG(c2, 0, c0, 2) /* Translation Table Base Control Register */ ////转换表基地址控制寄存器
#define DACR CP15_REG(c3, 0, c0, 0) /* Domain Access Control Register */ //域访问控制寄存器
/*
* Memory system fault registers (c5 & c6) //c5 - 内存失效状态 c6 - 内存失效地址
*/
#define DFSR CP15_REG(c5, 0, c0, 0) /* Data Fault Status Register */ //数据故障状态寄存器
#define IFSR CP15_REG(c5, 0, c0, 1) /* Instruction Fault Status Register */ //指令故障状态寄存器
#define DFAR CP15_REG(c6, 0, c0, 0) /* Data Fault Address Register */ //数据故障地址寄存器
#define IFAR CP15_REG(c6, 0, c0, 2) /* Instruction Fault Address Register */ //指令错误地址寄存器
/*
* Process, context and thread ID registers (c13) //c13 - 进程标识符
*/
#define FCSEIDR CP15_REG(c13, 0, c0, 0) /* FCSE Process ID Register */ //FCSE(Fast Context Switch Extension,快速上下文切换)进程ID寄存器 位于CPU和MMU之间
#define CONTEXTIDR CP15_REG(c13, 0, c0, 1) /* Context ID Register */ //上下文ID寄存器
#define TPIDRURW CP15_REG(c13, 0, c0, 2) /* User Read/Write Thread ID Register */ //用户读/写线程ID寄存器
#define TPIDRURO CP15_REG(c13, 0, c0, 3) /* User Read-Only Thread ID Register */ //用户只读写线程ID寄存器
#define TPIDRPRW CP15_REG(c13, 0, c0, 4) /* PL1 only Thread ID Register */ //仅PL1线程ID寄存器
#define MPIDR_CPUID_MASK (0xffU)
//获取当前task
STATIC INLINE VOID *ArchCurrTaskGet(VOID)
{
return (VOID *)(UINTPTR)ARM_SYSREG_READ(TPIDRPRW);//读c13寄存器
}
STATIC INLINE VOID ArchCurrTaskSet(VOID *val)
{
ARM_SYSREG_WRITE(TPIDRPRW, (UINT32)(UINTPTR)val);
}
STATIC INLINE VOID ArchCurrUserTaskSet(UINTPTR val)
{
ARM_SYSREG_WRITE(TPIDRURO, (UINT32)val);
}
//https://www.keil.com/pack/doc/cmsis/Core_A/html/group__CMSIS__MPIDR.html
STATIC INLINE UINT32 ArchCurrCpuid(VOID)
{
#if (LOSCFG_KERNEL_SMP == YES)//CPU多核情况
return ARM_SYSREG_READ(MPIDR) & MPIDR_CPUID_MASK;
#else//ARM架构通过MPIDR(Multiprocessor Affinity Register)寄存器给每个CPU指定一个逻辑地址。
return 0;
#endif
}
STATIC INLINE UINT64 OsHwIDGet(VOID)
{
return ARM_SYSREG_READ(MPIDR);
}
STATIC INLINE UINT32 OsMainIDGet(VOID)
{
return ARM_SYSREG_READ(MIDR);
}
/* CPU interrupt mask handle implementation */
#if LOSCFG_ARM_ARCH >= 6
STATIC INLINE UINT32 ArchIntLock(VOID)
{
UINT32 intSave;
__asm__ __volatile__(
"mrs %0, cpsr \n"
"cpsid if "
: "=r"(intSave)
:
: "memory");
return intSave;
}
STATIC INLINE UINT32 ArchIntUnlock(VOID)
{
UINT32 intSave;
__asm__ __volatile__(
"mrs %0, cpsr \n"
"cpsie if "
: "=r"(intSave)
:
: "memory");
return intSave;
}
#else
STATIC INLINE UINT32 ArchIntLock(VOID)
{
UINT32 intSave, temp;
__asm__ __volatile__(
"mrs %0, cpsr \n"
"orr %1, %0, #0xc0 \n"
"msr cpsr_c, %1 "
:"=r"(intSave), "=r"(temp)
: :"memory");
return intSave;
}
STATIC INLINE UINT32 ArchIntUnlock(VOID)
{
UINT32 intSave;
__asm__ __volatile__(
"mrs %0, cpsr \n"
"bic %0, %0, #0xc0 \n"
"msr cpsr_c, %0 "
: "=r"(intSave)
: : "memory");
return intSave;
}
#endif
STATIC INLINE VOID ArchIntRestore(UINT32 intSave)
{
__asm__ __volatile__(
"msr cpsr_c, %0 "
:
: "r"(intSave)
: "memory");
}
#define PSR_I_BIT 0x00000080U
STATIC INLINE UINT32 OsIntLocked(VOID)
{
UINT32 intSave;
asm volatile(
"mrs %0, cpsr "
: "=r" (intSave)
:
: "memory", "cc");
return intSave & PSR_I_BIT;
}
STATIC INLINE UINT32 ArchSPGet(VOID)
{
UINT32 val;
__asm__ __volatile__("mov %0, sp" : "=r"(val));
return val;
}
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* _LOS_HW_CPU_H */
/*
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020, 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.
*/
/**
* @defgroup los_hw Hardware
* @ingroup kernel
*/
#ifndef _LOS_HW_CPU_H
#define _LOS_HW_CPU_H
#include "los_typedef.h"
#include "los_toolchain.h"
#include "los_hw_arch.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
/* ARM System Registers */
#define DSB __asm__ volatile("dsb" ::: "memory")
#define DMB __asm__ volatile("dmb" ::: "memory")
#define ISB __asm__ volatile("isb" ::: "memory")
#define BARRIER __asm__ volatile("":::"memory")
#define ARM_SYSREG_READ(REG) \
({ \
UINT32 _val; \
__asm__ volatile("mrc " REG : "=r" (_val)); \
_val; \
})
#define ARM_SYSREG_WRITE(REG, val) \
({ \
__asm__ volatile("mcr " REG :: "r" (val)); \
ISB; \
})
#define ARM_SYSREG64_READ(REG) \
({ \
UINT64 _val; \
__asm__ volatile("mrrc " REG : "=r" (_val)); \
_val; \
})
#define ARM_SYSREG64_WRITE(REG, val) \
({ \
__asm__ volatile("mcrr " REG :: "r" (val)); \
ISB; \
})
#define CP14_REG(CRn, Op1, CRm, Op2) "p14, "#Op1", %0, "#CRn","#CRm","#Op2
#define CP15_REG(CRn, Op1, CRm, Op2) "p15, "#Op1", %0, "#CRn","#CRm","#Op2
#define CP15_REG64(CRn, Op1) "p15, "#Op1", %0, %H0,"#CRn
//CP15 协处理器各寄存器信息
/*
* Identification registers (c0) //c0 - 身份寄存器
*/
#define MIDR CP15_REG(c0, 0, c0, 0) /* Main ID Register */ //主ID寄存器
#define MPIDR CP15_REG(c0, 0, c0, 5) /* Multiprocessor Affinity Register *///多处理器关联寄存器给每个CPU制定一个逻辑地址
#define CCSIDR CP15_REG(c0, 1, c0, 0) /* Cache Size ID Registers */ //缓存大小ID寄存器
#define CLIDR CP15_REG(c0, 1, c0, 1) /* Cache Level ID Register */ //缓存登记ID寄存器
#define VPIDR CP15_REG(c0, 4, c0, 0) /* Virtualization Processor ID Register */ //虚拟化处理器ID寄存器
#define VMPIDR CP15_REG(c0, 4, c0, 5) /* Virtualization Multiprocessor ID Register */ //虚拟化多处理器ID寄存器
/*
* System control registers (c1) //c1 - 系统控制寄存器 各种控制位(可读写)
*/
#define SCTLR CP15_REG(c1, 0, c0, 0) /* System Control Register */ //系统控制寄存器
#define ACTLR CP15_REG(c1, 0, c0, 1) /* Auxiliary Control Register */ //辅助控制寄存器
#define CPACR CP15_REG(c1, 0, c0, 2) /* Coprocessor Access Control Register */ //协处理器访问控制寄存器
/*
* Memory protection and control registers (c2 & c3) //c2 - 传说中的TTB寄存器,主要是给MMU使用 c3 - 域访问控制位
*/
#define TTBR0 CP15_REG(c2, 0, c0, 0) /* Translation Table Base Register 0 */ //转换表基地址寄存器0
#define TTBR1 CP15_REG(c2, 0, c0, 1) /* Translation Table Base Register 1 */ //转换表基地址寄存器1
#define TTBCR CP15_REG(c2, 0, c0, 2) /* Translation Table Base Control Register */ ////转换表基地址控制寄存器
#define DACR CP15_REG(c3, 0, c0, 0) /* Domain Access Control Register */ //域访问控制寄存器
/*
* Memory system fault registers (c5 & c6) //c5 - 内存失效状态 c6 - 内存失效地址
*/
#define DFSR CP15_REG(c5, 0, c0, 0) /* Data Fault Status Register */ //数据故障状态寄存器
#define IFSR CP15_REG(c5, 0, c0, 1) /* Instruction Fault Status Register */ //指令故障状态寄存器
#define DFAR CP15_REG(c6, 0, c0, 0) /* Data Fault Address Register */ //数据故障地址寄存器
#define IFAR CP15_REG(c6, 0, c0, 2) /* Instruction Fault Address Register */ //指令错误地址寄存器
/*
* Process, context and thread ID registers (c13) //c13 - 进程标识符
*/
#define FCSEIDR CP15_REG(c13, 0, c0, 0) /* FCSE Process ID Register */ //FCSE(Fast Context Switch Extension,快速上下文切换)进程ID寄存器 位于CPU和MMU之间
#define CONTEXTIDR CP15_REG(c13, 0, c0, 1) /* Context ID Register */ //上下文ID寄存器
#define TPIDRURW CP15_REG(c13, 0, c0, 2) /* User Read/Write Thread ID Register */ //用户读/写线程ID寄存器
#define TPIDRURO CP15_REG(c13, 0, c0, 3) /* User Read-Only Thread ID Register */ //用户只读写线程ID寄存器
#define TPIDRPRW CP15_REG(c13, 0, c0, 4) /* PL1 only Thread ID Register */ //仅PL1线程ID寄存器
#define MPIDR_CPUID_MASK (0xffU)
//获取当前task
STATIC INLINE VOID *ArchCurrTaskGet(VOID)
{
return (VOID *)(UINTPTR)ARM_SYSREG_READ(TPIDRPRW);//读c13寄存器
}
STATIC INLINE VOID ArchCurrTaskSet(VOID *val)
{
ARM_SYSREG_WRITE(TPIDRPRW, (UINT32)(UINTPTR)val);
}
STATIC INLINE VOID ArchCurrUserTaskSet(UINTPTR val)
{
ARM_SYSREG_WRITE(TPIDRURO, (UINT32)val);
}
//https://www.keil.com/pack/doc/cmsis/Core_A/html/group__CMSIS__MPIDR.html
STATIC INLINE UINT32 ArchCurrCpuid(VOID)
{
#if (LOSCFG_KERNEL_SMP == YES)//CPU多核情况
return ARM_SYSREG_READ(MPIDR) & MPIDR_CPUID_MASK;
#else//ARM架构通过MPIDR(Multiprocessor Affinity Register)寄存器给每个CPU指定一个逻辑地址。
return 0;
#endif
}
//获取CPU硬件ID,每个CPU都有自己的唯一标识
STATIC INLINE UINT64 OsHwIDGet(VOID)
{
return ARM_SYSREG_READ(MPIDR);
}
STATIC INLINE UINT32 OsMainIDGet(VOID)
{
return ARM_SYSREG_READ(MIDR);
}
/* CPU interrupt mask handle implementation */
#if LOSCFG_ARM_ARCH >= 6
STATIC INLINE UINT32 ArchIntLock(VOID)
{
UINT32 intSave;
__asm__ __volatile__(
"mrs %0, cpsr \n"
"cpsid if "
: "=r"(intSave)
:
: "memory");
return intSave;
}
STATIC INLINE UINT32 ArchIntUnlock(VOID)
{
UINT32 intSave;
__asm__ __volatile__(
"mrs %0, cpsr \n"
"cpsie if "
: "=r"(intSave)
:
: "memory");
return intSave;
}
#else
STATIC INLINE UINT32 ArchIntLock(VOID)
{
UINT32 intSave, temp;
__asm__ __volatile__(
"mrs %0, cpsr \n"
"orr %1, %0, #0xc0 \n"
"msr cpsr_c, %1 "
:"=r"(intSave), "=r"(temp)
: :"memory");
return intSave;
}
STATIC INLINE UINT32 ArchIntUnlock(VOID)
{
UINT32 intSave;
__asm__ __volatile__(
"mrs %0, cpsr \n"
"bic %0, %0, #0xc0 \n"
"msr cpsr_c, %0 "
: "=r"(intSave)
: : "memory");
return intSave;
}
#endif
STATIC INLINE VOID ArchIntRestore(UINT32 intSave)
{
__asm__ __volatile__(
"msr cpsr_c, %0 "
:
: "r"(intSave)
: "memory");
}
#define PSR_I_BIT 0x00000080U
STATIC INLINE UINT32 OsIntLocked(VOID)
{
UINT32 intSave;
asm volatile(
"mrs %0, cpsr "
: "=r" (intSave)
:
: "memory", "cc");
return intSave & PSR_I_BIT;
}
STATIC INLINE UINT32 ArchSPGet(VOID)
{
UINT32 val;
__asm__ __volatile__("mov %0, sp" : "=r"(val));
return val;
}
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* _LOS_HW_CPU_H */
/*
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020, 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_hw_pri.h"
#include "los_task_pri.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
/* support cpu vendors */
CpuVendor g_cpuTable[] = {//支持的CPU供应商
/* armv7-a */
{ 0xc07, "Cortex-A7" },
{ 0xc09, "Cortex-A9" },
{ 0, NULL }
};
/* logical cpu mapping */
UINT64 g_cpuMap[LOSCFG_KERNEL_CORE_NUM] = {
[0 ... LOSCFG_KERNEL_CORE_NUM - 1] = (UINT64)(-1)
};
/* bit[30] is enable FPU */
#define FP_EN (1U << 30)
LITE_OS_SEC_TEXT_INIT VOID OsTaskExit(VOID)
{// swi {cond} <immed_24>
__asm__ __volatile__("swi 0");//处理器产生软中断异常,swi指令的低24位存放的是0
}
#ifdef LOSCFG_GDB
STATIC VOID OsTaskEntrySetupLoopFrame(UINT32) __attribute__((noinline, naked));
VOID OsTaskEntrySetupLoopFrame(UINT32 arg0)
{
asm volatile("\tsub fp, sp, #0x4\n"
"\tpush {fp, lr}\n"
"\tadd fp, sp, #0x4\n"
"\tpush {fp, lr}\n"
"\tadd fp, sp, #0x4\n"
"\tbl OsTaskEntry\n"
"\tpop {fp, lr}\n"
"\tpop {fp, pc}\n");
}
#endif
LITE_OS_SEC_TEXT_INIT VOID *OsTaskStackInit(UINT32 taskID, UINT32 stackSize, VOID *topStack, BOOL initFlag)
{
UINT32 index = 1;
TaskContext *taskContext = NULL;
if (initFlag == TRUE) {
OsStackInit(topStack, stackSize);
}
taskContext = (TaskContext *)(((UINTPTR)topStack + stackSize) - sizeof(TaskContext));//注意看上下文将存放在栈的底部
/* initialize the task context */
#ifdef LOSCFG_GDB
taskContext->PC = (UINTPTR)OsTaskEntrySetupLoopFrame;
#else
taskContext->PC = (UINTPTR)OsTaskEntry;//程序计数器,CPU首次执行task时跑的第一条指令位置
#endif
taskContext->LR = (UINTPTR)OsTaskExit; /* LR should be kept, to distinguish it's THUMB or ARM instruction */
taskContext->resved = 0x0;
taskContext->R[0] = taskID; /* R0 */
taskContext->R[index++] = 0x01010101; /* R1, 0x01010101 : reg initialed magic word */
for (; index < GEN_REGS_NUM; index++) {//R2 - R12的初始化很有意思,为什么要这么做?
taskContext->R[index] = taskContext->R[index - 1] + taskContext->R[1]; /* R2 - R12 */
}
#ifdef LOSCFG_INTERWORK_THUMB // 16位模式
taskContext->regPSR = PSR_MODE_SVC_THUMB; /* CPSR (Enable IRQ and FIQ interrupts, THUMNB-mode) */
#else
taskContext->regPSR = PSR_MODE_SVC_ARM; /* CPSR (Enable IRQ and FIQ interrupts, ARM-mode) */
#endif
#if !defined(LOSCFG_ARCH_FPU_DISABLE)
/* 0xAAA0000000000000LL : float reg initialed magic word */
for (index = 0; index < FP_REGS_NUM; index++) {
taskContext->D[index] = 0xAAA0000000000000LL + index; /* D0 - D31 */
}
taskContext->regFPSCR = 0;
taskContext->regFPEXC = FP_EN;
#endif
return (VOID *)taskContext;
}
//把父任务上下文克隆给子任务
LITE_OS_SEC_TEXT VOID OsUserCloneParentStack(LosTaskCB *childTaskCB, LosTaskCB *parentTaskCB)
{
TaskContext *context = (TaskContext *)childTaskCB->stackPointer;
VOID *cloneStack = (VOID *)(((UINTPTR)parentTaskCB->topOfStack + parentTaskCB->stackSize) - sizeof(TaskContext));
//cloneStack指向 TaskContext
LOS_ASSERT(parentTaskCB->taskStatus & OS_TASK_STATUS_RUNNING);//当前任务一定是正在运行的task
(VOID)memcpy_s(childTaskCB->stackPointer, sizeof(TaskContext), cloneStack, sizeof(TaskContext));//直接把任务上下文拷贝了一份
context->R[0] = 0;//R0寄存器为0
}
//用户任务使用栈初始化
LITE_OS_SEC_TEXT_INIT VOID OsUserTaskStackInit(TaskContext *context, TSK_ENTRY_FUNC taskEntry, UINTPTR stack)
{
LOS_ASSERT(context != NULL);
#ifdef LOSCFG_INTERWORK_THUMB
context->regPSR = PSR_MODE_USR_THUMB;
#else
context->regPSR = PSR_MODE_USR_ARM;
#endif
context->R[0] = stack;//栈指针给r0寄存器
context->SP = TRUNCATE(stack, LOSCFG_STACK_POINT_ALIGN_SIZE);//异常模式所专用的堆栈 segment fault 输出回溯信息
context->LR = 0;//保存子程序返回地址 例如 a call b ,在b中保存 a地址
context->PC = (UINTPTR)taskEntry;//入口函数
}
VOID Sev(VOID)
{
__asm__ __volatile__ ("sev" : : : "memory");
}
VOID Wfe(VOID)//用在spinlock中 spinlock的功能,是在不同CPU core之间,保护共享资源
{
__asm__ __volatile__ ("wfe" : : : "memory");//在获得不到资源时,让Core进入busy loop,而通过插入WFE指令,可以节省功耗
}
VOID Wfi(VOID)//WFI指令:arm core 立即进入low-power standby state,直到有WFI Wakeup events发生
{
__asm__ __volatile__ ("wfi" : : : "memory");//一般用于cpuidle
}
VOID Dmb(VOID)//数据存储器隔离。DMB 指令保证: 仅当所有在它前面的存储器访问操作都执行完毕后,才提交(commit)在它后面的存储器访问操作。
{
__asm__ __volatile__ ("dmb" : : : "memory");
}
VOID Dsb(VOID)//数据同步隔离。比 DMB 严格: 仅当所有在它前面的存储器访问操作都执行完毕后,才执行在它后面的指令
{
__asm__ __volatile__("dsb" : : : "memory");
}
VOID Isb(VOID)//指令同步隔离。最严格:它会清洗流水线,以保证所有它前面的指令都执行完毕之后,才执行它后面的指令。
{
__asm__ __volatile__("isb" : : : "memory");
}
VOID FlushICache(VOID)
{
/*
* Use ICIALLUIS instead of ICIALLU. ICIALLUIS operates on all processors in the Inner
* shareable domain of the processor that performs the operation.
*/
__asm__ __volatile__ ("mcr p15, 0, %0, c7, c1, 0" : : "r" (0) : "memory");
}
VOID DCacheFlushRange(UINT32 start, UINT32 end)
{
arm_clean_cache_range(start, end);
}
VOID DCacheInvRange(UINT32 start, UINT32 end)
{
arm_inv_cache_range(start, end);
}
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
/*
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020, 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_hw_pri.h"
#include "los_task_pri.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
/* support cpu vendors */
CpuVendor g_cpuTable[] = { //支持的CPU供应商
/* armv7-a */
{ 0xc07, "Cortex-A7" },
{ 0xc09, "Cortex-A9" },
{ 0, NULL }
};
/* logical cpu mapping */ //逻辑层cpu映射
UINT64 g_cpuMap[LOSCFG_KERNEL_CORE_NUM] = {
[0 ... LOSCFG_KERNEL_CORE_NUM - 1] = (UINT64)(-1) //统一赋值,这个赋值方式还挺别致的.
};
/* bit[30] is enable FPU */
#define FP_EN (1U << 30)
LITE_OS_SEC_TEXT_INIT VOID OsTaskExit(VOID)
{// swi {cond} <immed_24>
__asm__ __volatile__("swi 0");//处理器产生软中断异常,swi指令的低24位存放的是0
}//该指令可以产生SWI异常,ARM通过该指令可以实现用户模式中对操作系统中特权模式的程序的调用,即系统调用实现的基础;
#ifdef LOSCFG_GDB
STATIC VOID OsTaskEntrySetupLoopFrame(UINT32) __attribute__((noinline, naked));
VOID OsTaskEntrySetupLoopFrame(UINT32 arg0)
{
asm volatile("\tsub fp, sp, #0x4\n"
"\tpush {fp, lr}\n"
"\tadd fp, sp, #0x4\n"
"\tpush {fp, lr}\n"
"\tadd fp, sp, #0x4\n"
"\tbl OsTaskEntry\n"
"\tpop {fp, lr}\n"
"\tpop {fp, pc}\n");
}
#endif
//任务栈初始化,非常重要的函数
LITE_OS_SEC_TEXT_INIT VOID *OsTaskStackInit(UINT32 taskID, UINT32 stackSize, VOID *topStack, BOOL initFlag)
{
UINT32 index = 1;
TaskContext *taskContext = NULL;
if (initFlag == TRUE) {
OsStackInit(topStack, stackSize);
}
taskContext = (TaskContext *)(((UINTPTR)topStack + stackSize) - sizeof(TaskContext));//注意看上下文将存放在栈的底部
/* initialize the task context */ //初始化任务上下文
#ifdef LOSCFG_GDB
taskContext->PC = (UINTPTR)OsTaskEntrySetupLoopFrame;
#else
taskContext->PC = (UINTPTR)OsTaskEntry;//程序计数器,CPU首次执行task时跑的第一条指令位置
#endif
taskContext->LR = (UINTPTR)OsTaskExit; /* LR should be kept, to distinguish it's THUMB or ARM instruction */
taskContext->resved = 0x0;
taskContext->R[0] = taskID; /* R0 */
taskContext->R[index++] = 0x01010101; /* R1, 0x01010101 : reg initialed magic word */
for (; index < GEN_REGS_NUM; index++) {//R2 - R12的初始化很有意思,为什么要这么做?
taskContext->R[index] = taskContext->R[index - 1] + taskContext->R[1]; /* R2 - R12 */
}
#ifdef LOSCFG_INTERWORK_THUMB // 16位模式
taskContext->regPSR = PSR_MODE_SVC_THUMB; /* CPSR (Enable IRQ and FIQ interrupts, THUMNB-mode) */
#else
taskContext->regPSR = PSR_MODE_SVC_ARM; /* CPSR (Enable IRQ and FIQ interrupts, ARM-mode) */
#endif
#if !defined(LOSCFG_ARCH_FPU_DISABLE)
/* 0xAAA0000000000000LL : float reg initialed magic word */
for (index = 0; index < FP_REGS_NUM; index++) {
taskContext->D[index] = 0xAAA0000000000000LL + index; /* D0 - D31 */
}
taskContext->regFPSCR = 0;
taskContext->regFPEXC = FP_EN;
#endif
return (VOID *)taskContext;
}
//把父任务上下文克隆给子任务
LITE_OS_SEC_TEXT VOID OsUserCloneParentStack(LosTaskCB *childTaskCB, LosTaskCB *parentTaskCB)
{
TaskContext *context = (TaskContext *)childTaskCB->stackPointer;
VOID *cloneStack = (VOID *)(((UINTPTR)parentTaskCB->topOfStack + parentTaskCB->stackSize) - sizeof(TaskContext));
//cloneStack指向 TaskContext
LOS_ASSERT(parentTaskCB->taskStatus & OS_TASK_STATUS_RUNNING);//当前任务一定是正在运行的task
(VOID)memcpy_s(childTaskCB->stackPointer, sizeof(TaskContext), cloneStack, sizeof(TaskContext));//直接把任务上下文拷贝了一份
context->R[0] = 0;//R0寄存器为0
}
//用户任务使用栈初始化
LITE_OS_SEC_TEXT_INIT VOID OsUserTaskStackInit(TaskContext *context, TSK_ENTRY_FUNC taskEntry, UINTPTR stack)
{
LOS_ASSERT(context != NULL);
#ifdef LOSCFG_INTERWORK_THUMB
context->regPSR = PSR_MODE_USR_THUMB;
#else
context->regPSR = PSR_MODE_USR_ARM;
#endif
context->R[0] = stack;//栈指针给r0寄存器
context->SP = TRUNCATE(stack, LOSCFG_STACK_POINT_ALIGN_SIZE);//异常模式所专用的堆栈 segment fault 输出回溯信息
context->LR = 0;//保存子程序返回地址 例如 a call b ,在b中保存 a地址
context->PC = (UINTPTR)taskEntry;//入口函数
}
VOID Sev(VOID)
{
__asm__ __volatile__ ("sev" : : : "memory");//多处理器环境中向所有的处理器发送事件(包括自身)
}
VOID Wfe(VOID)//等待事件,如果没有之前该事件的记录,进入休眠模式;如果有的话,则清除事件锁存并继续执行;
{
__asm__ __volatile__ ("wfe" : : : "memory");//wait for Events 等待事件,即下一次事件发生前都在此hold住不干活
}
VOID Wfi(VOID)//WFI指令:arm core 立即进入low-power standby state,等待中断,进入休眠模式。
{
__asm__ __volatile__ ("wfi" : : : "memory");//wait for Interrupt 等待中断,即下一次中断发生前都在此hold住不干活
}
VOID Dmb(VOID)//数据存储器隔离。DMB 指令保证: 仅当所有在它前面的存储器访问操作都执行完毕后,才提交(commit)在它后面的存储器访问操作。
{
__asm__ __volatile__ ("dmb" : : : "memory");
}
VOID Dsb(VOID)//数据同步隔离。比 DMB 严格: 仅当所有在它前面的存储器访问操作都执行完毕后,才执行在它后面的指令
{
__asm__ __volatile__("dsb" : : : "memory");
}
VOID Isb(VOID)//指令同步隔离。最严格:它会清洗流水线,以保证所有它前面的指令都执行完毕之后,才执行它后面的指令。
{
__asm__ __volatile__("isb" : : : "memory");
}
VOID FlushICache(VOID)
{
/*
* Use ICIALLUIS instead of ICIALLU. ICIALLUIS operates on all processors in the Inner
* shareable domain of the processor that performs the operation.
*/
__asm__ __volatile__ ("mcr p15, 0, %0, c7, c1, 0" : : "r" (0) : "memory");
}
VOID DCacheFlushRange(UINT32 start, UINT32 end)
{
arm_clean_cache_range(start, end);
}
VOID DCacheInvRange(UINT32 start, UINT32 end)
{
arm_inv_cache_range(start, end);
}
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
......@@ -272,9 +272,9 @@ bss_loop:
_start_hang:
b _start_hang
mmu_setup: //设置MMU
mov r12, #0 /*设置8号寄存器以控制TLB并将映射设置为无效*/
mcr p15, 0, r12, c8, c7, 0 /* Set c8 to control the TLB and set the mapping to invalid */
mmu_setup: //安装MMU
mov r12, #0
mcr p15, 0, r12, c8, c7, 0 /* Set c8 to control the TLB and set the mapping to invalid *//*设置8号寄存器以控制TLB并将映射设置为无效*/
isb
mcr p15, 0, r12, c2, c0, 2 /* Initialize the c2 register *///初始化C2寄存器
......@@ -323,8 +323,8 @@ reset_platform:
mov r0, #0
mov pc, r0 /* Jump to reset vector */
#endif
cpu_start:
bl secondary_cpu_start
cpu_start: /* 启动CPU */
bl secondary_cpu_start /* 启动次级CPU */
b .
......
/*
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020, 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.
*/
/**
* @defgroup los_hw Hardware
* @ingroup kernel
*/
#ifndef _LOS_HW_H
#define _LOS_HW_H
#include "los_typedef.h"
#include "los_hw_cpu.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
#define OS_SCHEDULE_IN_IRQ 0x0
#define OS_SCHEDULE_IN_TASK 0x1
#define PSR_T_ARM 0x00000000u
#define PSR_T_THUMB 0x00000020u
#define PSR_MODE_SVC 0x00000013u
#define PSR_MODE_SYS 0x0000001Fu
#define PSR_FIQ_DIS 0x00000040u
#define PSR_IRQ_DIS 0x00000080u
#define PSR_MODE_USR 0x00000010u
#define PSR_MODE_SVC_THUMB (PSR_MODE_SVC | PSR_T_THUMB | PSR_FIQ_DIS | PSR_IRQ_DIS)
#define PSR_MODE_SVC_ARM (PSR_MODE_SVC | PSR_T_ARM | PSR_FIQ_DIS | PSR_IRQ_DIS)
#define PSR_MODE_SYS_THUMB (PSR_MODE_SYS | PSR_T_THUMB)
#define PSR_MODE_SYS_ARM (PSR_MODE_SYS | PSR_T_ARM)
#define PSR_MODE_USR_THUMB (PSR_MODE_USR | PSR_T_THUMB)
#define PSR_MODE_USR_ARM (PSR_MODE_USR | PSR_T_ARM)
#define LOS_CHECK_SCHEDULE ((!OS_INT_ACTIVE) && OsPreemptable())
typedef struct {
const UINT32 partNo;
const CHAR *cpuName;
} CpuVendor;
extern CpuVendor g_cpuTable[];
extern UINT64 g_cpuMap[];
#define CPU_MAP_GET(cpuid) g_cpuMap[(cpuid)]
#define CPU_MAP_SET(cpuid, hwid) g_cpuMap[(cpuid)] = (hwid)
/**
* @ingroup los_hw
* @brief Set Event.
*
* @par Description:
* <ul>
* <li>This API is used to send an event to all cores within a muti-processor system.</li>
* </ul>
* @attention
* <ul>
* <li>This API is not implemented.</li>
* </ul>
*
* @param None.
*
* @retval #None.
*
* @par Dependency:
* los_hw.h: the header file that contains the API declaration.
* @see wfe.
*/
extern VOID Sev(VOID);
/**
* @ingroup los_hw
* @brief Wait for event.
*
* @par Description:
* <ul>
* <li>This API is used to suspend execution until events occurs if the event register is not set.</li>
* </ul>
* @attention
* <ul>
* <li>This API is not implemented.</li>
* </ul>
*
* @param None.
*
* @retval #None.
*
* @par Dependency:
* los_hw.h: the header file that contains the API declaration.
* @see sev.
*/
extern VOID Wfe(VOID);
/**
* @ingroup los_hw
* @brief Wait for interrupt.
*
* @par Description:
* <ul>
* <li>This API is used to suspend execution until interrupt or a debug request occurs.</li>
* </ul>
* @attention None.
*
* @param None.
*
* @retval #None.
*
* @par Dependency:
* los_hw.h: the header file that contains the API declaration.
* @see None.
*/
extern VOID Wfi(VOID);
/**
* @ingroup los_hw
* @brief Data Memory Barrier.
*
* @par Description:
* <ul>
* <li>This API is used as a memory barrier</li>
* </ul>
* @attention None.
*
* @param None.
*
* @retval #None.
*
* @par Dependency:
* los_hw.h: the header file that contains the API declaration.
* @see None.
*/
extern VOID Dmb(VOID);
/**
* @ingroup los_hw
* @brief Data Synchronization Barrier.
*
* @par Description:
* <ul>
* <li>This API is used as a special kind of memory barrier</li>
* </ul>
* @attention None.
*
* @param None.
*
* @retval #None.
*
* @par Dependency:
* los_hw.h: the header file that contains the API declaration.
* @see None.
*/
extern VOID Dsb(VOID);
/**
* @ingroup los_hw
* @brief Instruction Synchronization Barrier.
*
* @par Description:
* <ul>
* <li>This API is used to flush the pipeline in the processor,
* so that all instructions following the ISB are fetched from cache or memory,
* after the instruction has been completed.</li>
* </ul>
* @attention None.
*
* @param None.
*
* @retval #None.
*
* @par Dependency:
* los_hw.h: the header file that contains the API declaration.
* @see None.
*/
extern VOID Isb(VOID);
/**
* @ingroup los_hw
* @brief Invalidate instruction cache.
*
* @par Description:
* <ul>
* <li>This API is used to invalidate the instruction cache.</li>
* </ul>
* @attention None.
*
* @param None.
*
* @retval #None.
*
* @par Dependency:
* los_hw.h: the header file that contains the API declaration.
* @see None.
*/
extern VOID FlushICache(VOID);
/**
* @ingroup los_hw
* @brief Flush data cache.
*
* @par Description:
* <ul>
* <li>This API is used to flush the data cache to the memory.</li>
* </ul>
* @attention
* <ul>
* <li>The input end address must be greater than the input start address.</li>
* </ul>
*
* @param start [IN] Type #int Flush start address.
* @param end [IN] Type #int Flush end address.
*
* @retval #None.
*
* @par Dependency:
* los_hw.h: the header file that contains the API declaration.
* @see None.
*/
extern VOID DCacheFlushRange(UINTPTR start, UINTPTR end);
/**
* @ingroup los_hw
* @brief Invalidate data cache.
*
* @par Description:
* <ul>
* <li>This API is used to Invalidate the data in cache.</li>
* </ul>
* @attention
* <ul>
* <li>The input end address must be greater than the input start address.</li>
* </ul>
*
* @param start [IN] Type #int Invalidate start address.
* @param end [IN] Type #int Invalidate end address .
*
* @retval #None.
*
* @par Dependency:
* los_hw.h: the header file that contains the API declaration.
* @see None.
*/
extern VOID DCacheInvRange(UINTPTR start, UINTPTR end);
/**
* @ingroup los_hw
* @brief Get cpu core name.
*
* @par Description:
* <ul>
* <li>This API is used to get cpu core name.</li>
* </ul>
* @attention
* <ul>
* <li>None.</li>
* </ul>
*
* @param
* @retval #CHAR * cpu core name.
*
* @par Dependency:
* los_hw.h: the header file that contains the API declaration.
* @see None.
*/
STATIC INLINE const CHAR *LOS_CpuInfo(VOID)
{
INT32 i;
UINT32 midr = OsMainIDGet();
/* [15:4] is the primary part number */
UINT32 partNo = (midr & 0xFFF0) >> 0x4;
for (i = 0; g_cpuTable[i].partNo != 0; i++) {
if (partNo == g_cpuTable[i].partNo) {
return g_cpuTable[i].cpuName;
}
}
return "unknown";
}
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* _LOS_HW_H */
/*
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020, 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.
*/
/**
* @defgroup los_hw Hardware
* @ingroup kernel
*/
#ifndef _LOS_HW_H
#define _LOS_HW_H
#include "los_typedef.h"
#include "los_hw_cpu.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
#define OS_SCHEDULE_IN_IRQ 0x0
#define OS_SCHEDULE_IN_TASK 0x1
#define PSR_T_ARM 0x00000000u
#define PSR_T_THUMB 0x00000020u
#define PSR_MODE_SVC 0x00000013u
#define PSR_MODE_SYS 0x0000001Fu
#define PSR_FIQ_DIS 0x00000040u
#define PSR_IRQ_DIS 0x00000080u
#define PSR_MODE_USR 0x00000010u
#define PSR_MODE_SVC_THUMB (PSR_MODE_SVC | PSR_T_THUMB | PSR_FIQ_DIS | PSR_IRQ_DIS)
#define PSR_MODE_SVC_ARM (PSR_MODE_SVC | PSR_T_ARM | PSR_FIQ_DIS | PSR_IRQ_DIS)
#define PSR_MODE_SYS_THUMB (PSR_MODE_SYS | PSR_T_THUMB)
#define PSR_MODE_SYS_ARM (PSR_MODE_SYS | PSR_T_ARM)
#define PSR_MODE_USR_THUMB (PSR_MODE_USR | PSR_T_THUMB)
#define PSR_MODE_USR_ARM (PSR_MODE_USR | PSR_T_ARM)
#define LOS_CHECK_SCHEDULE ((!OS_INT_ACTIVE) && OsPreemptable()) //检查是否可以调度
typedef struct {//CPU供货商描述符
const UINT32 partNo; //编号
const CHAR *cpuName; //CPU名称
} CpuVendor;
extern CpuVendor g_cpuTable[];
extern UINT64 g_cpuMap[];
#define CPU_MAP_GET(cpuid) g_cpuMap[(cpuid)]
#define CPU_MAP_SET(cpuid, hwid) g_cpuMap[(cpuid)] = (hwid)
/**
* @ingroup los_hw
* @brief Set Event.
*
* @par Description:
* <ul>
* <li>This API is used to send an event to all cores within a muti-processor system.</li>
* </ul>
* @attention
* <ul>
* <li>This API is not implemented.</li>
* </ul>
*
* @param None.
*
* @retval #None.
*
* @par Dependency:
* los_hw.h: the header file that contains the API declaration.
* @see wfe.
*/
extern VOID Sev(VOID);
/**
* @ingroup los_hw
* @brief Wait for event.
*
* @par Description:
* <ul>
* <li>This API is used to suspend execution until events occurs if the event register is not set.</li>
* </ul>
* @attention
* <ul>
* <li>This API is not implemented.</li>
* </ul>
*
* @param None.
*
* @retval #None.
*
* @par Dependency:
* los_hw.h: the header file that contains the API declaration.
* @see sev.
*/
extern VOID Wfe(VOID);
/**
* @ingroup los_hw
* @brief Wait for interrupt.
*
* @par Description:
* <ul>
* <li>This API is used to suspend execution until interrupt or a debug request occurs.</li>
* </ul>
* @attention None.
*
* @param None.
*
* @retval #None.
*
* @par Dependency:
* los_hw.h: the header file that contains the API declaration.
* @see None.
*/
extern VOID Wfi(VOID);
/**
* @ingroup los_hw
* @brief Data Memory Barrier.
*
* @par Description:
* <ul>
* <li>This API is used as a memory barrier</li>
* </ul>
* @attention None.
*
* @param None.
*
* @retval #None.
*
* @par Dependency:
* los_hw.h: the header file that contains the API declaration.
* @see None.
*/
extern VOID Dmb(VOID);
/**
* @ingroup los_hw
* @brief Data Synchronization Barrier.
*
* @par Description:
* <ul>
* <li>This API is used as a special kind of memory barrier</li>
* </ul>
* @attention None.
*
* @param None.
*
* @retval #None.
*
* @par Dependency:
* los_hw.h: the header file that contains the API declaration.
* @see None.
*/
extern VOID Dsb(VOID);
/**
* @ingroup los_hw
* @brief Instruction Synchronization Barrier.
*
* @par Description:
* <ul>
* <li>This API is used to flush the pipeline in the processor,
* so that all instructions following the ISB are fetched from cache or memory,
* after the instruction has been completed.</li>
* </ul>
* @attention None.
*
* @param None.
*
* @retval #None.
*
* @par Dependency:
* los_hw.h: the header file that contains the API declaration.
* @see None.
*/
extern VOID Isb(VOID);
/**
* @ingroup los_hw
* @brief Invalidate instruction cache.
*
* @par Description:
* <ul>
* <li>This API is used to invalidate the instruction cache.</li>
* </ul>
* @attention None.
*
* @param None.
*
* @retval #None.
*
* @par Dependency:
* los_hw.h: the header file that contains the API declaration.
* @see None.
*/
extern VOID FlushICache(VOID);
/**
* @ingroup los_hw
* @brief Flush data cache.
*
* @par Description:
* <ul>
* <li>This API is used to flush the data cache to the memory.</li>
* </ul>
* @attention
* <ul>
* <li>The input end address must be greater than the input start address.</li>
* </ul>
*
* @param start [IN] Type #int Flush start address.
* @param end [IN] Type #int Flush end address.
*
* @retval #None.
*
* @par Dependency:
* los_hw.h: the header file that contains the API declaration.
* @see None.
*/
extern VOID DCacheFlushRange(UINTPTR start, UINTPTR end);
/**
* @ingroup los_hw
* @brief Invalidate data cache.
*
* @par Description:
* <ul>
* <li>This API is used to Invalidate the data in cache.</li>
* </ul>
* @attention
* <ul>
* <li>The input end address must be greater than the input start address.</li>
* </ul>
*
* @param start [IN] Type #int Invalidate start address.
* @param end [IN] Type #int Invalidate end address .
*
* @retval #None.
*
* @par Dependency:
* los_hw.h: the header file that contains the API declaration.
* @see None.
*/
extern VOID DCacheInvRange(UINTPTR start, UINTPTR end);
/**
* @ingroup los_hw
* @brief Get cpu core name.
*
* @par Description:
* <ul>
* <li>This API is used to get cpu core name.</li>
* </ul>
* @attention
* <ul>
* <li>None.</li>
* </ul>
*
* @param
* @retval #CHAR * cpu core name.
*
* @par Dependency:
* los_hw.h: the header file that contains the API declaration.
* @see None.
*/
STATIC INLINE const CHAR *LOS_CpuInfo(VOID)
{
INT32 i;
UINT32 midr = OsMainIDGet();
/* [15:4] is the primary part number */
UINT32 partNo = (midr & 0xFFF0) >> 0x4;
for (i = 0; g_cpuTable[i].partNo != 0; i++) {
if (partNo == g_cpuTable[i].partNo) {
return g_cpuTable[i].cpuName;
}
}
return "unknown";
}
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* _LOS_HW_H */
......@@ -108,7 +108,7 @@ extern "C" {
#error "swtmr maxnum cannot be zero"
#endif /* LOSCFG_BASE_CORE_SWTMR_LIMIT <= 0 */
LITE_OS_SEC_BSS SWTMR_CTRL_S *g_swtmrCBArray = NULL; /* First address in Timer memory space */
LITE_OS_SEC_BSS SWTMR_CTRL_S *g_swtmrCBArray = NULL; /* First address in Timer memory space *///定时器池
LITE_OS_SEC_BSS UINT8 *g_swtmrHandlerPool = NULL; /* Pool of Swtmr Handler *///用于注册软时钟的回调函数
LITE_OS_SEC_BSS LOS_DL_LIST g_swtmrFreeList; /* Free list of Software Timer */
......@@ -169,7 +169,7 @@ LITE_OS_SEC_TEXT_INIT VOID OsSwtmrRecycle(UINT32 processID)
}
}
}
//软时钟初始化
//软时钟初始化 ,注意函数在多CPU情况下会执行多次
LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrInit(VOID)
{
UINT32 size;
......@@ -178,7 +178,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrInit(VOID)
SWTMR_CTRL_S *swtmr = NULL;
UINT32 swtmrHandlePoolSize;
UINT32 cpuid = ArchCurrCpuid();
if (cpuid == 0) {
if (cpuid == 0) {//确保以下代码块由一个CPU执行,g_swtmrCBArray和g_swtmrHandlerPool 是所有CPU共用的
size = sizeof(SWTMR_CTRL_S) * LOSCFG_BASE_CORE_SWTMR_LIMIT;//申请软时钟内存大小
swtmr = (SWTMR_CTRL_S *)LOS_MemAlloc(m_aucSysMem0, size); /* system resident resource */ //常驻内存
if (swtmr == NULL) {
......@@ -190,33 +190,33 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrInit(VOID)
LOS_ListInit(&g_swtmrFreeList);//初始化空闲链表
for (index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++, swtmr++) {
swtmr->usTimerID = index;//按顺序赋值
LOS_ListTailInsert(&g_swtmrFreeList, &swtmr->stSortList.sortLinkNode);//用sortLinkNode把结构体全部 挂到空闲链表
LOS_ListTailInsert(&g_swtmrFreeList, &swtmr->stSortList.sortLinkNode);//通过sortLinkNode将节点挂到空闲链表
}
//用于软时钟注册的内存为何要用静态内存申请? 请大家想想这个问题
swtmrHandlePoolSize = LOS_MEMBOX_SIZE(sizeof(SwtmrHandlerItem), OS_SWTMR_HANDLE_QUEUE_SIZE);//申请静态内存
swtmrHandlePoolSize = LOS_MEMBOX_SIZE(sizeof(SwtmrHandlerItem), OS_SWTMR_HANDLE_QUEUE_SIZE);//计算所有注册函数内存大小
//规划一片内存区域作为软时钟处理函数的静态内存池。
g_swtmrHandlerPool = (UINT8 *)LOS_MemAlloc(m_aucSysMem1, swtmrHandlePoolSize); /* system resident resource *///常驻内存
if (g_swtmrHandlerPool == NULL) {
return LOS_ERRNO_SWTMR_NO_MEMORY;
}
ret = LOS_MemboxInit(g_swtmrHandlerPool, swtmrHandlePoolSize, sizeof(SwtmrHandlerItem));//初始化软时钟注册池
if (ret != LOS_OK) {
return LOS_ERRNO_SWTMR_HANDLER_POOL_NO_MEM;
}
}
//创建一个 OS_SWTMR_HANDLE_QUEUE_SIZE 的队列
//每个CPU都会创建一个属于自己的 OS_SWTMR_HANDLE_QUEUE_SIZE 的队列
ret = LOS_QueueCreate(NULL, OS_SWTMR_HANDLE_QUEUE_SIZE, &g_percpu[cpuid].swtmrHandlerQueue, 0, sizeof(CHAR *));//为当前CPU core 创建软时钟队列 maxMsgSize:sizeof(CHAR *)
if (ret != LOS_OK) {
return LOS_ERRNO_SWTMR_QUEUE_CREATE_FAILED;
}
ret = OsSwtmrTaskCreate();//创建软时钟任务,统一处理队列
ret = OsSwtmrTaskCreate();//每个CPU独自创建属于自己的软时钟任务,统一处理队列
if (ret != LOS_OK) {
return LOS_ERRNO_SWTMR_TASK_CREATE_FAILED;
}
ret = OsSortLinkInit(&g_percpu[cpuid].swtmrSortLink);//排序初始化,为啥要排序因为每个定时器的时间不一样,鸿蒙把用时短的排在前面
ret = OsSortLinkInit(&g_percpu[cpuid].swtmrSortLink);//每个CPU独自对自己软时钟链表排序初始化,为啥要排序因为每个定时器的时间不一样,鸿蒙把用时短的排在前面
if (ret != LOS_OK) {
return LOS_ERRNO_SWTMR_SORTLINK_CREATE_FAILED;
}
......@@ -233,9 +233,9 @@ LITE_OS_SEC_TEXT VOID OsSwtmrStart(SWTMR_CTRL_S *swtmr)
if ((swtmr->ucOverrun == 0) && ((swtmr->ucMode == LOS_SWTMR_MODE_ONCE) ||
(swtmr->ucMode == LOS_SWTMR_MODE_OPP) ||
(swtmr->ucMode == LOS_SWTMR_MODE_NO_SELFDELETE))) {
SET_SORTLIST_VALUE(&(swtmr->stSortList), swtmr->uwExpiry);//设置过期时间
SET_SORTLIST_VALUE(&(swtmr->stSortList), swtmr->uwExpiry);//设置一次性定时器的超时间隔
} else {
SET_SORTLIST_VALUE(&(swtmr->stSortList), swtmr->uwInterval);
SET_SORTLIST_VALUE(&(swtmr->stSortList), swtmr->uwInterval);//设置周期性定时器的超时间隔
}
OsAdd2SortLink(&OsPercpuGet()->swtmrSortLink, &swtmr->stSortList); //通过stSortList节点挂到CPU的软件定时器排序链表上
......@@ -381,7 +381,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsSwtmrTimeGet(const SWTMR_CTRL_S *swtmr)
return OsSortLinkGetTargetExpireTime(sortLinkHeader, &swtmr->stSortList);
}
//接口函数 创建一个定时器
//创建定时器,设置定时器的定时时长、定时器模式、回调函数,并返回定时器ID
LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval,
UINT8 mode,
SWTMR_PROC_FUNC handler,
......@@ -515,7 +515,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrID)
SWTMR_UNLOCK(intSave);
return ret;
}
//接口函数 获取定时器的时间 通过 *tick 带走
//接口函数 获得软件定时器剩余Tick数 通过 *tick 带走
LITE_OS_SEC_TEXT UINT32 LOS_SwtmrTimeGet(UINT16 swtmrID, UINT32 *tick)
{
SWTMR_CTRL_S *swtmr = NULL;
......
/*
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020, 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.
*/
#ifndef _LOS_SWTMR_PRI_H
#define _LOS_SWTMR_PRI_H
#include "los_swtmr.h"
#include "los_spinlock.h"
#ifdef LOSCFG_SECURITY_VID
#include "vid_api.h"
#else
#define MAX_INVALID_TIMER_VID OS_SWTMR_MAX_TIMERID //最大支持的软件定时器
#endif
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
/**
* @ingroup los_swtmr_pri
* Software timer state
*/
enum SwtmrState {
OS_SWTMR_STATUS_UNUSED, /**< The software timer is not used. */
OS_SWTMR_STATUS_CREATED, /**< The software timer is created. */
OS_SWTMR_STATUS_TICKING /**< The software timer is timing. */
};
/**
* @ingroup los_swtmr_pri
* Structure of the callback function that handles software timer timeout
*/
typedef struct {
SWTMR_PROC_FUNC handler; /**< Callback function that handles software timer timeout */
UINTPTR arg; /**< Parameter passed in when the callback function
that handles software timer timeout is called */
} SwtmrHandlerItem;
/**
* @ingroup los_swtmr_pri
* Type of the pointer to the structure of the callback function that handles software timer timeout
*/
typedef SwtmrHandlerItem *SwtmrHandlerItemPtr;
extern SWTMR_CTRL_S *g_swtmrCBArray;
extern SortLinkAttribute g_swtmrSortLink; /* The software timer count list */
#define OS_SWT_FROM_SID(swtmrID) ((SWTMR_CTRL_S *)g_swtmrCBArray + ((swtmrID) % LOSCFG_BASE_CORE_SWTMR_LIMIT))
/**
* @ingroup los_swtmr_pri
* @brief Scan a software timer.
*
* @par Description:
* <ul>
* <li>This API is used to scan a software timer when a Tick interrupt occurs and determine whether
* the software timer expires.</li>
* </ul>
* @attention
* <ul>
* <li>None.</li>
* </ul>
*
* @param None.
*
* @retval None.
* @par Dependency:
* <ul><li>los_swtmr_pri.h: the header file that contains the API declaration.</li></ul>
* @see LOS_SwtmrStop
*/
extern VOID OsSwtmrScan(VOID);
extern UINT32 OsSwtmrInit(VOID);
extern VOID OsSwtmrTask(VOID);
extern VOID OsSwtmrRecycle(UINT32 processID);
extern SPIN_LOCK_S g_swtmrSpin;
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* _LOS_SWTMR_PRI_H */
/*
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020, 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.
*/
#ifndef _LOS_SWTMR_PRI_H
#define _LOS_SWTMR_PRI_H
#include "los_swtmr.h"
#include "los_spinlock.h"
#ifdef LOSCFG_SECURITY_VID
#include "vid_api.h"
#else
#define MAX_INVALID_TIMER_VID OS_SWTMR_MAX_TIMERID //最大支持的软件定时器数量 <65535
#endif
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
/**
* @ingroup los_swtmr_pri
* Software timer state
*/
enum SwtmrState { //定时器状态
OS_SWTMR_STATUS_UNUSED, /**< The software timer is not used. */ //定时器未使用,系统在定时器模块初始化时,会将系统中所有定时器资源初始化成该状态。
OS_SWTMR_STATUS_CREATED, /**< The software timer is created. */ //定时器创建后未启动,或已停止.定时器创建后,不处于计数状态时,定时器将变成该状态。
OS_SWTMR_STATUS_TICKING /**< The software timer is timing. */ //定时器处于计数状态,在定时器创建后调用LOS_SwtmrStart接口启动,定时器将变成该状态,是定时器运行时的状态。
};
/**
* @ingroup los_swtmr_pri
* Structure of the callback function that handles software timer timeout
*/
typedef struct {//处理软件定时器超时的回调函数的结构体
SWTMR_PROC_FUNC handler; /**< Callback function that handles software timer timeout */ //处理软件定时器超时的回调函数
UINTPTR arg; /**< Parameter passed in when the callback function
that handles software timer timeout is called */ //调用处理软件计时器超时的回调函数时传入的参数
} SwtmrHandlerItem;
/**
* @ingroup los_swtmr_pri
* Type of the pointer to the structure of the callback function that handles software timer timeout
*/ //指向处理软件计时器超时的回调函数结构的指针的类型
typedef SwtmrHandlerItem *SwtmrHandlerItemPtr;
extern SWTMR_CTRL_S *g_swtmrCBArray;//软件定时器数组,后续统一注解为定时器池
extern SortLinkAttribute g_swtmrSortLink; /* The software timer count list */ //软件计时器计数链表
//通过参数ID找到对应定时器描述体
#define OS_SWT_FROM_SID(swtmrID) ((SWTMR_CTRL_S *)g_swtmrCBArray + ((swtmrID) % LOSCFG_BASE_CORE_SWTMR_LIMIT))
/**
* @ingroup los_swtmr_pri
* @brief Scan a software timer.
*
* @par Description:
* <ul>
* <li>This API is used to scan a software timer when a Tick interrupt occurs and determine whether
* the software timer expires.</li>
* </ul>
* @attention
* <ul>
* <li>None.</li>
* </ul>
*
* @param None.
*
* @retval None.
* @par Dependency:
* <ul><li>los_swtmr_pri.h: the header file that contains the API declaration.</li></ul>
* @see LOS_SwtmrStop
*/
extern VOID OsSwtmrScan(VOID);
extern UINT32 OsSwtmrInit(VOID);
extern VOID OsSwtmrTask(VOID);
extern VOID OsSwtmrRecycle(UINT32 processID);
extern SPIN_LOCK_S g_swtmrSpin;
#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
#endif /* _LOS_SWTMR_PRI_H */
......@@ -614,7 +614,7 @@ void OsSaveSignalContext(unsigned int *sp)
sigcb->context.R12 = sp[REG_R12];
sp[REG_PC] = sigHandler;//下一个要执行的函数,信号注册函数
sp[REG_R0] = signo; //信号注册函数参数
sp[REG_R1] = (unsigned int)(UINTPTR)(sigcb->sigunbinfo.si_value.sival_ptr); //@note_why 这里看明白,是干啥子用的?
sp[REG_R1] = (unsigned int)(UINTPTR)(sigcb->sigunbinfo.si_value.sival_ptr); //@note_why 这里没看明白是什么意思?
/* sig No bits 00000100 present sig No 3, but 1<< 3 = 00001000, so signo needs minus 1 */
sigcb->sigFlag ^= 1ULL << (signo - 1);
sigcb->context.count++; //代表已保存
......
......@@ -260,7 +260,7 @@ STATIC VOID OsMemNodeSave(LosMemDynNode *node);
(value) = (LOS_DL_LIST *)(((UINTPTR)&(value)) ^ (UINTPTR)(-1))
#define OS_MEM_MAGIC_VALID(value) \
(((UINTPTR)(value) ^ ((UINTPTR)&(value))) == (UINTPTR)(-1))
//变量前缀 uc:UINT8 us:UINT16 uw:UINT32 代表的意思
UINT8 *m_aucSysMem0 = NULL; //@note_why 不明白鸿蒙对虚拟内存分配为什么要用两个全局变量
UINT8 *m_aucSysMem1 = NULL; //auc是什么意思? 变量名最后0和1又代表什么意思? 就不能整个好听的名字吗?@note_thinking
......
......@@ -292,7 +292,7 @@ extern UINT32 __heap_end; // 堆区结束地址
* Maximum supported number of software timers rather than the number of usable software timers
*/
#ifndef LOSCFG_BASE_CORE_SWTMR_LIMIT
#define LOSCFG_BASE_CORE_SWTMR_LIMIT 1024 // 支持的最大软件计时器数量
#define LOSCFG_BASE_CORE_SWTMR_LIMIT 1024 // 最大支持的软件定时器数
#endif
/**
* @ingroup los_config
......
......@@ -335,7 +335,7 @@ extern "C" {
* @ingroup los_queue
* Structure of the block for queue information query
*/ //队列信息对外展示的结构体
typedef struct tagQueueInfo { //@note_why 一直没弄明白用 uw,us作为变量的前缀是啥意思
typedef struct tagQueueInfo { //变量前缀 uc:UINT8 us:UINT16 uw:UINT32 代表的意思
UINT32 uwQueueID; /**< Queue ID */ //队列ID
UINT16 usQueueLen; /**< Queue length *///队列中消息个数
UINT16 usQueueSize; /**< Node size */ //消息节点大小
......
......@@ -54,7 +54,7 @@ extern "C" {
* Value: 0x02000300
*
* Solution: Define the timeout handling function.
*/
*/ //软件定时器回调函数为空
#define LOS_ERRNO_SWTMR_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x00)
/**
......@@ -64,7 +64,7 @@ extern "C" {
* Value: 0x02000301
*
* Solution: Re-define the expiration time.
*/
*/ //软件定时器的定时时长为0
#define LOS_ERRNO_SWTMR_INTERVAL_NOT_SUITED LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x01)
/**
......@@ -74,7 +74,7 @@ extern "C" {
* Value: 0x02000302
*
* Solution: Check the mode value. The value range is [0,3].
*/
*/ //不正确的软件定时器模式
#define LOS_ERRNO_SWTMR_MODE_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x02)
/**
......@@ -84,7 +84,7 @@ extern "C" {
* Value: 0x02000303
*
* Solution: Define the software timer ID before passing it in.
*/
*/ //入参的软件定时器ID指针为NULL
#define LOS_ERRNO_SWTMR_RET_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x03)
/**
......@@ -95,7 +95,7 @@ extern "C" {
*
* Solution: Re-configure the permitted maximum number of software timers, or wait for a software timer to become
* available.
*/
*/ //软件定时器个数超过最大值
#define LOS_ERRNO_SWTMR_MAXSIZE LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x04)
/**
......@@ -105,7 +105,7 @@ extern "C" {
* Value: 0x02000305
*
* Solution: Pass in a valid software timer ID.
*/
*/ //入参的软件定时器ID不正确
#define LOS_ERRNO_SWTMR_ID_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x05)
/**
......@@ -115,7 +115,7 @@ extern "C" {
* Value: 0x02000306
*
* Solution: Create a software timer.
*/
*/ //软件定时器未创建
#define LOS_ERRNO_SWTMR_NOT_CREATED LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x06)
/**
......@@ -125,7 +125,7 @@ extern "C" {
* Value: 0x02000307
*
* Solution: Allocate bigger memory partition to software timer linked list creation.
*/
*/ //初始化软件定时器模块时,内存不足
#define LOS_ERRNO_SWTMR_NO_MEMORY LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x07)
/**
......@@ -135,7 +135,7 @@ extern "C" {
* Value: 0x02000308
*
* Solution: Re-configure the number of software timers.
*/
*/ //配置的软件计时器数无效
#define LOS_ERRNO_SWTMR_MAXSIZE_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x08)
/**
......@@ -145,7 +145,7 @@ extern "C" {
* Value: 0x02000309
*
* Solution: Change the source code and do not use the software timer during an interrupt.
*/
*/ //在中断中使用定时器-修改源代码确保不在中断中使用
#define LOS_ERRNO_SWTMR_HWI_ACTIVE LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x09)
/**
......@@ -155,7 +155,7 @@ extern "C" {
* Value: 0x0200030a
*
* Solution: Expand the memory allocated by membox.
*/
*/ //membox分配的内存不足
#define LOS_ERRNO_SWTMR_HANDLER_POOL_NO_MEM LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x0a)
/**
......@@ -165,7 +165,7 @@ extern "C" {
* Value: 0x0200030b
*
* Solution: Check whether more memory can be allocated to the queue to be created.
*/
*/ //在软件定时器初始化时,创建定时器队列失败 - 调整OS_SYS_MEM_SIZE,以确保有足够的内存供软件定时器创建队列
#define LOS_ERRNO_SWTMR_QUEUE_CREATE_FAILED LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x0b)
/**
......@@ -175,7 +175,7 @@ extern "C" {
* Value: 0x0200030c
*
* Solution: Check whether the memory is sufficient and re-create the task.
*/
*/ //在软件定时器初始化时,创建定时器任务失败 - 调整OS_SYS_MEM_SIZE,以确保有足够的内存供软件定时器创建任务
#define LOS_ERRNO_SWTMR_TASK_CREATE_FAILED LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x0c)
/**
......@@ -185,7 +185,7 @@ extern "C" {
* Value: 0x0200030d
*
* Solution: Start the software timer.
*/
*/ //未启动软件定时器 - 启动软件定时器
#define LOS_ERRNO_SWTMR_NOT_STARTED LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x0d)
/**
......@@ -195,13 +195,13 @@ extern "C" {
* Value: 0x0200030e
*
* Solution: Check the software timer state.
*/
*/ //不正确的软件定时器状态 - 检查确认软件定时器状态
#define LOS_ERRNO_SWTMR_STATUS_INVALID LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x0e)
/**
* @ingroup los_swtmr
* This error code is not in use temporarily.
*/
*/ //暂不使用该错误码
#define LOS_ERRNO_SWTMR_SORTLIST_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x0f)
/**
......@@ -211,7 +211,7 @@ extern "C" {
* Value: 0x02000310
*
* Solution: Define a variable of the number of remaining Ticks before passing in the number of remaining Ticks.
*/
*/ //用以获取软件定时器剩余Tick数的入参指针为NULL
#define LOS_ERRNO_SWTMR_TICK_PTR_NULL LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x10)
/**
......@@ -221,7 +221,7 @@ extern "C" {
* Value: 0x02000311
*
* Solution: Check whether the memory is sufficient and re-create the sortlink.
*/
*/ //在软件定时器初始化时,创建定时器链表失败
#define LOS_ERRNO_SWTMR_SORTLINK_CREATE_FAILED LOS_ERRNO_OS_ERROR(LOS_MOD_SWTMR, 0x11)
/**
......@@ -263,22 +263,22 @@ typedef VOID (*SWTMR_PROC_FUNC)(UINTPTR arg); //函数指针, 赋值给 SWTMR_CT
* @ingroup los_swtmr
* Software timer control structure
*/
typedef struct tagSwTmrCtrl {// @note_why 鸿蒙内核经常出现 uc uw us 这样的变量前缀命名,到底是什么意思?
typedef struct tagSwTmrCtrl {//变量前缀 uc:UINT8 us:UINT16 uw:UINT32 代表的意思
SortLinkList stSortList;
UINT8 ucState; /**< Software timer state */ //软件时器的状态
UINT8 ucMode; /**< Software timer mode */ //软件时器的模式
UINT8 ucOverrun; /**< Times that a software timer repeats timing */ //软件时器重复计时的次数
UINT16 usTimerID; /**< Software timer ID */ //软件时器ID,唯一标识,由软件计时器池分配
UINT32 uwCount; /**< Times that a software timer works */ //软件时器工作的时间
UINT32 uwInterval; /**< Timeout interval of a periodic software timer */ //周期性软件时器的超时间隔
UINT32 uwExpiry; /**< Timeout interval of an one-off software timer */ //一次性软件时器的超时间隔
UINT8 ucState; /**< Software timer state */ //软件时器的状态
UINT8 ucMode; /**< Software timer mode */ //软件时器的模式
UINT8 ucOverrun; /**< Times that a software timer repeats timing */ //软件时器重复计时的次数
UINT16 usTimerID; /**< Software timer ID */ //软件时器ID,唯一标识,由软件计时器池分配
UINT32 uwCount; /**< Times that a software timer works */ //软件时器工作的时间
UINT32 uwInterval; /**< Timeout interval of a periodic software timer */ //周期性软件时器的超时间隔
UINT32 uwExpiry; /**< Timeout interval of an one-off software timer */ //一次性软件时器的超时间隔
#if (LOSCFG_KERNEL_SMP == YES)
UINT32 uwCpuid; /**< The cpu where the timer running on */ //多核情况下,定时器运行的cpu
#endif
UINTPTR uwArg; /**< Parameter passed in when the callback function //回调函数的参数
that handles software timer timeout is called */
SWTMR_PROC_FUNC pfnHandler; /**< Callback function that handles software timer timeout */ //处理软件计时器超时的回调函数
UINT32 uwOwnerPid; /** Owner of this software timer */
UINT32 uwOwnerPid; /** Owner of this software timer */ //软件定时器所属进程ID号
} SWTMR_CTRL_S;
/**
......
/*
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020, 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_config.h"
#include "los_task_pri.h"
#include "los_swtmr_pri.h"
#include "los_printf.h"
#include "los_atomic.h"
#include "gic_common.h"
#include "uart.h"
#include "los_process_pri.h"
#include "los_arch_mmu.h"
#if (LOSCFG_KERNEL_SMP == YES)
STATIC Atomic g_ncpu = 1;
#endif
LITE_OS_SEC_TEXT_INIT VOID OsSystemInfo(VOID)
{
#ifdef LOSCFG_DEBUG_VERSION
const CHAR *buildType = "debug";
#else
const CHAR *buildType = "release";
#endif /* LOSCFG_DEBUG_VERSION */
PRINT_RELEASE("\n******************Welcome******************\n\n"
"Processor : %s"
#if (LOSCFG_KERNEL_SMP == YES)
" * %d\n"
"Run Mode : SMP\n"
#else
"\n"
"Run Mode : UP\n"
#endif
"GIC Rev : %s\n"
"build time : %s %s\n"
"Kernel : %s %d.%d.%d.%d/%s\n"
"\n*******************************************\n",
LOS_CpuInfo(),
#if (LOSCFG_KERNEL_SMP == YES)
LOSCFG_KERNEL_SMP_CORE_NUM,
#endif
HalIrqVersion(), __DATE__, __TIME__,\
KERNEL_NAME, KERNEL_MAJOR, KERNEL_MINOR, KERNEL_PATCH, KERNEL_ITRE, buildType);
}
LITE_OS_SEC_TEXT_INIT VOID secondary_cpu_start(VOID)
{
#if (LOSCFG_KERNEL_SMP == YES)
UINT32 cpuid = ArchCurrCpuid();
OsArchMmuInitPerCPU();
OsCurrTaskSet(OsGetMainTask());
/* increase cpu counter */
LOS_AtomicInc(&g_ncpu);
/* store each core's hwid */
CPU_MAP_SET(cpuid, OsHwIDGet());
HalIrqInitPercpu();
OsCurrProcessSet(OS_PCB_FROM_PID(OsGetKernelInitProcessID()));
OsSwtmrInit();
OsIdleTaskCreate();
OsStart();
while (1) {
__asm volatile("wfi");
}
#endif
}
#if (LOSCFG_KERNEL_SMP == YES)
#ifdef LOSCFG_TEE_ENABLE
#define TSP_CPU_ON 0xb2000011UL
STATIC INT32 raw_smc_send(UINT32 cmd)
{
register UINT32 smc_id asm("r0") = cmd;
do {
asm volatile (
"mov r0, %[a0]\n"
"smc #0\n"
: [a0] "+r"(smc_id)
);
} while (0);
return (INT32)smc_id;
}
STATIC VOID trigger_secondary_cpu(VOID)
{
(VOID)raw_smc_send(TSP_CPU_ON);
}
LITE_OS_SEC_TEXT_INIT VOID release_secondary_cores(VOID)
{
trigger_secondary_cpu();
/* wait until all APs are ready */
while (LOS_AtomicRead(&g_ncpu) < LOSCFG_KERNEL_CORE_NUM) {
asm volatile("wfe");
}
}
#else
#define CLEAR_RESET_REG_STATUS(regval) (regval) &= ~(1U << 2)
LITE_OS_SEC_TEXT_INIT VOID release_secondary_cores(VOID)
{
UINT32 regval;
/* clear the slave cpu reset */
READ_UINT32(regval, PERI_CRG30_BASE);
CLEAR_RESET_REG_STATUS(regval);
WRITE_UINT32(regval, PERI_CRG30_BASE);
/* wait until all APs are ready */
while (LOS_AtomicRead(&g_ncpu) < LOSCFG_KERNEL_CORE_NUM) {
asm volatile("wfe");
}
}
#endif /* LOSCFG_TEE_ENABLE */
#endif /* LOSCFG_KERNEL_SMP */
LITE_OS_SEC_TEXT_INIT INT32 main(VOID)
{
UINT32 uwRet = LOS_OK;
OsSetMainTask();// 设置CPU内核数的主任务
OsCurrTaskSet(OsGetMainTask());
/* set smp system counter freq */
#if (LOSCFG_KERNEL_SMP == YES)
#ifndef LOSCFG_TEE_ENABLE
HalClockFreqWrite(OS_SYS_CLOCK);
#endif
#endif
/* system and chip info */
OsSystemInfo();
PRINT_RELEASE("\nmain core booting up...\n");
uwRet = OsMain();// 内核各模块初始化
if (uwRet != LOS_OK) {
return LOS_NOK;
}
#if (LOSCFG_KERNEL_SMP == YES)//多核支持
PRINT_RELEASE("releasing %u secondary cores\n", LOSCFG_KERNEL_SMP_CORE_NUM - 1);
release_secondary_cores();//让CPU其他核也开始工作,真正的并行开始了.
#endif
CPU_MAP_SET(0, OsHwIDGet());
OsStart();//内核初始化完成,正式开始工作
while (1) {
__asm volatile("wfi");//让cpu进入idle状态
}
}
/*
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020, 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_config.h"
#include "los_task_pri.h"
#include "los_swtmr_pri.h"
#include "los_printf.h"
#include "los_atomic.h"
#include "gic_common.h"
#include "uart.h"
#include "los_process_pri.h"
#include "los_arch_mmu.h"
#if (LOSCFG_KERNEL_SMP == YES)
STATIC Atomic g_ncpu = 1; //统计CPU的数量
#endif
LITE_OS_SEC_TEXT_INIT VOID OsSystemInfo(VOID)
{
#ifdef LOSCFG_DEBUG_VERSION
const CHAR *buildType = "debug";
#else
const CHAR *buildType = "release";
#endif /* LOSCFG_DEBUG_VERSION */
PRINT_RELEASE("\n******************Welcome******************\n\n"
"Processor : %s"
#if (LOSCFG_KERNEL_SMP == YES)
" * %d\n"
"Run Mode : SMP\n"
#else
"\n"
"Run Mode : UP\n"
#endif
"GIC Rev : %s\n"
"build time : %s %s\n"
"Kernel : %s %d.%d.%d.%d/%s\n"
"\n*******************************************\n",
LOS_CpuInfo(),
#if (LOSCFG_KERNEL_SMP == YES)
LOSCFG_KERNEL_SMP_CORE_NUM,
#endif
HalIrqVersion(), __DATE__, __TIME__,\
KERNEL_NAME, KERNEL_MAJOR, KERNEL_MINOR, KERNEL_PATCH, KERNEL_ITRE, buildType);
}
//次级CPU初始化,本函数执行的次数由次级CPU的个数决定. 例如:在四核情况下,会被执行3次, 0号通常被定义为主CPU 执行main
LITE_OS_SEC_TEXT_INIT VOID secondary_cpu_start(VOID)
{
#if (LOSCFG_KERNEL_SMP == YES)
UINT32 cpuid = ArchCurrCpuid();
OsArchMmuInitPerCPU();//每个CPU都需要初始化MMU
OsCurrTaskSet(OsGetMainTask());//设置CPU的当前任务
/* increase cpu counter */
LOS_AtomicInc(&g_ncpu); //统计CPU的数量
/* store each core's hwid */
CPU_MAP_SET(cpuid, OsHwIDGet());//存储每个CPU的 hwid
HalIrqInitPercpu(); //CPU硬件中断初始化
OsCurrProcessSet(OS_PCB_FROM_PID(OsGetKernelInitProcessID())); //设置内核进程为CPU进程
OsSwtmrInit(); //定时任务初始化,每个CPU维护自己的定时器队列
OsIdleTaskCreate(); //创建空闲任务,每个CPU维护自己的任务队列
OsStart(); //本CPU正式启动在内核层的工作
while (1) {
__asm volatile("wfi");//wait for Interrupt 等待中断,即下一次中断发生前都在此hold住不干活
}//类似的还有 WFE: wait for Events 等待事件,即下一次事件发生前都在此hold住不干活
#endif
}
#if (LOSCFG_KERNEL_SMP == YES)
#ifdef LOSCFG_TEE_ENABLE //需使能,可信环境(Trusted Execute Environment)
#define TSP_CPU_ON 0xb2000011UL
STATIC INT32 raw_smc_send(UINT32 cmd)
{
register UINT32 smc_id asm("r0") = cmd;
do {
asm volatile (
"mov r0, %[a0]\n"
"smc #0\n"
: [a0] "+r"(smc_id)
);
} while (0);
return (INT32)smc_id;
}
//触发次级CPU工作
STATIC VOID trigger_secondary_cpu(VOID)
{
(VOID)raw_smc_send(TSP_CPU_ON);
}
//调动次级CPU干活
LITE_OS_SEC_TEXT_INIT VOID release_secondary_cores(VOID)
{
trigger_secondary_cpu();//触发次级CPU工作
/* wait until all APs are ready */
while (LOS_AtomicRead(&g_ncpu) < LOSCFG_KERNEL_CORE_NUM) {
asm volatile("wfe");//WFE: wait for Events 等待事件,即下一次事件发生前都在此hold住不干活
}
}
#else
#define CLEAR_RESET_REG_STATUS(regval) (regval) &= ~(1U << 2)
LITE_OS_SEC_TEXT_INIT VOID release_secondary_cores(VOID)//调动次级CPU干活
{
UINT32 regval;
/* clear the slave cpu reset */
READ_UINT32(regval, PERI_CRG30_BASE);
CLEAR_RESET_REG_STATUS(regval); //清除,并重置 从cpu寄存器状态
WRITE_UINT32(regval, PERI_CRG30_BASE);
/* wait until all APs are ready */
while (LOS_AtomicRead(&g_ncpu) < LOSCFG_KERNEL_CORE_NUM) {
asm volatile("wfe");//WFE: wait for Events 等待事件,即下一次事件发生前都在此hold住不干活
}
}
#endif /* LOSCFG_TEE_ENABLE */
#endif /* LOSCFG_KERNEL_SMP */
//内核入口函数,由汇编调用
LITE_OS_SEC_TEXT_INIT INT32 main(VOID)//由主CPU执行,默认 0号 为主CPU
{
UINT32 uwRet = LOS_OK;
OsSetMainTask();// 设置各CPU主任务
OsCurrTaskSet(OsGetMainTask());//设置当前CPU主任务
/* set smp system counter freq */
#if (LOSCFG_KERNEL_SMP == YES)
#ifndef LOSCFG_TEE_ENABLE
HalClockFreqWrite(OS_SYS_CLOCK); //多CPU情况下设置时钟频率
#endif
#endif
/* system and chip info */
OsSystemInfo();//输出系统和芯片的信息
PRINT_RELEASE("\nmain core booting up...\n"); //主内核启动中...
uwRet = OsMain();// 内核各模块初始化
if (uwRet != LOS_OK) {
return LOS_NOK;
}
#if (LOSCFG_KERNEL_SMP == YES)//多核支持
PRINT_RELEASE("releasing %u secondary cores\n", LOSCFG_KERNEL_SMP_CORE_NUM - 1);
release_secondary_cores();//让CPU其他核也开始工作,真正的并行开始了.
#endif
CPU_MAP_SET(0, OsHwIDGet());//设置CPU映射,参数0 代表0号CPU
OsStart();//内核初始化完成,正式开始工作
while (1) {
__asm volatile("wfi");//WFI: wait for Interrupt 等待中断,即下一次中断发生前都在此hold住不干活
}
}
git add -A
git commit -m '完善内存模块的注解
git commit -m '1.主从CPU是如何初始化的 2.搞明白了变量前缀 uc:UINT8 us:UINT16 uw:UINT32 代表的意思
搜索 @note_pic 方便理解画的字符图
搜索 @note_why 尚未看明白的地方,如果您看明白了,请告知完善
搜索 @note_thinking 一点思考和吐槽的地方
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册