/* ----------------------------------------------------------------------------
 * Copyright (c) Huawei Technologies Co., Ltd. 2020-2020. All rights reserved.
 * Description: Low-power Framework.
 * Author: Huawei LiteOS Team
 * Create: 2020-09-19
 * 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_lowpower_impl_pri.h"
#include "los_hwi.h"
#include "los_sortlink_pri.h"
#include "los_swtmr_pri.h"
#include "los_task_pri.h"
#include "los_tickless_pri.h"
#include "los_atomic.h"
#include "los_mp_pri.h"

#ifdef LOSCFG_KERNEL_RUNSTOP
#include "los_runstop_pri.h"
#endif

#ifdef LOSCFG_KERNEL_CPUP
#include "los_cpup_pri.h"
#endif

#if defined(LOSCFG_KERNEL_RUNSTOP) || defined(LOSCFG_KERNEL_DEEPSLEEP)
/* 如果系统是从内存映像中启动的，则该标志应为1；否则为0。*/
#ifdef LOSCFG_AARCH64
__attribute__((section(".data"))) INT64 g_resumeFromImg = LOS_COLD_RESET;
__attribute__((section(".data"))) STATIC INT64 g_otherCoreResume = 0;
#else
__attribute__((section(".data"))) INT32 g_resumeFromImg = LOS_COLD_RESET;
__attribute__((section(".data"))) INT32 g_otherCoreResume = 0;
#endif

#ifdef LOSCFG_AARCH64
/*
 * 16: 对齐内存的数量,
 * 34: 任务上下文寄存器的数量，指寄存器的集合(X0~X30, SP, DAIF, NZCV)
 */
LITE_OS_SEC_DATA_MINOR __attribute__((aligned(16))) UINT64 g_saveSRContext[34];
/* 3: The number of available universal registers(X0, X1, X2) temporarily saved */
LITE_OS_SEC_DATA_MINOR UINT64 g_saveAR[3];
#else
/* 18: The number of task context registers(R0~R15, SPSR, CPSR) */
LITE_OS_SEC_DATA_MINOR UINT32 g_saveSRContext[LOSCFG_KERNEL_CORE_NUM][18];
/* 2: The number of available universal registers(R0, R1) temporarily saved */
LITE_OS_SEC_DATA_MINOR UINT32 g_saveAR[2];
LITE_OS_SEC_DATA_MINOR LosTaskCB *g_saveTsk[LOSCFG_KERNEL_CORE_NUM];
#endif
#endif

#ifndef OFFSET_OF_FIELD
#define OFFSET_OF_FIELD(type, field) ((UINTPTR) & ((type *)0)->field)
#endif

#define RUNOPS_CALL_FUNC_VOID(func, ...) CALL_FUNC_NO_RETURN(g_pmRunOps, func, __VA_ARGS__)
#define CALL_RUN_OPS_FUNC_NO_RETURN(func) CallVoidFunction(&g_pmRunOps, OFFSET_OF_FIELD(PowerMgrRunOps, func));
#ifdef LOSCFG_KERNEL_DEEPSLEEP
#define DEEPOPS_CALL_FUNC_VOID(func, ...) CALL_FUNC_NO_RETURN(g_deepSleepOps, func, __VA_ARGS__)
#else
#define DEEPOPS_CALL_FUNC_VOID(func, ...)
#endif

#ifdef LOSCFG_LOWPOWER_TRACE_DEBUG
#define TRACE_FUNC_CALL() PRINTK("trace: %s, %s, %d\n", __FILE__, __FUNCTION__, __LINE__)
#else
#define TRACE_FUNC_CALL()
#endif

#define MAX_SLEEP_TIME      10000
#define MIN_DEEP_SLEEP_TIME 1000
#define MIN_SLEEP_TIME      100

typedef struct {
    PowerMgrDeepSleepOps *deepSleepOps;
    LowpowerExternalVoterHandle exVoterHandle;
    Atomic sleepVoteCount;
    UINT32 minSleepTicks;
    UINT32 maxSleepCount;
    UINT32 minDeepSleepTicks;
    UINT32 sleepTime[LOSCFG_KERNEL_CORE_NUM];
    Atomic deepSleepCores;
    Atomic resumeSleepCores;
    Atomic freq;
    Atomic freqPending;
    Atomic deepSleepDelay;
    Atomic freeLock;
    SPIN_LOCK_S lock;
    UINT8 sleepMode[LOSCFG_KERNEL_CORE_NUM];
} PowerMgr;

