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