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