]> git.proxmox.com Git - mirror_edk2.git/blob - ArmPkg/Library/BdsLib/BdsHelper.c
Patch from open source community for CryptoPkg to allow it to build for ARM using...
[mirror_edk2.git] / ArmPkg / Library / BdsLib / BdsHelper.c
1 /** @file
2 *
3 * Copyright (c) 2011, 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 #include <Library/DxeServicesTableLib.h>
18 #include <Library/HobLib.h>
19
20 EFI_STATUS
21 ShutdownUefiBootServices( VOID )
22 {
23 EFI_STATUS Status;
24 UINTN MemoryMapSize;
25 EFI_MEMORY_DESCRIPTOR *MemoryMap;
26 UINTN MapKey;
27 UINTN DescriptorSize;
28 UINT32 DescriptorVersion;
29 UINTN Pages;
30
31 MemoryMap = NULL;
32 MemoryMapSize = 0;
33 do {
34 Status = gBS->GetMemoryMap (
35 &MemoryMapSize,
36 MemoryMap,
37 &MapKey,
38 &DescriptorSize,
39 &DescriptorVersion
40 );
41 if (Status == EFI_BUFFER_TOO_SMALL) {
42
43 Pages = EFI_SIZE_TO_PAGES (MemoryMapSize) + 1;
44 MemoryMap = AllocatePages (Pages);
45
46 //
47 // Get System MemoryMap
48 //
49 Status = gBS->GetMemoryMap (
50 &MemoryMapSize,
51 MemoryMap,
52 &MapKey,
53 &DescriptorSize,
54 &DescriptorVersion
55 );
56 // Don't do anything between the GetMemoryMap() and ExitBootServices()
57 if (!EFI_ERROR (Status)) {
58 Status = gBS->ExitBootServices (gImageHandle, MapKey);
59 if (EFI_ERROR (Status)) {
60 FreePages (MemoryMap, Pages);
61 MemoryMap = NULL;
62 MemoryMapSize = 0;
63 }
64 }
65 }
66 } while (EFI_ERROR (Status));
67
68 return Status;
69 }
70
71 EFI_STATUS
72 BdsConnectAllDrivers( VOID ) {
73 UINTN HandleCount, Index;
74 EFI_HANDLE *HandleBuffer;
75 EFI_STATUS Status;
76
77 do {
78 // Locate all the driver handles
79 Status = gBS->LocateHandleBuffer (
80 AllHandles,
81 NULL,
82 NULL,
83 &HandleCount,
84 &HandleBuffer
85 );
86 if (EFI_ERROR (Status)) {
87 break;
88 }
89
90 // Connect every handles
91 for (Index = 0; Index < HandleCount; Index++) {
92 gBS->ConnectController(HandleBuffer[Index], NULL, NULL, TRUE);
93 }
94
95 if (HandleBuffer != NULL) {
96 FreePool (HandleBuffer);
97 }
98
99 // Check if new handles have been created after the start of the previous handles
100 Status = gDS->Dispatch ();
101 } while (!EFI_ERROR(Status));
102
103 return EFI_SUCCESS;
104 }
105
106 STATIC
107 EFI_STATUS
108 InsertSystemMemoryResources (
109 LIST_ENTRY *ResourceList,
110 EFI_HOB_RESOURCE_DESCRIPTOR *ResHob
111 )
112 {
113 BDS_SYSTEM_MEMORY_RESOURCE *NewResource;
114 LIST_ENTRY *Link;
115 LIST_ENTRY *NextLink;
116 LIST_ENTRY AttachedResources;
117 BDS_SYSTEM_MEMORY_RESOURCE *Resource;
118 EFI_PHYSICAL_ADDRESS NewResourceEnd;
119
120 if (IsListEmpty (ResourceList)) {
121 NewResource = AllocateZeroPool (sizeof(BDS_SYSTEM_MEMORY_RESOURCE));
122 NewResource->PhysicalStart = ResHob->PhysicalStart;
123 NewResource->ResourceLength = ResHob->ResourceLength;
124 InsertTailList (ResourceList, &NewResource->Link);
125 return EFI_SUCCESS;
126 }
127
128 InitializeListHead (&AttachedResources);
129
130 Link = ResourceList->ForwardLink;
131 ASSERT (Link != NULL);
132 while (Link != ResourceList) {
133 Resource = (BDS_SYSTEM_MEMORY_RESOURCE*)Link;
134
135 // Sanity Check. The resources should not overlapped.
136 ASSERT(!((ResHob->PhysicalStart >= Resource->PhysicalStart) && (ResHob->PhysicalStart < (Resource->PhysicalStart + Resource->ResourceLength))));
137 ASSERT(!((ResHob->PhysicalStart + ResHob->ResourceLength - 1 >= Resource->PhysicalStart) &&
138 ((ResHob->PhysicalStart + ResHob->ResourceLength - 1) < (Resource->PhysicalStart + Resource->ResourceLength))));
139
140 // The new resource is attached after this resource descriptor
141 if (ResHob->PhysicalStart == Resource->PhysicalStart + Resource->ResourceLength) {
142 Resource->ResourceLength = Resource->ResourceLength + ResHob->ResourceLength;
143
144 NextLink = RemoveEntryList (&Resource->Link);
145 InsertTailList (&AttachedResources, &Resource->Link);
146 Link = NextLink;
147 }
148 // The new resource is attached before this resource descriptor
149 else if (ResHob->PhysicalStart + ResHob->ResourceLength == Resource->PhysicalStart) {
150 Resource->PhysicalStart = ResHob->PhysicalStart;
151 Resource->ResourceLength = Resource->ResourceLength + ResHob->ResourceLength;
152
153 NextLink = RemoveEntryList (&Resource->Link);
154 InsertTailList (&AttachedResources, &Resource->Link);
155 Link = NextLink;
156 } else {
157 Link = Link->ForwardLink;
158 }
159 }
160
161 if (!IsListEmpty (&AttachedResources)) {
162 // See if we can merge the attached resource with other resources
163
164 NewResource = (BDS_SYSTEM_MEMORY_RESOURCE*)GetFirstNode (&AttachedResources);
165 Link = RemoveEntryList (&NewResource->Link);
166 while (!IsListEmpty (&AttachedResources)) {
167 // Merge resources
168 Resource = (BDS_SYSTEM_MEMORY_RESOURCE*)Link;
169
170 // Ensure they overlap each other
171 ASSERT(
172 ((NewResource->PhysicalStart >= Resource->PhysicalStart) && (NewResource->PhysicalStart < (Resource->PhysicalStart + Resource->ResourceLength))) ||
173 (((NewResource->PhysicalStart + NewResource->ResourceLength) >= Resource->PhysicalStart) && ((NewResource->PhysicalStart + NewResource->ResourceLength) < (Resource->PhysicalStart + Resource->ResourceLength)))
174 );
175
176 NewResourceEnd = MAX (NewResource->PhysicalStart + NewResource->ResourceLength, Resource->PhysicalStart + Resource->ResourceLength);
177 NewResource->PhysicalStart = MIN (NewResource->PhysicalStart, Resource->PhysicalStart);
178 NewResource->ResourceLength = NewResourceEnd - NewResource->PhysicalStart;
179
180 Link = RemoveEntryList (Link);
181 }
182 } else {
183 // None of the Resource of the list is attached to this ResHob. Create a new entry for it
184 NewResource = AllocateZeroPool (sizeof(BDS_SYSTEM_MEMORY_RESOURCE));
185 NewResource->PhysicalStart = ResHob->PhysicalStart;
186 NewResource->ResourceLength = ResHob->ResourceLength;
187 }
188 InsertTailList (ResourceList, &NewResource->Link);
189 return EFI_SUCCESS;
190 }
191
192 EFI_STATUS
193 GetSystemMemoryResources (
194 IN LIST_ENTRY *ResourceList
195 )
196 {
197 EFI_HOB_RESOURCE_DESCRIPTOR *ResHob;
198
199 InitializeListHead (ResourceList);
200
201 // Find the first System Memory Resource Descriptor
202 ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);
203 while ((ResHob != NULL) && (ResHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY)) {
204 ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,(VOID *)((UINTN)ResHob + ResHob->Header.HobLength));
205 }
206
207 // Did not find any
208 if (ResHob == NULL) {
209 return EFI_NOT_FOUND;
210 } else {
211 InsertSystemMemoryResources (ResourceList, ResHob);
212 }
213
214 ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,(VOID *)((UINTN)ResHob + ResHob->Header.HobLength));
215 while (ResHob != NULL) {
216 if (ResHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {
217 InsertSystemMemoryResources (ResourceList, ResHob);
218 }
219 ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,(VOID *)((UINTN)ResHob + ResHob->Header.HobLength));
220 }
221
222 return EFI_SUCCESS;
223 }