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