Home | History | Annotate | Download | only in FspNotifyDxe
      1 /** @file
      2   This driver will register two callbacks to call fsp's notifies.
      3 
      4   Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>
      5   This program and the accompanying materials
      6   are licensed and made available under the terms and conditions of the BSD License
      7   which accompanies this distribution.  The full text of the license may be found at
      8   http://opensource.org/licenses/bsd-license.php.
      9 
     10   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 #include <PiDxe.h>
     16 
     17 #include <Protocol/PciEnumerationComplete.h>
     18 
     19 #include <Library/UefiDriverEntryPoint.h>
     20 #include <Library/UefiBootServicesTableLib.h>
     21 #include <Library/DebugLib.h>
     22 #include <Library/BaseMemoryLib.h>
     23 #include <Library/UefiLib.h>
     24 #include <Library/FspApiLib.h>
     25 
     26 /**
     27   Relocate this image under 4G memory.
     28 
     29   @param  ImageHandle  Handle of driver image.
     30   @param  SystemTable  Pointer to system table.
     31 
     32   @retval EFI_SUCCESS  Image successfully relocated.
     33   @retval EFI_ABORTED  Failed to relocate image.
     34 
     35 **/
     36 EFI_STATUS
     37 RelocateImageUnder4GIfNeeded (
     38   IN EFI_HANDLE           ImageHandle,
     39   IN EFI_SYSTEM_TABLE     *SystemTable
     40   );
     41 
     42 FSP_INFO_HEADER *mFspHeader = NULL;
     43 
     44 /**
     45   PciEnumerationComplete Protocol notification event handler.
     46 
     47   @param[in] Event    Event whose notification function is being invoked.
     48   @param[in] Context  Pointer to the notification function's context.
     49 **/
     50 VOID
     51 EFIAPI
     52 OnPciEnumerationComplete (
     53   IN EFI_EVENT  Event,
     54   IN VOID       *Context
     55   )
     56 {
     57   NOTIFY_PHASE_PARAMS NotifyPhaseParams;
     58   EFI_STATUS          Status;
     59   VOID                *Interface;
     60 
     61   //
     62   // Try to locate it because gEfiPciEnumerationCompleteProtocolGuid will trigger it once when registration.
     63   // Just return if it is not found.
     64   //
     65   Status = gBS->LocateProtocol (
     66                   &gEfiPciEnumerationCompleteProtocolGuid,
     67                   NULL,
     68                   &Interface
     69                   );
     70   if (EFI_ERROR (Status)) {
     71     return ;
     72   }
     73 
     74   NotifyPhaseParams.Phase = EnumInitPhaseAfterPciEnumeration;
     75   Status = CallFspNotifyPhase (mFspHeader, &NotifyPhaseParams);
     76   if (Status != EFI_SUCCESS) {
     77     DEBUG((DEBUG_ERROR, "FSP NotifyPhase AfterPciEnumeration failed, status: 0x%x\n", Status));
     78   } else {
     79     DEBUG((DEBUG_INFO, "FSP NotifyPhase AfterPciEnumeration Success.\n"));
     80   }
     81 }
     82 
     83 /**
     84   Notification function of EVT_GROUP_READY_TO_BOOT event group.
     85 
     86   This is a notification function registered on EVT_GROUP_READY_TO_BOOT event group.
     87   When the Boot Manager is about to load and execute a boot option, it reclaims variable
     88   storage if free size is below the threshold.
     89 
     90   @param[in] Event        Event whose notification function is being invoked.
     91   @param[in] Context      Pointer to the notification function's context.
     92 
     93 **/
     94 VOID
     95 EFIAPI
     96 OnReadyToBoot (
     97   IN EFI_EVENT  Event,
     98   IN VOID       *Context
     99   )
    100 {
    101   NOTIFY_PHASE_PARAMS NotifyPhaseParams;
    102   EFI_STATUS          Status;
    103 
    104   gBS->CloseEvent (Event);
    105 
    106   NotifyPhaseParams.Phase = EnumInitPhaseReadyToBoot;
    107   Status = CallFspNotifyPhase (mFspHeader, &NotifyPhaseParams);
    108   if (Status != EFI_SUCCESS) {
    109     DEBUG((DEBUG_ERROR, "FSP NotifyPhase ReadyToBoot failed, status: 0x%x\n", Status));
    110   } else {
    111     DEBUG((DEBUG_INFO, "FSP NotifyPhase ReadyToBoot Success.\n"));
    112   }
    113 }
    114 
    115 /**
    116   Main entry for the FSP DXE module.
    117 
    118   This routine registers two callbacks to call fsp's notifies.
    119 
    120   @param[in] ImageHandle    The firmware allocated handle for the EFI image.
    121   @param[in] SystemTable    A pointer to the EFI System Table.
    122 
    123   @retval EFI_SUCCESS       The entry point is executed successfully.
    124   @retval other             Some error occurs when executing this entry point.
    125 
    126 **/
    127 EFI_STATUS
    128 EFIAPI
    129 FspDxeEntryPoint (
    130   IN EFI_HANDLE         ImageHandle,
    131   IN EFI_SYSTEM_TABLE   *SystemTable
    132   )
    133 {
    134   EFI_STATUS Status;
    135   EFI_EVENT  ReadyToBootEvent;
    136   VOID       *Registration;
    137   EFI_EVENT  ProtocolNotifyEvent;
    138 
    139   //
    140   // Load this driver's image to memory
    141   //
    142   Status = RelocateImageUnder4GIfNeeded (ImageHandle, SystemTable);
    143   if (EFI_ERROR (Status)) {
    144     return EFI_SUCCESS;
    145   }
    146 
    147   if (PcdGet32 (PcdFlashFvSecondFspBase) == 0) {
    148     mFspHeader = FspFindFspHeader (PcdGet32 (PcdFlashFvFspBase));
    149   } else {
    150     mFspHeader = FspFindFspHeader (PcdGet32 (PcdFlashFvSecondFspBase));
    151   }
    152   DEBUG ((DEBUG_INFO, "FspHeader - 0x%x\n", mFspHeader));
    153   if (mFspHeader == NULL) {
    154     return EFI_DEVICE_ERROR;
    155   }
    156 
    157   ProtocolNotifyEvent = EfiCreateProtocolNotifyEvent (
    158                           &gEfiPciEnumerationCompleteProtocolGuid,
    159                           TPL_CALLBACK,
    160                           OnPciEnumerationComplete,
    161                           NULL,
    162                           &Registration
    163                           );
    164   ASSERT (ProtocolNotifyEvent != NULL);
    165 
    166   Status = EfiCreateEventReadyToBootEx (
    167              TPL_CALLBACK,
    168              OnReadyToBoot,
    169              NULL,
    170              &ReadyToBootEvent
    171              );
    172   ASSERT_EFI_ERROR (Status);
    173 
    174   return EFI_SUCCESS;
    175 }
    176 
    177