enum { LOCK_OFF = 0, LOCK_ON };

__attribute__((section(".data"))) STATIC PowerMgr g_pmMgr = {
    .deepSleepOps = NULL,
    .exVoterHandle = NULL,
    .sleepVoteCount = 0,
    .maxSleepCount = MAX_SLEEP_TIME,
    .minSleepTicks = MIN_SLEEP_TIME,
    .minDeepSleepTicks = MIN_DEEP_SLEEP_TIME,
    .sleepTime = {0},
    .deepSleepCores = 0,
    .resumeSleepCores = 0,
    .freq = 1,
    .freqPending = 0,
    .deepSleepDelay = 0,
    .freeLock = 0,
    .sleepMode = {0},
};

STATIC VOID OsChangeFreq(VOID);

STATIC VOID OsLightSleepDefault(VOID);

STATIC VOID OsSetWakeUpTimerDefault(UINT32 sleepTick);

STATIC UINT32 OsWithrawWakeUpTimerDefault(VOID);

STATIC UINT32 OsGetSleepTimeDefault(VOID);

STATIC UINT32 OsSelectSleepModeDefault(UINT32 sleepTicks);

STATIC VOID OsChangeFreqDefault(UINT8 freq);

STATIC VOID OsEnterDeepSleepDefault(VOID);

STATIC UINT32 OsPreConfigDefault(VOID);

STATIC VOID OsPostConfigDefault(VOID);

STATIC PowerMgrRunOps g_pmRunOps = {
    .changeFreq = OsChangeFreqDefault,
    .enterLightSleep = OsLightSleepDefault,
    .enterDeepSleep = OsEnterDeepSleepDefault,
    .setWakeUpTimer = OsSetWakeUpTimerDefault,
    .withdrawWakeUpTimer = OsWithrawWakeUpTimerDefault,
    .getSleepTime = OsGetSleepTimeDefault,
    .selectSleepMode = OsSelectSleepModeDefault,
    .preConfig = OsPreConfigDefault,
    .postConfig = OsPostConfigDefault,
};

STATIC VOID OsLightSleepDefault(VOID)/*轻量级睡眠函数，执行wfi指令，让处理器进入睡眠状态*/
{
    TRACE_FUNC_CALL();
    wfi();
}

STATIC VOID OsSetWakeUpTimerDefault(UINT32 sleepTick)/*设置唤醒定时器，默认实现为空函数*/
{
    TRACE_FUNC_CALL();
}

STATIC UINT32 OsWithrawWakeUpTimerDefault(VOID)/*撤销唤醒定时器，默认实现返回0*/
{
    TRACE_FUNC_CALL();
    return 0;
}

STATIC UINT32 OsGetSleepTimeDefault(VOID)/*获取当前任务休眠时间*/
{
#ifdef LOSCFG_KERNEL_TICKLESS
    return OsSleepTicksGet();
#else
    return 0;
#endif
}

STATIC UINT32 OsSelectSleepModeDefault(UINT32 sleepTicks)/*选择合适的休眠模式*/
{
    if (sleepTicks < g_pmMgr.minSleepTicks) {
        return LOS_INTERMIT_NONE;
    }
    /*默认实现根据休眠时间和当前系统状态选择轻量级睡眠或者深度睡眠模式*/
    if (g_pmMgr.deepSleepOps != NULL && sleepTicks >= g_pmMgr.minDeepSleepTicks &&
        g_pmRunOps.getDeepSleepVoteCount() == 0) {
        return LOS_INTERMIT_DEEP_SLEEP;
    }

    return LOS_INTERMIT_LIGHT_SLEEP;
}

STATIC VOID OsChangeFreqDefault(UINT8 freq)/*改变处理器频率*/
{
    (VOID)freq;
    TRACE_FUNC_CALL();
}

STATIC VOID OsEnterDeepSleepDefault(VOID)// 进入深度睡眠模式函数
{
    TRACE_FUNC_CALL();
    wfi();
}

