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