3 * Copyright (c) 2011, ARM Limited. All rights reserved.
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
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.
15 #include "BdsInternal.h"
17 #include <Library/DxeServicesTableLib.h>
18 #include <Library/HobLib.h>
21 ShutdownUefiBootServices( VOID
)
25 EFI_MEMORY_DESCRIPTOR
*MemoryMap
;
28 UINT32 DescriptorVersion
;
34 Status
= gBS
->GetMemoryMap (
41 if (Status
== EFI_BUFFER_TOO_SMALL
) {
43 Pages
= EFI_SIZE_TO_PAGES (MemoryMapSize
) + 1;
44 MemoryMap
= AllocatePages (Pages
);
47 // Get System MemoryMap
49 Status
= gBS
->GetMemoryMap (
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
);
66 } while (EFI_ERROR (Status
));
72 BdsConnectAllDrivers( VOID
) {
73 UINTN HandleCount
, Index
;
74 EFI_HANDLE
*HandleBuffer
;
78 // Locate all the driver handles
79 Status
= gBS
->LocateHandleBuffer (
86 if (EFI_ERROR (Status
)) {
90 // Connect every handles
91 for (Index
= 0; Index
< HandleCount
; Index
++) {
92 gBS
->ConnectController(HandleBuffer
[Index
], NULL
, NULL
, TRUE
);
95 if (HandleBuffer
!= NULL
) {
96 FreePool (HandleBuffer
);
99 // Check if new handles have been created after the start of the previous handles
100 Status
= gDS
->Dispatch ();
101 } while (!EFI_ERROR(Status
));
108 InsertSystemMemoryResources (
109 LIST_ENTRY
*ResourceList
,
110 EFI_HOB_RESOURCE_DESCRIPTOR
*ResHob
113 BDS_SYSTEM_MEMORY_RESOURCE
*NewResource
;
115 LIST_ENTRY
*NextLink
;
116 LIST_ENTRY AttachedResources
;
117 BDS_SYSTEM_MEMORY_RESOURCE
*Resource
;
118 EFI_PHYSICAL_ADDRESS NewResourceEnd
;
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
);
128 InitializeListHead (&AttachedResources
);
130 Link
= ResourceList
->ForwardLink
;
131 ASSERT (Link
!= NULL
);
132 while (Link
!= ResourceList
) {
133 Resource
= (BDS_SYSTEM_MEMORY_RESOURCE
*)Link
;
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
))));
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
;
144 NextLink
= RemoveEntryList (&Resource
->Link
);
145 InsertTailList (&AttachedResources
, &Resource
->Link
);
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
;
153 NextLink
= RemoveEntryList (&Resource
->Link
);
154 InsertTailList (&AttachedResources
, &Resource
->Link
);
157 Link
= Link
->ForwardLink
;
161 if (!IsListEmpty (&AttachedResources
)) {
162 // See if we can merge the attached resource with other resources
164 NewResource
= (BDS_SYSTEM_MEMORY_RESOURCE
*)GetFirstNode (&AttachedResources
);
165 Link
= RemoveEntryList (&NewResource
->Link
);
166 while (!IsListEmpty (&AttachedResources
)) {
168 Resource
= (BDS_SYSTEM_MEMORY_RESOURCE
*)Link
;
170 // Ensure they overlap each other
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
)))
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
;
180 Link
= RemoveEntryList (Link
);
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
;
188 InsertTailList (ResourceList
, &NewResource
->Link
);
193 GetSystemMemoryResources (
194 IN LIST_ENTRY
*ResourceList
197 EFI_HOB_RESOURCE_DESCRIPTOR
*ResHob
;
199 InitializeListHead (ResourceList
);
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
));
208 if (ResHob
== NULL
) {
209 return EFI_NOT_FOUND
;
211 InsertSystemMemoryResources (ResourceList
, ResHob
);
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
);
219 ResHob
= (EFI_HOB_RESOURCE_DESCRIPTOR
*)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR
,(VOID
*)((UINTN
)ResHob
+ ResHob
->Header
.HobLength
));