STATIC UINT32 OsPreConfigDefault(VOID)//电源管理模块预配置函数
{
    TRACE_FUNC_CALL();
    return 1;
}

STATIC VOID OsPostConfigDefault(VOID)//电源管理模块后配置函数
{
}

#ifdef LOSCFG_KERNEL_DEEPSLEEP

STATIC BOOL OsCouldDeepSleepDefault(VOID)// 判断是否可以进入深度睡眠模式
{
    TRACE_FUNC_CALL();
    return true;
}

STATIC BOOL OsSuspendPreConfigDefault(VOID)// 休眠前的预配置函数
{
    TRACE_FUNC_CALL();
    return true;
}

STATIC VOID OsSuspendDeviceDefault(VOID)//休眠时设备挂起函数
{
    TRACE_FUNC_CALL();
}

STATIC VOID OsRollBackDefault(VOID)//唤醒后的回滚函数
{
    TRACE_FUNC_CALL();
}

STATIC VOID OsResumeDeviceDefault(VOID)//唤醒后的设备恢复函数
{
    TRACE_FUNC_CALL();
}

STATIC VOID OsResumePostConfigDefault(VOID)//唤醒后电源管理模块后配置函数
{
    TRACE_FUNC_CALL();
}

STATIC VOID OsSystemWakeupDefault(VOID)//系统唤醒函数
{
    TRACE_FUNC_CALL();
}

STATIC VOID OsResumeCallBackDefault(VOID)//唤醒后回调函数
{
    TRACE_FUNC_CALL();
}

STATIC VOID OsOtherCoreResumeDefault(VOID)//其他核心唤醒函数
{
    TRACE_FUNC_CALL();
}

STATIC VOID OsDeepSleepResume(VOID);

STATIC PowerMgrDeepSleepOps g_deepSleepOps = {
    .couldDeepSleep = OsCouldDeepSleepDefault, //判断是否可以进入深度睡眠模式的函数指针
    .systemWakeup = OsSystemWakeupDefault,//唤醒函数的函数指针
    .suspendPreConfig = OsSuspendPreConfigDefault,//修面前的预配置函数的函数指针
    .suspendDevice = OsSuspendDeviceDefault,//设备挂起函数的函数指针
    .rollback = OsRollBackDefault,//唤醒后的回滚函数的函数指针
    .resumeDevice = OsResumeDeviceDefault,//设备回复函数的函数指针
    .resumePostConfig = OsResumePostConfigDefault,//唤醒后电源管理模块后配置函数的函数指针
    .resumeCallBack = OsResumeCallBackDefault,//唤醒后回调函数的函数指针
    .otherCoreResume = OsOtherCoreResumeDefault//其他核心唤醒函数的函数指针
};

STATIC INLINE VOID OsTickResume(UINT32 sleepTicks)//用于更新系统始终，根据休眠时间调整系统时钟
{
    UINT32 cpuid = ArchCurrCpuid();
    if (sleepTicks > g_pmMgr.sleepTime[cpuid]) {
        sleepTicks -= g_pmMgr.sleepTime[cpuid];
    } else {
        sleepTicks = 0;
    }
    OsSysTimeUpdate(sleepTicks);
}

STATIC VOID OsDeepSleepResume(VOID)//深度睡眠唤醒后的处理函数
{
    DEEPOPS_CALL_FUNC_VOID(resumeFromReset);
    LOS_AtomicSet(&g_pmMgr.resumeSleepCores, OS_MP_CPU_ALL);

#ifdef LOSCFG_KERNEL_CPUP
    OsSetCpuCycle(0);
#endif
//恢复设置，恢复其他核心进程
#if (LOSCFG_KERNEL_SMP == YES)
    release_secondary_cores();
#endif
    OsSRRestoreRegister();
}

