]> git.proxmox.com Git - mirror_edk2.git/blob - DuetPkg/EfiLdr/Support.c
DuetPkg: Removing ipf which is no longer supported from edk2.
[mirror_edk2.git] / DuetPkg / EfiLdr / Support.c
1 /*++
2
3 Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
8
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11
12 Module Name:
13 Support.c
14
15 Abstract:
16
17 Revision History:
18
19 --*/
20 #include "EfiLdr.h"
21
22 EFI_STATUS
23 EfiAddMemoryDescriptor(
24 UINTN *NoDesc,
25 EFI_MEMORY_DESCRIPTOR *Desc,
26 EFI_MEMORY_TYPE Type,
27 EFI_PHYSICAL_ADDRESS BaseAddress,
28 UINT64 NoPages,
29 UINT64 Attribute
30 )
31 {
32 UINTN NumberOfDesc;
33 UINT64 Temp;
34 UINTN Index;
35
36 if (NoPages == 0) {
37 return EFI_SUCCESS;
38 }
39
40 //
41 // See if the new memory descriptor needs to be carved out of an existing memory descriptor
42 //
43
44 NumberOfDesc = *NoDesc;
45 for (Index = 0; Index < NumberOfDesc; Index++) {
46
47 if (Desc[Index].Type == EfiConventionalMemory) {
48
49 Temp = DivU64x32 ((BaseAddress - Desc[Index].PhysicalStart), EFI_PAGE_SIZE) + NoPages;
50
51 if ((Desc[Index].PhysicalStart < BaseAddress) && (Desc[Index].NumberOfPages >= Temp)) {
52 if (Desc[Index].NumberOfPages > Temp) {
53 Desc[*NoDesc].Type = EfiConventionalMemory;
54 Desc[*NoDesc].PhysicalStart = BaseAddress + MultU64x32 (NoPages, EFI_PAGE_SIZE);
55 Desc[*NoDesc].NumberOfPages = Desc[Index].NumberOfPages - Temp;
56 Desc[*NoDesc].VirtualStart = 0;
57 Desc[*NoDesc].Attribute = Desc[Index].Attribute;
58 *NoDesc = *NoDesc + 1;
59 }
60 Desc[Index].NumberOfPages = Temp - NoPages;
61 }
62
63 if ((Desc[Index].PhysicalStart == BaseAddress) && (Desc[Index].NumberOfPages == NoPages)) {
64 Desc[Index].Type = Type;
65 Desc[Index].Attribute = Attribute;
66 return EFI_SUCCESS;
67 }
68
69 if ((Desc[Index].PhysicalStart == BaseAddress) && (Desc[Index].NumberOfPages > NoPages)) {
70 Desc[Index].NumberOfPages -= NoPages;
71 Desc[Index].PhysicalStart += MultU64x32 (NoPages, EFI_PAGE_SIZE);
72 }
73 }
74 }
75
76 //
77 // Add the new memory descriptor
78 //
79
80 Desc[*NoDesc].Type = Type;
81 Desc[*NoDesc].PhysicalStart = BaseAddress;
82 Desc[*NoDesc].NumberOfPages = NoPages;
83 Desc[*NoDesc].VirtualStart = 0;
84 Desc[*NoDesc].Attribute = Attribute;
85 *NoDesc = *NoDesc + 1;
86
87 return EFI_SUCCESS;
88 }
89
90 UINTN
91 FindSpace (
92 UINTN NoPages,
93 IN UINTN *NumberOfMemoryMapEntries,
94 IN EFI_MEMORY_DESCRIPTOR *EfiMemoryDescriptor,
95 EFI_MEMORY_TYPE Type,
96 UINT64 Attribute
97 )
98 {
99 EFI_PHYSICAL_ADDRESS MaxPhysicalStart;
100 UINT64 MaxNoPages;
101 UINTN Index;
102 EFI_MEMORY_DESCRIPTOR *CurrentMemoryDescriptor;
103
104 MaxPhysicalStart = 0;
105 MaxNoPages = 0;
106 CurrentMemoryDescriptor = NULL;
107 for (Index = 0; Index < *NumberOfMemoryMapEntries; Index++) {
108 if (EfiMemoryDescriptor[Index].PhysicalStart + LShiftU64(EfiMemoryDescriptor[Index].NumberOfPages, EFI_PAGE_SHIFT) <= 0x100000) {
109 continue;
110 }
111 if ((EfiMemoryDescriptor[Index].Type == EfiConventionalMemory) &&
112 (EfiMemoryDescriptor[Index].NumberOfPages >= NoPages)) {
113 if (EfiMemoryDescriptor[Index].PhysicalStart > MaxPhysicalStart) {
114 if (EfiMemoryDescriptor[Index].PhysicalStart + LShiftU64(EfiMemoryDescriptor[Index].NumberOfPages, EFI_PAGE_SHIFT) <= 0x100000000ULL) {
115 MaxPhysicalStart = EfiMemoryDescriptor[Index].PhysicalStart;
116 MaxNoPages = EfiMemoryDescriptor[Index].NumberOfPages;
117 CurrentMemoryDescriptor = &EfiMemoryDescriptor[Index];
118 }
119 }
120 }
121 if ((EfiMemoryDescriptor[Index].Type == EfiReservedMemoryType) ||
122 (EfiMemoryDescriptor[Index].Type >= EfiACPIReclaimMemory) ) {
123 continue;
124 }
125 if ((EfiMemoryDescriptor[Index].Type == EfiRuntimeServicesCode) ||
126 (EfiMemoryDescriptor[Index].Type == EfiRuntimeServicesData)) {
127 break;
128 }
129 }
130
131 if (MaxPhysicalStart == 0) {
132 return 0;
133 }
134
135 if (MaxNoPages != NoPages) {
136 CurrentMemoryDescriptor->NumberOfPages = MaxNoPages - NoPages;
137 EfiMemoryDescriptor[*NumberOfMemoryMapEntries].Type = Type;
138 EfiMemoryDescriptor[*NumberOfMemoryMapEntries].PhysicalStart = MaxPhysicalStart + LShiftU64(MaxNoPages - NoPages, EFI_PAGE_SHIFT);
139 EfiMemoryDescriptor[*NumberOfMemoryMapEntries].NumberOfPages = NoPages;
140 EfiMemoryDescriptor[*NumberOfMemoryMapEntries].VirtualStart = 0;
141 EfiMemoryDescriptor[*NumberOfMemoryMapEntries].Attribute = Attribute;
142 *NumberOfMemoryMapEntries = *NumberOfMemoryMapEntries + 1;
143 } else {
144 CurrentMemoryDescriptor->Type = Type;
145 CurrentMemoryDescriptor->Attribute = Attribute;
146 }
147
148 return (UINTN)(MaxPhysicalStart + LShiftU64(MaxNoPages - NoPages, EFI_PAGE_SHIFT));
149 }
150
151 VOID
152 GenMemoryMap (
153 UINTN *NumberOfMemoryMapEntries,
154 EFI_MEMORY_DESCRIPTOR *EfiMemoryDescriptor,
155 BIOS_MEMORY_MAP *BiosMemoryMap
156 )
157 {
158 UINT64 BaseAddress;
159 UINT64 Length;
160 EFI_MEMORY_TYPE Type;
161 UINTN Index;
162 UINTN Attr;
163 UINT64 Ceiling;
164
165 Ceiling = 0xFFFFFFFF;
166 for (Index = 0; Index < BiosMemoryMap->MemoryMapSize / sizeof(BIOS_MEMORY_MAP_ENTRY); Index++) {
167
168 switch (BiosMemoryMap->MemoryMapEntry[Index].Type) {
169 case (INT15_E820_AddressRangeMemory):
170 Type = EfiConventionalMemory;
171 Attr = EFI_MEMORY_WB;
172 break;
173 case (INT15_E820_AddressRangeReserved):
174 Type = EfiReservedMemoryType;
175 Attr = EFI_MEMORY_UC;
176 break;
177 case (INT15_E820_AddressRangeACPI):
178 Type = EfiACPIReclaimMemory;
179 Attr = EFI_MEMORY_WB;
180 break;
181 case (INT15_E820_AddressRangeNVS):
182 Type = EfiACPIMemoryNVS;
183 Attr = EFI_MEMORY_UC;
184 break;
185 default:
186 // We should not get here, according to ACPI 2.0 Spec.
187 // BIOS behaviour of the Int15h, E820h
188 Type = EfiReservedMemoryType;
189 Attr = EFI_MEMORY_UC;
190 break;
191 }
192 if (Type == EfiConventionalMemory) {
193 BaseAddress = BiosMemoryMap->MemoryMapEntry[Index].BaseAddress;
194 Length = BiosMemoryMap->MemoryMapEntry[Index].Length;
195 if (BaseAddress & EFI_PAGE_MASK) {
196 Length = Length + (BaseAddress & EFI_PAGE_MASK) - EFI_PAGE_SIZE;
197 BaseAddress = LShiftU64 (RShiftU64 (BaseAddress, EFI_PAGE_SHIFT) + 1, EFI_PAGE_SHIFT);
198 }
199 } else {
200 BaseAddress = BiosMemoryMap->MemoryMapEntry[Index].BaseAddress;
201 Length = BiosMemoryMap->MemoryMapEntry[Index].Length + (BaseAddress & EFI_PAGE_MASK);
202 BaseAddress = LShiftU64 (RShiftU64 (BaseAddress, EFI_PAGE_SHIFT), EFI_PAGE_SHIFT);
203 if (Length & EFI_PAGE_MASK) {
204 Length = LShiftU64 (RShiftU64 (Length, EFI_PAGE_SHIFT) + 1, EFI_PAGE_SHIFT);
205 }
206 //
207 // Update Memory Ceiling
208 //
209 if ((BaseAddress >= 0x100000) && (BaseAddress < 0x100000000ULL)) {
210 if (Ceiling > BaseAddress) {
211 Ceiling = BaseAddress;
212 }
213 }
214 }
215 EfiAddMemoryDescriptor (
216 NumberOfMemoryMapEntries,
217 EfiMemoryDescriptor,
218 Type,
219 (EFI_PHYSICAL_ADDRESS)BaseAddress,
220 RShiftU64 (Length, EFI_PAGE_SHIFT),
221 Attr
222 );
223 }
224
225 //
226 // Update MemoryMap according to Ceiling
227 //
228 for (Index = 0; Index < *NumberOfMemoryMapEntries; Index++) {
229 if ((EfiMemoryDescriptor[Index].Type == EfiConventionalMemory) &&
230 (EfiMemoryDescriptor[Index].PhysicalStart > 0x100000) &&
231 (EfiMemoryDescriptor[Index].PhysicalStart < 0x100000000ULL)) {
232 if (EfiMemoryDescriptor[Index].PhysicalStart >= Ceiling) {
233 EfiMemoryDescriptor[Index].Type = EfiReservedMemoryType;
234 }
235 }
236 }
237 }