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>
19 #include <Library/TimerLib.h>
20 #include <Library/PrintLib.h>
21 #include <Library/SerialPortLib.h>
23 STATIC CHAR8
*mTokenList
[] = {
32 ShutdownUefiBootServices (
38 EFI_MEMORY_DESCRIPTOR
*MemoryMap
;
41 UINT32 DescriptorVersion
;
47 Status
= gBS
->GetMemoryMap (
54 if (Status
== EFI_BUFFER_TOO_SMALL
) {
56 Pages
= EFI_SIZE_TO_PAGES (MemoryMapSize
) + 1;
57 MemoryMap
= AllocatePages (Pages
);
60 // Get System MemoryMap
62 Status
= gBS
->GetMemoryMap (
69 // Don't do anything between the GetMemoryMap() and ExitBootServices()
70 if (!EFI_ERROR (Status
)) {
71 Status
= gBS
->ExitBootServices (gImageHandle
, MapKey
);
72 if (EFI_ERROR (Status
)) {
73 FreePages (MemoryMap
, Pages
);
79 } while (EFI_ERROR (Status
));
85 Connect all DXE drivers
87 @retval EFI_SUCCESS All drivers have been connected
88 @retval EFI_NOT_FOUND No handles match the search.
89 @retval EFI_OUT_OF_RESOURCES There is not resource pool memory to store the matching results.
93 BdsConnectAllDrivers (
97 UINTN HandleCount
, Index
;
98 EFI_HANDLE
*HandleBuffer
;
102 // Locate all the driver handles
103 Status
= gBS
->LocateHandleBuffer (
110 if (EFI_ERROR (Status
)) {
114 // Connect every handles
115 for (Index
= 0; Index
< HandleCount
; Index
++) {
116 gBS
->ConnectController (HandleBuffer
[Index
], NULL
, NULL
, TRUE
);
119 if (HandleBuffer
!= NULL
) {
120 FreePool (HandleBuffer
);
123 // Check if new handles have been created after the start of the previous handles
124 Status
= gDS
->Dispatch ();
125 } while (!EFI_ERROR(Status
));
132 InsertSystemMemoryResources (
133 LIST_ENTRY
*ResourceList
,
134 EFI_HOB_RESOURCE_DESCRIPTOR
*ResHob
137 BDS_SYSTEM_MEMORY_RESOURCE
*NewResource
;
139 LIST_ENTRY
*NextLink
;
140 LIST_ENTRY AttachedResources
;
141 BDS_SYSTEM_MEMORY_RESOURCE
*Resource
;
142 EFI_PHYSICAL_ADDRESS NewResourceEnd
;
144 if (IsListEmpty (ResourceList
)) {
145 NewResource
= AllocateZeroPool (sizeof(BDS_SYSTEM_MEMORY_RESOURCE
));
146 NewResource
->PhysicalStart
= ResHob
->PhysicalStart
;
147 NewResource
->ResourceLength
= ResHob
->ResourceLength
;
148 InsertTailList (ResourceList
, &NewResource
->Link
);
152 InitializeListHead (&AttachedResources
);
154 Link
= ResourceList
->ForwardLink
;
155 ASSERT (Link
!= NULL
);
156 while (Link
!= ResourceList
) {
157 Resource
= (BDS_SYSTEM_MEMORY_RESOURCE
*)Link
;
159 // Sanity Check. The resources should not overlapped.
160 ASSERT(!((ResHob
->PhysicalStart
>= Resource
->PhysicalStart
) && (ResHob
->PhysicalStart
< (Resource
->PhysicalStart
+ Resource
->ResourceLength
))));
161 ASSERT(!((ResHob
->PhysicalStart
+ ResHob
->ResourceLength
- 1 >= Resource
->PhysicalStart
) &&
162 ((ResHob
->PhysicalStart
+ ResHob
->ResourceLength
- 1) < (Resource
->PhysicalStart
+ Resource
->ResourceLength
))));
164 // The new resource is attached after this resource descriptor
165 if (ResHob
->PhysicalStart
== Resource
->PhysicalStart
+ Resource
->ResourceLength
) {
166 Resource
->ResourceLength
= Resource
->ResourceLength
+ ResHob
->ResourceLength
;
168 NextLink
= RemoveEntryList (&Resource
->Link
);
169 InsertTailList (&AttachedResources
, &Resource
->Link
);
172 // The new resource is attached before this resource descriptor
173 else if (ResHob
->PhysicalStart
+ ResHob
->ResourceLength
== Resource
->PhysicalStart
) {
174 Resource
->PhysicalStart
= ResHob
->PhysicalStart
;
175 Resource
->ResourceLength
= Resource
->ResourceLength
+ ResHob
->ResourceLength
;
177 NextLink
= RemoveEntryList (&Resource
->Link
);
178 InsertTailList (&AttachedResources
, &Resource
->Link
);
181 Link
= Link
->ForwardLink
;
185 if (!IsListEmpty (&AttachedResources
)) {
186 // See if we can merge the attached resource with other resources
188 NewResource
= (BDS_SYSTEM_MEMORY_RESOURCE
*)GetFirstNode (&AttachedResources
);
189 Link
= RemoveEntryList (&NewResource
->Link
);
190 while (!IsListEmpty (&AttachedResources
)) {
192 Resource
= (BDS_SYSTEM_MEMORY_RESOURCE
*)Link
;
194 // Ensure they overlap each other
196 ((NewResource
->PhysicalStart
>= Resource
->PhysicalStart
) && (NewResource
->PhysicalStart
< (Resource
->PhysicalStart
+ Resource
->ResourceLength
))) ||
197 (((NewResource
->PhysicalStart
+ NewResource
->ResourceLength
) >= Resource
->PhysicalStart
) && ((NewResource
->PhysicalStart
+ NewResource
->ResourceLength
) < (Resource
->PhysicalStart
+ Resource
->ResourceLength
)))
200 NewResourceEnd
= MAX (NewResource
->PhysicalStart
+ NewResource
->ResourceLength
, Resource
->PhysicalStart
+ Resource
->ResourceLength
);
201 NewResource
->PhysicalStart
= MIN (NewResource
->PhysicalStart
, Resource
->PhysicalStart
);
202 NewResource
->ResourceLength
= NewResourceEnd
- NewResource
->PhysicalStart
;
204 Link
= RemoveEntryList (Link
);
207 // None of the Resource of the list is attached to this ResHob. Create a new entry for it
208 NewResource
= AllocateZeroPool (sizeof(BDS_SYSTEM_MEMORY_RESOURCE
));
209 NewResource
->PhysicalStart
= ResHob
->PhysicalStart
;
210 NewResource
->ResourceLength
= ResHob
->ResourceLength
;
212 InsertTailList (ResourceList
, &NewResource
->Link
);
217 GetSystemMemoryResources (
218 IN LIST_ENTRY
*ResourceList
221 EFI_HOB_RESOURCE_DESCRIPTOR
*ResHob
;
223 InitializeListHead (ResourceList
);
225 // Find the first System Memory Resource Descriptor
226 ResHob
= (EFI_HOB_RESOURCE_DESCRIPTOR
*)GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR
);
227 while ((ResHob
!= NULL
) && (ResHob
->ResourceType
!= EFI_RESOURCE_SYSTEM_MEMORY
)) {
228 ResHob
= (EFI_HOB_RESOURCE_DESCRIPTOR
*)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR
,(VOID
*)((UINTN
)ResHob
+ ResHob
->Header
.HobLength
));
232 if (ResHob
== NULL
) {
233 return EFI_NOT_FOUND
;
235 InsertSystemMemoryResources (ResourceList
, ResHob
);
238 ResHob
= (EFI_HOB_RESOURCE_DESCRIPTOR
*)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR
,(VOID
*)((UINTN
)ResHob
+ ResHob
->Header
.HobLength
));
239 while (ResHob
!= NULL
) {
240 if (ResHob
->ResourceType
== EFI_RESOURCE_SYSTEM_MEMORY
) {
241 InsertSystemMemoryResources (ResourceList
, ResHob
);
243 ResHob
= (EFI_HOB_RESOURCE_DESCRIPTOR
*)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR
,(VOID
*)((UINTN
)ResHob
+ ResHob
->Header
.HobLength
));
256 CONST CHAR8
*Token
, *Module
;
257 UINT64 Start
, Stop
, TimeStamp
;
258 UINT64 Delta
, TicksPerSecond
, Milliseconds
;
264 TicksPerSecond
= GetPerformanceCounterProperties (&Start
, &Stop
);
274 Key
= GetPerformanceMeasurement (Key
, (CONST VOID
**)&Handle
, &Token
, &Module
, &Start
, &Stop
);
276 for (Index
= 0; mTokenList
[Index
] != NULL
; Index
++) {
277 if (AsciiStriCmp (mTokenList
[Index
], Token
) == 0) {
278 Delta
= CountUp
?(Stop
- Start
):(Start
- Stop
);
280 Milliseconds
= DivU64x64Remainder (MultU64x32 (Delta
, 1000), TicksPerSecond
, NULL
);
281 CharCount
= AsciiSPrint (Buffer
,sizeof (Buffer
),"%6a %6ld ms\n", Token
, Milliseconds
);
282 SerialPortWrite ((UINT8
*) Buffer
, CharCount
);
289 CharCount
= AsciiSPrint (Buffer
,sizeof (Buffer
),"Total Time = %ld ms\n\n", DivU64x64Remainder (MultU64x32 (TimeStamp
, 1000), TicksPerSecond
, NULL
));
290 SerialPortWrite ((UINT8
*) Buffer
, CharCount
);