STATIC INLINE VOID OsEnterDeepSleepMainCore(VOID)//用于主核心进入深度睡眠
{
    //挂起预配置
    LOS_AtomicAdd(&g_pmMgr.deepSleepCores, 1);
    g_deepSleepOps.suspendPreConfig();
    //是否可以进入神对睡眠判断
    if (g_pmMgr.deepSleepCores == LOSCFG_KERNEL_CORE_NUM && g_deepSleepOps.couldDeepSleep()) {
        g_deepSleepOps.suspendDevice();
        g_pmRunOps.setWakeUpTimer(g_pmMgr.sleepTime[0]);
        g_resumeFromImg = LOS_COLD_RESET;
        OsSRSaveRegister();
    //进入深度睡眠，进行回滚操作，保存上下文
        if (g_resumeFromImg == LOS_COLD_RESET) {
            g_resumeFromImg = LOS_DEEP_SLEEP_RESET;
            CALL_RUN_OPS_FUNC_NO_RETURN(contextSave);
            g_pmRunOps.enterDeepSleep();
            g_deepSleepOps.rollback();
        }
        //设置唤醒定时器
        g_deepSleepOps.resumeDevice();
        UINT32 sleepTicks = g_pmRunOps.withdrawWakeUpTimer();
        OsSysTimeUpdate(sleepTicks);
    } else {
#ifdef LOSCFG_KERNEL_TICKLESS
        OsTicklessOpen();
#endif
        g_pmRunOps.enterLightSleep();
    }
    g_deepSleepOps.resumePostConfig();
    LOS_AtomicSub(&g_pmMgr.deepSleepCores, 1);
}

STATIC INLINE VOID OsEnterSleepMode(VOID)//进入睡眠模式，包括主核心和其他核心的不同处理
{
#ifdef LOSCFG_KERNEL_SMP
    UINT32 currCpuid = ArchCurrCpuid();
    if (currCpuid == 0) { //如果是0则进入主核心深度睡眠
#endif
        OsEnterDeepSleepMainCore();
#ifdef LOSCFG_KERNEL_SMP //如果当前核心不是主核心，则直接返回，因为其他核心的睡眠处理逻辑不在此函数中处理
        return;
    }

    UINT32 cpuMask = 1 << currCpuid;
    LOS_AtomicAdd(&g_pmMgr.deepSleepCores, 1);
    OsSRSaveRegister();//保存相关寄存器状态并判断是否需要唤醒当前核心。
    if (g_pmMgr.resumeSleepCores & cpuMask) {
        INT32 val;
        do { //，将 g_pmMgr.resumeSleepCores 的值中当前核心的位清零，表示该核心已被唤醒。
            val = LOS_AtomicRead(&g_pmMgr.resumeSleepCores);
        } while (LOS_AtomicCmpXchg32bits(&g_pmMgr.resumeSleepCores, val & (~cpuMask), val));
        g_deepSleepOps.otherCoreResume();
        UINT32 sleepTicks = g_pmRunOps.withdrawWakeUpTimer();
        OsTickResume(sleepTicks);
        //执行其他核心的恢复操作，并从唤醒定时器中获取休眠时间，然后调用 OsTickResume 函数更新系统时钟。
    } else {
        if (g_pmMgr.deepSleepCores == LOSCFG_KERNEL_CORE_NUM) {//如果不需要唤醒，则判断是否所有核心都进入了深度睡眠
            LOS_MpSchedule(1 << 0);//调用函数选择一个核心唤醒系统
        }
#ifdef LOSCFG_KERNEL_TICKLESS
        OsTicklessOpen();//开启节能模式
#endif
        g_pmRunOps.enterLightSleep();
    }
    LOS_AtomicSub(&g_pmMgr.deepSleepCores, 1);//将 g_pmMgr.deepSleepCores 的值减1，表示当前核心已经处理完睡眠状态
#endif // LOSCFG_KERNEL_SMP
}

STATIC INLINE VOID OsSystemSuspend(LosIntermitMode *mode)//选择合适的低功耗模式（深度，轻度
{
    // If enterShutdownMode is not defined, will fall through to standby mode
    // If enterStandbyMode is not defined, will fall through to stop mode
    // If enterStopMode is not defined, will fall through to sleep mode
    switch (*mode) {
        case LOS_INTERMIT_SHUTDOWN:
            /* fall through */
        case LOS_INTERMIT_STANDBY:
            /* fall through */
        case LOS_INTERMIT_DEEP_SLEEP:
#ifdef LOSCFG_KERNEL_DEEPSLEEP
            if (g_pmRunOps.enterDeepSleep != NULL) {
                OsEnterSleepMode();
                break;
            }
#endif
            /* fall through */
        default:
            *mode = LOS_INTERMIT_LIGHT_SLEEP;
            break;
    }
}
#endif

