Home | History | Annotate | Download | only in SmmBaseHelper
      1 /** @file
      2 
      3   Copyright (c) 2014 - 2015, Intel Corporation. All rights reserved.<BR>
      4   This program and the accompanying materials
      5   are licensed and made available under the terms and conditions of the BSD License
      6   which accompanies this distribution.  The full text of the license may be found at
      7   http://opensource.org/licenses/bsd-license.php.
      8 
      9   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     10   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     11 
     12 **/
     13 
     14 #include <PiSmm.h>
     15 
     16 #include <Library/BaseLib.h>
     17 #include <Library/MemoryAllocationLib.h>
     18 #include <Library/UefiBootServicesTableLib.h>
     19 #include <Library/SmmServicesTableLib.h>
     20 #include <Library/DevicePathLib.h>
     21 #include <Library/BaseMemoryLib.h>
     22 #include <Library/DebugLib.h>
     23 #include <Library/PcdLib.h>
     24 #include <Protocol/SmmCommunication.h>
     25 
     26 #include <Guid/MemoryProfile.h>
     27 
     28 EFI_SMM_COMMUNICATION_PROTOCOL *mSmmCommunication = NULL;
     29 
     30 /**
     31   Get the GUID file name from the file path.
     32 
     33   @param FilePath  File path.
     34 
     35   @return The GUID file name from the file path.
     36 
     37 **/
     38 EFI_GUID *
     39 GetFileNameFromFilePath (
     40   IN EFI_DEVICE_PATH_PROTOCOL   *FilePath
     41   )
     42 {
     43   MEDIA_FW_VOL_FILEPATH_DEVICE_PATH     *ThisFilePath;
     44 
     45   ThisFilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) FilePath;
     46   while (!IsDevicePathEnd (ThisFilePath)) {
     47     if ((DevicePathType (ThisFilePath) == MEDIA_DEVICE_PATH) && (DevicePathSubType (ThisFilePath) == MEDIA_PIWG_FW_FILE_DP)) {
     48       return &ThisFilePath->FvFileName;
     49     }
     50     ThisFilePath = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) NextDevicePathNode (ThisFilePath);
     51   }
     52 
     53   return NULL;
     54 }
     55 
     56 /**
     57   Register SMM image to SMRAM profile.
     58 
     59   @param[in] FilePath           File path of the image.
     60   @param[in] ImageBuffer        Image base address.
     61   @param[in] NumberOfPage       Number of page.
     62 
     63   @retval TRUE                  Register success.
     64   @retval FALSE                 Register fail.
     65 
     66 **/
     67 BOOLEAN
     68 RegisterSmramProfileImage (
     69   IN EFI_DEVICE_PATH_PROTOCOL   *FilePath,
     70   IN PHYSICAL_ADDRESS           ImageBuffer,
     71   IN UINTN                      NumberOfPage
     72   )
     73 {
     74   EFI_GUID                                      *FileName;
     75   EFI_STATUS                                    Status;
     76   UINTN                                         CommSize;
     77   UINT8                                         CommBuffer[sizeof (EFI_GUID) + sizeof (UINTN) + sizeof (SMRAM_PROFILE_PARAMETER_REGISTER_IMAGE)];
     78   EFI_SMM_COMMUNICATE_HEADER                    *CommHeader;
     79   SMRAM_PROFILE_PARAMETER_REGISTER_IMAGE        *CommRegisterImage;
     80 
     81   if ((PcdGet8 (PcdMemoryProfilePropertyMask) & BIT1) == 0) {
     82     return FALSE;
     83   }
     84 
     85   FileName = GetFileNameFromFilePath (FilePath);
     86 
     87   if (mSmmCommunication == NULL) {
     88     Status = gBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **) &mSmmCommunication);
     89     ASSERT_EFI_ERROR (Status);
     90   }
     91 
     92   CommHeader = (EFI_SMM_COMMUNICATE_HEADER *) &CommBuffer[0];
     93   CopyMem (&CommHeader->HeaderGuid, &gEdkiiMemoryProfileGuid, sizeof (gEdkiiMemoryProfileGuid));
     94   CommHeader->MessageLength = sizeof (SMRAM_PROFILE_PARAMETER_REGISTER_IMAGE);
     95 
     96   CommRegisterImage = (SMRAM_PROFILE_PARAMETER_REGISTER_IMAGE *)&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)];
     97   CommRegisterImage->Header.Command      = SMRAM_PROFILE_COMMAND_REGISTER_IMAGE;
     98   CommRegisterImage->Header.DataLength   = sizeof (*CommRegisterImage);
     99   CommRegisterImage->Header.ReturnStatus = (UINT64)-1;
    100   CopyMem (&CommRegisterImage->FileName, FileName, sizeof(EFI_GUID));
    101   CommRegisterImage->ImageBuffer         = ImageBuffer;
    102   CommRegisterImage->NumberOfPage        = NumberOfPage;
    103 
    104   CommSize = sizeof (EFI_GUID) + sizeof (UINTN) + CommHeader->MessageLength;
    105   Status = mSmmCommunication->Communicate (mSmmCommunication, CommBuffer, &CommSize);
    106   ASSERT_EFI_ERROR (Status);
    107 
    108   if (CommRegisterImage->Header.ReturnStatus != 0) {
    109     return FALSE;
    110   }
    111 
    112   return TRUE;
    113 }
    114 
    115 /**
    116   Unregister SMM image from SMRAM profile.
    117 
    118   @param[in] FilePath           File path of the image.
    119   @param[in] ImageBuffer        Image base address.
    120   @param[in] NumberOfPage       Number of page.
    121 
    122   @retval TRUE                  Unregister success.
    123   @retval FALSE                 Unregister fail.
    124 
    125 **/
    126 BOOLEAN
    127 UnregisterSmramProfileImage (
    128   IN EFI_DEVICE_PATH_PROTOCOL   *FilePath,
    129   IN PHYSICAL_ADDRESS           ImageBuffer,
    130   IN UINTN                      NumberOfPage
    131   )
    132 {
    133   EFI_GUID                                      *FileName;
    134   EFI_STATUS                                    Status;
    135   UINTN                                         CommSize;
    136   UINT8                                         CommBuffer[sizeof (EFI_GUID) + sizeof (UINTN) + sizeof (SMRAM_PROFILE_PARAMETER_UNREGISTER_IMAGE)];
    137   EFI_SMM_COMMUNICATE_HEADER                    *CommHeader;
    138   SMRAM_PROFILE_PARAMETER_UNREGISTER_IMAGE      *CommUnregisterImage;
    139 
    140   if ((PcdGet8 (PcdMemoryProfilePropertyMask) & BIT1) == 0) {
    141     return FALSE;
    142   }
    143 
    144   FileName = GetFileNameFromFilePath (FilePath);
    145 
    146   if (mSmmCommunication == NULL) {
    147     Status = gBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **) &mSmmCommunication);
    148     ASSERT_EFI_ERROR (Status);
    149   }
    150 
    151   CommHeader = (EFI_SMM_COMMUNICATE_HEADER *)&CommBuffer[0];
    152   CopyMem (&CommHeader->HeaderGuid, &gEdkiiMemoryProfileGuid, sizeof(gEdkiiMemoryProfileGuid));
    153   CommHeader->MessageLength = sizeof(SMRAM_PROFILE_PARAMETER_UNREGISTER_IMAGE);
    154 
    155   CommUnregisterImage = (SMRAM_PROFILE_PARAMETER_UNREGISTER_IMAGE *)&CommBuffer[OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)];
    156   CommUnregisterImage->Header.Command      = SMRAM_PROFILE_COMMAND_UNREGISTER_IMAGE;
    157   CommUnregisterImage->Header.DataLength   = sizeof (*CommUnregisterImage);
    158   CommUnregisterImage->Header.ReturnStatus = (UINT64)-1;
    159   CopyMem (&CommUnregisterImage->FileName, FileName, sizeof(EFI_GUID));
    160   CommUnregisterImage->ImageBuffer         = ImageBuffer;
    161   CommUnregisterImage->NumberOfPage        = NumberOfPage;
    162 
    163   CommSize = sizeof (EFI_GUID) + sizeof (UINTN) + CommHeader->MessageLength;
    164   Status = mSmmCommunication->Communicate (mSmmCommunication, CommBuffer, &CommSize);
    165   ASSERT_EFI_ERROR (Status);
    166 
    167   if (CommUnregisterImage->Header.ReturnStatus != 0) {
    168     return FALSE;
    169   }
    170 
    171   return TRUE;
    172 }
    173