1 /** @file
2 *
3 *  Copyright (c) 2011-2015, ARM Limited. All rights reserved.
4 *
5 *  This program and the accompanying materials
6 *  are licensed and made available under the terms and conditions of the BSD License
7 *  which accompanies this distribution.  The full text of the license may be found at
8 *  http://opensource.org/licenses/bsd-license.php
9 *
10 *  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 *  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 *
13 **/
14 
15 #include "BdsInternal.h"
16 
17 EFI_STATUS
ShutdownUefiBootServices(VOID)18 ShutdownUefiBootServices (
19   VOID
20   )
21 {
22   EFI_STATUS              Status;
23   UINTN                   MemoryMapSize;
24   EFI_MEMORY_DESCRIPTOR   *MemoryMap;
25   UINTN                   MapKey;
26   UINTN                   DescriptorSize;
27   UINT32                  DescriptorVersion;
28   UINTN                   Pages;
29 
30   MemoryMap = NULL;
31   MemoryMapSize = 0;
32   Pages = 0;
33 
34   do {
35     Status = gBS->GetMemoryMap (
36                     &MemoryMapSize,
37                     MemoryMap,
38                     &MapKey,
39                     &DescriptorSize,
40                     &DescriptorVersion
41                     );
42     if (Status == EFI_BUFFER_TOO_SMALL) {
43 
44       Pages = EFI_SIZE_TO_PAGES (MemoryMapSize) + 1;
45       MemoryMap = AllocatePages (Pages);
46 
47       //
48       // Get System MemoryMap
49       //
50       Status = gBS->GetMemoryMap (
51                       &MemoryMapSize,
52                       MemoryMap,
53                       &MapKey,
54                       &DescriptorSize,
55                       &DescriptorVersion
56                       );
57     }
58 
59     // Don't do anything between the GetMemoryMap() and ExitBootServices()
60     if (!EFI_ERROR(Status)) {
61       Status = gBS->ExitBootServices (gImageHandle, MapKey);
62       if (EFI_ERROR(Status)) {
63         FreePages (MemoryMap, Pages);
64         MemoryMap = NULL;
65         MemoryMapSize = 0;
66       }
67     }
68   } while (EFI_ERROR(Status));
69 
70   return Status;
71 }
72 
73 /**
74   Connect all DXE drivers
75 
76   @retval EFI_SUCCESS           All drivers have been connected
77   @retval EFI_NOT_FOUND         No handles match the search.
78   @retval EFI_OUT_OF_RESOURCES  There is not resource pool memory to store the matching results.
79 
80 **/
81 EFI_STATUS
BdsConnectAllDrivers(VOID)82 BdsConnectAllDrivers (
83   VOID
84   )
85 {
86   UINTN                     HandleCount, Index;
87   EFI_HANDLE                *HandleBuffer;
88   EFI_STATUS                Status;
89 
90   do {
91     // Locate all the driver handles
92     Status = gBS->LocateHandleBuffer (
93                 AllHandles,
94                 NULL,
95                 NULL,
96                 &HandleCount,
97                 &HandleBuffer
98                 );
99     if (EFI_ERROR (Status)) {
100       break;
101     }
102 
103     // Connect every handles
104     for (Index = 0; Index < HandleCount; Index++) {
105       gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);
106     }
107 
108     if (HandleBuffer != NULL) {
109       FreePool (HandleBuffer);
110     }
111 
112     // Check if new handles have been created after the start of the previous handles
113     Status = gDS->Dispatch ();
114   } while (!EFI_ERROR(Status));
115 
116   return EFI_SUCCESS;
117 }
118 
119 EFI_STATUS
GetGlobalEnvironmentVariable(IN CONST CHAR16 * VariableName,IN VOID * DefaultValue,IN OUT UINTN * Size,OUT VOID ** Value)120 GetGlobalEnvironmentVariable (
121   IN     CONST CHAR16*   VariableName,
122   IN     VOID*           DefaultValue,
123   IN OUT UINTN*          Size,
124   OUT    VOID**          Value
125   )
126 {
127   return GetEnvironmentVariable (VariableName, &gEfiGlobalVariableGuid,
128            DefaultValue, Size, Value);
129 }
130 
131 EFI_STATUS
GetEnvironmentVariable(IN CONST CHAR16 * VariableName,IN EFI_GUID * VendorGuid,IN VOID * DefaultValue,IN OUT UINTN * Size,OUT VOID ** Value)132 GetEnvironmentVariable (
133   IN     CONST CHAR16*   VariableName,
134   IN     EFI_GUID*       VendorGuid,
135   IN     VOID*           DefaultValue,
136   IN OUT UINTN*          Size,
137   OUT    VOID**          Value
138   )
139 {
140   EFI_STATUS  Status;
141   UINTN       VariableSize;
142 
143   // Try to get the variable size.
144   *Value = NULL;
145   VariableSize = 0;
146   Status = gRT->GetVariable ((CHAR16 *) VariableName, VendorGuid, NULL, &VariableSize, *Value);
147   if (Status == EFI_NOT_FOUND) {
148     if ((DefaultValue != NULL) && (Size != NULL) && (*Size != 0)) {
149       // If the environment variable does not exist yet then set it with the default value
150       Status = gRT->SetVariable (
151                     (CHAR16*)VariableName,
152                     VendorGuid,
153                     EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
154                     *Size,
155                     DefaultValue
156                     );
157       *Value = AllocateCopyPool (*Size, DefaultValue);
158     } else {
159       return EFI_NOT_FOUND;
160     }
161   } else if (Status == EFI_BUFFER_TOO_SMALL) {
162     // Get the environment variable value
163     *Value = AllocatePool (VariableSize);
164     if (*Value == NULL) {
165       return EFI_OUT_OF_RESOURCES;
166     }
167 
168     Status = gRT->GetVariable ((CHAR16 *)VariableName, VendorGuid, NULL, &VariableSize, *Value);
169     if (EFI_ERROR (Status)) {
170       FreePool(*Value);
171       return EFI_INVALID_PARAMETER;
172     }
173 
174     if (Size) {
175       *Size = VariableSize;
176     }
177   } else {
178     *Value = AllocateCopyPool (*Size, DefaultValue);
179     return Status;
180   }
181 
182   return EFI_SUCCESS;
183 }
184