//************************************************************************* //************************************************************************* //** ** //** (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. // //************************************************************************* // // // Name: SmiHandlerGeneric2.c // // Description: This file contains implementation of generic SMI handler II // functions // // //************************************************************************* //--------------------------------------------------------------------------- // Include(s) //--------------------------------------------------------------------------- #include #include #include #include "SmmChildDispatch2.h" #include //--------------------------------------------------------------------------- // 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 //--------------------------------------------------------------------------- // //---------------------------------------------------------------------------- // // 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 //---------------------------------------------------------------------------- // EFI_STATUS SmmSwAddHandler2 ( IN VOID *Context ) { if (Smm2Handler[EfiSmmSwSmi2].RegisteredCallbacks.Size == 1) SwSmiEnable(); return EFI_SUCCESS; } // //---------------------------------------------------------------------------- // // 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 //---------------------------------------------------------------------------- // 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; } // //---------------------------------------------------------------------------- // // 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 //---------------------------------------------------------------------------- // 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; } // //---------------------------------------------------------------------------- // // 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 //---------------------------------------------------------------------------- // 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; } // //---------------------------------------------------------------------------- // // Procedure: SmmSwDispatchSmi2 // // Description: This function dispatches SW SMI II event based on context // // Input: None // // Output: EFI_STATUS // // Notes: GENERALLY NO PORTING REQUIRED //---------------------------------------------------------------------------- // 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 //--------------------------------------------------------------------------- // //---------------------------------------------------------------------------- // // 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 //---------------------------------------------------------------------------- // EFI_STATUS SmmSxAddHandler2 ( IN VOID *Context ) { #if SLP_SMI_ENABLE_ON_REGISTER if (Smm2Handler[EfiSmmSxSmi2].RegisteredCallbacks.Size == 1) SxSmiEnable(); #endif return EFI_SUCCESS; } // //---------------------------------------------------------------------------- // // 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 //---------------------------------------------------------------------------- // 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; } // //---------------------------------------------------------------------------- // // 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 //---------------------------------------------------------------------------- // 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; } // //---------------------------------------------------------------------------- // // 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 //---------------------------------------------------------------------------- // BOOLEAN SmmSxGetContext2 (VOID) { UINT16 SxSleepState; BOOLEAN SxSmiDetected; SxSmiDetected = SxSmiDetect( &SxSleepState ); SmiContext.SxContext.Type = SxSleepState; SmiContext.SxContext.Phase = SxEntry; return SxSmiDetected; } // //---------------------------------------------------------------------------- // // Procedure: SmmSxDispatchSmi2 // // Description: This function dispatches Sx SMI II event based on context // // Input: None // // Output: EFI_STATUS // // Notes: GENERALLY NO PORTING REQUIRED //---------------------------------------------------------------------------- // 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 //--------------------------------------------------------------------------- // //---------------------------------------------------------------------------- // // 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 //---------------------------------------------------------------------------- // 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; } // //---------------------------------------------------------------------------- // // 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 //---------------------------------------------------------------------------- // 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; } // //---------------------------------------------------------------------------- // // 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 //---------------------------------------------------------------------------- // 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; } // //---------------------------------------------------------------------------- // // 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 //---------------------------------------------------------------------------- // BOOLEAN SmmTimerGetContext2 (VOID) { UINT16 TimerType; BOOLEAN TimerSmiDetected; TimerSmiDetected = TimerSmiDetect2( &TimerType ); SmiContext.TimerContext.OrgContext.SmiTickInterval = gCurrentInterval; return TimerSmiDetected; } // //---------------------------------------------------------------------------- // // Procedure: SmmTimerDispatchSmi2 // // Description: This function dispatches Periodic timer SMI event based on // context // // Input: None // // Output: EFI_STATUS // // Notes: GENERALLY NO PORTING REQUIRED //---------------------------------------------------------------------------- // 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 //--------------------------------------------------------------------------- // //---------------------------------------------------------------------------- // // 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 //---------------------------------------------------------------------------- // 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; } // //---------------------------------------------------------------------------- // // 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 //---------------------------------------------------------------------------- // 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; } // //---------------------------------------------------------------------------- // // 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 //---------------------------------------------------------------------------- // 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; } // //---------------------------------------------------------------------------- // // 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 //---------------------------------------------------------------------------- // BOOLEAN SmmUsbGetContext2 (VOID) { BOOLEAN UsbSmiDetected; UsbSmiDetected = UsbSmiDetect( &gActiveUsbSmi ); SmiContext.UsbContext.Type = UsbLegacy; return UsbSmiDetected; } // //---------------------------------------------------------------------------- // // Procedure: SmmUsbDispatchSmi2 // // Description: This function dispatches USB SMI II event based on context // // Input: None // // Output: EFI_STATUS // // Notes: GENERALLY NO PORTING REQUIRED //---------------------------------------------------------------------------- // 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 //--------------------------------------------------------------------------- // //---------------------------------------------------------------------------- // // 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 //---------------------------------------------------------------------------- // 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; } // //---------------------------------------------------------------------------- // // 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 //---------------------------------------------------------------------------- // 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; } // //---------------------------------------------------------------------------- // // 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 //---------------------------------------------------------------------------- // 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; } // //---------------------------------------------------------------------------- // // 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 //---------------------------------------------------------------------------- // BOOLEAN SmmGpiGetContext2 (VOID) { BOOLEAN GpiSmiDetected; UINT32 GpiSmiNum; GpiSmiDetected = GpiSmiDetect( &GpiSmiNum ); SmiContext.GpiContext.GpiNum = GpiSmiNum; return GpiSmiDetected; } // //---------------------------------------------------------------------------- // // Procedure: SmmGpiDispatchSmi2 // // Description: This function dispatches GPI SMI event based on context // // Input: None // // Output: EFI_STATUS // // Notes: GENERALLY NO PORTING REQUIRED //---------------------------------------------------------------------------- // 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 //--------------------------------------------------------------------------- // //---------------------------------------------------------------------------- // // 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 //---------------------------------------------------------------------------- // EFI_STATUS SmmSButtonAddHandler2 ( IN VOID *Context ) { if (Smm2Handler[EfiSmmStandbyButtonSmi2].RegisteredCallbacks.Size == 1) SButtonSmiEnable(); return EFI_SUCCESS; } // //---------------------------------------------------------------------------- // // 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 //---------------------------------------------------------------------------- // EFI_STATUS SmmSButtonRemoveHandler2 ( IN VOID *Context ) { if (Smm2Handler[EfiSmmStandbyButtonSmi2].RegisteredCallbacks.Size == 1) SButtonSmiDisable(); return EFI_SUCCESS; } // //---------------------------------------------------------------------------- // // 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 //---------------------------------------------------------------------------- // 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; } // //---------------------------------------------------------------------------- // // 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 //---------------------------------------------------------------------------- // BOOLEAN SmmSButtonGetContext2 (VOID) { UINT16 Dummy = 0; BOOLEAN SButtonSmiDetected; SButtonSmiDetected = SButtonSmiDetect( &Dummy ); SmiContext.SBtnContext.Phase = EfiStandbyButtonEntry; return SButtonSmiDetected; } // //---------------------------------------------------------------------------- // // Procedure: SmmSButtonDispatchSmi2 // // Description: This function dispatches Standby button SMI II event based on // context // // Input: None // // Output: EFI_STATUS // // Notes: GENERALLY NO PORTING REQUIRED //---------------------------------------------------------------------------- // 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 //--------------------------------------------------------------------------- // //---------------------------------------------------------------------------- // // 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 //---------------------------------------------------------------------------- // EFI_STATUS SmmPButtonAddHandler2 ( IN VOID *Context ) { if (Smm2Handler[EfiSmmPowerButtonSmi2].RegisteredCallbacks.Size == 1) PButtonSmiEnable(); return EFI_SUCCESS; } // //---------------------------------------------------------------------------- // // 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 //---------------------------------------------------------------------------- // EFI_STATUS SmmPButtonRemoveHandler2 ( IN VOID *Context ) { if (Smm2Handler[EfiSmmPowerButtonSmi2].RegisteredCallbacks.Size == 1) PButtonSmiDisable(); return EFI_SUCCESS; } // //---------------------------------------------------------------------------- // // 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 //---------------------------------------------------------------------------- // 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; } // //---------------------------------------------------------------------------- // // 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 //---------------------------------------------------------------------------- // BOOLEAN SmmPButtonGetContext2 (VOID) { UINT16 Dummy = 0; BOOLEAN PButtonSmiDetected; PButtonSmiDetected = PButtonSmiDetect( &Dummy ); SmiContext.PBtnContext.Phase = EfiPowerButtonEntry; return PButtonSmiDetected; } // //---------------------------------------------------------------------------- // // Procedure: SmmPButtonDispatchSmi2 // // Description: This function dispatches Power button SMI II event based on // context // // Input: None // // Output: EFI_STATUS // // Notes: GENERALLY NO PORTING REQUIRED //---------------------------------------------------------------------------- // 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 //--------------------------------------------------------------------------- // //---------------------------------------------------------------------------- // // 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 //---------------------------------------------------------------------------- // 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; } // //---------------------------------------------------------------------------- // // 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 //---------------------------------------------------------------------------- // 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; } // //---------------------------------------------------------------------------- // // 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 //---------------------------------------------------------------------------- // 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; } // //---------------------------------------------------------------------------- // // 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 //---------------------------------------------------------------------------- // BOOLEAN SmmIoTrapGetContext2 (VOID) { return IoTrapSmiDetect2( &SmiContext.IoTrapContext, &gIoTrapWriteData ); } // //---------------------------------------------------------------------------- // // 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 //---------------------------------------------------------------------------- // 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 ** //** ** //************************************************************************* //*************************************************************************