]> git.proxmox.com Git - mirror_edk2.git/blob - ArmPkg/Application/LinuxLoader/LinuxLoaderHelper.c
4d7a8445843147c630d1ef8dc6155e88a354b52a
[mirror_edk2.git] / ArmPkg / Application / LinuxLoader / LinuxLoaderHelper.c
1 /** @file
2 *
3 * Copyright (c) 2011-2015, 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 <PiDxe.h>
16 #include <Library/HobLib.h>
17 #include <Library/TimerLib.h>
18 #include <Library/SerialPortLib.h>
19
20 #include "LinuxLoader.h"
21
22 STATIC CONST CHAR8 *mTokenList[] = {
23 /*"SEC",*/
24 "PEI",
25 "DXE",
26 "BDS",
27 NULL
28 };
29
30 VOID
31 PrintPerformance (
32 VOID
33 )
34 {
35 UINTN Key;
36 CONST VOID *Handle;
37 CONST CHAR8 *Token, *Module;
38 UINT64 Start, Stop, TimeStamp;
39 UINT64 Delta, TicksPerSecond, Milliseconds;
40 UINTN Index;
41 CHAR8 Buffer[100];
42 UINTN CharCount;
43 BOOLEAN CountUp;
44
45 TicksPerSecond = GetPerformanceCounterProperties (&Start, &Stop);
46 if (Start < Stop) {
47 CountUp = TRUE;
48 } else {
49 CountUp = FALSE;
50 }
51
52 TimeStamp = 0;
53 Key = 0;
54 do {
55 Key = GetPerformanceMeasurement (Key, (CONST VOID **)&Handle, &Token, &Module, &Start, &Stop);
56 if (Key != 0) {
57 for (Index = 0; mTokenList[Index] != NULL; Index++) {
58 if (AsciiStriCmp (mTokenList[Index], Token) == 0) {
59 Delta = CountUp ? (Stop - Start) : (Start - Stop);
60 TimeStamp += Delta;
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);
64 break;
65 }
66 }
67 }
68 } while (Key != 0);
69
70 CharCount = AsciiSPrint (Buffer, sizeof (Buffer), "Total Time = %ld ms\n\n",
71 DivU64x64Remainder (MultU64x32 (TimeStamp, 1000), TicksPerSecond, NULL));
72 SerialPortWrite ((UINT8 *) Buffer, CharCount);
73 }
74
75 STATIC
76 EFI_STATUS
77 InsertSystemMemoryResources (
78 LIST_ENTRY *ResourceList,
79 EFI_HOB_RESOURCE_DESCRIPTOR *ResHob
80 )
81 {
82 SYSTEM_MEMORY_RESOURCE *NewResource;
83 LIST_ENTRY *Link;
84 LIST_ENTRY *NextLink;
85 LIST_ENTRY AttachedResources;
86 SYSTEM_MEMORY_RESOURCE *Resource;
87 EFI_PHYSICAL_ADDRESS NewResourceEnd;
88
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);
94 return EFI_SUCCESS;
95 }
96
97 InitializeListHead (&AttachedResources);
98
99 Link = ResourceList->ForwardLink;
100 ASSERT (Link != NULL);
101 while (Link != ResourceList) {
102 Resource = (SYSTEM_MEMORY_RESOURCE*)Link;
103
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))));
108
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;
112
113 NextLink = RemoveEntryList (&Resource->Link);
114 InsertTailList (&AttachedResources, &Resource->Link);
115 Link = NextLink;
116 }
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;
121
122 NextLink = RemoveEntryList (&Resource->Link);
123 InsertTailList (&AttachedResources, &Resource->Link);
124 Link = NextLink;
125 } else {
126 Link = Link->ForwardLink;
127 }
128 }
129
130 if (!IsListEmpty (&AttachedResources)) {
131 // See if we can merge the attached resource with other resources
132
133 NewResource = (SYSTEM_MEMORY_RESOURCE*)GetFirstNode (&AttachedResources);
134 Link = RemoveEntryList (&NewResource->Link);
135 while (!IsListEmpty (&AttachedResources)) {
136 // Merge resources
137 Resource = (SYSTEM_MEMORY_RESOURCE*)Link;
138
139 // Ensure they overlap each other
140 ASSERT (
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)))
143 );
144
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;
148
149 Link = RemoveEntryList (Link);
150 }
151 } else {
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;
156 }
157 InsertTailList (ResourceList, &NewResource->Link);
158 return EFI_SUCCESS;
159 }
160
161 EFI_STATUS
162 GetSystemMemoryResources (
163 IN LIST_ENTRY *ResourceList
164 )
165 {
166 EFI_HOB_RESOURCE_DESCRIPTOR *ResHob;
167
168 InitializeListHead (ResourceList);
169
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));
174 }
175
176 // Did not find any
177 if (ResHob == NULL) {
178 return EFI_NOT_FOUND;
179 } else {
180 InsertSystemMemoryResources (ResourceList, ResHob);
181 }
182
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);
187 }
188 ResHob = (EFI_HOB_RESOURCE_DESCRIPTOR *)GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, (VOID *)((UINTN)ResHob + ResHob->Header.HobLength));
189 }
190
191 return EFI_SUCCESS;
192 }