Changes for V4 ============== 1) Remove Unicode character from C source file 2) Move delete of QuarkSocPkg\QuarkNorthCluster\Binary\QuarkMicrocode from QuarkPlatformPkg commit to QuarkSocPkg commit Changes for V2 ============== 1) Sync with new APIs in SmmCpuFeaturesLib class 2) Use new generic PCI serial driver PciSioSerialDxe in MdeModulePkg 3) Remove PCI serial driver from QuarkSocPkg 4) Apply optimizations to MtrrLib from MtrrLib in UefiCpuPkg 5) Convert all UNI files to utf-8 6) Replace tabs with spaces and remove trailing spaces 7) Add License.txt Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Michael Kinney <michael.d.kinney@intel.com> Acked-by: Jordan Justen <jordan.l.justen@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@19286 6f19259b-4bc3-4df7-8a09-765794883524
154 lines
3.7 KiB
C
154 lines
3.7 KiB
C
/** @file
|
|
File to contain all the hardware specific stuff for the Smm Sx dispatch protocol.
|
|
|
|
Copyright (c) 2013-2015 Intel Corporation.
|
|
|
|
This program and the accompanying materials
|
|
are licensed and made available under the terms and conditions of the BSD License
|
|
which accompanies this distribution. The full text of the license may be found at
|
|
http://opensource.org/licenses/bsd-license.php
|
|
|
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
|
|
|
|
**/
|
|
|
|
//
|
|
// Include common header file for this module.
|
|
//
|
|
#include "CommonHeader.h"
|
|
|
|
#include "QNCSmmHelpers.h"
|
|
|
|
CONST QNC_SMM_SOURCE_DESC SX_SOURCE_DESC = {
|
|
QNC_SMM_NO_FLAGS,
|
|
{
|
|
{
|
|
{GPE_ADDR_TYPE, {R_QNC_GPE0BLK_SMIE}}, S_QNC_GPE0BLK_SMIE, N_QNC_GPE0BLK_SMIE_SLP
|
|
},
|
|
NULL_BIT_DESC_INITIALIZER
|
|
},
|
|
{
|
|
{
|
|
{GPE_ADDR_TYPE, {R_QNC_GPE0BLK_SMIS}}, S_QNC_GPE0BLK_SMIS, N_QNC_GPE0BLK_SMIS_SLP
|
|
}
|
|
}
|
|
};
|
|
|
|
VOID
|
|
SxGetContext(
|
|
IN DATABASE_RECORD *Record,
|
|
OUT QNC_SMM_CONTEXT *Context
|
|
)
|
|
{
|
|
UINT32 Pm1Cnt;
|
|
|
|
Pm1Cnt = IoRead32 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C);
|
|
|
|
//
|
|
// By design, the context phase will always be ENTRY
|
|
//
|
|
Context->Sx.Phase = SxEntry;
|
|
|
|
//
|
|
// Map the PM1_CNT register's SLP_TYP bits to the context type
|
|
//
|
|
switch (Pm1Cnt & B_QNC_PM1BLK_PM1C_SLPTP) {
|
|
|
|
case V_S0:
|
|
Context->Sx.Type = SxS0;
|
|
break;
|
|
|
|
case V_S3:
|
|
Context->Sx.Type = SxS3;
|
|
break;
|
|
|
|
case V_S4:
|
|
Context->Sx.Type = SxS4;
|
|
break;
|
|
|
|
case V_S5:
|
|
Context->Sx.Type = SxS5;
|
|
break;
|
|
|
|
default:
|
|
ASSERT (FALSE);
|
|
break;
|
|
};
|
|
}
|
|
|
|
BOOLEAN
|
|
SxCmpContext (
|
|
IN QNC_SMM_CONTEXT *Context1,
|
|
IN QNC_SMM_CONTEXT *Context2
|
|
)
|
|
{
|
|
return (BOOLEAN)(Context1->Sx.Type == Context2->Sx.Type);
|
|
}
|
|
|
|
VOID
|
|
QNCSmmSxGoToSleep(
|
|
VOID
|
|
)
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
When we get an SMI that indicates that we are transitioning to a sleep state,
|
|
we need to actually transition to that state. We do this by disabling the
|
|
"SMI on sleep enable" feature, which generates an SMI when the operating system
|
|
tries to put the system to sleep, and then physically putting the system to sleep.
|
|
|
|
Returns:
|
|
|
|
None.
|
|
|
|
--*/
|
|
{
|
|
UINT32 Pm1Cnt;
|
|
|
|
//
|
|
// Flush cache into memory before we go to sleep. It is necessary for S3 sleep
|
|
// because we may update memory in SMM Sx sleep handlers -- the updates are in cache now
|
|
//
|
|
AsmWbinvd();
|
|
|
|
//
|
|
// Disable SMIs
|
|
//
|
|
QNCSmmClearSource (&SX_SOURCE_DESC );
|
|
QNCSmmDisableSource (&SX_SOURCE_DESC);
|
|
|
|
//
|
|
// Clear Sleep Type Enable
|
|
//
|
|
IoAnd16 ((UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) + R_QNC_GPE0BLK_SMIE, (UINT16)(~B_QNC_GPE0BLK_SMIE_SLP));
|
|
|
|
// clear sleep SMI status
|
|
IoAnd16 ((UINT16)(LpcPciCfg32 (R_QNC_LPC_GPE0BLK) & 0xFFFF) + R_QNC_GPE0BLK_SMIS, (UINT16)(S_QNC_GPE0BLK_SMIS));
|
|
|
|
//
|
|
// Now that SMIs are disabled, write to the SLP_EN bit again to trigger the sleep
|
|
//
|
|
Pm1Cnt = IoOr32 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C, B_QNC_PM1BLK_PM1C_SLPEN);
|
|
|
|
//
|
|
// The system just went to sleep. If the sleep state was S1, then code execution will resume
|
|
// here when the system wakes up.
|
|
//
|
|
Pm1Cnt = IoRead32 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C);
|
|
if ((Pm1Cnt & B_QNC_PM1BLK_PM1C_SCIEN) == 0) {
|
|
//
|
|
// An ACPI OS isn't present, clear the sleep information
|
|
//
|
|
Pm1Cnt &= ~B_QNC_PM1BLK_PM1C_SLPTP;
|
|
Pm1Cnt |= V_S0;
|
|
|
|
IoWrite32 (PcdGet16 (PcdPm1blkIoBaseAddress) + R_QNC_PM1BLK_PM1C, Pm1Cnt);
|
|
}
|
|
|
|
QNCSmmClearSource (&SX_SOURCE_DESC);
|
|
QNCSmmEnableSource (&SX_SOURCE_DESC);
|
|
}
|