STATIC VOID OsLowpowerLightSleep(UINT32 mode, UINT32 cpuid, UINT32 sleepTicks)//轻度睡眠中的模式调整
{
    if (g_pmRunOps.preConfig != NULL) {
        sleepTicks = g_pmRunOps.getSleepTime();//获取休眠时间
    }
    if (sleepTicks > 1) {
        g_pmMgr.sleepMode[cpuid] = (mode & 0x0FF);
        g_pmMgr.sleepTime[cpuid] = (sleepTicks & 0x0FF);
#ifdef LOSCFG_KERNEL_TICKLESS
        OsTicklessOpen();
#endif
        if (mode == LOS_INTERMIT_LIGHT_SLEEP && g_pmRunOps.enterLightSleep != NULL) {
            g_pmRunOps.enterLightSleep();//进入轻度睡眠
        } else {
            wfi();
        }
    } else {
        g_pmMgr.sleepMode[cpuid] = LOS_INTERMIT_NONE;//等待中断事件
        g_pmMgr.sleepTime[cpuid] = 0;
        wfi();
    }
}

STATIC VOID OsLowpowerDeepSleep(LosIntermitMode *mode, UINT32 cpuid, UINT32 sleepTicks)
//深度睡眠设置
{
#ifdef LOSCFG_KERNEL_DEEPSLEEP
    if (g_pmRunOps.enterDeepSleep == NULL) {
        *mode = LOS_INTERMIT_LIGHT_SLEEP;
    } else {
        *mode = LOS_INTERMIT_DEEP_SLEEP;
        g_pmMgr.sleepMode[cpuid] = *mode;
        g_pmMgr.sleepTime[cpuid] = sleepTicks;

        OsSystemSuspend(mode);
    }
#else
    *mode = LOS_INTERMIT_LIGHT_SLEEP;//若不支持深度睡眠则强制进入轻度睡眠
#endif
}

STATIC VOID OsLowpowerProcess(VOID)//处理系统进入低功耗模式的过程
{
#ifdef LOSCFG_KERNEL_RUNSTOP//检查系统是否需要在进入低功耗模式前保存系统消息
    if (OsWowSysDoneFlagGet() == OS_STORE_SYSTEM) {
        OsStoreSystemInfoBeforeSuspend();
    }
#endif
    /* Change frequency is pended, need to change the freq here. */
    if ((g_pmRunOps.changeFreq != NULL)) {//如果需要改变频率则调整切换
        OsChangeFreq();
    }
    //禁止中断，锁住任务调度，并获取当前CPUID和休眠时间
    UINT32 intSave = LOS_IntLock();
    LOS_TaskLock();
    RUNOPS_CALL_FUNC_VOID(preConfig);
    UINT32 cpuid = ArchCurrCpuid();
    UINT32 sleepTicks = g_pmRunOps.getSleepTime();
    /*如果休眠时间小于等于最小休眠时间（g_pmMgr.minSleepTicks）
    或者有任务请求不进入深度睡眠（LOS_PowerMgrGetDeepSleepVoteCount 返回值不为0），
    则将当前 CPU 设置为不进入任何中断模式，清零休眠时间，
    并调用 postConfig 函数。*/
    if (sleepTicks <= g_pmMgr.minSleepTicks || LOS_PowerMgrGetDeepSleepVoteCount() != 0) {
        g_pmMgr.sleepMode[cpuid] = LOS_INTERMIT_NONE;
        g_pmMgr.sleepTime[cpuid] = 0;

        RUNOPS_CALL_FUNC_VOID(postConfig);

#ifdef LOSCFG_KERNEL_TICKLESS
        OsTicklessOpen();
#endif

        wfi();

        PRINT_WARN("\r\n [PM] Application is runing in work mode, powermgr do not process.\n");
    } else {
        if (sleepTicks > g_pmMgr.maxSleepCount) {
            sleepTicks = g_pmMgr.maxSleepCount;
        }
        UINT32 mode = g_pmRunOps.selectSleepMode(sleepTicks);
        if (mode >= LOS_INTERMIT_DEEP_SLEEP) {//如果支持深度睡眠
            g_pmMgr.sleepTime[cpuid] = g_pmRunOps.withdrawWakeUpTimer();
            OsLowpowerDeepSleep(&mode, cpuid, sleepTicks);
        }

        RUNOPS_CALL_FUNC_VOID(postConfig);

        if (mode < LOS_INTERMIT_DEEP_SLEEP) {//进入轻度睡眠
            OsLowpowerLightSleep(mode, cpuid, sleepTicks);
        }
    }

    LOS_TaskUnlock();
    LOS_IntRestore(intSave);//解锁任务调度并恢复中断
}

