1 /** @file 2 3 Implment all four UEFI runtime variable services and 4 install variable architeture protocol. 5 6 Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR> 7 This program and the accompanying materials 8 are licensed and made available under the terms and conditions of the BSD License 9 which accompanies this distribution. The full text of the license may be found at 10 http://opensource.org/licenses/bsd-license.php 11 12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 14 15 **/ 16 17 #include "Variable.h" 18 19 EFI_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 **/ 39 EFI_STATUS 40 EFIAPI 41 RuntimeServiceGetVariable ( 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 **/ 73 EFI_STATUS 74 EFIAPI 75 RuntimeServiceGetNextVariableName ( 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 **/ 107 EFI_STATUS 108 EFIAPI 109 RuntimeServiceSetVariable ( 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 **/ 147 EFI_STATUS 148 EFIAPI 149 RuntimeServiceQueryVariableInfo ( 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 **/ 175 VOID 176 EFIAPI 177 VariableClassAddressChangeEvent ( 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 **/ 208 EFI_STATUS 209 EFIAPI 210 VariableServiceInitialize ( 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