+++ /dev/null
-/*++\r
-\r
-Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials \r
-are licensed and made available under the terms and conditions of the BSD License \r
-which accompanies this distribution. The full text of the license may be found at \r
-http://opensource.org/licenses/bsd-license.php \r
- \r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
-\r
-Module Name:\r
- Support.c\r
-\r
-Abstract:\r
-\r
-Revision History:\r
-\r
---*/\r
-#include "EfiLdr.h"\r
-\r
-EFI_STATUS\r
-EfiAddMemoryDescriptor(\r
- UINTN *NoDesc,\r
- EFI_MEMORY_DESCRIPTOR *Desc,\r
- EFI_MEMORY_TYPE Type,\r
- EFI_PHYSICAL_ADDRESS BaseAddress,\r
- UINT64 NoPages,\r
- UINT64 Attribute\r
- )\r
-{\r
- UINTN NumberOfDesc;\r
- UINT64 Temp;\r
- UINTN Index;\r
-\r
- if (NoPages == 0) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // See if the new memory descriptor needs to be carved out of an existing memory descriptor\r
- //\r
-\r
- NumberOfDesc = *NoDesc;\r
- for (Index = 0; Index < NumberOfDesc; Index++) {\r
-\r
- if (Desc[Index].Type == EfiConventionalMemory) {\r
-\r
- Temp = DivU64x32 ((BaseAddress - Desc[Index].PhysicalStart), EFI_PAGE_SIZE) + NoPages;\r
-\r
- if ((Desc[Index].PhysicalStart < BaseAddress) && (Desc[Index].NumberOfPages >= Temp)) {\r
- if (Desc[Index].NumberOfPages > Temp) {\r
- Desc[*NoDesc].Type = EfiConventionalMemory;\r
- Desc[*NoDesc].PhysicalStart = BaseAddress + MultU64x32 (NoPages, EFI_PAGE_SIZE);\r
- Desc[*NoDesc].NumberOfPages = Desc[Index].NumberOfPages - Temp;\r
- Desc[*NoDesc].VirtualStart = 0;\r
- Desc[*NoDesc].Attribute = Desc[Index].Attribute;\r
- *NoDesc = *NoDesc + 1;\r
- }\r
- Desc[Index].NumberOfPages = Temp - NoPages;\r
- }\r
-\r
- if ((Desc[Index].PhysicalStart == BaseAddress) && (Desc[Index].NumberOfPages == NoPages)) {\r
- Desc[Index].Type = Type;\r
- Desc[Index].Attribute = Attribute;\r
- return EFI_SUCCESS;\r
- }\r
-\r
- if ((Desc[Index].PhysicalStart == BaseAddress) && (Desc[Index].NumberOfPages > NoPages)) {\r
- Desc[Index].NumberOfPages -= NoPages;\r
- Desc[Index].PhysicalStart += MultU64x32 (NoPages, EFI_PAGE_SIZE);\r
- }\r
- }\r
- }\r
-\r
- //\r
- // Add the new memory descriptor\r
- //\r
-\r
- Desc[*NoDesc].Type = Type;\r
- Desc[*NoDesc].PhysicalStart = BaseAddress;\r
- Desc[*NoDesc].NumberOfPages = NoPages;\r
- Desc[*NoDesc].VirtualStart = 0;\r
- Desc[*NoDesc].Attribute = Attribute;\r
- *NoDesc = *NoDesc + 1;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-UINTN\r
-FindSpace (\r
- UINTN NoPages,\r
- IN UINTN *NumberOfMemoryMapEntries,\r
- IN EFI_MEMORY_DESCRIPTOR *EfiMemoryDescriptor,\r
- EFI_MEMORY_TYPE Type,\r
- UINT64 Attribute\r
- )\r
-{\r
- EFI_PHYSICAL_ADDRESS MaxPhysicalStart;\r
- UINT64 MaxNoPages;\r
- UINTN Index;\r
- EFI_MEMORY_DESCRIPTOR *CurrentMemoryDescriptor;\r
-\r
- MaxPhysicalStart = 0;\r
- MaxNoPages = 0;\r
- CurrentMemoryDescriptor = NULL;\r
- for (Index = 0; Index < *NumberOfMemoryMapEntries; Index++) {\r
- if (EfiMemoryDescriptor[Index].PhysicalStart + LShiftU64(EfiMemoryDescriptor[Index].NumberOfPages, EFI_PAGE_SHIFT) <= 0x100000) {\r
- continue;\r
- }\r
- if ((EfiMemoryDescriptor[Index].Type == EfiConventionalMemory) && \r
- (EfiMemoryDescriptor[Index].NumberOfPages >= NoPages)) {\r
- if (EfiMemoryDescriptor[Index].PhysicalStart > MaxPhysicalStart) {\r
- if (EfiMemoryDescriptor[Index].PhysicalStart + LShiftU64(EfiMemoryDescriptor[Index].NumberOfPages, EFI_PAGE_SHIFT) <= 0x100000000ULL) {\r
- MaxPhysicalStart = EfiMemoryDescriptor[Index].PhysicalStart;\r
- MaxNoPages = EfiMemoryDescriptor[Index].NumberOfPages;\r
- CurrentMemoryDescriptor = &EfiMemoryDescriptor[Index];\r
- }\r
- }\r
- }\r
- if ((EfiMemoryDescriptor[Index].Type == EfiReservedMemoryType) ||\r
- (EfiMemoryDescriptor[Index].Type >= EfiACPIReclaimMemory) ) {\r
- continue;\r
- }\r
- if ((EfiMemoryDescriptor[Index].Type == EfiRuntimeServicesCode) ||\r
- (EfiMemoryDescriptor[Index].Type == EfiRuntimeServicesData)) {\r
- break;\r
- }\r
- }\r
- \r
- if (MaxPhysicalStart == 0) {\r
- return 0;\r
- }\r
-\r
- if (MaxNoPages != NoPages) {\r
- CurrentMemoryDescriptor->NumberOfPages = MaxNoPages - NoPages;\r
- EfiMemoryDescriptor[*NumberOfMemoryMapEntries].Type = Type;\r
- EfiMemoryDescriptor[*NumberOfMemoryMapEntries].PhysicalStart = MaxPhysicalStart + LShiftU64(MaxNoPages - NoPages, EFI_PAGE_SHIFT);\r
- EfiMemoryDescriptor[*NumberOfMemoryMapEntries].NumberOfPages = NoPages;\r
- EfiMemoryDescriptor[*NumberOfMemoryMapEntries].VirtualStart = 0;\r
- EfiMemoryDescriptor[*NumberOfMemoryMapEntries].Attribute = Attribute;\r
- *NumberOfMemoryMapEntries = *NumberOfMemoryMapEntries + 1;\r
- } else {\r
- CurrentMemoryDescriptor->Type = Type;\r
- CurrentMemoryDescriptor->Attribute = Attribute;\r
- }\r
-\r
- return (UINTN)(MaxPhysicalStart + LShiftU64(MaxNoPages - NoPages, EFI_PAGE_SHIFT));\r
-}\r
-\r
-VOID\r
-GenMemoryMap (\r
- UINTN *NumberOfMemoryMapEntries,\r
- EFI_MEMORY_DESCRIPTOR *EfiMemoryDescriptor,\r
- BIOS_MEMORY_MAP *BiosMemoryMap\r
- )\r
-{\r
- UINT64 BaseAddress;\r
- UINT64 Length;\r
- EFI_MEMORY_TYPE Type;\r
- UINTN Index;\r
- UINTN Attr;\r
- UINT64 Ceiling;\r
-\r
- Ceiling = 0xFFFFFFFF;\r
- for (Index = 0; Index < BiosMemoryMap->MemoryMapSize / sizeof(BIOS_MEMORY_MAP_ENTRY); Index++) {\r
-\r
- switch (BiosMemoryMap->MemoryMapEntry[Index].Type) { \r
- case (INT15_E820_AddressRangeMemory):\r
- Type = EfiConventionalMemory;\r
- Attr = EFI_MEMORY_WB;\r
- break;\r
- case (INT15_E820_AddressRangeReserved):\r
- Type = EfiReservedMemoryType;\r
- Attr = EFI_MEMORY_UC;\r
- break;\r
- case (INT15_E820_AddressRangeACPI):\r
- Type = EfiACPIReclaimMemory;\r
- Attr = EFI_MEMORY_WB;\r
- break;\r
- case (INT15_E820_AddressRangeNVS):\r
- Type = EfiACPIMemoryNVS;\r
- Attr = EFI_MEMORY_UC;\r
- break;\r
- default:\r
- // We should not get here, according to ACPI 2.0 Spec.\r
- // BIOS behaviour of the Int15h, E820h\r
- Type = EfiReservedMemoryType;\r
- Attr = EFI_MEMORY_UC;\r
- break;\r
- }\r
- if (Type == EfiConventionalMemory) {\r
- BaseAddress = BiosMemoryMap->MemoryMapEntry[Index].BaseAddress;\r
- Length = BiosMemoryMap->MemoryMapEntry[Index].Length;\r
- if (BaseAddress & EFI_PAGE_MASK) {\r
- Length = Length + (BaseAddress & EFI_PAGE_MASK) - EFI_PAGE_SIZE;\r
- BaseAddress = LShiftU64 (RShiftU64 (BaseAddress, EFI_PAGE_SHIFT) + 1, EFI_PAGE_SHIFT);\r
- }\r
- } else {\r
- BaseAddress = BiosMemoryMap->MemoryMapEntry[Index].BaseAddress;\r
- Length = BiosMemoryMap->MemoryMapEntry[Index].Length + (BaseAddress & EFI_PAGE_MASK);\r
- BaseAddress = LShiftU64 (RShiftU64 (BaseAddress, EFI_PAGE_SHIFT), EFI_PAGE_SHIFT);\r
- if (Length & EFI_PAGE_MASK) {\r
- Length = LShiftU64 (RShiftU64 (Length, EFI_PAGE_SHIFT) + 1, EFI_PAGE_SHIFT);\r
- }\r
- //\r
- // Update Memory Ceiling\r
- //\r
- if ((BaseAddress >= 0x100000) && (BaseAddress < 0x100000000ULL)) {\r
- if (Ceiling > BaseAddress) {\r
- Ceiling = BaseAddress;\r
- }\r
- }\r
- }\r
- EfiAddMemoryDescriptor (\r
- NumberOfMemoryMapEntries,\r
- EfiMemoryDescriptor,\r
- Type,\r
- (EFI_PHYSICAL_ADDRESS)BaseAddress,\r
- RShiftU64 (Length, EFI_PAGE_SHIFT),\r
- Attr\r
- );\r
- }\r
-\r
- //\r
- // Update MemoryMap according to Ceiling\r
- //\r
- for (Index = 0; Index < *NumberOfMemoryMapEntries; Index++) {\r
- if ((EfiMemoryDescriptor[Index].Type == EfiConventionalMemory) &&\r
- (EfiMemoryDescriptor[Index].PhysicalStart > 0x100000) && \r
- (EfiMemoryDescriptor[Index].PhysicalStart < 0x100000000ULL)) {\r
- if (EfiMemoryDescriptor[Index].PhysicalStart >= Ceiling) {\r
- EfiMemoryDescriptor[Index].Type = EfiReservedMemoryType;\r
- }\r
- }\r
- }\r
-}\r