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