summaryrefslogtreecommitdiff
path: root/Chipset/SB/Smm2/SmiHandlerGeneric2.c
diff options
context:
space:
mode:
Diffstat (limited to 'Chipset/SB/Smm2/SmiHandlerGeneric2.c')
-rw-r--r--Chipset/SB/Smm2/SmiHandlerGeneric2.c1644
1 files changed, 1644 insertions, 0 deletions
diff --git a/Chipset/SB/Smm2/SmiHandlerGeneric2.c b/Chipset/SB/Smm2/SmiHandlerGeneric2.c
new file mode 100644
index 0000000..d476784
--- /dev/null
+++ b/Chipset/SB/Smm2/SmiHandlerGeneric2.c
@@ -0,0 +1,1644 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//*************************************************************************
+// $Header: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmmChildDispatcher2/SmiHandlerGeneric2.c 7 8/17/14 11:55p Mirayang $
+//
+// $Revision: 7 $
+//
+// $Date: 8/17/14 11:55p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Chipset/Intel/SouthBridge/LynxPoint/Intel Pch SB Chipset/SmmChildDispatcher2/SmiHandlerGeneric2.c $
+//
+// 7 8/17/14 11:55p Mirayang
+// Fix Build Error when token "PI_0_9_CHILD_DISPATCHER_SUPPORT" = 0
+//
+// 6 3/25/13 4:59a Wesleychen
+// [TAG] None
+// [Category] Improvement
+// [Description] Refine GPI SMM2 related routines.
+// [Files] SmiHandlerGeneric2.c; SmiHandlerPorting2.c;
+// SmmChildDispatch2.h
+//
+// 5 3/15/13 2:25a Scottyang
+// [TAG] None
+// [Category] Improvement
+// [Description] Support ULT GPISMI.
+// [Files] SmiHandlerGeneric2.c
+//
+// 4 1/03/13 7:00a Scottyang
+// [TAG] None
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] GPISMI cannot use.
+// [RootCause] GPISMI2 will clear status before GPISMI.
+// [Solution] GPISMI2 do not clear status when GPISMI has register.
+// [Files] SmmChildDispatcher2.sdl; SmiHandlerGeneric2.c
+//
+// 3 8/30/12 9:50a Victortu
+// [TAG] None
+// [Category] Improvement
+// [Description] Implement EIP#73211 and EIP#79156 for OA 3.0 function.
+// [Files] SmiHandlerGeneric2.c, SmmChildDispatch2Main.c
+//
+// 2 4/25/12 9:32a Victortu
+// [TAG] None
+// [Category] Improvement
+// [Description] Reprogram SMM ChildDispatcher drivers.
+// [Files] SmiHandlerGeneric.c; SmiHandlerPorting.c;
+// SmiHandlerGeneric2.c; SmmChildDispatch2Main.c; SmmChildDispatcher2.mak;
+// SmmChildDispatcher2.sdl; SmmChildDispatch.h; SmmChildDispatchMain.c;
+// SmmChildDispatchProtocol.c; SmmChildDispatcher.dxs;
+// PchSmiDispatcher.sdl
+//
+// 1 2/08/12 8:28a Yurenlai
+// Intel Lynx Point/SB eChipset initially releases.
+//
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: SmiHandlerGeneric2.c
+//
+// Description: This file contains implementation of generic SMI handler II
+// functions
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+
+//---------------------------------------------------------------------------
+// Include(s)
+//---------------------------------------------------------------------------
+
+#include <Token.h>
+#include <AmiDxeLib.h>
+#include <AmiCspLib.h>
+#include "SmmChildDispatch2.h"
+#include <AmiSmm.h>
+
+//---------------------------------------------------------------------------
+// Constant, Macro and Type Definition(s)
+//---------------------------------------------------------------------------
+// Constant Definition(s)
+
+// Macro Definition(s)
+
+// Type Definition(s)
+
+// Function Prototype(s)
+
+//---------------------------------------------------------------------------
+// Variable and External Declaration(s)
+//---------------------------------------------------------------------------
+// Variable Declaration(s)
+
+static UINT64 gCurrentInterval = 0xffffffffffffffff;
+static UINT16 gEnabledUsbSmi = 0;
+static UINT16 gActiveUsbSmi = 0;
+static UINT32 gEnabledGpiSmi = 0;
+static UINT32 gEnabledTcoSmi = 0;
+static UINT32 gEnabledIoTrapSmi = 0;
+static UINT32 gIoTrapWriteData = 0;
+
+BOOLEAN gIsLastState = FALSE;
+
+// GUID Definition(s)
+
+// Protocol Definition(s)
+
+// External Declaration(s)
+
+extern EFI_SMM_SYSTEM_TABLE2 *gSmst2;
+extern SMM_CHILD_DISPATCHER2 Smm2Handler[];
+extern EFI_SMM_SMI_CONTEXT2 SmiContext;
+
+extern UINT64 gSupportedIntervals[];
+
+// Function Definition(s)
+
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// Software SMI II Handler functions
+//---------------------------------------------------------------------------
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmSwAddHandler2
+//
+// Description: This function adds SW SMI II handler
+//
+// Input: *Context - Pointer to EFI_SMM_SW_REGISTER_CONTEXT
+//
+// Output: EFI_SUCCESS
+//
+// Notes: GENERALLY NO PORTING REQUIRED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmSwAddHandler2 (
+ IN VOID *Context )
+{
+ if (Smm2Handler[EfiSmmSwSmi2].RegisteredCallbacks.Size == 1) SwSmiEnable();
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmSwRemoveHandler2
+//
+// Description: This function removes SW SMI II handler
+//
+// Input: *Context - Pointer to EFI_SMM_SW_REGISTER_CONTEXT
+//
+// Output: EFI_SUCCESS
+//
+// Notes: GENERALLY NO PORTING REQUIRED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmSwRemoveHandler2 (
+ IN VOID *Context )
+{
+#if (PI_0_9_CHILD_DISPATCHER_SUPPORT == 0)
+ if (Smm2Handler[EfiSmmSwSmi2].RegisteredCallbacks.Size == 1) SwSmiDisable();
+#endif
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmSwVerifyContext2
+//
+// Description: This function verifies SW SMI II context
+//
+// Input: *Context - Pointer to SMI II context
+//
+// Output: EFI_STATUS
+// EFI_INVALID_PARAMETER - Given context is invalid
+// EFI_SUCCESS - Context verified
+//
+// Notes: GENERALLY NO PORTING REQUIRED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmSwVerifyContext2 (
+ IN VOID *Context )
+{
+ HANDLER_LINK2 *Handler = (HANDLER_LINK2 *)\
+ Smm2Handler[EfiSmmSwSmi2].RegisteredCallbacks.pHead;
+ EFI_SMM_SW_REGISTER_CONTEXT *SwContext;
+ EFI_SMM_SW_REGISTER_CONTEXT *RegisteredSwContext;
+
+ SwContext = (EFI_SMM_SW_REGISTER_CONTEXT *)Context;
+ // First check if we already registered handler for this value
+ while (Handler != NULL) {
+ RegisteredSwContext = (EFI_SMM_SW_REGISTER_CONTEXT *)Handler->Context;
+ if(SwContext->SwSmiInputValue == RegisteredSwContext->SwSmiInputValue)
+ // Handler with this value already registered
+ return EFI_INVALID_PARAMETER;
+
+ Handler = (HANDLER_LINK2 *)Handler->Link.pNext;
+ }
+
+ // Second check if given value is extended SMI value,
+ // check the lowest byte
+ if ((SwContext->SwSmiInputValue & 0xff) == EXTENDED_SMI)
+ return EFI_SUCCESS; // Accept value of UINTN size
+
+ // Third check if given value is in default range
+ return (SwContext->SwSmiInputValue > MAX_SW_SMI_INPUT_VALUE) ? \
+ EFI_INVALID_PARAMETER : EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmSwGetContext2
+//
+// Description: This function verifies SW SMI II event and sets SW SMI II
+// context
+//
+// Input: None
+//
+// Output: BOOLEAN
+// TRUE - SW SMI occured, context saved
+// FALSE - There was no SW SMI II
+//
+// Notes: GENERALLY NO PORTING REQUIRED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN SmmSwGetContext2 (VOID)
+{
+ UINT16 SwSmiNumber;
+ BOOLEAN SwSmiDetected;
+
+ SwSmiDetected = SwSmiDetect( &SwSmiNumber );
+
+ if (SwSmiDetected) {
+ if(SwSmiNumber == EXTENDED_SMI) {
+ // Get the actual number from EAX register
+ SmiContext.SwContext.SwSmiInputValue = GetEAX();
+ } else {
+ SmiContext.SwContext.SwSmiInputValue = SwSmiNumber;
+ }
+ }
+
+ return SwSmiDetected;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmSwDispatchSmi2
+//
+// Description: This function dispatches SW SMI II event based on context
+//
+// Input: None
+//
+// Output: EFI_STATUS
+//
+// Notes: GENERALLY NO PORTING REQUIRED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmSwDispatchSmi2 ( VOID )
+{
+ EFI_STATUS Status = EFI_WARN_INTERRUPT_SOURCE_QUIESCED;
+ HANDLER_LINK2 *Handler;
+ EFI_SMM_SW_REGISTER_CONTEXT *SwRegisterContext;
+
+ EFI_SMM_SW_CONTEXT SwContext;
+ UINTN SwContextSize;
+ UINT16 i;
+ EFI_GUID SwSmiCpuTriggerGuid = SW_SMI_CPU_TRIGGER_GUID;
+ SW_SMI_CPU_TRIGGER *SwSmiCpuTrigger;
+ UINTN Cpu = pSmst->CurrentlyExecutingCpu - 1; //default cpu #
+
+ for (i = 0; i < pSmst->NumberOfTableEntries; i++)
+ {
+ if (guidcmp(&(pSmst->SmmConfigurationTable[i].VendorGuid), &SwSmiCpuTriggerGuid) == 0)
+ break;
+ }
+
+ //If found table, check for the CPU that caused the software Smi.
+ if (i != pSmst->NumberOfTableEntries)
+ {
+ SwSmiCpuTrigger = pSmst->SmmConfigurationTable[i].VendorTable;
+ Cpu = SwSmiCpuTrigger->Cpu;
+ }
+
+ SwContext.SwSmiCpuIndex = Cpu;
+ SwContext.CommandPort = IoRead8(SW_SMI_IO_ADDRESS);
+ SwContext.DataPort = IoRead8(SW_SMI_IO_ADDRESS + 1);
+ SwContextSize = sizeof(SwContext);
+
+ Handler = \
+ (HANDLER_LINK2 *)Smm2Handler[EfiSmmSwSmi2].RegisteredCallbacks.pHead;
+ while (Handler != NULL) {
+ SwRegisterContext = (EFI_SMM_SW_REGISTER_CONTEXT *)Handler->Context;
+ if(SwRegisterContext->SwSmiInputValue == SmiContext.SwContext.SwSmiInputValue)
+ Status = Handler->Callback(Handler, SwRegisterContext, &SwContext, &SwContextSize);
+
+ Handler = (HANDLER_LINK2 *)Handler->Link.pNext;
+ }
+
+/*#if (CHILD_DISPATCHER_SUPPORT != 0)
+ if (!EFI_ERROR(Status))
+#endif*/
+if (Status != EFI_WARN_INTERRUPT_SOURCE_QUIESCED)
+ SwSmiClear();
+
+ return EFI_WARN_INTERRUPT_SOURCE_QUIESCED;
+}
+
+//---------------------------------------------------------------------------
+// Sleep SMI II Handler functions
+//---------------------------------------------------------------------------
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmSxAddHandler2
+//
+// Description: This function adds Sx SMI II handler
+//
+// Input: *Context - Pointer to EFI_SMM_SX_REGISTER_CONTEXT
+//
+// Output: EFI_SUCCESS
+//
+// Notes: GENERALLY NO PORTING REQUIRED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmSxAddHandler2 (
+ IN VOID *Context )
+{
+#if SLP_SMI_ENABLE_ON_REGISTER
+ if (Smm2Handler[EfiSmmSxSmi2].RegisteredCallbacks.Size == 1) SxSmiEnable();
+#endif
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmSxRemoveHandler2
+//
+// Description: This function removes Sx SMI II handler
+//
+// Input: *Context - Pointer to EFI_SMM_SX_REGISTER_CONTEXT
+//
+// Output: EFI_SUCCESS
+//
+// Notes: GENERALLY NO PORTING REQUIRED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmSxRemoveHandler2 (
+ IN VOID *Context )
+{
+#if SLP_SMI_ENABLE_ON_REGISTER && (PI_0_9_CHILD_DISPATCHER_SUPPORT == 0)
+ if (Smm2Handler[EfiSmmSxSmi2].RegisteredCallbacks.Size == 1) SxSmiDisable();
+#endif
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmSxVerifyContext2
+//
+// Description: This function verifies Sx SMI II context
+//
+// Input: *Context - Pointer to SMI II context
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS - Context verified
+// EFI_INVALID_PARAMETER - Given context is invalid
+// EFI_UNSUPPORTED - Context is not supported
+//
+// Notes: GENERALLY NO PORTING REQUIRED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmSxVerifyContext2 (
+ IN VOID *Context )
+{
+ EFI_SMM_SX_REGISTER_CONTEXT *SxContext;
+
+ SxContext = (EFI_SMM_SX_REGISTER_CONTEXT *)Context;
+ if ((SxContext->Type >= EfiMaximumSleepType) || \
+ (SxContext->Phase >= EfiMaximumPhase))
+ return EFI_INVALID_PARAMETER;
+
+ return ((SxContext->Phase) != SxEntry) ? EFI_UNSUPPORTED : EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmSxGetContext2
+//
+// Description: This function verifies Sx SMI II event and sets SX SMI II
+// context
+//
+// Input: None
+//
+// Output: BOOLEAN
+// TRUE - Sx SMI occured, context saved
+// FALSE - There was no SX SMI II
+//
+// Notes: GENERALLY NO PORTING REQUIRED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN SmmSxGetContext2 (VOID)
+{
+ UINT16 SxSleepState;
+ BOOLEAN SxSmiDetected;
+
+ SxSmiDetected = SxSmiDetect( &SxSleepState );
+
+ SmiContext.SxContext.Type = SxSleepState;
+ SmiContext.SxContext.Phase = SxEntry;
+
+ return SxSmiDetected;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmSxDispatchSmi2
+//
+// Description: This function dispatches Sx SMI II event based on context
+//
+// Input: None
+//
+// Output: EFI_STATUS
+//
+// Notes: GENERALLY NO PORTING REQUIRED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmSxDispatchSmi2 (VOID)
+{
+ EFI_STATUS Status = EFI_WARN_INTERRUPT_SOURCE_QUIESCED;
+ HANDLER_LINK2 *Handler;
+ EFI_SMM_SX_REGISTER_CONTEXT *SxContext;
+
+ Handler = \
+ (HANDLER_LINK2 *)Smm2Handler[EfiSmmSxSmi2].RegisteredCallbacks.pHead;
+ while (Handler != NULL) {
+ SxContext = (EFI_SMM_SX_REGISTER_CONTEXT *)Handler->Context;
+
+ if ((SxContext->Type == SmiContext.SxContext.Type) && \
+ (SxContext->Phase == SmiContext.SxContext.Phase))
+ Status = Handler->Callback(Handler, SxContext, NULL, NULL);
+
+ Handler = (HANDLER_LINK2 *)Handler->Link.pNext;
+ }
+
+#if (PI_0_9_CHILD_DISPATCHER_SUPPORT == 0)
+ SxSmiClear();
+
+ if (SmiContext.SxContext.Type == SxS0) return Status;
+
+ PutToSleep( &(SmiContext.SxContext) );
+
+ // Control returns here on S1.
+
+ SxSmiClear();
+
+ return Status;
+#else
+ return EFI_WARN_INTERRUPT_SOURCE_QUIESCED;
+#endif
+}
+
+//---------------------------------------------------------------------------
+// Periodic timer SMI II Handler functions
+//---------------------------------------------------------------------------
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmTimerAddHandler2
+//
+// Description: This function adds Periodic timer SMI II handler
+//
+// Input: *Context - Pointer to EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT
+//
+// Output: EFI_SUCCESS
+//
+// Notes: GENERALLY NO PORTING REQUIRED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmTimerAddHandler2 (
+ IN VOID *Context )
+{
+ EFI_SMM_PERIODIC_TIMER_EXT_REGISTER_CONTEXT *TimerContext;
+
+ TimerContext = (EFI_SMM_PERIODIC_TIMER_EXT_REGISTER_CONTEXT *)Context;
+
+ if (Smm2Handler[EfiSmmPeriodicTimerSmi2].RegisteredCallbacks.Size == 1) {
+ gCurrentInterval = TimerContext->OrgContext.SmiTickInterval;
+ TimerSetInterval2( TimerContext->OrgContext.SmiTickInterval );
+ TimerSmiClear2();
+ TimerSmiEnable2();
+ return EFI_SUCCESS;
+ }
+
+ if (gCurrentInterval > TimerContext->OrgContext.SmiTickInterval) {
+ gCurrentInterval = TimerContext->OrgContext.SmiTickInterval;
+ TimerSetInterval2( TimerContext->OrgContext.SmiTickInterval );
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmTimerRemoveHandler2
+//
+// Description: This function removes Periodic timer SMI II handler
+//
+// Input: *Context - Pointer to EFI_SMM_PERIODIC_TIMER_REGISTER_CONTEXT
+//
+// Output: EFI_SUCCESS
+//
+// Notes: GENERALLY NO PORTING REQUIRED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmTimerRemoveHandler2 (
+ IN VOID *Context )
+{
+ HANDLER_LINK2 *Handler = (HANDLER_LINK2 *)\
+ Smm2Handler[EfiSmmPeriodicTimerSmi2].RegisteredCallbacks.pHead;
+ EFI_SMM_PERIODIC_TIMER_EXT_REGISTER_CONTEXT *TimerContext;
+ EFI_SMM_PERIODIC_TIMER_EXT_REGISTER_CONTEXT *CurrentTimerContext;
+ UINT64 Interval = 0xffffffffffffffff;
+
+ UINT16 CurrentIntervalCounter = 0;
+ UINT64 *SupportedIntervals = gSupportedIntervals;
+
+ if (Smm2Handler[EfiSmmPeriodicTimerSmi2].RegisteredCallbacks.Size == 1) {
+ gCurrentInterval = 0xffffffffffffffff;
+ TimerSmiDisable2();
+ return EFI_SUCCESS;
+ }
+
+ CurrentTimerContext = \
+ (EFI_SMM_PERIODIC_TIMER_EXT_REGISTER_CONTEXT *)Context;
+ while (Handler != NULL) {
+ TimerContext = \
+ (EFI_SMM_PERIODIC_TIMER_EXT_REGISTER_CONTEXT *)Handler->Context;
+ if (Interval > TimerContext->OrgContext.SmiTickInterval)
+ Interval = TimerContext->OrgContext.SmiTickInterval;
+ if (TimerContext->OrgContext.SmiTickInterval == \
+ CurrentTimerContext->OrgContext.SmiTickInterval)
+ CurrentIntervalCounter++;
+ Handler = (HANDLER_LINK2 *)Handler->Link.pNext;
+ }
+
+ if ((Interval == CurrentTimerContext->OrgContext.SmiTickInterval) && \
+ (CurrentIntervalCounter == 1)) {
+ Interval = 0xffffffffffffffff;
+ while (*SupportedIntervals != 0) {
+ if (*SupportedIntervals != \
+ CurrentTimerContext->OrgContext.SmiTickInterval)
+ if (*SupportedIntervals < Interval)
+ Interval = *SupportedIntervals;
+ SupportedIntervals++;
+ }
+ }
+
+ // This means lowest rate timer no longer active
+ if (gCurrentInterval < Interval) {
+ gCurrentInterval = Interval;
+ TimerSetInterval2( Interval );
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmTimerVerifyContext2
+//
+// Description: This function verifies Periodic timer SMI II context
+//
+// Input: *Context - Pointer to SMI II context
+//
+// Output: EFI_STATUS
+// EFI_INVALID_PARAMETER - Given context is invalid
+// EFI_SUCCESS - Context verified
+//
+// Notes: GENERALLY NO PORTING REQUIRED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmTimerVerifyContext2 (
+ IN VOID *Context )
+{
+ EFI_SMM_PERIODIC_TIMER_EXT_REGISTER_CONTEXT *TimerContext;
+ UINT64 *Interval = gSupportedIntervals;
+
+ TimerContext = (EFI_SMM_PERIODIC_TIMER_EXT_REGISTER_CONTEXT *)Context;
+ while (*Interval != 0) {
+ if (*Interval == TimerContext->OrgContext.SmiTickInterval)
+ return EFI_SUCCESS;
+ Interval++;
+ }
+
+ return EFI_INVALID_PARAMETER;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmTimerGetContext2
+//
+// Description: This function verifies Periodic timer SMI II event and sets
+// Periodic timer SMI II context
+//
+// Input: None
+//
+// Output: BOOLEAN
+// TRUE - Periodic timer SMI occured, context saved
+// FALSE - There was no Periodic timer SMI
+//
+// Notes: GENERALLY NO PORTING REQUIRED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN SmmTimerGetContext2 (VOID)
+{
+ UINT16 TimerType;
+ BOOLEAN TimerSmiDetected;
+
+ TimerSmiDetected = TimerSmiDetect2( &TimerType );
+ SmiContext.TimerContext.OrgContext.SmiTickInterval = gCurrentInterval;
+
+ return TimerSmiDetected;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmTimerDispatchSmi2
+//
+// Description: This function dispatches Periodic timer SMI event based on
+// context
+//
+// Input: None
+//
+// Output: EFI_STATUS
+//
+// Notes: GENERALLY NO PORTING REQUIRED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmTimerDispatchSmi2 (VOID)
+{
+ EFI_STATUS Status = EFI_WARN_INTERRUPT_SOURCE_QUIESCED;
+ HANDLER_LINK2 *Handler = (HANDLER_LINK2 *)\
+ Smm2Handler[EfiSmmPeriodicTimerSmi2].RegisteredCallbacks.pHead;
+ EFI_SMM_PERIODIC_TIMER_EXT_REGISTER_CONTEXT *TimerContext;
+
+ while (Handler != NULL) {
+ TimerContext = \
+ (EFI_SMM_PERIODIC_TIMER_EXT_REGISTER_CONTEXT *)Handler->Context;
+
+ TimerContext->ElapsedTime += \
+ SmiContext.TimerContext.OrgContext.SmiTickInterval;
+ if (TimerContext->ElapsedTime >= TimerContext->OrgContext.Period){
+ Status = Handler->Callback(Handler, TimerContext, NULL, NULL);
+ TimerContext->ElapsedTime = 0;
+ }
+ Handler = (HANDLER_LINK2 *)Handler->Link.pNext;
+ }
+
+#if (PI_0_9_CHILD_DISPATCHER_SUPPORT == 0)
+ TimerSmiClear2();
+ return Status;
+#else
+ return EFI_WARN_INTERRUPT_SOURCE_QUIESCED;
+#endif
+
+}
+
+//---------------------------------------------------------------------------
+// USB SMI II Handler functions
+//---------------------------------------------------------------------------
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmUsbAddHandler2
+//
+// Description: This function adds USB SMI II handler
+//
+// Input: *Context - Pointer to EFI_SMM_USB_REGISTER_CONTEXT
+//
+// Output: EFI_SUCCESS
+//
+// Notes: GENERALLY NO PORTING REQUIRED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmUsbAddHandler2 (
+ IN VOID *Context
+)
+{
+ EFI_STATUS Status;
+ EFI_SMM_USB_REGISTER_CONTEXT *UsbContext;
+ UINT16 ControllerType;
+ VOID *NewDp;
+ UINTN Length;
+
+ UsbContext = (EFI_SMM_USB_REGISTER_CONTEXT *)Context;
+
+ // Save USB device path protocol into SMM memory
+ Length = DPLength( UsbContext->Device );
+ Status = gSmst2->SmmAllocatePool( 0, Length, &NewDp );
+ if (EFI_ERROR(Status)) return Status;
+ MemCpy( NewDp, UsbContext->Device, Length );
+ UsbContext->Device = (EFI_DEVICE_PATH_PROTOCOL *)NewDp;
+
+ ControllerType = GetControllerType( UsbContext->Device );
+ if((ControllerType & gEnabledUsbSmi) == 0) {
+ gEnabledUsbSmi |= ControllerType;
+ UsbSmiSet( gEnabledUsbSmi );
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmUsbRemoveHandler2
+//
+// Description: This function removes USB SMI II handler
+//
+// Input: *Context - Pointer to EFI_SMM_USB_REGISTER_CONTEXT
+//
+// Output: EFI_SUCCESS
+//
+// Notes: GENERALLY NO PORTING REQUIRED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmUsbRemoveHandler2 (
+ IN VOID *Context )
+{
+ HANDLER_LINK2 *Handler = (HANDLER_LINK2 *)\
+ Smm2Handler[EfiSmmUsbSmi2].RegisteredCallbacks.pHead;
+ EFI_SMM_USB_REGISTER_CONTEXT *UsbContext;
+ UINT16 ControllerType = 0;
+
+ UsbContext = (EFI_SMM_USB_REGISTER_CONTEXT *)Context;
+
+ gSmst2->SmmFreePool( UsbContext->Device );
+
+ if (Smm2Handler[EfiSmmUsbSmi2].RegisteredCallbacks.Size == 1) {
+ gEnabledUsbSmi = 0;
+ UsbSmiSet( gEnabledUsbSmi );
+ return EFI_SUCCESS;
+ }
+
+ while (Handler != NULL) {
+ UsbContext = (EFI_SMM_USB_REGISTER_CONTEXT *)Handler->Context;
+ ControllerType |= GetControllerType( UsbContext->Device );
+ Handler = (HANDLER_LINK2 *)Handler->Link.pNext;
+ }
+
+ if (ControllerType != gEnabledUsbSmi) {
+ gEnabledUsbSmi = ControllerType;
+ UsbSmiSet( gEnabledUsbSmi );
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmUsbVerifyContext2
+//
+// Description: This function verifies USB SMI II context
+//
+// Input: *Context - Pointer to SMI II context
+//
+// Output: EFI_STATUS
+// EFI_INVALID_PARAMETER - Given context is invalid
+// EFI_SUCCESS - Context verified
+// EFI_UNSUPPORTED - Context is not supported
+//
+// Notes: GENERALLY NO PORTING REQUIRED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmUsbVerifyContext2 (
+ IN VOID *Context )
+{
+ EFI_SMM_USB_REGISTER_CONTEXT *UsbContext;
+ UINT16 ControllerType;
+
+ UsbContext = (EFI_SMM_USB_REGISTER_CONTEXT *)Context;
+ ControllerType = GetControllerType( UsbContext->Device );
+ if (((ControllerType & 7) == 0) || (UsbContext->Type > UsbWake))
+ return EFI_INVALID_PARAMETER;
+
+ return ((UsbContext->Type) > UsbLegacy) ? EFI_UNSUPPORTED : EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmUsbGetContext2
+//
+// Description: This function verifies USB SMI II event and sets USB SMI II
+// context
+//
+// Input: None
+//
+// Output: BOOLEAN
+// TRUE - USB SMI occured, context saved
+// FALSE - There was no USB SMI
+//
+// Notes: GENERALLY NO PORTING REQUIRED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN SmmUsbGetContext2 (VOID)
+{
+ BOOLEAN UsbSmiDetected;
+
+ UsbSmiDetected = UsbSmiDetect( &gActiveUsbSmi );
+ SmiContext.UsbContext.Type = UsbLegacy;
+
+ return UsbSmiDetected;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmUsbDispatchSmi2
+//
+// Description: This function dispatches USB SMI II event based on context
+//
+// Input: None
+//
+// Output: EFI_STATUS
+//
+// Notes: GENERALLY NO PORTING REQUIRED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmUsbDispatchSmi2 (VOID)
+{
+ EFI_STATUS Status = EFI_WARN_INTERRUPT_SOURCE_QUIESCED;
+ HANDLER_LINK2 *Handler = (HANDLER_LINK2 *)\
+ Smm2Handler[EfiSmmUsbSmi2].RegisteredCallbacks.pHead;
+ EFI_SMM_USB_REGISTER_CONTEXT *UsbContext;
+ UINT16 ControllerType;
+
+ while (Handler != NULL) {
+ UsbContext = (EFI_SMM_USB_REGISTER_CONTEXT *)Handler->Context;
+ ControllerType = GetControllerType( UsbContext->Device );
+
+ if (((ControllerType & gActiveUsbSmi) != 0) && \
+ (UsbContext->Type == SmiContext.UsbContext.Type))
+ Status = Handler->Callback(Handler, UsbContext, NULL, NULL);
+
+ Handler = (HANDLER_LINK2 *)Handler->Link.pNext;
+ }
+
+#if (PI_0_9_CHILD_DISPATCHER_SUPPORT == 0)
+ UsbSmiClear( gActiveUsbSmi );
+ gActiveUsbSmi = 0;
+ return Status;
+#else
+ gActiveUsbSmi = 0;
+ return EFI_WARN_INTERRUPT_SOURCE_QUIESCED;
+#endif
+
+}
+
+//---------------------------------------------------------------------------
+// GPI SMI II Handler functions
+//---------------------------------------------------------------------------
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmGpiAddHandler2
+//
+// Description: This function adds GPI SMI II handler
+//
+// Input: VOID *Context - Pointer to EFI_SMM_GPI_REGISTER_CONTEXT
+//
+// Output: EFI_SUCCESS
+//
+// Notes: GENERALLY NO PORTING REQUIRED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmGpiAddHandler2 (
+ IN VOID *Context )
+{
+ EFI_SMM_GPI_REGISTER_CONTEXT *GpiContext;
+ UINT32 GpiBitMap = 0;
+
+ GpiContext = (EFI_SMM_GPI_REGISTER_CONTEXT *)Context;
+
+ GpiBitMap = ConvertGpi (GpiContext->GpiNum);
+
+ if ((GpiBitMap & gEnabledGpiSmi) == 0) {
+ gEnabledGpiSmi |= GpiBitMap;
+ GpiSmiSet( GpiBitMap );
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmGpiRemoveHandler2
+//
+// Description: This function removes GPI SMI II handler
+//
+// Input: *Context - Pointer to EFI_SMM_GPI_REGISTER_CONTEXT
+//
+// Output: EFI_SUCCESS
+//
+// Notes: GENERALLY NO PORTING REQUIRED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmGpiRemoveHandler2 (
+ IN VOID *Context )
+{
+ EFI_SMM_GPI_REGISTER_CONTEXT *GpiContext;
+ UINT32 GpiBitMap = 0;
+
+ GpiContext = (EFI_SMM_GPI_REGISTER_CONTEXT *)Context;
+
+ GpiBitMap = ConvertGpi (GpiContext->GpiNum);
+
+ gEnabledGpiSmi &= ~(GpiBitMap);
+
+ GpiSmiReset( GpiBitMap );
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmGpiVerifyContext2
+//
+// Description: This function verifies GPI SMI II context
+//
+// Input: *Context - Pointer to SMI II context
+//
+// Output: EFI_STATUS
+// EFI_INVALID_PARAMETER - Given context is invalid
+// EFI_SUCCESS - Context verified
+//
+// Notes: GENERALLY NO PORTING REQUIRED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmGpiVerifyContext2 (
+ IN VOID *Context )
+{
+ EFI_SMM_GPI_REGISTER_CONTEXT *GpiContext;
+ UINT32 GpiBitMap = 0;
+
+ GpiContext = (EFI_SMM_GPI_REGISTER_CONTEXT *)Context;
+
+ GpiBitMap = ConvertGpi (GpiContext->GpiNum);
+
+ if ((GpiBitMap & SUPPORTED_GPIS2) == 0)
+ return EFI_INVALID_PARAMETER;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmGpiGetContext2
+//
+// Description: This function verifies GPI SMI II event and sets GPI SMI II
+// context
+//
+// Input: None
+//
+// Output: BOOLEAN
+// TRUE - GPI SMI occured, context saved
+// FALSE - There was no GPI SMI
+//
+// Notes: GENERALLY NO PORTING REQUIRED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN SmmGpiGetContext2 (VOID)
+{
+ BOOLEAN GpiSmiDetected;
+ UINT32 GpiSmiNum;
+
+ GpiSmiDetected = GpiSmiDetect( &GpiSmiNum );
+ SmiContext.GpiContext.GpiNum = GpiSmiNum;
+
+ return GpiSmiDetected;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmGpiDispatchSmi2
+//
+// Description: This function dispatches GPI SMI event based on context
+//
+// Input: None
+//
+// Output: EFI_STATUS
+//
+// Notes: GENERALLY NO PORTING REQUIRED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmGpiDispatchSmi2 (VOID)
+{
+ EFI_STATUS Status = EFI_WARN_INTERRUPT_SOURCE_QUIESCED;
+ HANDLER_LINK2 *Handler = (HANDLER_LINK2 *)\
+ Smm2Handler[EfiSmmGpiSmi2].RegisteredCallbacks.pHead;
+ EFI_SMM_GPI_REGISTER_CONTEXT *GpiContext;
+ UINT32 GpiBitMap = 0;
+ BOOLEAN GpiSmiServiced = FALSE;
+
+ while (Handler != NULL) {
+ GpiContext = (EFI_SMM_GPI_REGISTER_CONTEXT *)Handler->Context;
+
+ GpiBitMap = ConvertGpi (GpiContext->GpiNum);
+
+ GpiSmiServiced = FALSE;
+ if ((SmiContext.GpiContext.GpiNum & GpiBitMap) != 0) {
+ Status = Handler->Callback( Handler, GpiContext, NULL, NULL );
+ GpiSmiServiced = TRUE;
+ }
+
+ Handler = (HANDLER_LINK2 *)Handler->Link.pNext;
+ }
+
+ if (GpiSmiServiced)
+ GpiSmiClear( (UINT16)SmiContext.GpiContext.GpiNum );
+
+#if (PI_0_9_CHILD_DISPATCHER_SUPPORT == 0)
+ return Status;
+#else
+ return EFI_WARN_INTERRUPT_SOURCE_QUIESCED;
+#endif
+
+}
+
+//---------------------------------------------------------------------------
+// Standby button SMI II Handler functions
+//---------------------------------------------------------------------------
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmSButtonAddHandler2
+//
+// Description: This function adds Standby button SMI II handler
+//
+// Input: *Context - Pointer to EFI_SMM_STANDBY_BUTTON_REGISTER_CONTEXT
+//
+// Output: EFI_SUCCESS
+//
+// Notes: GENERALLY NO PORTING REQUIRED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmSButtonAddHandler2 (
+ IN VOID *Context )
+{
+ if (Smm2Handler[EfiSmmStandbyButtonSmi2].RegisteredCallbacks.Size == 1)
+ SButtonSmiEnable();
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmSButtonRemoveHandler2
+//
+// Description: This function removes Standby button SMI II handler
+//
+// Input: *Context - Pointer to EFI_SMM_STANDBY_BUTTON_REGISTER_CONTEXT
+//
+// Output: EFI_SUCCESS
+//
+// Notes: GENERALLY NO PORTING REQUIRED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmSButtonRemoveHandler2 (
+ IN VOID *Context )
+{
+ if (Smm2Handler[EfiSmmStandbyButtonSmi2].RegisteredCallbacks.Size == 1)
+ SButtonSmiDisable();
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmSButtonVerifyContext2
+//
+// Description: This function verifies Standby button SMI II context
+//
+// Input: VOID *Context - Pointer to SMI II context
+//
+// Output: EFI_STATUS
+// EFI_INVALID_PARAMETER - Given context is invalid
+// EFI_SUCCESS - Context verified
+// EFI_UNSUPPORTED - Context is not supported
+//
+// Notes: GENERALLY NO PORTING REQUIRED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmSButtonVerifyContext2 (
+ IN VOID *Context )
+{
+ EFI_SMM_STANDBY_BUTTON_REGISTER_CONTEXT *SButtonContext;
+
+ SButtonContext = (EFI_SMM_STANDBY_BUTTON_REGISTER_CONTEXT *)Context;
+ if (SButtonContext->Phase >= EfiStandbyButtonMax)
+ return EFI_INVALID_PARAMETER;
+
+ return (SButtonContext->Phase > EfiStandbyButtonEntry) \
+ ? EFI_UNSUPPORTED : EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmSButtonGetContext2
+//
+// Description: This function verifies Standby button SMI II event and sets
+// Standby button SMI II context
+//
+// Input: None
+//
+// Output: BOOLEAN
+// TRUE - Standby button SMI occured, context saved
+// FALSE - There was no Standby button SMI
+//
+// Notes: GENERALLY NO PORTING REQUIRED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN SmmSButtonGetContext2 (VOID)
+{
+ UINT16 Dummy = 0;
+ BOOLEAN SButtonSmiDetected;
+
+ SButtonSmiDetected = SButtonSmiDetect( &Dummy );
+
+ SmiContext.SBtnContext.Phase = EfiStandbyButtonEntry;
+
+ return SButtonSmiDetected;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmSButtonDispatchSmi2
+//
+// Description: This function dispatches Standby button SMI II event based on
+// context
+//
+// Input: None
+//
+// Output: EFI_STATUS
+//
+// Notes: GENERALLY NO PORTING REQUIRED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmSButtonDispatchSmi2 (VOID)
+{
+ EFI_STATUS Status = EFI_WARN_INTERRUPT_SOURCE_QUIESCED;
+ HANDLER_LINK2 *Handler = (HANDLER_LINK2 *)\
+ Smm2Handler[EfiSmmStandbyButtonSmi2].RegisteredCallbacks.pHead;
+ EFI_SMM_STANDBY_BUTTON_REGISTER_CONTEXT *SButtonContext;
+
+ while (Handler != NULL) {
+ SButtonContext = \
+ (EFI_SMM_STANDBY_BUTTON_REGISTER_CONTEXT *)Handler->Context;
+
+ if (SButtonContext->Phase == SmiContext.SBtnContext.Phase)
+ Status = Handler->Callback( Handler, SButtonContext, NULL, NULL );
+
+ Handler = (HANDLER_LINK2 *)Handler->Link.pNext;
+ }
+
+#if (PI_0_9_CHILD_DISPATCHER_SUPPORT == 0)
+ SButtonSmiClear();
+
+ return Status;
+#else
+ return EFI_WARN_INTERRUPT_SOURCE_QUIESCED;
+#endif
+}
+
+//---------------------------------------------------------------------------
+// Power button SMI II Handler functions
+//---------------------------------------------------------------------------
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmPButtonAddHandler2
+//
+// Description: This function adds Power button SMI II handler
+//
+// Input: *Context - pointer to EFI_SMM_POWER_BUTTON_REGISTER_CONTEXT
+//
+// Output: EFI_SUCCESS
+//
+// Notes: GENERALLY NO PORTING REQUIRED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmPButtonAddHandler2 (
+ IN VOID *Context )
+{
+ if (Smm2Handler[EfiSmmPowerButtonSmi2].RegisteredCallbacks.Size == 1)
+ PButtonSmiEnable();
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmPButtonRemoveHandler2
+//
+// Description: This function removes Power button SMI II handler
+//
+// Input: *Context - Pointer to EFI_SMM_POWER_BUTTON_REGISTER_CONTEXT
+//
+// Output: EFI_SUCCESS;
+//
+// Notes: GENERALLY NO PORTING REQUIRED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmPButtonRemoveHandler2 (
+ IN VOID *Context )
+{
+ if (Smm2Handler[EfiSmmPowerButtonSmi2].RegisteredCallbacks.Size == 1)
+ PButtonSmiDisable();
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmPButtonVerifyContext2
+//
+// Description: This function verifies Power button SMI II context
+//
+// Input: *Context - Pointer to SMI II context
+//
+// Output: EFI_STATUS
+// EFI_INVALID_PARAMETER - Given context is invalid
+// EFI_SUCCESS - Context verified
+// EFI_UNSUPPORTED - Context is not supported
+//
+// Notes: GENERALLY NO PORTING REQUIRED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmPButtonVerifyContext2 (
+ IN VOID *Context )
+{
+ EFI_SMM_POWER_BUTTON_REGISTER_CONTEXT *PButtonContext;
+
+ PButtonContext = (EFI_SMM_POWER_BUTTON_REGISTER_CONTEXT *)Context;
+ if (PButtonContext->Phase >= EfiPowerButtonMax)
+ return EFI_INVALID_PARAMETER;
+
+ return (PButtonContext->Phase > EfiPowerButtonEntry) ? \
+ EFI_UNSUPPORTED : EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmPButtonGetContext2
+//
+// Description: This function verifies Power button SMI II event and sets
+// Power button SMI II context
+//
+// Input: None
+//
+// Output: BOOLEAN
+// TRUE - Power button SMI occured, context saved
+// FALSE - There was no Power button SMI
+//
+// Notes: GENERALLY NO PORTING REQUIRED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN SmmPButtonGetContext2 (VOID)
+{
+ UINT16 Dummy = 0;
+ BOOLEAN PButtonSmiDetected;
+
+ PButtonSmiDetected = PButtonSmiDetect( &Dummy );
+
+ SmiContext.PBtnContext.Phase = EfiPowerButtonEntry;
+
+ return PButtonSmiDetected;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmPButtonDispatchSmi2
+//
+// Description: This function dispatches Power button SMI II event based on
+// context
+//
+// Input: None
+//
+// Output: EFI_STATUS
+//
+// Notes: GENERALLY NO PORTING REQUIRED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmPButtonDispatchSmi2 (VOID)
+{
+ EFI_STATUS Status = EFI_WARN_INTERRUPT_SOURCE_QUIESCED;
+ HANDLER_LINK2 *Handler = (HANDLER_LINK2 *)\
+ Smm2Handler[EfiSmmPowerButtonSmi2].RegisteredCallbacks.pHead;
+ EFI_SMM_POWER_BUTTON_REGISTER_CONTEXT *PButtonContext;
+
+ while (Handler != NULL) {
+ PButtonContext = \
+ (EFI_SMM_POWER_BUTTON_REGISTER_CONTEXT *)Handler->Context;
+
+ if (PButtonContext->Phase == SmiContext.PBtnContext.Phase)
+ Status = Handler->Callback( Handler, PButtonContext, NULL, NULL );
+
+ Handler = (HANDLER_LINK2 *)Handler->Link.pNext;
+ }
+
+#if (PI_0_9_CHILD_DISPATCHER_SUPPORT == 0)
+ PButtonSmiClear();
+ SBLib_Shutdown();
+
+ return Status;
+#else
+ return EFI_WARN_INTERRUPT_SOURCE_QUIESCED;
+#endif
+}
+
+//---------------------------------------------------------------------------
+// I/O Trap SMI II Handler functions
+//---------------------------------------------------------------------------
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmIoTrapAddHandler2
+//
+// Description: This function adds I/O Trap SMI II handler
+//
+// Input: *Context - Pointer to EFI_SMM_IO_TRAP_REGISTER_CONTEXT
+//
+// Output: EFI_SUCCESS - The context has been registerd successfully.
+//
+// Notes: GENERALLY NO PORTING REQUIRED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmIoTrapAddHandler2 (
+ IN VOID *Context )
+{
+ HANDLER_LINK2 *Handler;
+ EFI_SMM_IO_TRAP_REGISTER_CONTEXT *RegedContext;
+ EFI_SMM_IO_TRAP_REGISTER_CONTEXT *IoTrapContext;
+ UINT32 TrapRegIndex = 0;
+ UINT32 i = 0;
+
+ IoTrapContext = (EFI_SMM_IO_TRAP_REGISTER_CONTEXT *)Context;
+
+ Handler = \
+ (HANDLER_LINK2 *)Smm2Handler[EfiSmmIoTrapSmi2].RegisteredCallbacks.pHead;
+
+ while (Handler != NULL) {
+ RegedContext = (EFI_SMM_IO_TRAP_REGISTER_CONTEXT *)Handler->Context;
+ if ((RegedContext->Address == IoTrapContext->Address) && \
+ (RegedContext->Type == IoTrapContext->Type) && \
+ (RegedContext->Length == IoTrapContext->Length)) {
+ i++;
+ }
+ Handler = (HANDLER_LINK2 *)Handler->Link.pNext;
+ }
+
+ if (i > 1) return EFI_SUCCESS;
+
+ IoTrapSmiSet2( IoTrapContext, &TrapRegIndex );
+
+ gEnabledIoTrapSmi |= (UINT32)(1 << TrapRegIndex);
+
+ if (Smm2Handler[EfiSmmIoTrapSmi2].RegisteredCallbacks.Size == 1)
+ IoTrapSmiEnable2();
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmIoTrapRemoveHandler2
+//
+// Description: This function removes I/O Trap SMI II handler
+//
+// Input: *Context - Pointer to EFI_SMM_IO_TRAP_REGISTER_CONTEXT
+//
+// Output: EFI_SUCCESS
+//
+// Notes: GENERALLY NO PORTING REQUIRED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmIoTrapRemoveHandler2 (
+ IN VOID *Context )
+{
+ HANDLER_LINK2 *Handler;
+ EFI_SMM_IO_TRAP_REGISTER_CONTEXT *RegedContext;
+ EFI_SMM_IO_TRAP_REGISTER_CONTEXT *RemoveContext;
+ UINT32 i = 0;
+ UINT32 TrapRegIndex = 0;
+
+ RemoveContext = (EFI_SMM_IO_TRAP_REGISTER_CONTEXT *)Context;
+
+ Handler = \
+ (HANDLER_LINK2 *)Smm2Handler[EfiSmmIoTrapSmi2].RegisteredCallbacks.pHead;
+
+ while (Handler != NULL) {
+ RegedContext = (EFI_SMM_IO_TRAP_REGISTER_CONTEXT *)Handler->Context;
+ if ((RegedContext->Address == RemoveContext->Address) && \
+ (RegedContext->Type == RemoveContext->Type) && \
+ (RegedContext->Length == RemoveContext->Length)) i++;
+ Handler = (HANDLER_LINK2 *)Handler->Link.pNext;
+ }
+
+ if (i > 1) return EFI_SUCCESS;
+
+ IoTrapSmiReset2( Context, &TrapRegIndex );
+
+ gEnabledIoTrapSmi &= ~(1 << TrapRegIndex);
+
+ if (gEnabledIoTrapSmi == 0) IoTrapSmiDisable2();
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmIoTrapVerifyContext2
+//
+// Description: This function verifies I/O Trap SMI II context
+//
+// Input: *Context - Pointer to SMI II context
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS - Context verified
+// EFI_INVALID_PARAMETER - Given context is invalid
+// EFI_UNSUPPORTED - Context is not supported
+// EFI_OUT_OF_RESOURCES - There is no I/O Trap register
+// available
+//
+// Notes: GENERALLY NO PORTING REQUIRED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmIoTrapVerifyContext2 (
+ IN VOID *Context )
+{
+ HANDLER_LINK2 *Handler;
+ EFI_SMM_IO_TRAP_REGISTER_CONTEXT *RegedContext;
+ EFI_SMM_IO_TRAP_REGISTER_CONTEXT *IoTrapContext;
+
+ Handler = \
+ (HANDLER_LINK2 *)Smm2Handler[EfiSmmIoTrapSmi2].RegisteredCallbacks.pHead;
+
+ IoTrapContext = (EFI_SMM_IO_TRAP_REGISTER_CONTEXT *)Context;
+
+ while (Handler != NULL) {
+ RegedContext = (EFI_SMM_IO_TRAP_REGISTER_CONTEXT *)Handler->Context;
+ if ((RegedContext->Address == IoTrapContext->Address) && \
+ (RegedContext->Type == IoTrapContext->Type)) {
+ if ( IoTrapContext->Length > MAX_SUPPORTED_IOTRAP_LENGTH)
+ return EFI_INVALID_PARAMETER;
+ return EFI_SUCCESS;
+ }
+ Handler = (HANDLER_LINK2 *)Handler->Link.pNext;
+ }
+
+ if (gEnabledIoTrapSmi >= ((1 << MAX_SUPPORTED_IOTRAP_REGS) - 1))
+ return EFI_OUT_OF_RESOURCES;
+
+ if (IoTrapContext->Length > MAX_SUPPORTED_IOTRAP_LENGTH)
+ return EFI_INVALID_PARAMETER;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmIoTrapGetContext2
+//
+// Description: This function verifies I/O Trap SMI II event and sets
+// I/O Trap SMI II context.
+//
+// Input: None
+//
+// Output: BOOLEAN
+// TRUE - I/O Trap SMI occured, context saved
+// FALSE - There was no I/O Trap SMI
+// The global variable gIoTrapWriteData will save the data from
+// I/O write cycle.
+//
+// Notes: GENERALLY NO PORTING REQUIRED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN SmmIoTrapGetContext2 (VOID)
+{
+ return IoTrapSmiDetect2( &SmiContext.IoTrapContext, &gIoTrapWriteData );
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmIoTrapDispatchSmi2
+//
+// Description: This function dispatches I/O Trap SMI II event based on
+// context.
+//
+// Input: None
+//
+// Output: EFI_STATUS
+//
+// Notes: GENERALLY NO PORTING REQUIRED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmIoTrapDispatchSmi2 (VOID)
+{
+ EFI_STATUS Status = EFI_WARN_INTERRUPT_SOURCE_QUIESCED;
+ HANDLER_LINK2 *Handler;
+ EFI_SMM_IO_TRAP_REGISTER_CONTEXT *IoTrapContext;
+ volatile UINT16 MaxAddress;
+
+ Handler = \
+ (HANDLER_LINK2 *)Smm2Handler[EfiSmmIoTrapSmi2].RegisteredCallbacks.pHead;
+ while (Handler != NULL) {
+ IoTrapContext = (EFI_SMM_IO_TRAP_REGISTER_CONTEXT *)Handler->Context;
+ MaxAddress = IoTrapContext->Address + IoTrapContext->Length;
+ if ((IoTrapContext->Address <= SmiContext.IoTrapContext.Address) && \
+ (MaxAddress > SmiContext.IoTrapContext.Address)) {
+ if ((IoTrapContext->Type == ReadWriteTrap) || \
+ (IoTrapContext->Type == SmiContext.IoTrapContext.Type)) {
+ Status = Handler->Callback( \
+ Handler, \
+ (EFI_SMM_IO_TRAP_CONTEXT*)&gIoTrapWriteData, \
+ NULL, \
+ NULL );
+ }
+ }
+ Handler = (HANDLER_LINK2 *)Handler->Link.pNext;
+ }
+#if (PI_0_9_CHILD_DISPATCHER_SUPPORT == 0)
+ if (Status != EFI_WARN_INTERRUPT_SOURCE_QUIESCED) IoTrapSmiClear2();
+ return Status;
+#else
+ return EFI_WARN_INTERRUPT_SOURCE_QUIESCED;
+#endif
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************