Загрузка данных


/*--------------------------------------------------------------------------*/
/* Sleep the system                                                         */
/*--------------------------------------------------------------------------*/
int32_t DEV_SM_SystemSleep(uint32_t sleepMode)
{
    static const uint32_t s_clkRootSleepList[DEV_SM_NUM_SLEEP_ROOTS] =
    {
        [0] = CLOCK_ROOT_ELE,
        [1] = CLOCK_ROOT_BUSAON,
        [2] = CLOCK_ROOT_M33
    };
    static const uint32_t s_pllVcoList[CLOCK_NUM_PLL] =
    {
        [CLOCK_PLL_SYS1] = CLOCK_SRC_SYSPLL1_VCO,
        [CLOCK_PLL_AUDIO1] = CLOCK_SRC_AUDIOPLL1_VCO,
        [CLOCK_PLL_AUDIO2] = CLOCK_SRC_AUDIOPLL2_VCO,
        [CLOCK_PLL_VIDEO1] = CLOCK_SRC_VIDEOPLL1_VCO,
        [CLOCK_PLL_ARM] = CLOCK_SRC_ARMPLL_VCO,
        [CLOCK_PLL_DRAM] = CLOCK_SRC_DRAMPLL_VCO,
        [CLOCK_PLL_HSIO] = CLOCK_SRC_HSIOPLL_VCO,
        [CLOCK_PLL_LDB] = CLOCK_SRC_LDBPLL_VCO
    };
    static src_mem_slice_t const *const s_srcMemPtrs[] = SRC_MEM_BASE_PTRS;

    int32_t status = SM_ERR_SUCCESS;
    uint32_t s_clkRootCtrl[DEV_SM_NUM_SLEEP_ROOTS];
    uint32_t cpuWakeMask[CPU_NUM_IDX][GPC_CPU_CTRL_CMC_IRQ_WAKEUP_MASK_COUNT];
    uint32_t sysWakeMask[GPC_CPU_CTRL_CMC_IRQ_WAKEUP_MASK_COUNT];
    uint32_t nvicISER[GPC_CPU_CTRL_CMC_IRQ_WAKEUP_MASK_COUNT];

    /* Capture start of sleep entry */
    uint64_t sleepEntryStart = DEV_SM_Usec64Get();
    uint64_t sleepExitStart = sleepEntryStart;

    /* Reset wake source of sleep record */
    g_syslog.sysSleepRecord.wakeSource = 0U;

    /* Capture system sleep mode/flags */
    g_syslog.sysSleepRecord.sysSleepMode = s_sysSleepMode;
    g_syslog.sysSleepRecord.sysSleepFlags = s_sysSleepFlags;

    /* Capture power status of MIXes */
    g_syslog.sysSleepRecord.mixPwrStat = 0U;
    for (uint32_t mixIdx = 0U; mixIdx < PWR_NUM_MIX_SLICE; mixIdx++)
    {
        if (SRC_MixIsPwrSwitchOn(mixIdx))
        {
            g_syslog.sysSleepRecord.mixPwrStat |= (1UL << mixIdx);
        }
    }

    /* Capture power status of memories */
    g_syslog.sysSleepRecord.memPwrStat = 0U;
    for (uint32_t memIdx = 0U; memIdx < PWR_NUM_MEM_SLICE; memIdx++)
    {
        const src_mem_slice_t *srcMem = s_srcMemPtrs[memIdx];
        if ((srcMem->MEM_CTRL & SRC_MEM_MEM_CTRL_MEM_LP_MODE_MASK) != 0U)
        {
            g_syslog.sysSleepRecord.memPwrStat |= (1UL << memIdx);
        }
    }

    /* Capture power status of PLLs */
    g_syslog.sysSleepRecord.pllPwrStat = 0U;
    for (uint32_t pllIdx = 0U; pllIdx < CLOCK_NUM_PLL; pllIdx++)
    {
        uint32_t sourceIdx = s_pllVcoList[pllIdx];
        if (CLOCK_SourceGetEnable(sourceIdx))
        {
            g_syslog.sysSleepRecord.pllPwrStat |= (1UL << pllIdx);
        }
    }

    /* Initialize wake masks */
    for (uint32_t wakeIdx = 0;
        wakeIdx < GPC_CPU_CTRL_CMC_IRQ_WAKEUP_MASK_COUNT;
        wakeIdx++)
    {
        sysWakeMask[wakeIdx] = 0xFFFFFFFFU;

        for (uint32_t cpuIdx = 0U; cpuIdx < CPU_NUM_IDX; cpuIdx++)
        {
            cpuWakeMask[cpuIdx][wakeIdx] = 0xFFFFFFFFU;
        }
    }

    /* Initialize NOC/WAKEUP MIX dependencies */
    uint32_t lpmSettingNoc = CPU_PD_LPM_ON_NEVER;
    uint32_t lpmSettingWakeup = CPU_PD_LPM_ON_NEVER;

    /* Scan CPUs, update GPC wake masks, assess NOC/WAKEUP MIX dependencies */
    for (uint32_t cpuIdx = 0U; cpuIdx < CPU_NUM_IDX; cpuIdx++)
    {
        if (cpuIdx != CPU_IDX_M33P)
        {
            /* Check if sleep is forced for the CPU */
            bool sleepForce;
            if (CPU_SleepForceGet(cpuIdx, &sleepForce))
            {
                /* If sleep is not forced, manage GPC masks */
                if (!sleepForce)
                {
                    /* IRQs enabled at NVIC level become GPC wake sources */
                    for (uint32_t wakeIdx = 0;
                        wakeIdx < GPC_CPU_CTRL_CMC_IRQ_WAKEUP_MASK_COUNT;
                        wakeIdx++)
                    {
                        uint32_t wakeVal;
                        if (CPU_IrqWakeGet(cpuIdx, wakeIdx, &wakeVal))
                        {
                            cpuWakeMask[cpuIdx][wakeIdx] = wakeVal;
                            sysWakeMask[wakeIdx] &= wakeVal;
                            (void) CPU_IrqWakeSet(cpuIdx, wakeIdx,
                                0xFFFFFFFFU);
                        }
                    }

                    /* Update NOCMIX dependency */
                    uint32_t lpmSetting;
                    if (SRC_MixCpuLpmGet(PWR_MIX_SLICE_IDX_NOC, cpuIdx,
                        &lpmSetting))
                    {
                        if (lpmSetting > lpmSettingNoc)
                        {
                            lpmSettingNoc = lpmSetting;
                        }
                    }

                    /* Update WAKEUPMIX dependency */
                    if (SRC_MixCpuLpmGet(PWR_MIX_SLICE_IDX_WAKEUP, cpuIdx,
                        &lpmSetting))
                    {
                        if (lpmSetting > lpmSettingWakeup)
                        {
                            lpmSettingWakeup = lpmSetting;
                        }
                    }
                }
                /* Disable GPC wakeups for CPUs forced to sleep */
                else
                {
                    /* IRQs enabled at NVIC level become GPC wake sources */
                    for (uint32_t wakeIdx = 0;
                        wakeIdx < GPC_CPU_CTRL_CMC_IRQ_WAKEUP_MASK_COUNT;
                        wakeIdx++)
                    {
                        uint32_t wakeVal;
                        if (CPU_IrqWakeGet(cpuIdx, wakeIdx, &wakeVal))
                        {
                            cpuWakeMask[cpuIdx][wakeIdx] = wakeVal;
                            (void) CPU_IrqWakeSet(cpuIdx, wakeIdx,
                                0xFFFFFFFFU);
                        }
                    }
                }
            }
        }
    }

    /* Check system sleep status after clearing GPC masks */
    uint32_t sysSleepStat;
    if (CPU_SystemSleepStatusGet(&sysSleepStat))
    {
        /* If system can sleep after clearing GPC masks, SUSPEND
         * processing has reached point of coherency.  Agent CPUs
         * cannot wake without SM completion of SUSPEND entry/exit
         * sequence below.
         */
        if (sysSleepStat == CPU_SLEEP_MODE_SUSPEND)
        {
            /* Board-level sleep prepare */
            BOARD_SystemSleepPrepare(s_sysSleepMode, s_sysSleepFlags);

            /* Disable sensor */
            (void) DEV_SM_SensorPowerDown(DEV_SM_SENSOR_TEMP_ANA);

            /* Check the value doesn't wrap */
            if (g_syslog.sysSleepRecord.sleepCnt <= (UINT32_MAX - 1U))
            {
                /*! Increment system sleep counter */
                g_syslog.sysSleepRecord.sleepCnt++;
            }
            else
            {
                /* Initialize to zero in case of wrap */
                g_syslog.sysSleepRecord.sleepCnt = 0U;
            }

            bool ddrInRetention = false;
            /* Limit DDR access path to SM  */
            if (DEV_SM_RdcDdrBlock(true) == SM_ERR_SUCCESS)
            {
                /* Attempt to place DDR into retention */
                if (DEV_SM_MemDdrRetentionEnter() == SM_ERR_SUCCESS)
                {
                    /* Set flag to indicate DDR retention is active */
                    ddrInRetention = true;

                    /* Power down DDRMIX */
                    if (DEV_SM_PowerStateSet(DEV_SM_PD_DDR, DEV_SM_POWER_STATE_OFF)
                        == SM_ERR_SUCCESS)
                    {
                        g_syslog.sysSleepRecord.mixPwrStat &=
                            (~(1UL << PWR_MIX_SLICE_IDX_DDR));
                    }
                }
            }

            /* If NOCMIX powered down during SUSPEND, force power down */
            if (lpmSettingNoc <= sleepMode)
            {
                if (DEV_SM_PowerStateSet(DEV_SM_PD_NOC, DEV_SM_POWER_STATE_OFF)
                    == SM_ERR_SUCCESS)
                {
                    g_syslog.sysSleepRecord.mixPwrStat &=
                        (~(1UL << PWR_MIX_SLICE_IDX_NOC));
                }
            }

            /* Query if any CPU in LP compute mode */
            bool lpComputeActive = (CPU_LpComputeListGet() != 0U);

            /* Track if WAKEUPMIX powered down */
            bool wakeupMixOff = false;

            /* Track if WAKEUPMIX performance level forced */
            bool restoreWakeupMixPerf = false;
            uint32_t savedWakeupMixPerf;

            /* If WAKEUPMIX powered down during SUSPEND, force power down */
            if ((lpmSettingWakeup <= sleepMode) &&
                ((CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) == 0x0U))
            {
                /* Keep WAKEUPMIX powered at parked level during LP compute */
                if (lpComputeActive)
                {
                    if (DEV_SM_PerfLevelGet(DEV_SM_PERF_WAKEUP,
                        &savedWakeupMixPerf) == SM_ERR_SUCCESS)
                    {
                        if (DEV_SM_PerfLevelSet(DEV_SM_PERF_WAKEUP,
                            DEV_SM_PERF_LVL_PRK) == SM_ERR_SUCCESS)
                        {
                            restoreWakeupMixPerf = true;
                        }
                    }
                }
                else
                {
                    if (DEV_SM_PowerStateSet(DEV_SM_PD_WAKEUP,
                        DEV_SM_POWER_STATE_OFF) == SM_ERR_SUCCESS)
                    {
                        g_syslog.sysSleepRecord.mixPwrStat &=
                            (~(1UL << PWR_MIX_SLICE_IDX_WAKEUP));
                        wakeupMixOff = true;
                    }
                }
            }

            /* Inhibit all GPC LP handshakes during SUSPEND */
            uint32_t lpHsSm = BLK_CTRL_S_AONMIX->LP_HANDSHAKE_SM;
            BLK_CTRL_S_AONMIX->LP_HANDSHAKE_SM = 0U;
            uint32_t lpHs2Sm = BLK_CTRL_S_AONMIX->LP_HANDSHAKE2_SM;
            BLK_CTRL_S_AONMIX->LP_HANDSHAKE2_SM = 0U;
            uint32_t lpHsEle = BLK_CTRL_S_AONMIX->LP_HANDSHAKE_ELE;
            BLK_CTRL_S_AONMIX->LP_HANDSHAKE_ELE = 0U;
            uint32_t lpHs2Ele = BLK_CTRL_S_AONMIX->LP_HANDSHAKE2_ELE;
            BLK_CTRL_S_AONMIX->LP_HANDSHAKE2_ELE = 0U;

            /* Configure SM GPC_CTRL and NVIC for system-level wake events */
            for (uint32_t wakeIdx = 0;
                wakeIdx < GPC_CPU_CTRL_CMC_IRQ_WAKEUP_MASK_COUNT;
                wakeIdx++)
            {
                /* Save context of SM IRQs enabled at NVIC level */
                nvicISER[wakeIdx] = NVIC->ISER[wakeIdx];

                /* Clear unused system-level IRQs */
                uint32_t maskVal = ~nvicISER[wakeIdx];
                NVIC->ICPR[wakeIdx] = 0xFFFFFFFFU & maskVal;

                /* Add system-level wake events */
                maskVal &= sysWakeMask[wakeIdx];

                /* Update GPC wake mask */
                (void) CPU_IrqWakeSet(CPU_IDX_M33P, wakeIdx, maskVal);

                /* Update NVIC wake mask */
                NVIC->ICER[wakeIdx] = 0xFFFFFFFFU;
                NVIC->ISER[wakeIdx] = ~maskVal;
            }

            /* Configure M33P to wake from GPC */
            (void) CPU_WakeMuxSet(CPU_IDX_M33P, false);

            /* Set target M33P sleep mode */
            (void) CPU_SleepModeSet(CPU_IDX_M33P, sleepMode);

            /* Extract and clamp performance level from system sleep mode */
            uint32_t perfLevelSleep = (s_sysSleepMode & 0xF0U) >> 4U;
            if (perfLevelSleep > DEV_SM_PERF_LVL_ODV)
            {
                perfLevelSleep = DEV_SM_PERF_LVL_ODV;
            }

            /* System remains active during sleep based on performance level
             * and OSC24M configuration.
             */
            bool activeSleep = (perfLevelSleep != DEV_SM_PERF_LVL_PRK) ||
                ((s_sysSleepFlags & DEV_SM_SSF_OSC24M_ACTIVE_MASK) != 0U) ||
                lpComputeActive;

            /* Check if OSC24M must remain active */
            if (activeSleep)
            {
                /* Keep OSC_24M active during system sleep */
                GPC_GLOBAL->GPC_ROSC_CTRL = 0U;
            }
            else
            {
                /* Shut off OSC_24M during system sleep */
                GPC_GLOBAL->GPC_ROSC_CTRL =
                    GPC_GLOBAL_GPC_ROSC_CTRL_ROSC_OFF_EN_MASK;
            }

            /* Check PMIC_STBY system sleep mode flag */
            if ((s_sysSleepFlags & DEV_SM_SSF_PMIC_STBY_INACTIVE_MASK) == 0U)
            {
                /* Enable GPC PMIC standby control */
                GPC_GLOBAL->GPC_PMIC_CTRL =
                    GPC_GLOBAL_GPC_PMIC_CTRL_PMIC_STBY_EN_MASK;
            }
            else
            {
                /* Disable GPC PMIC standby control */
                GPC_GLOBAL->GPC_PMIC_CTRL = 0U;
            }

            /* Power down eFUSE */
            GPC_GLOBAL->GPC_EFUSE_CTRL =
                GPC_GLOBAL_GPC_EFUSE_CTRL_EFUSE_PD_EN_MASK;

            /* Disable bypass for clock sources */
            DEV_SM_ClockSourceBypass(false, true);

            if (activeSleep)
            {
                /* If staying active, move to system sleep performance level */
                (void) DEV_SM_PerfSystemSleep(perfLevelSleep);
            }
            else
            {
                /* Notify ELE of suspend entry */
                ELE_StartDvfsChange(ELE_DVFS_FLAG_SUSPEND, 0U, 0U, 0U);

                /* Move ELE and SM clock roots to OSC_24M to allow SysPLL to be
                 * powered down. OSC_24M may be gated by hardware during final phases
                 * of system SUSPEND entry.
                 */
                for (uint32_t sleepRootIdx = 0U;
                    sleepRootIdx < DEV_SM_NUM_SLEEP_ROOTS;
                    sleepRootIdx++)
                {
                    uint32_t rootIdx = s_clkRootSleepList[sleepRootIdx];

                    /* Save clock root context */
                    s_clkRootCtrl[sleepRootIdx] =
                        CCM_CTRL->CLOCK_ROOT[rootIdx].CLOCK_ROOT_CONTROL.RW;

                    /* Set MUX = 0 (OSC_24M) */
                    CCM_CTRL->CLOCK_ROOT[rootIdx].CLOCK_ROOT_CONTROL.CLR =
                        CCM_CLOCK_ROOT_MUX_MASK;

                    /* Set DIV = 0 (/1) */
                    CCM_CTRL->CLOCK_ROOT[rootIdx].CLOCK_ROOT_CONTROL.CLR =
                        CCM_CLOCK_ROOT_DIV_MASK;
                }
            }

            /* Check if sleep performance level allows SYSPLL disable */
            if (perfLevelSleep == DEV_SM_PERF_LVL_PRK)
            {
                /* Power down SYSPLL clock nodes */
                uint32_t clkSrcIdx = CLOCK_SRC_SYSPLL1_PFD2_DIV2;
                while (clkSrcIdx >= CLOCK_SRC_SYSPLL1_VCO)
                {
                    (void) CLOCK_SourceSetEnable(clkSrcIdx, false);
                    clkSrcIdx--;
                }
                g_syslog.sysSleepRecord.pllPwrStat &= (~(1UL << CLOCK_PLL_SYS1));
            }

            /* Board-level sleep entry */
            BOARD_SystemSleepEnter(s_sysSleepMode, s_sysSleepFlags);

            /* Process SM LPIs for sleep entry */
            (void) CPU_PerLpiProcess(CPU_IDX_M33P, sleepMode);

            /* Check the expression values doesn't wrap */
            if (DEV_SM_Usec64Get() >= sleepEntryStart)
            {
                /* Capture sleep entry latency */
                g_syslog.sysSleepRecord.sleepEntryUsec =
                    UINT64_L(DEV_SM_Usec64Get() - sleepEntryStart);
            }
            else
            {
                /* Initialize to zero in case of wrap */
                g_syslog.sysSleepRecord.sleepEntryUsec = 0U;
            }

            /* Check SYSCTR system sleep mode flag */
            if ((s_sysSleepFlags & DEV_SM_SSF_SYSCTR_ACTIVE_MASK) != 0U)
            {
                /* Switch SYSCTR to low-freq mode (blocking) */
                SYSCTR_FreqMode(true, true);
            }

            /* Manage FRO based on system sleep flags and active sleep state */
            if (((s_sysSleepFlags & DEV_SM_SSF_FRO_ACTIVE_MASK) == 0U) &&
                !activeSleep)
            {
                /* Power down FRO */
                FRO->CSR.CLR = FRO_CSR_FROEN_MASK;
            }

            /* Enter WFI to trigger sleep entry */
            __DSB();
            /* coverity[misra_c_2012_rule_1_2_violation] */
            __WFI();
            __ISB();

            /* Power up FRO */
            FRO->CSR.SET = FRO_CSR_FROEN_MASK;

            /* Check SYSCTR system sleep mode flag
             *
             * NOTE: switch completion required before read of exit timestamp
             */
            if ((s_sysSleepFlags & DEV_SM_SSF_SYSCTR_ACTIVE_MASK) != 0U)
            {
                /* Switch SYSCTR to high-freq mode (blocking) */
                SYSCTR_FreqMode(false, true);
            }

            /* Capture start of sleep exit */
            sleepExitStart = DEV_SM_Usec64Get();

            /* Capture wake source */
            g_syslog.sysSleepRecord.wakeSource =
                (SCB->ICSR & SCB_ICSR_VECTPENDING_Msk)
                >> SCB_ICSR_VECTPENDING_Pos;

            /* Process SM LPIs for sleep exit */
            (void) CPU_PerLpiProcess(CPU_IDX_M33P, CPU_SLEEP_MODE_RUN);

            /* Board-level sleep exit */
            BOARD_SystemSleepExit(s_sysSleepMode, s_sysSleepFlags);

            /* Check if sleep performance level requires SYSPLL enable */
            if (perfLevelSleep == DEV_SM_PERF_LVL_PRK)
            {
                /* Power up SYSPLL clock nodes */
                uint32_t clkSrcIdx = CLOCK_SRC_SYSPLL1_VCO;
                while (clkSrcIdx <= CLOCK_SRC_SYSPLL1_PFD2_DIV2)
                {
                    (void) CLOCK_SourceSetEnable(clkSrcIdx, true);
                    clkSrcIdx++;
                }
            }

            if (activeSleep)
            {
                /* Move to system wake performance level */
                (void) DEV_SM_PerfSystemWake(perfLevelSleep);
            }
            else
            {
                /* Restore ELE and SM clock roots */
                for (uint32_t sleepRootIdx = 0U;
                    sleepRootIdx < DEV_SM_NUM_SLEEP_ROOTS;
                    sleepRootIdx++)
                {
                    uint32_t rootIdx = s_clkRootSleepList[sleepRootIdx];

                    /* Restore DIV */
                    CCM_CTRL->CLOCK_ROOT[rootIdx].CLOCK_ROOT_CONTROL.SET =
                        s_clkRootCtrl[sleepRootIdx] & CCM_CLOCK_ROOT_DIV_MASK;

                    /* Restore MUX */
                    CCM_CTRL->CLOCK_ROOT[rootIdx].CLOCK_ROOT_CONTROL.SET =
                        s_clkRootCtrl[sleepRootIdx] & CCM_CLOCK_ROOT_MUX_MASK;
                }

                /* Notify ELE of suspend exit */
                ELE_StopDvfsChange();
            }

            /* Enable bypass for clock sources */
            DEV_SM_ClockSourceBypass(true, true);

            /* Power up eFUSE */
            GPC_GLOBAL->GPC_EFUSE_CTRL = 0U;

            /* Restore GPC LP handshakes */
            BLK_CTRL_S_AONMIX->LP_HANDSHAKE_SM = lpHsSm;
            BLK_CTRL_S_AONMIX->LP_HANDSHAKE2_SM = lpHs2Sm;
            BLK_CTRL_S_AONMIX->LP_HANDSHAKE_ELE = lpHsEle;
            BLK_CTRL_S_AONMIX->LP_HANDSHAKE2_ELE = lpHs2Ele;

            /* If WAKEUPMIX powered down during SUSPEND, force power up */
            if (wakeupMixOff)
            {
                status = DEV_SM_PowerStateSet(DEV_SM_PD_WAKEUP,
                    DEV_SM_POWER_STATE_ON);
            }

            /* Check if WAKEUPMIX forced to parked level during LP compute */
            if ((status == SM_ERR_SUCCESS) && restoreWakeupMixPerf)
            {
                /* Restore saved WAKEUPMIX performance level */
                status = DEV_SM_PerfLevelSet(DEV_SM_PERF_WAKEUP,
                    savedWakeupMixPerf);
            }

            if (status == SM_ERR_SUCCESS)
            {
                /* If NOCMIX powered down during SUSPEND, force power up */
                if (lpmSettingNoc <= sleepMode)
                {
                    status = DEV_SM_PowerStateSet(DEV_SM_PD_NOC,
                        DEV_SM_POWER_STATE_ON);
                }
                else
                {
                    /* Reopen DDR access if NOCMIX TRDC is not reloaded */
                    status = DEV_SM_RdcDdrBlock(false);
                }
            }

            /* Check if DDR retention active */
            if (ddrInRetention)
            {
                if (status == SM_ERR_SUCCESS)
                {
                    /* Power up DDRMIX */
                    status = DEV_SM_PowerStateSet(DEV_SM_PD_DDR,
                        DEV_SM_POWER_STATE_ON);
                }

                if (status == SM_ERR_SUCCESS)
                {
                    /* Take DDR out of retention */
                    status = DEV_SM_MemDdrRetentionExit();
                }
            }

            /* Restore SM NVIC */
            for (uint32_t wakeIdx = 0;
                wakeIdx < GPC_CPU_CTRL_CMC_IRQ_WAKEUP_MASK_COUNT;
                wakeIdx++)
            {
                NVIC->ICER[wakeIdx] = 0xFFFFFFFFU;
                NVIC->ISER[wakeIdx] = nvicISER[wakeIdx];
            }

            /* Enable sensor */
            (void) DEV_SM_SensorPowerUp(DEV_SM_SENSOR_TEMP_ANA);

            /* Board-level sleep unprepare */
            BOARD_SystemSleepUnprepare(s_sysSleepMode, s_sysSleepFlags);
        }
    }

    /* Check if system did not sleep */
    if (g_syslog.sysSleepRecord.wakeSource == 0U)
    {
        sleepExitStart = DEV_SM_Usec64Get();

        /* Check the expression doesn't wrap */
        if (sleepExitStart >= sleepEntryStart)
        {
            g_syslog.sysSleepRecord.sleepEntryUsec =
                UINT64_L(sleepExitStart - sleepEntryStart);
        }
        else
        {
            /* Initialize to zero in case of wrap */
            g_syslog.sysSleepRecord.sleepEntryUsec = 0U;
        }
    }

    /* Restore GPC wake sources modified during sleep flow */
    for (uint32_t cpuIdx = 0U; cpuIdx < CPU_NUM_IDX; cpuIdx++)
    {
        if (cpuIdx != CPU_IDX_M33P)
        {
            /* Restore saved GPC wake sources */
            for (uint32_t wakeIdx = 0U;
                wakeIdx < GPC_CPU_CTRL_CMC_IRQ_WAKEUP_MASK_COUNT;
                wakeIdx++)
            {
                (void) CPU_IrqWakeSet(cpuIdx, wakeIdx,
                    cpuWakeMask[cpuIdx][wakeIdx]);
            }
        }
    }

    /* Check the expression value doesn't wrap */
    if (DEV_SM_Usec64Get() >= sleepExitStart)
    {
        g_syslog.sysSleepRecord.sleepExitUsec =
            UINT64_L(DEV_SM_Usec64Get() - sleepExitStart);
    }
    else
    {
        /* Initialize to zero in case of wrap */
        g_syslog.sysSleepRecord.sleepExitUsec = 0U;
    }

    return status;
}