STATIC VOID OsLowpowerWakeupFromReset(VOID)//处理系统从重置状态唤醒的情况
{
#ifdef LOSCFG_KERNEL_RUNSTOP
    if (g_resumeFromImg == LOS_RUN_STOP_RESET) {
        OsSystemWakeup();
        return;
    }
#endif
#ifdef LOSCFG_KERNEL_DEEPSLEEP
    if (g_resumeFromImg == LOS_DEEP_SLEEP_RESET) {
        OsDeepSleepResume();
    }
#endif
}

STATIC VOID OsLowpowerWakeupFromInterrupt(UINT32 intNum)//用于处理系统从重置状态唤醒的情况
{
#ifdef LOSCFG_KERNEL_TICKLESS
    OsTicklessUpdate(intNum);
#else
    (VOID)intNum;
#endif
}

STATIC VOID OsChangeFreq(VOID)//处理改变系统频率的操作
{
    UINT32 freq;
    BOOL ret;

    do {//尝试获取频率切换的自旋锁（通过原子操作实现）
    //如果成功获取锁，则说明没有其他线程正在频率切换过程中，可以继续执行
        ret = LOS_AtomicCmpXchg32bits(&g_pmMgr.freeLock, LOCK_ON, LOCK_OFF);
        if (ret) {
            return;
        }
        freq = (UINT32)g_pmMgr.freqPending;//获取频率切换的目标频率，并进行频率切换
        if (freq != (UINT32)g_pmMgr.freq) {
            g_pmRunOps.changeFreq(freq);//更新频率
            LOS_AtomicSet(&g_pmMgr.freq, (INT32)freq);
        }
        LOS_AtomicSet(&g_pmMgr.freeLock, LOCK_OFF);//释放自旋锁
    } while (FreqHigher(g_pmMgr.freqPending, freq));
}

STATIC VOID OsLowpowerChangeFreq(LosFreqMode freq)//改变系统频率
{
    TRACE_FUNC_CALL();
    if (g_pmRunOps.changeFreq == NULL) {
        PRINT_DEBUG("\r\n [PM] freq function is null.\n");
        return;
    }

    if (freq >= LOS_SYS_FREQ_MAX) {
        PRINT_DEBUG("\r\n [PM] freq(%d) is invalid.\n", freq);
        return;
    }

    // The OsChangeFreq procedure deals with the latest setting only.
    LOS_AtomicSet(&g_pmMgr.freqPending, (INT32)freq);

    // We get a high frequency request, then change it
    if (FreqHigher(g_pmMgr.freqPending, g_pmMgr.freq) && g_pmRunOps.changeFreq != NULL) {
        OsChangeFreq();//如果目标频率高于当前频率，并且 g_pmRunOps.changeFreq 不为空，则调用 OsChangeFreq 函数进行频率切换。
    }
}

STATIC VOID OsLowpowerDeepSleepVoteBegin(VOID)//开始深度睡眠投票
{
    TRACE_FUNC_CALL();
    LOS_AtomicInc(&g_pmMgr.sleepVoteCount);//用原子操作将 g_pmMgr.sleepVoteCount 加一，并断言 g_pmMgr.sleepVoteCount 大于零。
    LOS_ASSERT(g_pmMgr.sleepVoteCount > 0);
}

