1 /** @file 2 SMM Access2 Protocol on SMM Access Protocol Thunk driver. 3 4 Copyright (c) 2009 - 2010, 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 "SmmAccess2OnSmmAccessThunk.h" 16 17 EFI_SMM_ACCESS2_PROTOCOL gSmmAccess2 = { 18 SmmAccess2Open, 19 SmmAccess2Close, 20 SmmAccess2Lock, 21 SmmAccess2GetCapabilities, 22 FALSE, 23 FALSE 24 }; 25 26 EFI_SMM_ACCESS_PROTOCOL *mSmmAccess; 27 UINTN mSmramRegionNumber; 28 29 /** 30 Opens the SMRAM area to be accessible by a boot-service driver. 31 32 This function "opens" SMRAM so that it is visible while not inside of SMM. The function should 33 return EFI_UNSUPPORTED if the hardware does not support hiding of SMRAM. The function 34 should return EFI_DEVICE_ERROR if the SMRAM configuration is locked. 35 36 @param[in] This The EFI_SMM_ACCESS2_PROTOCOL instance. 37 38 @retval EFI_SUCCESS The operation was successful. 39 @retval EFI_UNSUPPORTED The system does not support opening and closing of SMRAM. 40 @retval EFI_DEVICE_ERROR SMRAM cannot be opened, perhaps because it is locked. 41 **/ 42 EFI_STATUS 43 EFIAPI 44 SmmAccess2Open ( 45 IN EFI_SMM_ACCESS2_PROTOCOL *This 46 ) 47 { 48 EFI_STATUS Status; 49 UINTN DescriptorIndex; 50 51 /// 52 /// Open all SMRAM regions via SMM Access Protocol 53 /// 54 55 Status = EFI_SUCCESS; 56 for (DescriptorIndex = 0; DescriptorIndex < mSmramRegionNumber && !EFI_ERROR (Status); DescriptorIndex++) { 57 Status = mSmmAccess->Open (mSmmAccess, DescriptorIndex); 58 } 59 if (!EFI_ERROR (Status)) { 60 gSmmAccess2.OpenState = TRUE; 61 } 62 return Status; 63 } 64 65 /** 66 Inhibits access to the SMRAM. 67 68 This function "closes" SMRAM so that it is not visible while outside of SMM. The function should 69 return EFI_UNSUPPORTED if the hardware does not support hiding of SMRAM. 70 71 @param [in] This The EFI_SMM_ACCESS2_PROTOCOL instance. 72 73 @retval EFI_SUCCESS The operation was successful. 74 @retval EFI_UNSUPPORTED The system does not support opening and closing of SMRAM. 75 @retval EFI_DEVICE_ERROR SMRAM cannot be closed. 76 **/ 77 EFI_STATUS 78 EFIAPI 79 SmmAccess2Close ( 80 IN EFI_SMM_ACCESS2_PROTOCOL *This 81 ) 82 { 83 EFI_STATUS Status; 84 UINTN DescriptorIndex; 85 86 /// 87 /// Close all SMRAM regions via SMM Access Protocol 88 /// 89 90 Status = EFI_SUCCESS; 91 for (DescriptorIndex = 0; DescriptorIndex < mSmramRegionNumber && !EFI_ERROR (Status); DescriptorIndex++) { 92 Status = mSmmAccess->Close (mSmmAccess, DescriptorIndex); 93 } 94 if (!EFI_ERROR (Status)) { 95 gSmmAccess2.OpenState = FALSE; 96 } 97 return Status; 98 } 99 100 /** 101 Inhibits access to the SMRAM. 102 103 This function prohibits access to the SMRAM region. This function is usually implemented such 104 that it is a write-once operation. 105 106 @param[in] This The EFI_SMM_ACCESS2_PROTOCOL instance. 107 108 @retval EFI_SUCCESS The device was successfully locked. 109 @retval EFI_UNSUPPORTED The system does not support locking of SMRAM. 110 **/ 111 EFI_STATUS 112 EFIAPI 113 SmmAccess2Lock ( 114 IN EFI_SMM_ACCESS2_PROTOCOL *This 115 ) 116 { 117 EFI_STATUS Status; 118 UINTN DescriptorIndex; 119 120 /// 121 /// Lock all SMRAM regions via SMM Access Protocol 122 /// 123 124 Status = EFI_SUCCESS; 125 for (DescriptorIndex = 0; DescriptorIndex < mSmramRegionNumber && !EFI_ERROR (Status); DescriptorIndex++) { 126 Status = mSmmAccess->Lock (mSmmAccess, DescriptorIndex); 127 } 128 if (!EFI_ERROR (Status)) { 129 gSmmAccess2.LockState = TRUE; 130 } 131 return Status; 132 } 133 134 /** 135 Queries the memory controller for the possible regions that will support SMRAM. 136 137 @param[in] This The EFI_SMM_ACCESS2_PROTOCOL instance. 138 @param[in, out] SmramMapSize A pointer to the size, in bytes, of the SmramMemoryMap buffer. 139 @param[in, out] SmramMap A pointer to the buffer in which firmware places the current memory map. 140 141 @retval EFI_SUCCESS The chipset supported the given resource. 142 @retval EFI_BUFFER_TOO_SMALL The SmramMap parameter was too small. The current buffer size 143 needed to hold the memory map is returned in SmramMapSize. 144 **/ 145 EFI_STATUS 146 EFIAPI 147 SmmAccess2GetCapabilities ( 148 IN CONST EFI_SMM_ACCESS2_PROTOCOL *This, 149 IN OUT UINTN *SmramMapSize, 150 IN OUT EFI_SMRAM_DESCRIPTOR *SmramMap 151 ) 152 { 153 return mSmmAccess->GetCapabilities (mSmmAccess, SmramMapSize, SmramMap); 154 } 155 156 /** 157 Entry Point for SMM Access2 On SMM Access Thunk driver. 158 159 @param[in] ImageHandle Image handle of this driver. 160 @param[in] SystemTable A Pointer to the EFI System Table. 161 162 @retval EFI_SUCCESS The entry point is executed successfully. 163 @retval other Some error occurred when executing this entry point. 164 **/ 165 EFI_STATUS 166 EFIAPI 167 SmmAccess2ThunkMain ( 168 IN EFI_HANDLE ImageHandle, 169 IN EFI_SYSTEM_TABLE *SystemTable 170 ) 171 { 172 EFI_STATUS Status; 173 UINTN SmramMapSize; 174 175 /// 176 /// Locate SMM Access Protocol 177 /// 178 Status = gBS->LocateProtocol (&gEfiSmmAccessProtocolGuid, NULL, (VOID **)&mSmmAccess); 179 ASSERT_EFI_ERROR (Status); 180 181 /// 182 /// Calculate number of SMRAM regions 183 /// 184 SmramMapSize = 0; 185 Status = mSmmAccess->GetCapabilities (mSmmAccess, &SmramMapSize, NULL); 186 ASSERT (Status == EFI_BUFFER_TOO_SMALL); 187 188 mSmramRegionNumber = SmramMapSize/sizeof (EFI_SMRAM_DESCRIPTOR); 189 ASSERT (mSmramRegionNumber > 0); 190 191 /// 192 /// Assume all SMRAM regions have consistent OPEN and LOCK states 193 /// 194 gSmmAccess2.OpenState = mSmmAccess->OpenState; 195 gSmmAccess2.LockState = mSmmAccess->LockState; 196 197 /// 198 /// Publish PI SMM Access2 Protocol 199 /// 200 Status = gBS->InstallProtocolInterface ( 201 &ImageHandle, 202 &gEfiSmmAccess2ProtocolGuid, 203 EFI_NATIVE_INTERFACE, 204 &gSmmAccess2 205 ); 206 return Status; 207 } 208 209