Home | History | Annotate | Download | only in SmramSaveInfoHandlerSmm
      1 /** @file
      2   A helper driver to save information to SMRAM after SMRR is enabled.
      3 
      4   This driver is for ECP platforms.
      5 
      6   Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
      7 
      8   This program and the accompanying materials are licensed and made available under
     10   the terms and conditions of the BSD License that accompanies this distribution.
     12   The full text of the license may be found at
     14   http://opensource.org/licenses/bsd-license.php.
     16 
     18   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     20   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     22 
     24 
     26 **/
     27 
     28 #include <PiSmm.h>
     29 #include <Library/DebugLib.h>
     30 #include <Library/UefiDriverEntryPoint.h>
     31 #include <Library/UefiRuntimeServicesTableLib.h>
     32 #include <Library/SmmServicesTableLib.h>
     33 #include <Library/BaseLib.h>
     34 #include <Library/BaseMemoryLib.h>
     35 #include <Library/IoLib.h>
     36 #include <Protocol/SmmSwDispatch.h>
     37 #include <Protocol/SmmReadyToLock.h>
     38 #include <Protocol/SmmControl.h>
     39 #include <Guid/Vlv2DeviceRefCodePkgTokenSpace.h>
     40 
     41 #define SMM_FROM_SMBASE_DRIVER        0x55
     42 #define SMM_FROM_CPU_DRIVER_SAVE_INFO 0x81
     43 
     44 #define EFI_SMRAM_CPU_NVS_HEADER_GUID \
     45   { \
     46     0x429501d9, 0xe447, 0x40f4, 0x86, 0x7b, 0x75, 0xc9, 0x3a, 0x1d, 0xb5, 0x4e \
     47   }
     48 
     49 UINT8    mSmiDataRegister;
     50 BOOLEAN  mLocked = FALSE;
     51 EFI_GUID mSmramCpuNvsHeaderGuid = EFI_SMRAM_CPU_NVS_HEADER_GUID;
     52 
     53 /**
     54   Dispatch function for a Software SMI handler.
     55 
     56   @param  DispatchHandle        The handle of this dispatch function.
     57   @param  DispatchContext       The pointer to the dispatch function's context.
     58                                 The SwSmiInputValue field is filled in
     59                                 by the software dispatch driver prior to
     60                                 invoking this dispatch function.
     61                                 The dispatch function will only be called
     62                                 for input values for which it is registered.
     63 
     64   @return None
     65 
     66 **/
     67 VOID
     68 EFIAPI
     69 SmramSaveInfoHandler (
     70   IN  EFI_HANDLE                    DispatchHandle,
     71   IN  EFI_SMM_SW_DISPATCH_CONTEXT   *DispatchContext
     72   )
     73 {
     74   ASSERT (DispatchContext != NULL);
     75   ASSERT (DispatchContext->SwSmiInputValue == SMM_FROM_SMBASE_DRIVER);
     76 
     77   if (!mLocked && IoRead8 (mSmiDataRegister) == SMM_FROM_CPU_DRIVER_SAVE_INFO) {
     78       CopyMem (
     79         (VOID *)(UINTN)(PcdGetEx64 (&gEfiVLVTokenSpaceGuid, PcdCpuLockBoxDataAddress)),
     80         (VOID *)(UINTN)(PcdGetEx64 (&gEfiVLVTokenSpaceGuid, PcdCpuSmramCpuDataAddress)),
     81         (UINTN)(PcdGetEx64 (&gEfiVLVTokenSpaceGuid, PcdCpuLockBoxSize))
     82         );
     83   }
     84 }
     85 
     86 /**
     87   Smm Ready To Lock event notification handler.
     88 
     89   It sets a flag indicating that SMRAM has been locked.
     90 
     91   @param[in] Protocol   Points to the protocol's unique identifier.
     92   @param[in] Interface  Points to the interface instance.
     93   @param[in] Handle     The handle on which the interface was installed.
     94 
     95   @retval EFI_SUCCESS   Notification handler runs successfully.
     96  **/
     97 EFI_STATUS
     98 EFIAPI
     99 SmmReadyToLockEventNotify (
    100   IN CONST EFI_GUID  *Protocol,
    101   IN VOID            *Interface,
    102   IN EFI_HANDLE      Handle
    103   )
    104 {
    105   mLocked = TRUE;
    106   return EFI_SUCCESS;
    107 }
    108 
    109 /**
    110   Entry point function of this driver.
    111 
    112   @param[in] ImageHandle  The firmware allocated handle for the EFI image.
    113   @param[in] SystemTable  A pointer to the EFI System Table.
    114 
    115   @retval EFI_SUCCESS     The entry point is executed successfully.
    116   @retval other           Some error occurs when executing this entry point.
    117 **/
    118 EFI_STATUS
    119 EFIAPI
    120 SmramSaveInfoHandlerSmmMain (
    121   IN EFI_HANDLE        ImageHandle,
    122   IN EFI_SYSTEM_TABLE  *SystemTable
    123   )
    124 {
    125   EFI_STATUS                    Status;
    126   EFI_SMM_SW_DISPATCH_PROTOCOL  *SmmSwDispatch;
    127   EFI_SMM_SW_DISPATCH_CONTEXT   SmmSwDispatchContext;
    128   EFI_HANDLE                    DispatchHandle;
    129   EFI_SMM_CONTROL_PROTOCOL      *SmmControl;
    130   EFI_SMM_CONTROL_REGISTER      SmmControlRegister;
    131   VOID                          *Registration;
    132 
    133   //
    134   // Get SMI data register
    135   //
    136   Status = SystemTable->BootServices->LocateProtocol (
    137                                         &gEfiSmmControlProtocolGuid,
    138                                         NULL,
    139                                         (VOID **)&SmmControl
    140                                         );
    141   ASSERT_EFI_ERROR (Status);
    142   Status = SmmControl->GetRegisterInfo (SmmControl, &SmmControlRegister);
    143   ASSERT_EFI_ERROR (Status);
    144   mSmiDataRegister = SmmControlRegister.SmiDataRegister;
    145 
    146   //
    147   // Register software SMI handler
    148   //
    149 
    150   Status = SystemTable->BootServices->LocateProtocol (
    151                                         &gEfiSmmSwDispatchProtocolGuid,
    152                                         NULL,
    153                                         (VOID **)&SmmSwDispatch
    154                                         );
    155   ASSERT_EFI_ERROR (Status);
    156 
    157   SmmSwDispatchContext.SwSmiInputValue = SMM_FROM_SMBASE_DRIVER;
    158   Status = SmmSwDispatch->Register (
    159                             SmmSwDispatch,
    160                             &SmramSaveInfoHandler,
    161                             &SmmSwDispatchContext,
    162                             &DispatchHandle
    163                             );
    164   ASSERT_EFI_ERROR (Status);
    165 
    166   //
    167   // Register SMM Ready To Lock Protocol notification
    168   //
    169   Status = gSmst->SmmRegisterProtocolNotify (
    170                     &gEfiSmmReadyToLockProtocolGuid,
    171                     SmmReadyToLockEventNotify,
    172                     &Registration
    173                     );
    174   ASSERT_EFI_ERROR (Status);
    175 
    176   return Status;
    177 }
    178 
    179