summaryrefslogtreecommitdiff
path: root/Platform/BroxtonPlatformPkg
diff options
context:
space:
mode:
Diffstat (limited to 'Platform/BroxtonPlatformPkg')
-rw-r--r--Platform/BroxtonPlatformPkg/Common/PlatformSmm/Platform.c1074
-rw-r--r--Platform/BroxtonPlatformPkg/Common/PlatformSmm/PlatformSmm.inf95
-rw-r--r--Platform/BroxtonPlatformPkg/Common/PlatformSmm/S3Save.c82
-rw-r--r--Platform/BroxtonPlatformPkg/Common/PlatformSmm/SmmPlatform.h223
4 files changed, 1474 insertions, 0 deletions
diff --git a/Platform/BroxtonPlatformPkg/Common/PlatformSmm/Platform.c b/Platform/BroxtonPlatformPkg/Common/PlatformSmm/Platform.c
new file mode 100644
index 0000000000..673df3aedd
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/PlatformSmm/Platform.c
@@ -0,0 +1,1074 @@
+/** @file
+ This is a generic template for a child of the IchSmm driver.
+
+ Copyright (c) 1999 - 2016, 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
+ 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 "SmmPlatform.h"
+#include <Library/SideBandLib.h>
+#include <Library/ReportStatusCodeLib.h>
+#define PROGRESS_CODE_S3_SUSPEND_START _gPcd_FixedAtBuild_PcdProgressCodeS3SuspendStart
+
+#define NMI_REG_OFFSET 0x3330
+#define NMI_NOW BIT0
+#define NMI2SMI_EN BIT2
+
+
+//
+// Local variables
+//
+typedef struct {
+ UINT8 Device;
+ UINT8 Function;
+} EFI_PCI_BUS_MASTER;
+
+EFI_PCI_BUS_MASTER mPciBm[] = {
+ { PCI_DEVICE_NUMBER_SC_PCIE_DEVICE_1, PCI_FUNCTION_NUMBER_PCIE_ROOT_PORT_1 },
+};
+
+
+BOARD_AA_NUMBER_DECODE DefectiveBoardIdTable [] = {
+ {"E76523", 302}, //BLKD510MO
+ {"E76525", 301}, //LAD510MO
+ {"E67982", 303} //LAD510MOV
+};
+UINTN DefectiveBoardIdTableSize = sizeof (DefectiveBoardIdTable) / sizeof (BOARD_AA_NUMBER_DECODE);
+
+EFI_SMM_SYSTEM_TABLE2 *mSmst;
+UINT16 mAcpiBaseAddr;
+SYSTEM_CONFIGURATION mSystemConfiguration;
+EFI_SMM_VARIABLE_PROTOCOL *mSmmVariable;
+EFI_GLOBAL_NVS_AREA_PROTOCOL *mGlobalNvsAreaPtr;
+BOOLEAN mSetSmmVariableProtocolSmiAllowed = TRUE;
+
+//
+// Variables. Need to initialize this from Setup
+//
+BOOLEAN mWakeOnLanS5Variable;
+BOOLEAN mWakeOnRtcVariable;
+BOOLEAN mWakeOnLanVariable;
+UINT8 mWakeupDay;
+UINT8 mWakeupHour;
+UINT8 mWakeupMinute;
+UINT8 mWakeupSecond;
+UINT8 mDeepStandby=0;
+
+//
+// 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
+ );
+
+EFI_STATUS
+S5SleepWakeOnRtcCallBack (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN UINTN *CommBufferSize OPTIONAL
+ );
+
+
+VOID
+EnableS5WakeOnRtc ();
+
+EFI_STATUS
+Stall (
+ IN UINTN Microseconds
+ );
+
+UINT8
+HexToBcd(
+ UINT8 HexValue
+ );
+
+UINT8
+BcdToHex(
+ IN UINT8 BcdValue
+ );
+
+EFI_STATUS
+EfiSmmGetTime (
+ IN OUT EFI_TIME *Time
+ );
+
+VOID
+CpuSmmSxWorkAround(
+ );
+
+
+/**
+ Initializes the SMM Handler Driver
+
+ @param[in] ImageHandle A handle for the image that is initializing this driver.
+ @param[in] SystemTable A pointer to the EFI system table.
+
+ @retval None
+
+**/
+EFI_STATUS
+InitializePlatformSmm (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ UINT8 Index;
+ EFI_HANDLE Handle;
+ EFI_SMM_POWER_BUTTON_REGISTER_CONTEXT PowerButtonContext;
+ EFI_SMM_ICHN_DISPATCH_CONTEXT IchnContext;
+ EFI_SMM_POWER_BUTTON_DISPATCH2_PROTOCOL *PowerButtonDispatch;
+ EFI_SMM_ICHN_DISPATCH_PROTOCOL *IchnDispatch;
+ EFI_SMM_SX_DISPATCH2_PROTOCOL *SxDispatch;
+ EFI_SMM_SX_REGISTER_CONTEXT EntryDispatchContext;
+ EFI_SMM_SW_DISPATCH2_PROTOCOL *SwDispatch;
+ EFI_SMM_SW_REGISTER_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);
+
+ //
+ // Initialize global variables
+ //
+ mSmst = gSmst;
+
+ //
+ // Get the ACPI Base Address
+ //
+ mAcpiBaseAddr = (UINT16) PcdGet16 (PcdScAcpiIoPortBaseAddress);
+
+ VarSize = sizeof (SYSTEM_CONFIGURATION);
+ Status = gRT->GetVariable (
+ L"Setup",
+ &gEfiSetupVariableGuid,
+ NULL,
+ &VarSize,
+ &mSystemConfiguration
+ );
+
+ if (!EFI_ERROR (Status)) {
+ mAcLossVariable = mSystemConfiguration.StateAfterG3;
+ mDeepStandby = mSystemConfiguration.DeepStandby;
+
+ //
+ // If LAN is disabled, WOL function should be disabled too.
+ //
+ if (mSystemConfiguration.Lan == 0x01) {
+ mWakeOnLanS5Variable = mSystemConfiguration.WakeOnLanS5;
+ } else {
+ mWakeOnLanS5Variable = FALSE;
+ }
+
+ mWakeOnLanVariable = mSystemConfiguration.Wol;
+ mWakeOnRtcVariable = mSystemConfiguration.WakeOnRtcS5;
+ }
+
+ BootMode = GetBootModeHob ();
+
+ //
+ // Get the Power Button protocol
+ //
+ Status = gSmst->SmmLocateProtocol (
+ &gEfiSmmPowerButtonDispatch2ProtocolGuid,
+ NULL,
+ (VOID **) &PowerButtonDispatch
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ if (BootMode != BOOT_ON_FLASH_UPDATE) {
+ //
+ // Register for the power button event
+ //
+ PowerButtonContext.Phase = EfiPowerButtonEntry;
+ Status = PowerButtonDispatch->Register(
+ PowerButtonDispatch,
+ PowerButtonCallback,
+ &PowerButtonContext,
+ &Handle
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ //
+ // Get the Sx dispatch protocol
+ //
+ Status = gSmst->SmmLocateProtocol (
+ &gEfiSmmSxDispatch2ProtocolGuid,
+ NULL,
+ (VOID **) &SxDispatch
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Register entry phase call back function
+ //
+ EntryDispatchContext.Type = SxS3;
+ EntryDispatchContext.Phase = SxEntry;
+
+ Status = SxDispatch->Register (
+ SxDispatch,
+ 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 = gSmst->SmmLocateProtocol (
+ &gEfiSmmSwDispatch2ProtocolGuid,
+ 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 the TPM PTS & SMBS Handler
+ //
+ SwContext.SwSmiInputValue = 0x5A;
+
+ Status = SwDispatch->Register (
+ SwDispatch,
+ TpmPtsSmbsCallback,
+ &SwContext,
+ &Handle
+ );
+
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Get the ICHn protocol
+ //
+ Status = gSmst->SmmLocateProtocol (
+ &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,
+ DummyTco1Callback,
+ &IchnContext,
+ &Handle
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ //
+ // Lock TCO_EN bit.
+ //
+ IoWrite16 (mAcpiBaseAddr + R_TCO_CNT, IoRead16 (mAcpiBaseAddr + R_TCO_CNT) | B_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
+StallInternalFunction(
+ IN UINTN Microseconds
+ )
+{
+ UINTN Ticks;
+ UINTN Counts;
+ UINT32 CurrentTick;
+ UINT32 OriginalTick;
+ UINT64 RemainingTick;
+
+ OriginalTick = IoRead32 (mAcpiBaseAddr + R_ACPI_PM1_TMR);
+
+ CurrentTick = OriginalTick;
+
+ //
+ //The timer frequency is 3.579545 MHz, so 1 ms corresponds 3.58 clocks
+ //
+ Ticks = Microseconds * 358 / 100 + OriginalTick + 1;
+ Counts = Ticks / V_ACPI_PM1_TMR_MAX_VAL; //The loops needed by timer overflow
+ RemainingTick = Ticks % V_ACPI_PM1_TMR_MAX_VAL; //remaining clocks within one loop
+
+ //
+ //not intend to use TMROF_STS bit of register PM1_STS, because this adds extra
+ //one I/O operation, and maybe generate SMI
+ //
+
+ while (Counts != 0) {
+ CurrentTick = IoRead32 (mAcpiBaseAddr + R_ACPI_PM1_TMR);
+ if (CurrentTick <= OriginalTick) {
+ Counts --;
+ }
+ OriginalTick = CurrentTick;
+ }
+
+ while ((RemainingTick > CurrentTick) && (OriginalTick <= CurrentTick) ) {
+ OriginalTick = CurrentTick;
+ CurrentTick = IoRead32(mAcpiBaseAddr + R_ACPI_PM1_TMR);
+ }
+}
+
+
+/**
+ Waits for at least the given number of microseconds.
+
+ @param[in] Microseconds Desired length of time to wait
+
+ @retval EFI_SUCCESS If the desired amount of time passed.
+
+**/
+EFI_STATUS
+Stall (
+ IN UINTN Microseconds
+ )
+{
+ if (Microseconds == 0) {
+ return EFI_SUCCESS;
+ }
+
+ StallInternalFunction (Microseconds);
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+SmmReadyToBootCallback (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN UINTN *CommBufferSize OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+
+ if (mSetSmmVariableProtocolSmiAllowed) {
+ //
+ // It is okay to use gBS->LocateProtocol here because
+ // we are still in trusted execution.
+ //
+ Status = gSmst->SmmLocateProtocol(
+ &gEfiSmmVariableProtocolGuid,
+ NULL,
+ (VOID **) &mSmmVariable
+ );
+
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // mSetSmmVariableProtocolSmiAllowed will prevent this function from
+ // being executed more than 1 time.
+ //
+ mSetSmmVariableProtocolSmiAllowed = FALSE;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ The CallBack function of SxSleep Entry.
+
+ @param[in] DispatchHandle The handle of this callback, obtained when registering
+ @param[in] DispatchContext The predefined context which contained sleep type and phase
+
+ @retval EFI_SUCCESS Operation successfully performed
+
+**/
+EFI_STATUS
+SxSleepEntryCallBack (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN UINTN *CommBufferSize OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Data32;
+
+ REPORT_STATUS_CODE (EFI_PROGRESS_CODE, PROGRESS_CODE_S3_SUSPEND_START);
+
+ Status = SaveRuntimeScriptTable (mSmst);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Set GPIO_35 to low
+ //
+ Data32 = MmioRead32 (PcdGet32 (PcdP2SBBaseAddress) + N_GPIO_35);
+ Data32 = Data32 & ~(0x0100);
+ Data32 = Data32 & ~(0x1);
+ MmioWrite32 (PcdGet32 (PcdP2SBBaseAddress) + N_GPIO_35, Data32);
+
+ //
+ // Enable GPIO TIER1 SCI EN bit for LID wake function.
+ //
+ IoOr32 (mAcpiBaseAddr + R_ACPI_GPE0a_EN, B_ACPI_GPE0a_EN_GPIO_TIER1_SCI_EN);
+
+ //
+ // Enable PCIE WAKE EN bit if WOL feature is enabled
+ //
+
+ if (mWakeOnLanVariable) {
+ IoOr32 (mAcpiBaseAddr + R_ACPI_GPE0a_EN, B_ACPI_GPE0a_EN_PCIE_WAKE0_EN);
+ IoOr32 (mAcpiBaseAddr + R_ACPI_GPE0a_EN, B_ACPI_GPE0a_EN_PCIE_WAKE1_EN);
+ IoOr32 (mAcpiBaseAddr + R_ACPI_GPE0a_EN, B_ACPI_GPE0a_EN_PCIE_WAKE2_EN);
+ }
+
+ //
+ // Workaround for S3 wake hang if C State is enabled
+ //
+ CpuSmmSxWorkAround ();
+
+ return EFI_SUCCESS;
+}
+
+
+VOID
+CpuSmmSxWorkAround(
+ )
+{
+ UINT64 MsrValue;
+
+ MsrValue = AsmReadMsr64 (EFI_MSR_PMG_CST_CONFIG);
+
+ if (MsrValue & B_EFI_MSR_PMG_CST_CONFIG_CST_CONTROL_LOCK) {
+ //
+ // Cannot do anything if the register is locked.
+ //
+ return;
+ }
+
+ if (MsrValue & B_EFI_MSR_PMG_CST_CONFIG_IO_MWAIT_REDIRECTION_ENABLE) {
+ //
+ // If C State enabled, disable it before going into S3
+ // The MSR will be restored back during S3 wake
+ //
+ MsrValue &= ~B_EFI_MSR_PMG_CST_CONFIG_IO_MWAIT_REDIRECTION_ENABLE;
+ AsmWriteMsr64 (EFI_MSR_PMG_CST_CONFIG, 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_SC,
+ mPciBm[Index].Device,
+ mPciBm[Index].Function,
+ PCI_COMMAND_OFFSET
+ )
+ );
+ Command &= ~EFI_PCI_COMMAND_BUS_MASTER;
+ MmioWrite8 (
+ MmPciAddress (0,
+ DEFAULT_PCI_BUS_NUMBER_SC,
+ mPciBm[Index].Device,
+ mPciBm[Index].Function,
+ PCI_COMMAND_OFFSET
+ ),
+ Command
+ );
+ }
+}
+
+
+/**
+ Set the AC Loss to turn on or off.
+
+ @retval None
+
+**/
+VOID
+SetAfterG3On (
+ BOOLEAN Enable
+ )
+{
+ UINT8 PmCon1;
+
+ //
+ // SC handling portion
+ //
+ PmCon1 = MmioRead8 (PMC_BASE_ADDRESS + R_PMC_GEN_PMCON_1);
+ PmCon1 &= ~B_PMC_GEN_PMCON_AFTERG3_EN;
+
+ if (Enable) {
+ PmCon1 |= B_PMC_GEN_PMCON_AFTERG3_EN;
+ }
+
+ MmioWrite8 (PMC_BASE_ADDRESS + R_PMC_GEN_PMCON_1, PmCon1);
+}
+
+
+/**
+ When a power button event happens, it shuts off the machine
+
+ @retval None
+
+**/
+EFI_STATUS
+PowerButtonCallback (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN UINTN *CommBufferSize OPTIONAL
+ )
+{
+ //
+ // 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 ();
+
+ Data16 = (UINT16)(IoRead16(mAcpiBaseAddr + R_ACPI_GPE0a_EN));
+ Data16 &= B_ACPI_GPE0a_EN_PCIE_GPE_EN;
+
+ //
+ // Clear Sleep SMI Status
+ //
+ IoWrite16 (
+ mAcpiBaseAddr + R_SMI_STS,
+ (UINT16) (IoRead16 (mAcpiBaseAddr + R_SMI_STS) | B_SMI_STS_ON_SLP_EN)
+ );
+
+ //
+ // Clear Sleep Type Enable
+ //
+ IoWrite16 (
+ mAcpiBaseAddr + R_SMI_EN,
+ (UINT16) (IoRead16 (mAcpiBaseAddr + R_SMI_EN) & (~B_SMI_EN_ON_SLP_EN))
+ );
+
+ //
+ // Clear Power Button Status
+ //
+ IoWrite16 (mAcpiBaseAddr + R_ACPI_PM1_STS, B_ACPI_PM1_STS_PWRBTN);
+
+ //
+ // Shut it off now!
+ //
+ IoWrite16 (mAcpiBaseAddr + R_ACPI_PM1_CNT, V_ACPI_PM1_CNT_S5);
+ IoWrite16 (mAcpiBaseAddr + R_ACPI_PM1_CNT, B_ACPI_PM1_CNT_SLP_EN | V_ACPI_PM1_CNT_S5);
+
+ return EFI_SUCCESS;
+}
+
+
+VOID
+PmeCallback (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_ICHN_DISPATCH_CONTEXT *DispatchContext
+ )
+{
+
+}
+
+
+EFI_STATUS
+S5SleepAcLossCallBack (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN UINTN *CommBufferSize OPTIONAL
+ )
+{
+ //
+ // Check what the state to return to after AC Loss. If Last State, then
+ // set it to Off.
+ //
+ if (mAcLossVariable == 1) {
+ SetAfterG3On (TRUE);
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+S4S5CallBack (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN UINTN *CommBufferSize OPTIONAL
+ )
+{
+ return EFI_SUCCESS;
+}
+
+
+/**
+ 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 1.0 section 4.7.2.4)
+
+ Enable SCI
+
+ @param[in] DispatchHandle EFI Handle
+ @param[in] DispatchContext Pointer to the EFI_SMM_SW_DISPATCH_CONTEXT
+
+ @retval Nothing
+
+**/
+EFI_STATUS
+EnableAcpiCallback (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN OUT UINTN *CommBufferSize OPTIONAL
+ )
+{
+ UINT8 OutputValue;
+ UINT32 SmiEn;
+ UINT16 Pm1Cnt;
+
+
+ //
+ // Disable SW SMI Timer
+ //
+ SmiEn = IoRead32 (mAcpiBaseAddr + R_SMI_EN);
+ SmiEn &= ~B_SMI_STS_SWSMI_TMR;
+ IoWrite32 (mAcpiBaseAddr + R_SMI_EN, SmiEn);
+
+
+ //
+ // Disable PM sources except power button
+ //
+ IoWrite16 (mAcpiBaseAddr + R_ACPI_PM1_EN, B_ACPI_PM1_EN_PWRBTN);
+
+ //
+ // Guarantee day-of-month alarm is invalid (ACPI 1.0 section 4.7.2.4)
+ //
+ OutputValue = RTC_ADDRESS_REGISTER_D;
+ IoWrite8 (PCAT_RTC_ADDRESS_REGISTER, OutputValue);
+ OutputValue = 0x0;
+ OutputValue = IoRead8 (PCAT_RTC_DATA_REGISTER);
+
+ //
+ // Enable SCI
+ //
+ Pm1Cnt = IoRead16 (mAcpiBaseAddr + R_ACPI_PM1_CNT);
+ Pm1Cnt |= B_ACPI_PM1_CNT_SCI_EN;
+ IoWrite16 (mAcpiBaseAddr + R_ACPI_PM1_CNT, Pm1Cnt);
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ 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[in] DispatchHandle EFI Handle
+ @param[in] DispatchContext Pointer to the EFI_SMM_SW_DISPATCH_CONTEXT
+
+ @retval Nothing
+
+**/
+EFI_STATUS
+DisableAcpiCallback (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN UINTN *CommBufferSize OPTIONAL
+ )
+{
+ UINT16 Pm1Cnt;
+
+ //
+ // Disable SCI
+ //
+ Pm1Cnt = IoRead16 (mAcpiBaseAddr + R_ACPI_PM1_CNT);
+ Pm1Cnt &= ~B_ACPI_PM1_CNT_SCI_EN;
+ IoWrite16 (mAcpiBaseAddr + R_ACPI_PM1_CNT, Pm1Cnt);
+
+ return EFI_SUCCESS;
+}
+
+
+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);
+}
+
+
+EFI_STATUS
+S5SleepWakeOnRtcCallBack (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN UINTN *CommBufferSize OPTIONAL
+ )
+{
+ EnableS5WakeOnRtc ();
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Returns:
+ Check Alarm interrupt is not set.
+ Clear Alarm interrupt.
+ Set RTC wake up date and time.
+ Enable RTC wake up alarm.
+ 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);
+
+ Status = gRT->GetVariable (
+ 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);
+ Stall (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);
+ Stall (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);
+ Stall (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);
+ Stall (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_ACPI_PM1_STS, B_ACPI_PM1_STS_RTC);
+
+ //
+ // Enable ICH RTC event
+ //
+ IoWrite16 (mAcpiBaseAddr + R_ACPI_PM1_EN,
+ (UINT16) (IoRead16 (mAcpiBaseAddr + R_ACPI_PM1_EN) | B_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
+ )
+{
+ UINTN HighByte;
+ UINTN LowByte;
+
+ HighByte = (UINTN) ((BcdValue >> 4) * 10);
+ LowByte = (UINTN) (BcdValue & 0x0F);
+
+ return ((UINT8) (LowByte + HighByte));
+}
+
+
+/**
+ TPM Handler
+
+ @param[in] DispatchHandle The handle of this callback, obtained when registering
+ @param[in] DispatchContext Pointer to the EFI_SMM_SW_DISPATCH_CONTEXT
+
+ @retval None.
+
+**/
+EFI_STATUS
+TpmPtsSmbsCallback (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN UINTN *CommBufferSize OPTIONAL
+ )
+{
+ UINT8 TpmSetting;
+
+ //
+ // Setting MORD
+ //
+ TpmSetting = EFI_ACPI_TPM_MORD;
+ mSmst->SmmIo.Io.Write (&mSmst->SmmIo, SMM_IO_UINT8, 0x72, 1, &TpmSetting);
+ TpmSetting = mGlobalNvsAreaPtr->Area->MorData;
+ mSmst->SmmIo.Io.Write (&mSmst->SmmIo, SMM_IO_UINT8, 0x73, 1, &TpmSetting);
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/PlatformSmm/PlatformSmm.inf b/Platform/BroxtonPlatformPkg/Common/PlatformSmm/PlatformSmm.inf
new file mode 100644
index 0000000000..82a251cd19
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/PlatformSmm/PlatformSmm.inf
@@ -0,0 +1,95 @@
+## @file
+# Component description file for SMM Platform handler module.
+#
+# Copyright (c) 1999 - 2016, 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
+# 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.
+#
+##
+
+[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
+ UefiRuntimeServicesTableLib
+ SmmServicesTableLib
+ DebugLib
+ IoLib
+ PcdLib
+ BaseLib
+ BaseMemoryLib
+ DevicePathLib
+ HobLib
+ S3BootScriptLib
+ StallSmmLib
+ SideBandLib
+ ReportStatusCodeLib
+ GpioLib
+
+[Guids]
+ gEfiSetupVariableGuid
+ gDmiDataGuid
+ gEfiAcpiVariableCompatiblityGuid
+ gEfiPciLanInfoGuid
+ gEfiPciLanInfoGuid
+
+[Protocols]
+ gEfiSmmBase2ProtocolGuid
+ gEfiSmmIchnDispatchProtocolGuid
+ gEfiGlobalNvsAreaProtocolGuid
+ gEfiSmmSwDispatch2ProtocolGuid
+ gEfiSmmPowerButtonDispatch2ProtocolGuid
+ gEfiSmmSxDispatch2ProtocolGuid
+ gEfiSmmVariableProtocolGuid
+ gEfiSmmCpuProtocolGuid
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ IntelFrameworkPkg/IntelFrameworkPkg.dec
+ BroxtonSiPkg/BroxtonSiPkg.dec
+ BroxtonPlatformPkg/PlatformPkg.dec
+ IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+
+[Pcd]
+ gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
+ gEfiBxtTokenSpaceGuid.PcdScAcpiIoPortBaseAddress
+ gEfiBxtTokenSpaceGuid.PcdPmcGcrBaseAddress
+ gEfiMdeModulePkgTokenSpaceGuid.PcdProgressCodeS3SuspendStart
+ gEfiBxtTokenSpaceGuid.PcdP2SBBaseAddress
+
+[Depex]
+ gEfiSmmBase2ProtocolGuid AND
+ gEfiSmmAccess2ProtocolGuid AND
+ gEfiSmmPowerButtonDispatch2ProtocolGuid AND
+ gEfiSmmSxDispatch2ProtocolGuid AND
+ gEfiSmmIchnDispatchProtocolGuid AND
+ gEfiSmmSwDispatch2ProtocolGuid AND
+ gEfiVariableArchProtocolGuid AND
+ gEfiVariableWriteArchProtocolGuid AND
+ gEfiGlobalNvsAreaProtocolGuid
+
diff --git a/Platform/BroxtonPlatformPkg/Common/PlatformSmm/S3Save.c b/Platform/BroxtonPlatformPkg/Common/PlatformSmm/S3Save.c
new file mode 100644
index 0000000000..4b3f34fc3f
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/PlatformSmm/S3Save.c
@@ -0,0 +1,82 @@
+/** @file
+ SMM S3 handler Driver implementation file.
+
+ Copyright (c) 1999 - 2016, 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
+ 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 "SmmPlatform.h"
+
+extern UINT16 mAcpiBaseAddr;
+
+EFI_STATUS
+SaveRuntimeScriptTable (
+ IN EFI_SMM_SYSTEM_TABLE2 *Smst
+ )
+{
+ UINT32 Data32;
+ UINT16 Data16;
+ UINT8 Data8;
+ UINT32 DwordData;
+ UINT32 PciOffset;
+
+ IoWrite8 (0x80, 0x53);
+
+ for (PciOffset = 0x10; PciOffset < 0x0cf; PciOffset += 4) {
+ DwordData = MmioRead32 (MmPciAddress (0, SA_IGD_BUS, SA_IGD_DEV, SA_IGD_FUN_0, PciOffset));
+
+ S3BootScriptSaveMemWrite (
+ S3BootScriptWidthUint32,
+ MmPciAddress (0, SA_IGD_BUS, SA_IGD_DEV, SA_IGD_FUN_0, PciOffset),
+ 1,
+ &DwordData
+ );
+ }
+
+ IoWrite8 (0x80, 0x53);
+
+ //
+ // Save I/O ports to S3 script table
+ //
+
+ //
+ // Selftest KBC
+ //
+ Data8 = 0xAA;
+ S3BootScriptSaveIoWrite (
+ S3BootScriptWidthUint8,
+ 0x64,
+ (UINTN) 1,
+ &Data8
+ );
+
+ Data32 = IoRead32 (mAcpiBaseAddr + R_SMI_EN);
+ S3BootScriptSaveIoWrite (
+ S3BootScriptWidthUint32,
+ (mAcpiBaseAddr + R_SMI_EN),
+ 1,
+ &Data32
+ );
+
+ //
+ // Save B_ICH_TCO_CNT_LOCK so it will be done on S3 resume path.
+ //
+ Data16 = IoRead16 (mAcpiBaseAddr + R_TCO_CNT);
+ S3BootScriptSaveIoWrite (
+ S3BootScriptWidthUint16,
+ mAcpiBaseAddr + R_TCO_CNT,
+ 1,
+ &Data16
+ );
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Platform/BroxtonPlatformPkg/Common/PlatformSmm/SmmPlatform.h b/Platform/BroxtonPlatformPkg/Common/PlatformSmm/SmmPlatform.h
new file mode 100644
index 0000000000..0689f31647
--- /dev/null
+++ b/Platform/BroxtonPlatformPkg/Common/PlatformSmm/SmmPlatform.h
@@ -0,0 +1,223 @@
+/** @file
+ Header file for Platform Smm driver.
+
+ Copyright (c) 1999 - 2016, 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
+ 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.
+
+**/
+
+#ifndef _PLATFORM_H
+#define _PLATFORM_H
+
+#include <PiSmm.h>
+#include <Protocol/SmmBase2.h>
+#include <Protocol/FirmwareVolume2.h>
+#include <Protocol/SmmPowerButtonDispatch2.h>
+#include <Protocol/SmmSxDispatch2.h>
+#include <Protocol/SmmSwDispatch2.h>
+#include <Protocol/SmmIchnDispatch.h>
+#include <Protocol/SmmAccess2.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 "ScAccess.h"
+#include "CpuRegs.h"
+#include "CmosMap.h"
+#include "PlatformBaseAddresses.h"
+#include "SaRegs.h"
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.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/SmmServicesTableLib.h>
+#include <Protocol/SmmCpu.h>
+#include <Library/GpioLib.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 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
+
+//
+// Callback function prototypes
+//
+EFI_STATUS
+PowerButtonCallback (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN UINTN *CommBufferSize OPTIONAL
+ );
+
+EFI_STATUS
+S5SleepWakeOnLanCallBack (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN UINTN *CommBufferSize OPTIONAL
+ );
+
+EFI_STATUS
+S5SleepAcLossCallBack (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN UINTN *CommBufferSize OPTIONAL
+ );
+
+
+EFI_STATUS
+S4S5CallBack (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN UINTN *CommBufferSize OPTIONAL
+ );
+
+EFI_STATUS
+EnableAcpiCallback (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN UINTN *CommBufferSize OPTIONAL
+ );
+
+EFI_STATUS
+DisableAcpiCallback (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN UINTN *CommBufferSize OPTIONAL
+ );
+
+EFI_STATUS
+SmmReadyToBootCallback (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN UINTN *CommBufferSize OPTIONAL
+ );
+
+VOID
+DummyTco1Callback (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_ICHN_DISPATCH_CONTEXT *DispatchContext
+ );
+
+VOID
+PmeCallback (
+ 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
+EnableWatchdogCallback (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_ICHN_DISPATCH_CONTEXT *DispatchContext
+ );
+
+VOID
+SetAfterG3On (
+ BOOLEAN Enable
+ );
+
+VOID
+TurnOffVregUsb (
+ );
+
+EFI_STATUS
+SxSleepEntryCallBack (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN UINTN *CommBufferSize OPTIONAL
+ );
+
+EFI_STATUS
+SaveRuntimeScriptTable (
+ IN EFI_SMM_SYSTEM_TABLE2 *Smst
+ );
+
+EFI_STATUS
+TpmPtsSmbsCallback (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN UINTN *CommBufferSize OPTIONAL
+ );
+
+#endif
+