STATIC VOID OsLowpowerDeepSleepVoteEnd(VOID)//结束深度睡眠投票
{
    TRACE_FUNC_CALL();
    LOS_AtomicDec(&g_pmMgr.sleepVoteCount);//原子操作将 g_pmMgr.sleepVoteCount 减一，并断言 g_pmMgr.sleepVoteCount 大于等于零。
    LOS_ASSERT(g_pmMgr.sleepVoteCount >= 0);
}

STATIC VOID OsLowpowerDeepSleepVoteDelay(UINT32 delayTicks)//延迟深度睡眠投票
{
    TRACE_FUNC_CALL();
}

STATIC VOID OsLowpowerRegisterExternalVoter(LowpowerExternalVoterHandle callback)//注册外部投票者
{
    TRACE_FUNC_CALL();
    g_pmMgr.exVoterHandle = callback;
}

STATIC UINT32 OsLowpowerGetDeepSleepVoteCount(VOID)//获取深度睡眠投票数
{
    if (g_pmMgr.exVoterHandle == NULL) {
        return (UINT32)g_pmMgr.sleepVoteCount;
    } else {
        return (UINT32)g_pmMgr.sleepVoteCount + (UINT32)g_pmMgr.exVoterHandle();
    }
}

STATIC PowerMgrOps g_pmOps = {
    .process = OsLowpowerProcess, //该函数指针用于处理低功耗过程，即在进入低功耗模式前需要执行的操作
    .wakeupFromReset = OsLowpowerWakeupFromReset,//该函数指针用于处理从复位状态唤醒时的操作
    .resumeFromInterrupt = OsLowpowerWakeupFromInterrupt,//该函数指针用于处理从中断状态恢复时的操作。
    .changeFreq = OsLowpowerChangeFreq,//该函数指针用于改变系统频率的操作，可以根据需要调整系统的工作频率
    .deepSleepVoteBegin = OsLowpowerDeepSleepVoteBegin,//该函数指针用于开始深度休眠投票，即在进入深度休眠模式前需要执行的操作
    .deepSleepVoteEnd = OsLowpowerDeepSleepVoteEnd,//该函数指针用于结束深度休眠投票，即在退出深度休眠模式后需要执行的操作
    .deepSleepVoteDelay = OsLowpowerDeepSleepVoteDelay,//该函数指针用于处理深度休眠投票延迟的操作，可以根据需要延迟深度休眠的投票
    .registerExternalVoter = OsLowpowerRegisterExternalVoter,//该函数指针用于注册外部投票者，即在系统中存在其他模块也需要参与低功耗投票时的操作
    .getDeepSleepVoteCount = OsLowpowerGetDeepSleepVoteCount,//该函数指针用于获取当前深度休眠投票的数量，可以用来监控系统中参与休眠投票的模块数量
    .getSleepMode = NULL,//该函数指针用于获取当前的睡眠模式，即获取系统当前是否处于睡眠状态
    .setSleepMode = NULL,//该函数指针用于设置睡眠模式，即将系统设置为指定的睡眠模式
    //以上提及的函数均为函数指针
};

#define FORCE_NULL_CALLBACK (void *)0x3f3f3f3f
//以下定义是用于给结构体成员赋值，如果某个回调函数指针为特殊空值，则将相应的成员置为空，否则进行赋值
#define ASSIGN_MEMBER(lhs, rhs, member)       
//lhs 是左操作数，表示要赋值的结构体指针；
//rhs 是右操作数，表示要赋给成员的值；
//member 是要赋值的结构体成员      
    do {                                            \
        if ((rhs)->member == FORCE_NULL_CALLBACK) { \
            (lhs)->member = NULL;                   \
        } else if ((rhs)->member != NULL) {         \
            (lhs)->member = (rhs)->member;          \
        }                                           \
    } while (0)

#define ASSIGN_MEMBER_NOT_NULL(lhs, rhs, member) \
    do {                                         \
        ASSIGN_MEMBER(lhs, rhs, member);         \
        if ((lhs)->member == NULL) {             \
            PRINT_ERR("\r\n [PM] %s must be non-null.\n", __FUNCTION__); \
            while (1) {};                        \
        }                                        \
    } while (0)

