1/** @file 2 3 Implment all four UEFI runtime variable services and 4 install variable architeture protocol. 5 6Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR> 7This program and the accompanying materials 8are licensed and made available under the terms and conditions of the BSD License 9which accompanies this distribution. The full text of the license may be found at 10http://opensource.org/licenses/bsd-license.php 11 12THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 13WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 14 15**/ 16 17#include "Variable.h" 18 19EFI_EVENT mVirtualAddressChangeEvent = NULL; 20 21/** 22 23 This code finds variable in storage blocks (Volatile or Non-Volatile). 24 25 @param VariableName Name of Variable to be found. 26 @param VendorGuid Variable vendor GUID. 27 @param Attributes Attribute value of the variable found. 28 @param DataSize Size of Data found. If size is less than the 29 data, this value contains the required size. 30 @param Data The buffer to return the contents of the variable. May be NULL 31 with a zero DataSize in order to determine the size buffer needed. 32 33 @return EFI_INVALID_PARAMETER Invalid parameter 34 @return EFI_SUCCESS Find the specified variable 35 @return EFI_NOT_FOUND Not found 36 @return EFI_BUFFER_TO_SMALL DataSize is too small for the result 37 38**/ 39EFI_STATUS 40EFIAPI 41RuntimeServiceGetVariable ( 42 IN CHAR16 *VariableName, 43 IN EFI_GUID *VendorGuid, 44 OUT UINT32 *Attributes OPTIONAL, 45 IN OUT UINTN *DataSize, 46 OUT VOID *Data OPTIONAL 47 ) 48{ 49 return EmuGetVariable ( 50 VariableName, 51 VendorGuid, 52 Attributes OPTIONAL, 53 DataSize, 54 Data, 55 &mVariableModuleGlobal->VariableGlobal[Physical] 56 ); 57} 58 59/** 60 61 This code Finds the Next available variable. 62 63 @param VariableNameSize Size of the variable name 64 @param VariableName Pointer to variable name 65 @param VendorGuid Variable Vendor Guid 66 67 @return EFI_INVALID_PARAMETER Invalid parameter 68 @return EFI_SUCCESS Find the specified variable 69 @return EFI_NOT_FOUND Not found 70 @return EFI_BUFFER_TO_SMALL DataSize is too small for the result 71 72**/ 73EFI_STATUS 74EFIAPI 75RuntimeServiceGetNextVariableName ( 76 IN OUT UINTN *VariableNameSize, 77 IN OUT CHAR16 *VariableName, 78 IN OUT EFI_GUID *VendorGuid 79 ) 80{ 81 return EmuGetNextVariableName ( 82 VariableNameSize, 83 VariableName, 84 VendorGuid, 85 &mVariableModuleGlobal->VariableGlobal[Physical] 86 ); 87} 88 89/** 90 91 This code sets variable in storage blocks (Volatile or Non-Volatile). 92 93 @param VariableName Name of Variable to be found 94 @param VendorGuid Variable vendor GUID 95 @param Attributes Attribute value of the variable found 96 @param DataSize Size of Data found. If size is less than the 97 data, this value contains the required size. 98 @param Data Data pointer 99 100 @return EFI_INVALID_PARAMETER Invalid parameter 101 @return EFI_SUCCESS Set successfully 102 @return EFI_OUT_OF_RESOURCES Resource not enough to set variable 103 @return EFI_NOT_FOUND Not found 104 @return EFI_WRITE_PROTECTED Variable is read-only 105 106**/ 107EFI_STATUS 108EFIAPI 109RuntimeServiceSetVariable ( 110 IN CHAR16 *VariableName, 111 IN EFI_GUID *VendorGuid, 112 IN UINT32 Attributes, 113 IN UINTN DataSize, 114 IN VOID *Data 115 ) 116{ 117 return EmuSetVariable ( 118 VariableName, 119 VendorGuid, 120 Attributes, 121 DataSize, 122 Data, 123 &mVariableModuleGlobal->VariableGlobal[Physical], 124 &mVariableModuleGlobal->VolatileLastVariableOffset, 125 &mVariableModuleGlobal->NonVolatileLastVariableOffset 126 ); 127} 128 129/** 130 131 This code returns information about the EFI variables. 132 133 @param Attributes Attributes bitmask to specify the type of variables 134 on which to return information. 135 @param MaximumVariableStorageSize Pointer to the maximum size of the storage space available 136 for the EFI variables associated with the attributes specified. 137 @param RemainingVariableStorageSize Pointer to the remaining size of the storage space available 138 for EFI variables associated with the attributes specified. 139 @param MaximumVariableSize Pointer to the maximum size of an individual EFI variables 140 associated with the attributes specified. 141 142 @return EFI_INVALID_PARAMETER An invalid combination of attribute bits was supplied. 143 @return EFI_SUCCESS Query successfully. 144 @return EFI_UNSUPPORTED The attribute is not supported on this platform. 145 146**/ 147EFI_STATUS 148EFIAPI 149RuntimeServiceQueryVariableInfo ( 150 IN UINT32 Attributes, 151 OUT UINT64 *MaximumVariableStorageSize, 152 OUT UINT64 *RemainingVariableStorageSize, 153 OUT UINT64 *MaximumVariableSize 154 ) 155{ 156 return EmuQueryVariableInfo ( 157 Attributes, 158 MaximumVariableStorageSize, 159 RemainingVariableStorageSize, 160 MaximumVariableSize, 161 &mVariableModuleGlobal->VariableGlobal[Physical] 162 ); 163} 164 165/** 166 Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE. 167 168 This is a notification function registered on EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event. 169 It convers pointer to new virtual address. 170 171 @param Event Event whose notification function is being invoked. 172 @param Context Pointer to the notification function's context. 173 174**/ 175VOID 176EFIAPI 177VariableClassAddressChangeEvent ( 178 IN EFI_EVENT Event, 179 IN VOID *Context 180 ) 181{ 182 EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->PlatformLangCodes); 183 EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->LangCodes); 184 EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal->PlatformLang); 185 EfiConvertPointer ( 186 0x0, 187 (VOID **) &mVariableModuleGlobal->VariableGlobal[Physical].NonVolatileVariableBase 188 ); 189 EfiConvertPointer ( 190 0x0, 191 (VOID **) &mVariableModuleGlobal->VariableGlobal[Physical].VolatileVariableBase 192 ); 193 EfiConvertPointer (0x0, (VOID **) &mVariableModuleGlobal); 194} 195 196/** 197 EmuVariable Driver main entry point. The Variable driver places the 4 EFI 198 runtime services in the EFI System Table and installs arch protocols 199 for variable read and write services being available. It also registers 200 notification function for EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event. 201 202 @param[in] ImageHandle The firmware allocated handle for the EFI image. 203 @param[in] SystemTable A pointer to the EFI System Table. 204 205 @retval EFI_SUCCESS Variable service successfully initialized. 206 207**/ 208EFI_STATUS 209EFIAPI 210VariableServiceInitialize ( 211 IN EFI_HANDLE ImageHandle, 212 IN EFI_SYSTEM_TABLE *SystemTable 213 ) 214{ 215 EFI_HANDLE NewHandle; 216 EFI_STATUS Status; 217 218 Status = VariableCommonInitialize (ImageHandle, SystemTable); 219 ASSERT_EFI_ERROR (Status); 220 221 SystemTable->RuntimeServices->GetVariable = RuntimeServiceGetVariable; 222 SystemTable->RuntimeServices->GetNextVariableName = RuntimeServiceGetNextVariableName; 223 SystemTable->RuntimeServices->SetVariable = RuntimeServiceSetVariable; 224 SystemTable->RuntimeServices->QueryVariableInfo = RuntimeServiceQueryVariableInfo; 225 226 // 227 // Now install the Variable Runtime Architectural Protocol on a new handle 228 // 229 NewHandle = NULL; 230 Status = gBS->InstallMultipleProtocolInterfaces ( 231 &NewHandle, 232 &gEfiVariableArchProtocolGuid, 233 NULL, 234 &gEfiVariableWriteArchProtocolGuid, 235 NULL, 236 NULL 237 ); 238 ASSERT_EFI_ERROR (Status); 239 240 Status = gBS->CreateEventEx ( 241 EVT_NOTIFY_SIGNAL, 242 TPL_NOTIFY, 243 VariableClassAddressChangeEvent, 244 NULL, 245 &gEfiEventVirtualAddressChangeGuid, 246 &mVirtualAddressChangeEvent 247 ); 248 ASSERT_EFI_ERROR (Status); 249 250 return EFI_SUCCESS; 251} 252