📄 off.c
字号:
//------------------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
// NOTE: stubs are being used - this isn't done
//
//------------------------------------------------------------------------------
//
// Copyright (C) 2004, Freescale Semiconductor, Inc. All Rights Reserved
// THIS SOURCE CODE IS CONFIDENTIAL AND PROPRIETARY AND MAY NOT
// BE USED OR DISTRIBUTED WITHOUT THE WRITTEN PERMISSION OF
// FREESCALE SEMICONDUCTOR, INC.
//
//------------------------------------------------------------------------------
//
// File: off.c
//
// This file provides the capabilities to suspend the system and controlling
// wake sources.
//
//------------------------------------------------------------------------------
#include <windows.h>
#include <ceddk.h>
#include <nkintr.h>
#include <cmnintrin.h>
#include <oal.h>
#include "csp.h"
//------------------------------------------------------------------------------
// External Functions
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// External Variables
//------------------------------------------------------------------------------
extern UINT32 g_oalIrqTranslate[OAL_INTR_IRQ_MAXIMUM];
extern UINT32 g_oalGpioTranslate[DDK_GPIO_PORT3+1][GPIO_INTR_SOURCES_MAX];
extern ULARGE_INTEGER g_oalIrqMask[OAL_INTR_IRQ_MAXIMUM];
extern UINT32 g_oalGpioMask[DDK_GPIO_PORT3+1][OAL_INTR_IRQ_MAXIMUM];
extern PCSP_AVIC_REGS g_pAVIC;
extern PCSP_GPIO_REGS g_pGPIO1;
extern PCSP_GPIO_REGS g_pGPIO2;
extern PCSP_GPIO_REGS g_pGPIO3;
extern PCSP_CCM_REGS g_pCCM;
//------------------------------------------------------------------------------
// Defines
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Types
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Global Variables
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Local Variables
//------------------------------------------------------------------------------
static ULARGE_INTEGER g_avicWakeMask = {0, 0};
static UINT32 g_gpioWakeMask[DDK_GPIO_PORT3+1];
static UINT32 g_WakeSource;
static BOOL bSuspendEnabled = TRUE;
//------------------------------------------------------------------------------
// Local Functions
//------------------------------------------------------------------------------
BOOL OALIoCtlHalEnableSuspend(UINT32 code, VOID *pInpBuffer,
UINT32 inpSize, VOID *pOutBuffer, UINT32 outSize, UINT32 *pOutSize)
{
BOOL rc = FALSE;
OALMSG(OAL_FUNC&&OAL_POWER, (_T("+OALIoCtlHalEnableSuspend\r\n")));
if ((pInpBuffer == NULL) || (inpSize != sizeof(BOOL))) {
NKSetLastError(ERROR_INVALID_PARAMETER);
OALMSG(OAL_WARN, (
L"WARN: IOCTL_HAL_ENABLE_SUSPEND invalid parameters\r\n"
));
goto cleanUp;
}
bSuspendEnabled= *(UINT32*)pInpBuffer;
rc = TRUE;
cleanUp:
OALMSG(OAL_FUNC&&OAL_POWER, (_T("-OALIoCtlHalEnableSuspend (rc = %d)\r\n"), rc));
return rc;
}
//-----------------------------------------------------------------------------
//
// Function: OEMPowerOff
//
// Called when the system is to transition to it's lowest power mode. This
// function stores off some of the important registers (not really needed for
// DSM since registers will not lose state in DSM).
//
// Parameters:
// None
//
// Returns:
// None
//
//-----------------------------------------------------------------------------
void OEMPowerOff()
{
UINT32 registerStore[6];
UINT32 irq;
UINT32 line;
// Reset the wake source global
g_WakeSource = SYSWAKE_UNKNOWN;
// If any of the GPIO interrupts are wakes sources, add the corresponding
// AVIC interrupt to the wake mask
if (g_gpioWakeMask[DDK_GPIO_PORT1])
{
g_avicWakeMask.QuadPart |= CSP_IRQMASK(IRQ_GPIO1);
}
if (g_gpioWakeMask[DDK_GPIO_PORT2])
{
g_avicWakeMask.QuadPart |= CSP_IRQMASK(IRQ_GPIO2);
}
if (g_gpioWakeMask[DDK_GPIO_PORT3])
{
g_avicWakeMask.QuadPart |= CSP_IRQMASK(IRQ_GPIO3);
}
// If no wake sources are registered, we should not allow power off
if (!g_avicWakeMask.QuadPart)
{
OALMSG(OAL_ERROR, (_T("ERROR: OEMPowerOff has no wake sources!\r\n")));
return;
}
// Switch off power for KITL device
OALKitlPowerOff();
// Save state of enabled interrupts
registerStore[0] = INREG32(&g_pAVIC->INTENABLEH);
registerStore[1] = INREG32(&g_pAVIC->INTENABLEL);
registerStore[2] = INREG32(&g_pGPIO1->IMR);
registerStore[3] = INREG32(&g_pGPIO2->IMR);
registerStore[4] = INREG32(&g_pGPIO3->IMR);
// Disable all GPIO interrups except for desired wake sources
OUTREG32(&g_pGPIO1->IMR, g_gpioWakeMask[DDK_GPIO_PORT1]);
OUTREG32(&g_pGPIO2->IMR, g_gpioWakeMask[DDK_GPIO_PORT2]);
OUTREG32(&g_pGPIO3->IMR, g_gpioWakeMask[DDK_GPIO_PORT3]);
// Disable all interrupts except for desired wake sources
OUTREG32(&g_pAVIC->INTENABLEH, g_avicWakeMask.HighPart);
OUTREG32(&g_pAVIC->INTENABLEL, g_avicWakeMask.LowPart);
// Place the system in suspend state and wait for an interrupt.
OALMSG(OAL_POWER, (_T("INFO: OEMPowerOff entering suspend. INTENABLEH = 0x%x, INTENABLEL = 0x%x\r\n"),
INREG32(&g_pAVIC->INTENABLEH), INREG32(&g_pAVIC->INTENABLEL)));
// Allow platform code to finish the power off sequence
if (bSuspendEnabled)
{
BSPPowerOff();
}
// Get interrupt source
irq = EXTREG32BF(&g_pAVIC->NIVECSR, AVIC_NIVECSR_NIVECTOR);
OALMSG(OAL_POWER, (_T("INFO: OEMPowerOff leaving suspend. NIVECSR = 0x%x\r\n"), irq));
// If valid wake interrupt is pending
if (irq < AVIC_IRQ_SOURCES_MAX)
{
if (irq == IRQ_GPIO1)
{
// detect GPIO line that is asserting interrupt
line = _CountLeadingZeros(INREG32(&g_pGPIO1->ISR)
& INREG32(&g_pGPIO1->IMR));
// If at least one GPIO interrupt line is asserted
if (line < 32)
{
irq = g_oalGpioTranslate[0][31 - line];
}
} // GPIO1 special case
else if (irq == IRQ_GPIO2)
{
// detect GPIO line that is asserting interrupt
line = _CountLeadingZeros(INREG32(&g_pGPIO2->ISR)
& INREG32(&g_pGPIO2->IMR));
// If at least one GPIO interrupt line is asserted
if (line < 32)
{
irq = g_oalGpioTranslate[1][31 - line];
}
} // GPIO2 special case
else if (irq == IRQ_GPIO3)
{
// detect GPIO line that is asserting interrupt
line = _CountLeadingZeros(INREG32(&g_pGPIO3->ISR)
& INREG32(&g_pGPIO3->IMR));
// If at least one GPIO interrupt line is asserted
if (line < 32)
{
irq = g_oalGpioTranslate[2][31 - line];
}
} // GPIO3 special case
else
{
irq = g_oalIrqTranslate[irq];
}
// Map the irq to a SYSINTR
g_WakeSource = OALIntrTranslateIrq(irq);
}
// Restore state of enabled interrupts
OUTREG32(&g_pAVIC->INTENABLEH, registerStore[0]);
OUTREG32(&g_pAVIC->INTENABLEL, registerStore[1]);
// Restore state of enabled GPIO interrupts
OUTREG32(&g_pGPIO1->IMR, registerStore[2]);
OUTREG32(&g_pGPIO2->IMR, registerStore[3]);
OUTREG32(&g_pGPIO3->IMR, registerStore[4]);
// Remove GPIO as wake source
g_avicWakeMask.QuadPart &= (~(CSP_IRQMASK(IRQ_GPIO1) |
CSP_IRQMASK(IRQ_GPIO2) | CSP_IRQMASK(IRQ_GPIO3)));
// Switch on power for KITL device
OALKitlPowerOn();
// Do platform dependent power on actions
BSPPowerOn();
}
//-----------------------------------------------------------------------------
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -