Upload BSD-licensed Vlv2TbltDevicePkg and Vlv2DeviceRefCodePkg to

https://svn.code.sf.net/p/edk2/code/trunk/edk2/, 

which are for MinnowBoard MAX open source project.


Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: David Wei <david.wei@intel.com>
Reviewed-by: Mike Wu <mike.wu@intel.com>
Reviewed-by: Hot Tian <hot.tian@intel.com>


git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16599 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
David Wei
2015-01-12 09:37:20 +00:00
committed by zwei4
parent 6f785cfcc3
commit 3cbfba02fe
518 changed files with 118538 additions and 0 deletions

View File

@@ -0,0 +1,977 @@
/** @file
Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available under
the terms and conditions of the BSD License that 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.
Module Name:
Platform.c
Abstract:
This is a generic template for a child of the IchSmm driver.
--*/
#include "SmmPlatform.h"
#include <Protocol/CpuIo2.h>
//
// Local variables
//
typedef struct {
UINT8 Device;
UINT8 Function;
} EFI_PCI_BUS_MASTER;
EFI_PCI_BUS_MASTER mPciBm[] = {
{ PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_1 },
{ PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_2 },
{ PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_3 },
{ PCI_DEVICE_NUMBER_PCH_PCIE_ROOT_PORTS, PCI_FUNCTION_NUMBER_PCH_PCIE_ROOT_PORT_4 },
{ PCI_DEVICE_NUMBER_PCH_USB, PCI_FUNCTION_NUMBER_PCH_EHCI }
};
UINT16 mAcpiBaseAddr;
SYSTEM_CONFIGURATION mSystemConfiguration;
EFI_SMM_VARIABLE_PROTOCOL *mSmmVariable;
EFI_GLOBAL_NVS_AREA_PROTOCOL *mGlobalNvsAreaPtr;
UINT16 mPM1_SaveState16;
UINT32 mGPE_SaveState32;
BOOLEAN mSetSmmVariableProtocolSmiAllowed = TRUE;
//
// Variables. Need to initialize this from Setup
//
BOOLEAN mWakeOnLanS5Variable;
BOOLEAN mWakeOnRtcVariable;
UINT8 mWakeupDay;
UINT8 mWakeupHour;
UINT8 mWakeupMinute;
UINT8 mWakeupSecond;
//
// Use an enum. 0 is Stay Off, 1 is Last State, 2 is Stay On
//
UINT8 mAcLossVariable;
static
UINT8 mTco1Sources[] = {
IchnNmi
};
UINTN
DevicePathSize (
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
);
VOID
S4S5ProgClock();
EFI_STATUS
InitRuntimeScriptTable (
IN EFI_SYSTEM_TABLE *SystemTable
);
VOID
S5SleepWakeOnRtcCallBack (
IN EFI_HANDLE DispatchHandle,
IN EFI_SMM_SX_DISPATCH_CONTEXT *DispatchContext
);
VOID
EnableS5WakeOnRtc();
UINT8
HexToBcd(
UINT8 HexValue
);
UINT8
BcdToHex(
IN UINT8 BcdValue
);
VOID
CpuSmmSxWorkAround(
);
/**
Initializes the SMM Handler Driver
@param ImageHandle
@param SystemTable
@retval None
**/
EFI_STATUS
EFIAPI
InitializePlatformSmm (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
UINT8 Index;
EFI_HANDLE Handle;
EFI_SMM_POWER_BUTTON_DISPATCH_CONTEXT PowerButtonContext;
EFI_SMM_POWER_BUTTON_DISPATCH_PROTOCOL *PowerButtonDispatch;
EFI_SMM_ICHN_DISPATCH_CONTEXT IchnContext;
EFI_SMM_ICHN_DISPATCH_PROTOCOL *IchnDispatch;
EFI_SMM_SX_DISPATCH_PROTOCOL *SxDispatch;
EFI_SMM_SX_DISPATCH_CONTEXT EntryDispatchContext;
EFI_SMM_SW_DISPATCH_PROTOCOL *SwDispatch;
EFI_SMM_SW_DISPATCH_CONTEXT SwContext;
UINTN VarSize;
EFI_BOOT_MODE BootMode;
Handle = NULL;
//
// Locate the Global NVS Protocol.
//
Status = gBS->LocateProtocol (
&gEfiGlobalNvsAreaProtocolGuid,
NULL,
(void **)&mGlobalNvsAreaPtr
);
ASSERT_EFI_ERROR (Status);
//
// Get the ACPI Base Address
//
mAcpiBaseAddr = PchLpcPciCfg16( R_PCH_LPC_ACPI_BASE ) & B_PCH_LPC_ACPI_BASE_BAR;
VarSize = sizeof(SYSTEM_CONFIGURATION);
Status = SystemTable->RuntimeServices->GetVariable(
L"Setup",
&gEfiSetupVariableGuid,
NULL,
&VarSize,
&mSystemConfiguration
);
if (!EFI_ERROR(Status)) {
mAcLossVariable = mSystemConfiguration.StateAfterG3;
//
// If LAN is disabled, WOL function should be disabled too.
//
if (mSystemConfiguration.Lan == 0x01){
mWakeOnLanS5Variable = mSystemConfiguration.WakeOnLanS5;
} else {
mWakeOnLanS5Variable = FALSE;
}
mWakeOnRtcVariable = mSystemConfiguration.WakeOnRtcS5;
}
BootMode = GetBootModeHob ();
//
// Get the Power Button protocol
//
Status = gBS->LocateProtocol(
&gEfiSmmPowerButtonDispatchProtocolGuid,
NULL,
(void **)&PowerButtonDispatch
);
ASSERT_EFI_ERROR(Status);
if (BootMode != BOOT_ON_FLASH_UPDATE) {
//
// Register for the power button event
//
PowerButtonContext.Phase = PowerButtonEntry;
Status = PowerButtonDispatch->Register(
PowerButtonDispatch,
PowerButtonCallback,
&PowerButtonContext,
&Handle
);
ASSERT_EFI_ERROR(Status);
}
//
// Get the Sx dispatch protocol
//
Status = gBS->LocateProtocol (
&gEfiSmmSxDispatchProtocolGuid,
NULL,
(void **)&SxDispatch
);
ASSERT_EFI_ERROR(Status);
//
// Register entry phase call back function
//
EntryDispatchContext.Type = SxS3;
EntryDispatchContext.Phase = SxEntry;
Status = SxDispatch->Register (
SxDispatch,
(EFI_SMM_SX_DISPATCH)SxSleepEntryCallBack,
&EntryDispatchContext,
&Handle
);
EntryDispatchContext.Type = SxS4;
Status = SxDispatch->Register (
SxDispatch,
S4S5CallBack,
&EntryDispatchContext,
&Handle
);
ASSERT_EFI_ERROR(Status);
EntryDispatchContext.Type = SxS5;
Status = SxDispatch->Register (
SxDispatch,
S4S5CallBack,
&EntryDispatchContext,
&Handle
);
ASSERT_EFI_ERROR(Status);
Status = SxDispatch->Register (
SxDispatch,
S5SleepAcLossCallBack,
&EntryDispatchContext,
&Handle
);
ASSERT_EFI_ERROR(Status);
//
// Get the Sw dispatch protocol
//
Status = gBS->LocateProtocol (
&gEfiSmmSwDispatchProtocolGuid,
NULL,
(void **)&SwDispatch
);
ASSERT_EFI_ERROR(Status);
//
// Register ACPI enable handler
//
SwContext.SwSmiInputValue = ACPI_ENABLE;
Status = SwDispatch->Register (
SwDispatch,
EnableAcpiCallback,
&SwContext,
&Handle
);
ASSERT_EFI_ERROR(Status);
//
// Register ACPI disable handler
//
SwContext.SwSmiInputValue = ACPI_DISABLE;
Status = SwDispatch->Register (
SwDispatch,
DisableAcpiCallback,
&SwContext,
&Handle
);
ASSERT_EFI_ERROR(Status);
//
// Register for SmmReadyToBootCallback
//
SwContext.SwSmiInputValue = SMI_SET_SMMVARIABLE_PROTOCOL;
Status = SwDispatch->Register(
SwDispatch,
SmmReadyToBootCallback,
&SwContext,
&Handle
);
ASSERT_EFI_ERROR(Status);
//
// Get the ICHn protocol
//
Status = gBS->LocateProtocol(
&gEfiSmmIchnDispatchProtocolGuid,
NULL,
(void **)&IchnDispatch
);
ASSERT_EFI_ERROR(Status);
//
// Register for the events that may happen that we do not care.
// This is true for SMI related to TCO since TCO is enabled by BIOS WP
//
for (Index = 0; Index < sizeof(mTco1Sources)/sizeof(UINT8); Index++) {
IchnContext.Type = mTco1Sources[Index];
Status = IchnDispatch->Register(
IchnDispatch,
(EFI_SMM_ICHN_DISPATCH)DummyTco1Callback,
&IchnContext,
&Handle
);
ASSERT_EFI_ERROR( Status );
}
//
// Lock TCO_EN bit.
//
IoWrite16( mAcpiBaseAddr + R_PCH_TCO_CNT, IoRead16( mAcpiBaseAddr + R_PCH_TCO_CNT ) | B_PCH_TCO_CNT_LOCK );
//
// Set to power on from G3 dependent on WOL instead of AC Loss variable in order to support WOL from G3 feature.
//
//
// Set wake from G3 dependent on AC Loss variable and Wake On LAN variable.
// This is because no matter how, if WOL enabled or AC Loss variable not disabled, the board needs to wake from G3 to program the LAN WOL settings.
// This needs to be done after LAN enable/disable so that the PWR_FLR state clear not impacted the WOL from G3 feature.
//
if (mAcLossVariable != 0x00) {
SetAfterG3On (TRUE);
} else {
SetAfterG3On (FALSE);
}
return EFI_SUCCESS;
}
VOID
EFIAPI
SmmReadyToBootCallback (
IN EFI_HANDLE DispatchHandle,
IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
)
{
EFI_STATUS Status;
if (mSetSmmVariableProtocolSmiAllowed)
{
//
// It is okay to use gBS->LocateProtocol here because
// we are still in trusted execution.
//
Status = gBS->LocateProtocol(
&gEfiSmmVariableProtocolGuid,
NULL,
(void **)&mSmmVariable
);
ASSERT_EFI_ERROR(Status);
//
// mSetSmmVariableProtocolSmiAllowed will prevent this function from
// being executed more than 1 time.
//
mSetSmmVariableProtocolSmiAllowed = FALSE;
}
}
/**
@param DispatchHandle The handle of this callback, obtained when registering
@param DispatchContext The predefined context which contained sleep type and phase
@retval EFI_SUCCESS Operation successfully performed
**/
EFI_STATUS
EFIAPI
SxSleepEntryCallBack (
IN EFI_HANDLE DispatchHandle,
IN EFI_SMM_SX_DISPATCH_CONTEXT *DispatchContext
)
{
EFI_STATUS Status;
Status = SaveRuntimeScriptTable ();
if (EFI_ERROR(Status)) {
return Status;
}
//
// Workaround for S3 wake hang if C State is enabled
//
CpuSmmSxWorkAround();
return EFI_SUCCESS;
}
VOID
CpuSmmSxWorkAround(
)
{
UINT64 MsrValue;
MsrValue = AsmReadMsr64 (0xE2);
if (MsrValue & BIT15) {
return;
}
if (MsrValue & BIT10) {
MsrValue &= ~BIT10;
AsmWriteMsr64 (0xE2, MsrValue);
}
}
VOID
ClearP2PBusMaster(
)
{
UINT8 Command;
UINT8 Index;
for (Index = 0; Index < sizeof(mPciBm)/sizeof(EFI_PCI_BUS_MASTER); Index++) {
Command = MmioRead8 (
MmPciAddress (0,
DEFAULT_PCI_BUS_NUMBER_PCH,
mPciBm[Index].Device,
mPciBm[Index].Function,
PCI_COMMAND_OFFSET
)
);
Command &= ~EFI_PCI_COMMAND_BUS_MASTER;
MmioWrite8 (
MmPciAddress (0,
DEFAULT_PCI_BUS_NUMBER_PCH,
mPciBm[Index].Device,
mPciBm[Index].Function,
PCI_COMMAND_OFFSET
),
Command
);
}
}
/**
Set the AC Loss to turn on or off.
**/
VOID
SetAfterG3On (
BOOLEAN Enable
)
{
UINT8 PmCon1;
//
// ICH handling portion
//
PmCon1 = MmioRead8 ( PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1 );
PmCon1 &= ~B_PCH_PMC_GEN_PMCON_AFTERG3_EN;
if (Enable) {
PmCon1 |= B_PCH_PMC_GEN_PMCON_AFTERG3_EN;
}
MmioWrite8 (PMC_BASE_ADDRESS + R_PCH_PMC_GEN_PMCON_1, PmCon1);
}
/**
When a power button event happens, it shuts off the machine
**/
VOID
EFIAPI
PowerButtonCallback (
IN EFI_HANDLE DispatchHandle,
IN EFI_SMM_POWER_BUTTON_DISPATCH_CONTEXT *DispatchContext
)
{
//
// Check what the state to return to after AC Loss. If Last State, then
// set it to Off.
//
UINT16 data16;
if (mWakeOnRtcVariable) {
EnableS5WakeOnRtc();
}
if (mAcLossVariable == 1) {
SetAfterG3On (TRUE);
}
ClearP2PBusMaster();
//
// Program clock chip
//
S4S5ProgClock();
data16 = (UINT16)(IoRead16(mAcpiBaseAddr + R_PCH_ACPI_GPE0a_EN));
data16 &= B_PCH_ACPI_GPE0a_EN_PCI_EXP;
//
// Clear Sleep SMI Status
//
IoWrite16 (mAcpiBaseAddr + R_PCH_SMI_STS,
(UINT16)(IoRead16 (mAcpiBaseAddr + R_PCH_SMI_STS) | B_PCH_SMI_STS_ON_SLP_EN));
//
// Clear Sleep Type Enable
//
IoWrite16 (mAcpiBaseAddr + R_PCH_SMI_EN,
(UINT16)(IoRead16 (mAcpiBaseAddr + R_PCH_SMI_EN) & (~B_PCH_SMI_EN_ON_SLP_EN)));
//
// Clear Power Button Status
//
IoWrite16(mAcpiBaseAddr + R_PCH_ACPI_PM1_STS, B_PCH_ACPI_PM1_STS_PWRBTN);
//
// Shut it off now!
//
IoWrite16(mAcpiBaseAddr + R_PCH_ACPI_PM1_CNT, V_PCH_ACPI_PM1_CNT_S5);
IoWrite16(mAcpiBaseAddr + R_PCH_ACPI_PM1_CNT, B_PCH_ACPI_PM1_CNT_SLP_EN | V_PCH_ACPI_PM1_CNT_S5);
//
// Should not return
//
CpuDeadLoop();
}
/**
@param DispatchHandle - The handle of this callback, obtained when registering
@param DispatchContext - The predefined context which contained sleep type and phase
**/
VOID
EFIAPI
S5SleepAcLossCallBack (
IN EFI_HANDLE DispatchHandle,
IN EFI_SMM_SX_DISPATCH_CONTEXT *DispatchContext
)
{
//
// Check what the state to return to after AC Loss. If Last State, then
// set it to Off.
//
if (mAcLossVariable == 1) {
SetAfterG3On (TRUE);
}
}
/**
@param DispatchHandle The handle of this callback, obtained when registering
@param DispatchContext The predefined context which contained sleep type and phase
@retval Clears the Save State bit in the clock.
**/
VOID
EFIAPI
S4S5CallBack (
IN EFI_HANDLE DispatchHandle,
IN EFI_SMM_SX_DISPATCH_CONTEXT *DispatchContext
)
{
UINT32 Data32;
//
// Enable/Disable USB Charging
//
if (mSystemConfiguration.UsbCharging == 0x01) {
Data32 = IoRead32 (GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_LVL);
Data32 |= BIT8;
IoWrite32(GPIO_BASE_ADDRESS + R_PCH_GPIO_SC_LVL, Data32);
}
}
VOID
S4S5ProgClock()
{
}
/**
SMI handler to enable ACPI mode
Dispatched on reads from APM port with value 0xA0
Disables the SW SMI Timer.
ACPI events are disabled and ACPI event status is cleared.
SCI mode is then enabled.
Disable SW SMI Timer
Clear all ACPI event status and disable all ACPI events
Disable PM sources except power button
Clear status bits
Disable GPE0 sources
Clear status bits
Disable GPE1 sources
Clear status bits
Guarantee day-of-month alarm is invalid (ACPI 5.0 Section 4.8.2.4 "Real Time Clock Alarm")
Enable SCI
@param DispatchHandle - EFI Handle
@param DispatchContext - Pointer to the EFI_SMM_SW_DISPATCH_CONTEXT
@retval Nothing
**/
VOID
EFIAPI
EnableAcpiCallback (
IN EFI_HANDLE DispatchHandle,
IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
)
{
UINT32 SmiEn;
UINT16 Pm1Cnt;
UINT16 wordValue;
UINT32 RegData32;
//
// Disable SW SMI Timer
//
SmiEn = IoRead32(mAcpiBaseAddr + R_PCH_SMI_EN);
SmiEn &= ~B_PCH_SMI_STS_SWSMI_TMR;
IoWrite32(mAcpiBaseAddr + R_PCH_SMI_EN, SmiEn);
wordValue = IoRead16(mAcpiBaseAddr + R_PCH_ACPI_PM1_STS);
if(wordValue & B_PCH_ACPI_PM1_STS_WAK) {
IoWrite32((mAcpiBaseAddr + R_PCH_ACPI_GPE0a_EN), 0x0000);
IoWrite32((mAcpiBaseAddr + R_PCH_ACPI_GPE0a_STS), 0xffffffff);
}
else {
mPM1_SaveState16 = IoRead16(mAcpiBaseAddr + R_PCH_ACPI_PM1_EN);
//
// Disable PM sources except power button
//
// power button is enabled only for PCAT. Disabled it on Tablet platform
//
IoWrite16(mAcpiBaseAddr + R_PCH_ACPI_PM1_EN, B_PCH_ACPI_PM1_EN_PWRBTN);
IoWrite16(mAcpiBaseAddr + R_PCH_ACPI_PM1_STS, 0xffff);
mGPE_SaveState32 = IoRead16(mAcpiBaseAddr + R_PCH_ACPI_GPE0a_EN);
IoWrite32(mAcpiBaseAddr + R_PCH_ACPI_GPE0a_EN, 0x0000);
IoWrite32(mAcpiBaseAddr + R_PCH_ACPI_GPE0a_STS, 0xffffffff);
}
//
// Guarantee day-of-month alarm is invalid (ACPI 5.0 Section 4.8.2.4 "Real Time Clock Alarm")
// Clear Status D reg VM bit, Date of month Alarm to make Data in CMOS RAM is no longer Valid
//
IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_D);
IoWrite8 (PCAT_RTC_DATA_REGISTER, 0x0);
RegData32 = IoRead32(ACPI_BASE_ADDRESS + R_PCH_ALT_GP_SMI_EN);
RegData32 &= ~(BIT7);
IoWrite32((ACPI_BASE_ADDRESS + R_PCH_ALT_GP_SMI_EN), RegData32);
//
// Enable SCI
//
Pm1Cnt = IoRead16(mAcpiBaseAddr + R_PCH_ACPI_PM1_CNT);
Pm1Cnt |= B_PCH_ACPI_PM1_CNT_SCI_EN;
IoWrite16(mAcpiBaseAddr + R_PCH_ACPI_PM1_CNT, Pm1Cnt);
}
/**
SMI handler to disable ACPI mode
Dispatched on reads from APM port with value 0xA1
ACPI events are disabled and ACPI event status is cleared.
SCI mode is then disabled.
Clear all ACPI event status and disable all ACPI events
Disable PM sources except power button
Clear status bits
Disable GPE0 sources
Clear status bits
Disable GPE1 sources
Clear status bits
Disable SCI
@param DispatchHandle - EFI Handle
@param DispatchContext - Pointer to the EFI_SMM_SW_DISPATCH_CONTEXT
@retval Nothing
**/
VOID
EFIAPI
DisableAcpiCallback (
IN EFI_HANDLE DispatchHandle,
IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
)
{
UINT16 Pm1Cnt;
IoWrite16(mAcpiBaseAddr + R_PCH_ACPI_PM1_STS, 0xffff);
IoWrite16(mAcpiBaseAddr + R_PCH_ACPI_PM1_EN, mPM1_SaveState16);
IoWrite32(mAcpiBaseAddr + R_PCH_ACPI_GPE0a_STS, 0xffffffff);
IoWrite32(mAcpiBaseAddr + R_PCH_ACPI_GPE0a_EN, mGPE_SaveState32);
//
// Disable SCI
//
Pm1Cnt = IoRead16(mAcpiBaseAddr + R_PCH_ACPI_PM1_CNT);
Pm1Cnt &= ~B_PCH_ACPI_PM1_CNT_SCI_EN;
IoWrite16(mAcpiBaseAddr + R_PCH_ACPI_PM1_CNT, Pm1Cnt);
}
/**
When an unknown event happen.
@retval None
**/
VOID
DummyTco1Callback (
IN EFI_HANDLE DispatchHandle,
IN EFI_SMM_ICHN_DISPATCH_CONTEXT *DispatchContext
)
{
}
UINTN
DevicePathSize (
IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
)
{
EFI_DEVICE_PATH_PROTOCOL *Start;
if (DevicePath == NULL) {
return 0;
}
//
// Search for the end of the device path structure
//
Start = DevicePath;
while (!IsDevicePathEnd (DevicePath)) {
DevicePath = NextDevicePathNode (DevicePath);
}
//
// Compute the size and add back in the size of the end device path structure
//
return ((UINTN)DevicePath - (UINTN)Start) + sizeof(EFI_DEVICE_PATH_PROTOCOL);
}
/**
@param DispatchHandle The handle of this callback, obtained when registering
@param DispatchContext The predefined context which contained sleep type and phase
**/
VOID
S5SleepWakeOnRtcCallBack (
IN EFI_HANDLE DispatchHandle,
IN EFI_SMM_SX_DISPATCH_CONTEXT *DispatchContext
)
{
EnableS5WakeOnRtc();
}
/**
@retval 1. Check Alarm interrupt is not set.
2. Clear Alarm interrupt.
2. Set RTC wake up date and time.
2. Enable RTC wake up alarm.
3. Enable ICH PM1 EN Bit 10(RTC_EN)
**/
VOID
EnableS5WakeOnRtc()
{
UINT8 CmosData;
UINTN i;
EFI_STATUS Status;
UINTN VarSize;
//
// make sure EFI_SMM_VARIABLE_PROTOCOL is available
//
if (!mSmmVariable) {
return;
}
VarSize = sizeof(SYSTEM_CONFIGURATION);
//
// read the variable into the buffer
//
Status = mSmmVariable->SmmGetVariable(
L"Setup",
&gEfiSetupVariableGuid,
NULL,
&VarSize,
&mSystemConfiguration
);
if (EFI_ERROR(Status) || (!mSystemConfiguration.WakeOnRtcS5)) {
return;
}
mWakeupDay = HexToBcd((UINT8)mSystemConfiguration.RTCWakeupDate);
mWakeupHour = HexToBcd((UINT8)mSystemConfiguration.RTCWakeupTimeHour);
mWakeupMinute = HexToBcd((UINT8)mSystemConfiguration.RTCWakeupTimeMinute);
mWakeupSecond = HexToBcd((UINT8)mSystemConfiguration.RTCWakeupTimeSecond);
//
// Check RTC alarm interrupt is enabled. If enabled, someone already
// grabbed RTC alarm. Just return.
//
IoWrite8(PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_B);
if(IoRead8(PCAT_RTC_DATA_REGISTER) & B_RTC_ALARM_INT_ENABLE){
return;
}
//
// Set Date
//
IoWrite8(PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_D);
CmosData = IoRead8(PCAT_RTC_DATA_REGISTER);
CmosData &= ~(B_RTC_DATE_ALARM_MASK);
CmosData |= mWakeupDay ;
for(i = 0 ; i < 0xffff ; i++){
IoWrite8(PCAT_RTC_DATA_REGISTER, CmosData);
SmmStall(1);
if(((CmosData = IoRead8(PCAT_RTC_DATA_REGISTER)) & B_RTC_DATE_ALARM_MASK)
== mWakeupDay){
break;
}
}
//
// Set Second
//
IoWrite8(PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_SECOND_ALARM);
for(i = 0 ; i < 0xffff ; i++){
IoWrite8(PCAT_RTC_DATA_REGISTER, mWakeupSecond);
SmmStall(1);
if(IoRead8(PCAT_RTC_DATA_REGISTER) == mWakeupSecond){
break;
}
}
//
// Set Minute
//
IoWrite8(PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_MINUTE_ALARM);
for(i = 0 ; i < 0xffff ; i++){
IoWrite8(PCAT_RTC_DATA_REGISTER, mWakeupMinute);
SmmStall(1);
if(IoRead8(PCAT_RTC_DATA_REGISTER) == mWakeupMinute){
break;
}
}
//
// Set Hour
//
IoWrite8(PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_HOUR_ALARM);
for(i = 0 ; i < 0xffff ; i++){
IoWrite8(PCAT_RTC_DATA_REGISTER, mWakeupHour);
SmmStall(1);
if(IoRead8(PCAT_RTC_DATA_REGISTER) == mWakeupHour){
break;
}
}
//
// Wait for UIP to arm RTC alarm
//
IoWrite8(PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_A);
while (IoRead8(PCAT_RTC_DATA_REGISTER) & 0x80);
//
// Read RTC register 0C to clear pending RTC interrupts
//
IoWrite8(PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_C);
IoRead8(PCAT_RTC_DATA_REGISTER);
//
// Enable RTC Alarm Interrupt
//
IoWrite8(PCAT_RTC_ADDRESS_REGISTER, RTC_ADDRESS_REGISTER_B);
IoWrite8(PCAT_RTC_DATA_REGISTER, IoRead8(PCAT_RTC_DATA_REGISTER) | B_RTC_ALARM_INT_ENABLE);
//
// Clear ICH RTC Status
//
IoWrite16(mAcpiBaseAddr + R_PCH_ACPI_PM1_STS, B_PCH_ACPI_PM1_STS_RTC);
//
// Enable ICH RTC event
//
IoWrite16(mAcpiBaseAddr + R_PCH_ACPI_PM1_EN,
(UINT16)(IoRead16(mAcpiBaseAddr + R_PCH_ACPI_PM1_EN) | B_PCH_ACPI_PM1_EN_RTC));
}
UINT8
HexToBcd(
IN UINT8 HexValue
)
{
UINTN HighByte;
UINTN LowByte;
HighByte = (UINTN)HexValue / 10;
LowByte = (UINTN)HexValue % 10;
return ((UINT8)(LowByte + (HighByte << 4)));
}
UINT8
BcdToHex(
IN UINT8 BcdValue
)
{

View File

@@ -0,0 +1,98 @@
#
#
# Copyright (c) 1999 - 2014, Intel Corporation. All rights reserved
#
# This program and the accompanying materials are licensed and made available under
# the terms and conditions of the BSD License that 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.
#
#
#
# Module Name:
#
# Platform.inf
#
# Abstract:
#
# Component description file for SMM Platform handler module
#
#--*/
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = PlatformSmm
FILE_GUID = 99C20A37-042A-46e2-80F4-E4027FDBC86F
MODULE_TYPE = DXE_SMM_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = InitializePlatformSmm
PI_SPECIFICATION_VERSION = 0x0001000A
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64
#
[Sources]
S3Save.c
Platform.c
[LibraryClasses]
UefiDriverEntryPoint
UefiBootServicesTableLib
DebugLib
IoLib
BaseLib
BaseMemoryLib
DevicePathLib
HobLib
S3BootScriptLib
StallSmmLib
PchPlatformLib
[Guids]
gEfiSetupVariableGuid
gDmiDataGuid
gEfiAcpiVariableCompatiblityGuid
gEfiPciLanInfoGuid
gEfiPciLanInfoGuid
[FeaturePcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSwitchToLongMode
[Protocols]
gEfiSmmBaseProtocolGuid
gEfiSmmIchnDispatchProtocolGuid
gEfiGlobalNvsAreaProtocolGuid
gEfiSmmSwDispatchProtocolGuid
gEfiSmmPowerButtonDispatchProtocolGuid
gEfiSmmSxDispatchProtocolGuid
gEfiSmmVariableProtocolGuid
gEfiCpuIo2ProtocolGuid
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
IntelFrameworkPkg/IntelFrameworkPkg.dec
Vlv2DeviceRefCodePkg/Vlv2DeviceRefCodePkg.dec
Vlv2TbltDevicePkg/PlatformPkg.dec
IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
[Pcd.common]
gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
[Depex]
gEfiSmmBaseProtocolGuid AND

View File

@@ -0,0 +1,382 @@
/** @file
Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available under
the terms and conditions of the BSD License that 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.
Module Name:
IchS3Save.c
Abstract:
SMM S3 handler Driver implementation file
Revision History
**/
#include "SmmPlatform.h"
extern UINT16 mAcpiBaseAddr;
EFI_PHYSICAL_ADDRESS mRuntimeScriptTableBase;
EFI_STATUS
InitRuntimeScriptTable (
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
UINT32 VarAttrib;
UINTN VarSize;
ACPI_VARIABLE_SET_COMPATIBILITY *AcpiVariableBase;
//
// Allocate runtime ACPI script table space. We need it to save some
// settings done by CSM, which runs after normal script table closed
//
Status = gBS->AllocatePages (
AllocateAnyPages,
EfiACPIReclaimMemory,
1,
&mRuntimeScriptTableBase
);
if (EFI_ERROR(Status)) {
return EFI_OUT_OF_RESOURCES ;
}
//
// Save runtime script table base into global ACPI variable
//
VarAttrib = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS
| EFI_VARIABLE_NON_VOLATILE;
VarSize = sizeof (UINTN);
Status = SystemTable->RuntimeServices->GetVariable (
ACPI_GLOBAL_VARIABLE,
&gEfiAcpiVariableCompatiblityGuid,
&VarAttrib,
&VarSize,
&AcpiVariableBase
);
if (EFI_ERROR(Status)) {
return Status;
}
AcpiVariableBase->RuntimeScriptTableBase = mRuntimeScriptTableBase;
return EFI_SUCCESS;
}
EFI_STATUS
SaveRuntimeScriptTable (
VOID
)
{
SMM_PCI_IO_ADDRESS PciAddress;
UINT32 Data32;
UINT16 Data16;
UINT8 Data8;
UINT8 Mask;
UINTN Index;
UINTN Offset;
UINT8 RegTable[] = {
//
//Bus , Dev, Func, DMI
//
0x00 , 0x00, 0x00,
//
//00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
//
0x00 , 0x08, 0x00, 0x00, 0x30, 0x00, 0x00, 0xa0,
//
//Bus , Dev, Func, LPC device
//
0x00 , 0x1F, 0x00,
//
//00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
//
0x00 , 0x08, 0x00, 0x07, 0x00, 0x00, 0x90, 0x00,
//
//Bus , Dev, Func, PCIE device
//
0x00 , 0x1C, 0x00,
//
//00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
//
0xC0 , 0x83, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
//
//Bus , Dev, Func, PCIE device
//
0x00 , 0x1C, 0x00,
//
//00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
//
0x03 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
//
//Bus , Dev, Func, SATA device
//
0x00 , 0x13, 0x00,
//
//00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
//
0xf4 , 0xab, 0x27, 0x10, 0xf1, 0x1d, 0x00, 0x40,
//
//Bus , Dev, Func, EHCI device
//
0x00 , 0x1D, 0x00,
//
//00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
//
0x10 , 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
//
//Bus , Dev, Func, SMBUS device
//
0x00 , 0x1f, 0x03,
//
//00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
//
0x10 , 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
//
//Bus , Dev, Func, SMBUS device
//
0x00 , 0x1f, 0x03,
//
//00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
//
0x02 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
//
//Bus , Dev, Func, VGA bus1
//
0x01 , 0x00, 0x00,
//
//00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
//
0x58 , 0x81, 0x18, 0x01, 0xb0, 0x00, 0x00, 0x00,
//
//Bus , Dev, Func, VGA bus1
//
0x01 , 0x00, 0x00,
//
//00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
//
0x02 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
//
//Bus , Dev, Func, VGA bus1 function 1
//
0x01 , 0x00, 0x01,
//
//00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
//
0x51 , 0x80, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00,
//
//Bus , Dev, Func, VGA bus1 function 1
//
0x01 , 0x00, 0x01,
//
//00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
//
0x02 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
//
//Bus , Dev, Func, IGD bus0 function 0
//
0x00 , 0x02, 0x00,
//
//00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
//
0x42 , 0x81, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00,
//
//Bus , Dev, Func, USB bus0 function 0
//
0x00 , 0x16, 0x00,
//
//00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
//
0x32 , 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
//
//Bus , Dev, Func, HD Audio bus0 function 0
//
0x00 , 0x1B, 0x00,
//
//00-1F, 20-3F, 40-5F, 60-7F, 80-9F, A0-BF, C0-DF, E0-FF
//
0x00 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
//
//0xFF indicates the end of the table
//
0xFF
};
//
// These registers have to set in byte order
//
UINT8 ExtReg[] = { 0x9E, 0x9D }; // SMRAM settings
//
// Save PCI-Host bridge settings (0, 0, 0). 0x90, 94 and 9c are changed by CSM
// and vital to S3 resume. That's why we put save code here
//
PciAddress.Bus = 0;
PciAddress.Device = 0;
PciAddress.Function = 0;
PciAddress.ExtendedRegister = 0;
for (Index = 0; Index < 2; Index++) {
//
// Read SRAM setting from Pci(0, 0, 0)
//
PciAddress.Register = ExtReg[Index];
Data8 = MmioRead8 (
MmPciAddress (0,
PciAddress.Bus,
PciAddress.Device,
PciAddress.Function,
PciAddress.Register
)
);
//
// Save latest settings to runtime script table
//
S3BootScriptSavePciCfgWrite(
S3BootScriptWidthUint8,
*(UINT64*)&PciAddress,
1,
&Data8
);
}
//
// Save PCI-Host bridge settings (0, 0, 0). 0x90, 94 and 9c are changed by CSM
// and vital to S3 resume. That's why we put save code here
//
Index = 0;
while (RegTable[Index] != 0xFF) {
PciAddress.Bus = RegTable[Index++];
PciAddress.Device = RegTable[Index++];
PciAddress.Function = RegTable[Index++];
PciAddress.Register = 0;
PciAddress.ExtendedRegister = 0;
Data16 = MmioRead16 (
MmPciAddress (0,
PciAddress.Bus,
PciAddress.Device,
PciAddress.Function,
PciAddress.Register
)
);
if (Data16 == 0xFFFF) {
Index+=8;
continue;
}
for (Offset = 0, Mask = 0x01; Offset < 256; Offset+=4, Mask<<=1) {
if (Mask == 0x00) {
Mask = 0x01;
}
if (RegTable[Index + Offset/32] & Mask ) {
PciAddress.Register = (UINT8)Offset;
Data32 = MmioRead32 (MmPciAddress (0, PciAddress.Bus, PciAddress.Device, PciAddress.Function, PciAddress.Register));
//
// Save latest settings to runtime script table
//
S3BootScriptSavePciCfgWrite (
S3BootScriptWidthUint32,
*(UINT64*)&PciAddress,
1,
&Data32
);
}
}
Index += 8;
}
//
// Save I/O ports to S3 script table
//
//
// Selftest KBC
//
Data8 = 0xAA;
S3BootScriptSaveIoWrite (
S3BootScriptWidthUint8,
0x64,
(UINTN)1,
&Data8
);
Data32 = IoRead32(mAcpiBaseAddr + R_PCH_SMI_EN);
S3BootScriptSaveIoWrite (
S3BootScriptWidthUint32,
(mAcpiBaseAddr + R_PCH_SMI_EN),
1,
&Data32
);
//
// Save B_ICH_TCO_CNT_LOCK so it will be done on S3 resume path.
//
Data16 = IoRead16(mAcpiBaseAddr + R_PCH_TCO_CNT);
S3BootScriptSaveIoWrite (

View File

@@ -0,0 +1,245 @@
/*++
Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available under
the terms and conditions of the BSD License that 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.
Module Name:
SmmPlatform.h
Abstract:
Header file for
++*/
#ifndef _PLATFORM_H
#define _PLATFORM_H
#include <PiSmm.h>
#include <Protocol/SmmBase.h>
#include <Protocol/FirmwareVolume.h>
#include <Protocol/SmmPowerButtonDispatch.h>
#include <Protocol/SmmSxDispatch.h>
#include <Protocol/SmmSwDispatch.h>
#include <Protocol/SmmSwDispatch2.h>
#include <Protocol/SmmIchnDispatch.h>
#include <Protocol/SmmAccess.h>
#include <Protocol/SmmVariable.h>
#include <Protocol/PciRootBridgeIo.h>
#include <Protocol/LoadedImage.h>
#include "Protocol/GlobalNvsArea.h"
#include <Guid/AcpiVariableCompatibility.h>
#include <Guid/SetupVariable.h>
#include <Guid/EfiVpdData.h>
#include <Guid/PciLanInfo.h>
#include <IndustryStandard/Pci22.h>
#include "PchAccess.h"
#include "PlatformBaseAddresses.h"
#include <Library/UefiBootServicesTableLib.h>
#include <Library/S3BootScriptLib.h>
#include <Library/IoLib.h>
#include <Library/DebugLib.h>
#include <Library/HobLib.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DevicePathLib.h>
#include <Library/PcdLib.h>
#include <Library/PchPlatformLib.h>
#include <Library/StallSmmLib.h>
typedef struct {
UINT8 Register;
UINT8 Function;
UINT8 Device;
UINT8 Bus;
UINT32 ExtendedRegister;
} SMM_PCI_IO_ADDRESS;
typedef struct {
CHAR8 BoardAaNumber[7];
UINTN BoardFabNumber;
} BOARD_AA_NUMBER_DECODE;
//
// BugBug -- Need to get these two values from acpi.h, but right now, they are
// declared in platform-specific variants of this file, so no easy
// way to pick-up the include file and work across platforms.
// Need these definitions to go into a file like common\acpi.h.
//
#define ACPI_ENABLE 0xA0
#define ACPI_DISABLE 0xA1
#define APM_12_FUNCS 0x50
#define SMI_SET_SMMVARIABLE_PROTOCOL 0x51 // this is used in Cpu\Pentium\Smm\Base\SmmBase.c
#define SMI_CMD_GET_MSEG_STATUS 0x70
#define SMI_CMD_UPDATE_MSEG_SIZE 0x71
#define SMI_CMD_LOAD_STM 0x72
#define SMI_CMD_UNLOAD_STM 0x73
#define SMI_CMD_GET_SMRAM_RANGES 0x74
#define PCAT_RTC_ADDRESS_REGISTER 0x74
#define PCAT_RTC_DATA_REGISTER 0x75
#define RTC_ADDRESS_SECOND 0x00
#define RTC_ADDRESS_SECOND_ALARM 0x01
#define RTC_ADDRESS_MINUTE 0x02
#define RTC_ADDRESS_MINUTE_ALARM 0x03
#define RTC_ADDRESS_HOUR 0x04
#define RTC_ADDRESS_HOUR_ALARM 0x05
#define RTC_ADDRESS_REGISTER_A 0x0A
#define RTC_ADDRESS_REGISTER_B 0x0B
#define RTC_ADDRESS_REGISTER_C 0x0C
#define RTC_ADDRESS_REGISTER_D 0x0D
#define B_RTC_ALARM_INT_ENABLE 0x20
#define B_RTC_ALARM_INT_STATUS 0x20
#define B_RTC_DATE_ALARM_MASK 0x3F
#define PCAT_CMOS_2_ADDRESS_REGISTER 0x72
#define PCAT_CMOS_2_DATA_REGISTER 0x73
#define EC_C_PORT 0x66
#define SMC_SMI_DISABLE 0xBC
#define SMC_ENABLE_ACPI_MODE 0xAA // Enable ACPI mode
#define IO_MISC 156
#define MAXIMUM_NUMBER_OF_PSTATES 12
#define ICH_SMM_DATA_PORT 0xB3
#define EFI_IA32_PMG_CST_CONFIG 0x000000E2
#define B_EFI_CST_CONTROL_LOCK BIT15
#define B_EFI_IO_MWAIT_REDIRECTION_ENABLE BIT10
#define EFI_IA32_PMG_IO_CAPTURE_ADDR 0x000000E4
extern EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *mPciRootBridgeIo;
//
// Callback function prototypes
//
VOID
EFIAPI
PowerButtonCallback (
IN EFI_HANDLE DispatchHandle,
IN EFI_SMM_POWER_BUTTON_DISPATCH_CONTEXT *DispatchContext
);
VOID
S5SleepWakeOnLanCallBack (
IN EFI_HANDLE DispatchHandle,
IN EFI_SMM_SX_DISPATCH_CONTEXT *DispatchContext
);
VOID
EFIAPI
S5SleepAcLossCallBack (
IN EFI_HANDLE DispatchHandle,
IN EFI_SMM_SX_DISPATCH_CONTEXT *DispatchContext
);
VOID
EFIAPI
S4S5CallBack (
IN EFI_HANDLE DispatchHandle,
IN EFI_SMM_SX_DISPATCH_CONTEXT *DispatchContext
);
VOID
EFIAPI
EnableAcpiCallback (
IN EFI_HANDLE DispatchHandle,
IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
);
VOID
EFIAPI
DisableAcpiCallback (
IN EFI_HANDLE DispatchHandle,
IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
);
VOID
EFIAPI
SmmReadyToBootCallback (
IN EFI_HANDLE DispatchHandle,
IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
);
VOID
DummyTco1Callback (
IN EFI_HANDLE DispatchHandle,
IN EFI_SMM_ICHN_DISPATCH_CONTEXT *DispatchContext
);
VOID
PerrSerrCallback (
IN EFI_HANDLE DispatchHandle,
IN EFI_SMM_ICHN_DISPATCH_CONTEXT *DispatchContext
);
VOID
RiCallback (
IN EFI_HANDLE DispatchHandle,
IN EFI_SMM_ICHN_DISPATCH_CONTEXT *DispatchContext
);
VOID
SetAfterG3On (
BOOLEAN Enable
);
VOID
TurnOffVregUsb (
);
VOID
PStateSupportCallback (
IN EFI_HANDLE DispatchHandle,
IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
);
VOID
PStateTransitionCallback (
IN EFI_HANDLE DispatchHandle,
IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
);
EFI_STATUS
EFIAPI
SxSleepEntryCallBack (
IN EFI_HANDLE DispatchHandle,
IN EFI_SMM_SX_DISPATCH_CONTEXT *DispatchContext
);

View File

@@ -0,0 +1,257 @@
/** @file
Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available under
the terms and conditions of the BSD License that 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.
Module Name:
SmmScriptSave.c
Abstract:
ScriptTableSave module at run time
--*/
#include "SmmScriptSave.h"
//
// internal functions
//
EFI_STATUS
BootScriptIoWrite (
IN EFI_SMM_SCRIPT_TABLE *ScriptTable,
IN VA_LIST Marker
);
EFI_STATUS
BootScriptPciCfgWrite (
IN EFI_SMM_SCRIPT_TABLE *ScriptTable,
IN VA_LIST Marker
);
VOID
SmmCopyMem (
IN UINT8 *Destination,
IN UINT8 *Source,
IN UINTN ByteCount
);
//
// Function implementations
//
EFI_STATUS
SmmBootScriptWrite (
IN OUT EFI_SMM_SCRIPT_TABLE *ScriptTable,
IN UINTN Type,
IN UINT16 OpCode,
...
)
{
EFI_STATUS Status;
VA_LIST Marker;
if (ScriptTable == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Build script according to opcode
//
switch ( OpCode ) {
case EFI_BOOT_SCRIPT_IO_WRITE_OPCODE:
VA_START(Marker, OpCode);
Status = BootScriptIoWrite (ScriptTable, Marker);
VA_END(Marker);
break;
case EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE:
VA_START(Marker, OpCode);
Status = BootScriptPciCfgWrite(ScriptTable, Marker);
VA_END(Marker);
break;
default:
Status = EFI_SUCCESS;
break;
}
return Status;
}
EFI_STATUS
SmmBootScriptCreateTable (
IN OUT EFI_SMM_SCRIPT_TABLE *ScriptTable,
IN UINTN Type
)
{
BOOT_SCRIPT_POINTERS Script;
UINT8 *Buffer;
if (ScriptTable == NULL) {
return EFI_INVALID_PARAMETER;
}
Buffer = (UINT8*) ((UINTN)(*ScriptTable));
//
// Fill Table Header
//
Script.Raw = Buffer;
Script.TableInfo->OpCode = EFI_BOOT_SCRIPT_TABLE_OPCODE;
Script.TableInfo->Length = sizeof(EFI_BOOT_SCRIPT_TABLE_HEADER);
Script.TableInfo->TableLength = sizeof(EFI_BOOT_SCRIPT_TABLE_HEADER);
//
// Update current table pointer
//
*ScriptTable = *ScriptTable + sizeof(EFI_BOOT_SCRIPT_TABLE_HEADER);
return EFI_SUCCESS;
}
EFI_STATUS
SmmBootScriptCloseTable (
IN EFI_SMM_SCRIPT_TABLE ScriptTableBase,
IN EFI_SMM_SCRIPT_TABLE ScriptTablePtr,
IN UINTN Type
)
{
BOOT_SCRIPT_POINTERS Script;
//
// Add final "termination" node to script table
//
Script.Raw = (UINT8*) ((UINTN)ScriptTablePtr);
Script.Terminate->OpCode = EFI_BOOT_SCRIPT_TERMINATE_OPCODE;
Script.Terminate->Length = sizeof (EFI_BOOT_SCRIPT_TERMINATE);
ScriptTablePtr += sizeof (EFI_BOOT_SCRIPT_TERMINATE);
//
// Update Table Header
//
Script.Raw = (UINT8*) ((UINTN)ScriptTableBase);
Script.TableInfo->OpCode = EFI_BOOT_SCRIPT_TABLE_OPCODE;
Script.TableInfo->Length = sizeof (EFI_BOOT_SCRIPT_TABLE_HEADER);
Script.TableInfo->TableLength = (UINT32)(ScriptTablePtr - ScriptTableBase);
return EFI_SUCCESS;
}
EFI_STATUS
BootScriptIoWrite (
IN EFI_SMM_SCRIPT_TABLE *ScriptTable,
IN VA_LIST Marker
)
{
BOOT_SCRIPT_POINTERS Script;
EFI_BOOT_SCRIPT_WIDTH Width;
UINTN Address;
UINTN Count;
UINT8 *Buffer;
UINTN NodeLength;
UINT8 WidthInByte;
Width = VA_ARG(Marker, EFI_BOOT_SCRIPT_WIDTH);
Address = VA_ARG(Marker, UINTN);
Count = VA_ARG(Marker, UINTN);
Buffer = VA_ARG(Marker, UINT8*);
WidthInByte = (UINT8)(0x01 << (Width & 0x03));
Script.Raw = (UINT8*) ((UINTN)(*ScriptTable));
NodeLength = sizeof (EFI_BOOT_SCRIPT_IO_WRITE) + (WidthInByte * Count);
//
// Build script data
//
Script.IoWrite->OpCode = EFI_BOOT_SCRIPT_IO_WRITE_OPCODE;
Script.IoWrite->Length = (UINT8)(NodeLength);
Script.IoWrite->Width = Width;
Script.IoWrite->Address = Address;
Script.IoWrite->Count = (UINT32)Count;
SmmCopyMem (
(UINT8*)(Script.Raw + sizeof (EFI_BOOT_SCRIPT_IO_WRITE)),
Buffer,
WidthInByte * Count
);
//
// Update Script table pointer
//
*ScriptTable = *ScriptTable + NodeLength;
return EFI_SUCCESS;
}
EFI_STATUS
BootScriptPciCfgWrite (
IN EFI_SMM_SCRIPT_TABLE *ScriptTable,
IN VA_LIST Marker
)
{
BOOT_SCRIPT_POINTERS Script;
EFI_BOOT_SCRIPT_WIDTH Width;
UINT64 Address;
UINTN Count;
UINT8 *Buffer;
UINTN NodeLength;
UINT8 WidthInByte;
Width = VA_ARG(Marker, EFI_BOOT_SCRIPT_WIDTH);
Address = VA_ARG(Marker, UINT64);
Count = VA_ARG(Marker, UINTN);
Buffer = VA_ARG(Marker, UINT8*);
WidthInByte = (UINT8)(0x01 << (Width & 0x03));
Script.Raw = (UINT8*) ((UINTN)(*ScriptTable));
NodeLength = sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE) + (WidthInByte * Count);
//
// Build script data
//
Script.PciWrite->OpCode = EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE;
Script.PciWrite->Length = (UINT8)(NodeLength);
Script.PciWrite->Width = Width;
Script.PciWrite->Address = Address;
Script.PciWrite->Count = (UINT32)Count;
SmmCopyMem (
(UINT8*)(Script.Raw + sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE)),
Buffer,
WidthInByte * Count
);
//
// Update Script table pointer
//
*ScriptTable = *ScriptTable + NodeLength;
return EFI_SUCCESS;
}
VOID
SmmCopyMem (
IN UINT8 *Destination,
IN UINT8 *Source,

View File

@@ -0,0 +1,55 @@
/*++
Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available under
the terms and conditions of the BSD License that 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.
Module Name:
SmmScriptSave.h
Abstract:
This is an implementation of the BootScript at run time.
--*/
#ifndef _RUNTIME_SCRIPT_SAVE_H
#define _RUNTIME_SCRIPT_SAVE_H
#include "Efi.h"
#include "EfiBootScript.h"
typedef EFI_PHYSICAL_ADDRESS EFI_SMM_SCRIPT_TABLE;
EFI_STATUS
SmmBootScriptCreateTable (
IN OUT EFI_SMM_SCRIPT_TABLE *ScriptTable,
IN UINTN Type
);
EFI_STATUS
SmmBootScriptWrite (
IN OUT EFI_SMM_SCRIPT_TABLE *ScriptTable,
IN UINTN Type,
IN UINT16 OpCode,
...
);