3 * Copyright (c) 2011-2015, 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.
16 #include <Library/HobLib.h>
17 #include <Library/TimerLib.h>
18 #include <Library/SerialPortLib.h>
20 #include "LinuxLoader.h"
22 STATIC CONST CHAR8
*mTokenList
[] = {
37 CONST CHAR8
*Token
, *Module
;
38 UINT64 Start
, Stop
, TimeStamp
;
39 UINT64 Delta
, TicksPerSecond
, Milliseconds
;
45 TicksPerSecond
= GetPerformanceCounterProperties (&Start
, &Stop
);
55 Key
= GetPerformanceMeasurement (Key
, (CONST VOID
**)&Handle
, &Token
, &Module
, &Start
, &Stop
);
57 for (Index
= 0; mTokenList
[Index
] != NULL
; Index
++) {
58 if (AsciiStriCmp (mTokenList
[Index
], Token
) == 0) {
59 Delta
= CountUp
? (Stop
- Start
) : (Start
- Stop
);
61 Milliseconds
= DivU64x64Remainder (MultU64x32 (Delta
, 1000), TicksPerSecond
, NULL
);
62 CharCount
= AsciiSPrint (Buffer
, sizeof (Buffer
), "%6a %6ld ms\n", Token
, Milliseconds
);
63 SerialPortWrite ((UINT8
*) Buffer
, CharCount
);
70 CharCount
= AsciiSPrint (Buffer
, sizeof (Buffer
), "Total Time = %ld ms\n\n",
71 DivU64x64Remainder (MultU64x32 (TimeStamp
, 1000), TicksPerSecond
, NULL
));
72 SerialPortWrite ((UINT8
*) Buffer
, CharCount
);
77 InsertSystemMemoryResources (
78 LIST_ENTRY
*ResourceList
,
79 EFI_HOB_RESOURCE_DESCRIPTOR
*ResHob
82 SYSTEM_MEMORY_RESOURCE
*NewResource
;
85 LIST_ENTRY AttachedResources
;
86 SYSTEM_MEMORY_RESOURCE
*Resource
;
87 EFI_PHYSICAL_ADDRESS NewResourceEnd
;
89 if (IsListEmpty (ResourceList
)) {
90 NewResource
= AllocateZeroPool (sizeof (SYSTEM_MEMORY_RESOURCE
));
91 NewResource
->PhysicalStart
= ResHob
->PhysicalStart
;
92 NewResource
->ResourceLength
= ResHob
->ResourceLength
;
93 InsertTailList (ResourceList
, &NewResource
->Link
);
97 InitializeListHead (&AttachedResources
);
99 Link
= ResourceList
->ForwardLink
;
100 ASSERT (Link
!= NULL
);
101 while (Link
!= ResourceList
) {
102 Resource
= (SYSTEM_MEMORY_RESOURCE
*)Link
;
104 // Sanity Check. The resources should not overlapped.
105 ASSERT (!((ResHob
->PhysicalStart
>= Resource
->PhysicalStart
) && (ResHob
->PhysicalStart
< (Resource
->PhysicalStart
+ Resource
->ResourceLength
))));
106 ASSERT (!((ResHob
->PhysicalStart
+ ResHob
->ResourceLength
- 1 >= Resource
->PhysicalStart
) &&
107 ((ResHob
->PhysicalStart
+ ResHob
->ResourceLength
- 1) < (Resource
->PhysicalStart
+ Resource
->ResourceLength
))));
109 // The new resource is attached after this resource descriptor
110 if (ResHob
->PhysicalStart
== Resource
->PhysicalStart
+ Resource
->ResourceLength
) {
111 Resource
->ResourceLength
= Resource
->ResourceLength
+ ResHob
->ResourceLength
;
113 NextLink
= RemoveEntryList (&Resource
->Link
);
114 InsertTailList (&AttachedResources
, &Resource
->Link
);
117 // The new resource is attached before this resource descriptor
118 else if (ResHob
->PhysicalStart
+ ResHob
->ResourceLength
== Resource
->PhysicalStart
) {
119 Resource
->PhysicalStart
= ResHob
->PhysicalStart
;
120 Resource
->ResourceLength
= Resource
->ResourceLength
+ ResHob
->ResourceLength
;
122 NextLink
= RemoveEntryList (&Resource
->Link
);
123 InsertTailList (&AttachedResources
, &Resource
->Link
);
126 Link
= Link
->ForwardLink
;
130 if (!IsListEmpty (&AttachedResources
)) {
131 // See if we can merge the attached resource with other resources
133 NewResource
= (SYSTEM_MEMORY_RESOURCE
*)GetFirstNode (&AttachedResources
);
134 Link
= RemoveEntryList (&NewResource
->Link
);
135 while (!IsListEmpty (&AttachedResources
)) {
137 Resource
= (SYSTEM_MEMORY_RESOURCE
*)Link
;
139 // Ensure they overlap each other
141 ((NewResource
->PhysicalStart
>= Resource
->PhysicalStart
) && (NewResource
->PhysicalStart
< (Resource
->PhysicalStart
+ Resource
->ResourceLength
))) ||
142 (((NewResource
->PhysicalStart
+ NewResource
->ResourceLength
) >= Resource
->PhysicalStart
) && ((NewResource
->PhysicalStart
+ NewResource
->ResourceLength
) < (Resource
->PhysicalStart
+ Resource
->ResourceLength
)))
145 NewResourceEnd
= MAX (NewResource
->PhysicalStart
+ NewResource
->ResourceLength
, Resource
->PhysicalStart
+ Resource
->ResourceLength
);
146 NewResource
->PhysicalStart
= MIN (NewResource
->PhysicalStart
, Resource
->PhysicalStart
);
147 NewResource
->ResourceLength
= NewResourceEnd
- NewResource
->PhysicalStart
;
149 Link
= RemoveEntryList (Link
);
152 // None of the Resource of the list is attached to this ResHob. Create a new entry for it
153 NewResource
= AllocateZeroPool (sizeof (SYSTEM_MEMORY_RESOURCE
));
154 NewResource
->PhysicalStart
= ResHob
->PhysicalStart
;
155 NewResource
->ResourceLength
= ResHob
->ResourceLength
;
157 InsertTailList (ResourceList
, &NewResource
->Link
);
162 GetSystemMemoryResources (
163 IN LIST_ENTRY
*ResourceList
166 EFI_HOB_RESOURCE_DESCRIPTOR
*ResHob
;
168 InitializeListHead (ResourceList
);
170 // Find the first System Memory Resource Descriptor
171 ResHob
= (EFI_HOB_RESOURCE_DESCRIPTOR
*)GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR
);
172 while ((ResHob
!= NULL
) && (ResHob
->ResourceType
!= EFI_RESOURCE_SYSTEM_MEMORY
)) {
173 ResHob
= (EFI_HOB_RESOURCE_DESCRIPTOR
*)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR
, (VOID
*)((UINTN
)ResHob
+ ResHob
->Header
.HobLength
));
177 if (ResHob
== NULL
) {
178 return EFI_NOT_FOUND
;
180 InsertSystemMemoryResources (ResourceList
, ResHob
);
183 ResHob
= (EFI_HOB_RESOURCE_DESCRIPTOR
*)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR
, (VOID
*)((UINTN
)ResHob
+ ResHob
->Header
.HobLength
));
184 while (ResHob
!= NULL
) {
185 if (ResHob
->ResourceType
== EFI_RESOURCE_SYSTEM_MEMORY
) {
186 InsertSystemMemoryResources (ResourceList
, ResHob
);
188 ResHob
= (EFI_HOB_RESOURCE_DESCRIPTOR
*)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR
, (VOID
*)((UINTN
)ResHob
+ ResHob
->Header
.HobLength
));