VOID LOS_PowerMgrInit(const PowerMgrParameter *para)
{
    const PowerMgrRunOps *runOps = NULL;
    const PowerMgrDeepSleepOps *deepSleepOps = NULL;
    (void)deepSleepOps;
    if (para != NULL) { //如果para为空，则运行操作和深度睡眠操作都为空指针
        runOps = &para->runOps;
#ifdef LOSCFG_KERNEL_DEEPSLEEP
        deepSleepOps = &para->deepSleepOps;
#endif
        g_pmMgr.minSleepTicks = para->config.minLightSleepTicks;//记录了系统中需要从睡眠状态唤醒的 CPU 核心数
        g_pmMgr.maxSleepCount = para->config.maxDeepSleepTicks;//用于保护电源管理模块在多线程环境下的并发访问
        g_pmMgr.minDeepSleepTicks = para->config.minDeepSleepTicks;//记录自旋锁是否被释放
    }
    //将传入的运行操作和深度睡眠操作分别赋值给全局变量 g_pmRunOps 和 g_deepSleepOps
    LOS_AtomicSet(&g_pmMgr.resumeSleepCores, 0);

    LOS_SpinInit(&g_pmMgr.lock);
    LOS_AtomicSet(&g_pmMgr.freeLock, LOCK_OFF);

    // verify and assign input operators.
    if (runOps != NULL) {
        ASSIGN_MEMBER(&g_pmRunOps, runOps, changeFreq);//改变CPU频率
        ASSIGN_MEMBER(&g_pmRunOps, runOps, enterLightSleep);//进入浅度睡眠
#ifdef LOSCFG_KERNEL_DEEPSLEEP
        ASSIGN_MEMBER_NOT_NULL(&g_pmRunOps, runOps, enterDeepSleep);//进入深度睡眠
        ASSIGN_MEMBER_NOT_NULL(&g_pmRunOps, runOps, setWakeUpTimer);//设置唤醒定时器
        ASSIGN_MEMBER_NOT_NULL(&g_pmRunOps, runOps, withdrawWakeUpTimer);//撤销定时器
#else
        ASSIGN_MEMBER(&g_pmRunOps, runOps, enterDeepSleep);
        ASSIGN_MEMBER(&g_pmRunOps, runOps, setWakeUpTimer);
        ASSIGN_MEMBER(&g_pmRunOps, runOps, withdrawWakeUpTimer);
#endif
        ASSIGN_MEMBER_NOT_NULL(&g_pmRunOps, runOps, getSleepTime);//货的睡眠时间
        ASSIGN_MEMBER_NOT_NULL(&g_pmRunOps, runOps, selectSleepMode);//选择不同的睡眠模式
        ASSIGN_MEMBER(&g_pmRunOps, runOps, preConfig);//预配置
        ASSIGN_MEMBER(&g_pmRunOps, runOps, postConfig);//后配置
    }

#ifdef LOSCFG_KERNEL_DEEPSLEEP
    if (deepSleepOps != NULL) {//进入深度睡眠
        ASSIGN_MEMBER(&g_deepSleepOps, deepSleepOps, couldDeepSleep);
        ASSIGN_MEMBER(&g_deepSleepOps, deepSleepOps, systemWakeup);
        ASSIGN_MEMBER(&g_deepSleepOps, deepSleepOps, suspendPreConfig);
        ASSIGN_MEMBER(&g_deepSleepOps, deepSleepOps, suspendDevice);
        ASSIGN_MEMBER(&g_deepSleepOps, deepSleepOps, rollback);
        ASSIGN_MEMBER(&g_deepSleepOps, deepSleepOps, resumeDevice);
        ASSIGN_MEMBER(&g_deepSleepOps, deepSleepOps, resumePostConfig);
        ASSIGN_MEMBER(&g_deepSleepOps, deepSleepOps, resumeCallBack);
        ASSIGN_MEMBER(&g_deepSleepOps, deepSleepOps, otherCoreResume);
    }
#endif
    // Register PowerMgr to Low-Power Framework.
    LOS_LowpowerInit(&g_pmOps);
    //将电源管理模块注册到低功耗框架中。
    //低功耗框架是一个用于管理处理器和设备进入低功耗模式的软件框架，
    //它能够最大限度地降低系统能耗，提高系统的电池寿命
}
