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
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.
23 EfiAddMemoryDescriptor(
25 EFI_MEMORY_DESCRIPTOR
*Desc
,
27 EFI_PHYSICAL_ADDRESS BaseAddress
,
41 // See if the new memory descriptor needs to be carved out of an existing memory descriptor
44 NumberOfDesc
= *NoDesc
;
45 for (Index
= 0; Index
< NumberOfDesc
; Index
++) {
47 if (Desc
[Index
].Type
== EfiConventionalMemory
) {
49 Temp
= DivU64x32 ((BaseAddress
- Desc
[Index
].PhysicalStart
), EFI_PAGE_SIZE
) + NoPages
;
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;
60 Desc
[Index
].NumberOfPages
= Temp
- NoPages
;
63 if ((Desc
[Index
].PhysicalStart
== BaseAddress
) && (Desc
[Index
].NumberOfPages
== NoPages
)) {
64 Desc
[Index
].Type
= Type
;
65 Desc
[Index
].Attribute
= Attribute
;
69 if ((Desc
[Index
].PhysicalStart
== BaseAddress
) && (Desc
[Index
].NumberOfPages
> NoPages
)) {
70 Desc
[Index
].NumberOfPages
-= NoPages
;
71 Desc
[Index
].PhysicalStart
+= MultU64x32 (NoPages
, EFI_PAGE_SIZE
);
77 // Add the new memory descriptor
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;
93 IN UINTN
*NumberOfMemoryMapEntries
,
94 IN EFI_MEMORY_DESCRIPTOR
*EfiMemoryDescriptor
,
99 EFI_PHYSICAL_ADDRESS MaxPhysicalStart
;
102 EFI_MEMORY_DESCRIPTOR
*CurrentMemoryDescriptor
;
104 MaxPhysicalStart
= 0;
106 CurrentMemoryDescriptor
= NULL
;
107 for (Index
= 0; Index
< *NumberOfMemoryMapEntries
; Index
++) {
108 if (EfiMemoryDescriptor
[Index
].PhysicalStart
+ LShiftU64(EfiMemoryDescriptor
[Index
].NumberOfPages
, EFI_PAGE_SHIFT
) <= 0x100000) {
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
];
121 if ((EfiMemoryDescriptor
[Index
].Type
== EfiReservedMemoryType
) ||
122 (EfiMemoryDescriptor
[Index
].Type
>= EfiACPIReclaimMemory
) ) {
125 if ((EfiMemoryDescriptor
[Index
].Type
== EfiRuntimeServicesCode
) ||
126 (EfiMemoryDescriptor
[Index
].Type
== EfiRuntimeServicesData
)) {
131 if (MaxPhysicalStart
== 0) {
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;
144 CurrentMemoryDescriptor
->Type
= Type
;
145 CurrentMemoryDescriptor
->Attribute
= Attribute
;
148 return (UINTN
)(MaxPhysicalStart
+ LShiftU64(MaxNoPages
- NoPages
, EFI_PAGE_SHIFT
));
153 UINTN
*NumberOfMemoryMapEntries
,
154 EFI_MEMORY_DESCRIPTOR
*EfiMemoryDescriptor
,
155 BIOS_MEMORY_MAP
*BiosMemoryMap
160 EFI_MEMORY_TYPE Type
;
165 Ceiling
= 0xFFFFFFFF;
166 for (Index
= 0; Index
< BiosMemoryMap
->MemoryMapSize
/ sizeof(BIOS_MEMORY_MAP_ENTRY
); Index
++) {
168 switch (BiosMemoryMap
->MemoryMapEntry
[Index
].Type
) {
169 case (INT15_E820_AddressRangeMemory
):
170 Type
= EfiConventionalMemory
;
171 Attr
= EFI_MEMORY_WB
;
173 case (INT15_E820_AddressRangeReserved
):
174 Type
= EfiReservedMemoryType
;
175 Attr
= EFI_MEMORY_UC
;
177 case (INT15_E820_AddressRangeACPI
):
178 Type
= EfiACPIReclaimMemory
;
179 Attr
= EFI_MEMORY_WB
;
181 case (INT15_E820_AddressRangeNVS
):
182 Type
= EfiACPIMemoryNVS
;
183 Attr
= EFI_MEMORY_UC
;
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
;
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
);
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
);
207 // Update Memory Ceiling
209 if ((BaseAddress
>= 0x100000) && (BaseAddress
< 0x100000000ULL
)) {
210 if (Ceiling
> BaseAddress
) {
211 Ceiling
= BaseAddress
;
215 EfiAddMemoryDescriptor (
216 NumberOfMemoryMapEntries
,
219 (EFI_PHYSICAL_ADDRESS
)BaseAddress
,
220 RShiftU64 (Length
, EFI_PAGE_SHIFT
),
226 // Update MemoryMap according to Ceiling
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
;