/** @file
Copyright (c) 2017, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
CHAR8 *mMemoryTypeShortName[] = {
"Reserved ",
"LoaderCode",
"LoaderData",
"BS_Code ",
"BS_Data ",
"RT_Code ",
"RT_Data ",
"Available ",
"Unusable ",
"ACPI_Recl ",
"ACPI_NVS ",
"MMIO ",
"MMIO_Port ",
"PalCode ",
"Persistent",
};
STATIC CHAR8 mUnknownStr[11];
CHAR8 *
ShortNameOfMemoryType(
IN UINT32 Type
)
{
if (Type < sizeof(mMemoryTypeShortName) / sizeof(mMemoryTypeShortName[0])) {
return mMemoryTypeShortName[Type];
} else {
AsciiSPrint(mUnknownStr, sizeof(mUnknownStr), "[%08x]", Type);
return mUnknownStr;
}
}
/**
Dump memory map.
@param MemoryMap A pointer to the buffer in which firmware places
the current memory map.
@param MemoryMapSize Size, in bytes, of the MemoryMap buffer.
@param DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR.
**/
VOID
TestPointDumpMemoryMap (
IN EFI_MEMORY_DESCRIPTOR *MemoryMap,
IN UINTN MemoryMapSize,
IN UINTN DescriptorSize
)
{
EFI_MEMORY_DESCRIPTOR *Entry;
UINTN NumberOfEntries;
UINTN Index;
UINT64 Pages[EfiMaxMemoryType];
ZeroMem (Pages, sizeof(Pages));
DEBUG ((EFI_D_INFO, "MemoryMap:\n"));
Entry = MemoryMap;
NumberOfEntries = MemoryMapSize / DescriptorSize;
DEBUG ((DEBUG_INFO, "Type Start End # Pages Attributes\n"));
for (Index = 0; Index < NumberOfEntries; Index++) {
DEBUG ((DEBUG_INFO, ShortNameOfMemoryType(Entry->Type)));
DEBUG ((DEBUG_INFO, " %016LX-%016LX %016LX %016LX\n",
Entry->PhysicalStart,
Entry->PhysicalStart+MultU64x64 (SIZE_4KB,Entry->NumberOfPages) - 1,
Entry->NumberOfPages,
Entry->Attribute
));
if (Entry->Type < EfiMaxMemoryType) {
Pages[Entry->Type] += Entry->NumberOfPages;
}
Entry = NEXT_MEMORY_DESCRIPTOR (Entry, DescriptorSize);
}
DEBUG ((DEBUG_INFO, "\n"));
DEBUG ((DEBUG_INFO, " Reserved : %14ld Pages (%ld Bytes)\n", Pages[EfiReservedMemoryType], MultU64x64(SIZE_4KB, Pages[EfiReservedMemoryType])));
DEBUG ((DEBUG_INFO, " LoaderCode: %14ld Pages (%ld Bytes)\n", Pages[EfiLoaderCode], MultU64x64(SIZE_4KB, Pages[EfiLoaderCode])));
DEBUG ((DEBUG_INFO, " LoaderData: %14ld Pages (%ld Bytes)\n", Pages[EfiLoaderData], MultU64x64(SIZE_4KB, Pages[EfiLoaderData])));
DEBUG ((DEBUG_INFO, " BS_Code : %14ld Pages (%ld Bytes)\n", Pages[EfiBootServicesCode], MultU64x64(SIZE_4KB, Pages[EfiBootServicesCode])));
DEBUG ((DEBUG_INFO, " BS_Data : %14ld Pages (%ld Bytes)\n", Pages[EfiBootServicesData], MultU64x64(SIZE_4KB, Pages[EfiBootServicesData])));
DEBUG ((DEBUG_INFO, " RT_Code : %14ld Pages (%ld Bytes)\n", Pages[EfiRuntimeServicesCode], MultU64x64(SIZE_4KB, Pages[EfiRuntimeServicesCode])));
DEBUG ((DEBUG_INFO, " RT_Data : %14ld Pages (%ld Bytes)\n", Pages[EfiRuntimeServicesData], MultU64x64(SIZE_4KB, Pages[EfiRuntimeServicesData])));
DEBUG ((DEBUG_INFO, " ACPI_Recl : %14ld Pages (%ld Bytes)\n", Pages[EfiACPIReclaimMemory], MultU64x64(SIZE_4KB, Pages[EfiACPIReclaimMemory])));
DEBUG ((DEBUG_INFO, " ACPI_NVS : %14ld Pages (%ld Bytes)\n", Pages[EfiACPIMemoryNVS], MultU64x64(SIZE_4KB, Pages[EfiACPIMemoryNVS])));
DEBUG ((DEBUG_INFO, " MMIO : %14ld Pages (%ld Bytes)\n", Pages[EfiMemoryMappedIO], MultU64x64(SIZE_4KB, Pages[EfiMemoryMappedIO])));
DEBUG ((DEBUG_INFO, " MMIO_Port : %14ld Pages (%ld Bytes)\n", Pages[EfiMemoryMappedIOPortSpace], MultU64x64(SIZE_4KB, Pages[EfiMemoryMappedIOPortSpace])));
DEBUG ((DEBUG_INFO, " PalCode : %14ld Pages (%ld Bytes)\n", Pages[EfiPalCode], MultU64x64(SIZE_4KB, Pages[EfiPalCode])));
DEBUG ((DEBUG_INFO, " Available : %14ld Pages (%ld Bytes)\n", Pages[EfiConventionalMemory], MultU64x64(SIZE_4KB, Pages[EfiConventionalMemory])));
DEBUG ((DEBUG_INFO, " Persistent: %14ld Pages (%ld Bytes)\n", Pages[EfiPersistentMemory], MultU64x64(SIZE_4KB, Pages[EfiPersistentMemory])));
DEBUG ((DEBUG_INFO, " -------------- \n"));
}
BOOLEAN
TestPointCheckUefiMemoryMapEntry (
IN EFI_MEMORY_DESCRIPTOR *MemoryMap,
IN UINTN MemoryMapSize,
IN UINTN DescriptorSize
)
{
EFI_MEMORY_DESCRIPTOR *Entry;
UINTN NumberOfEntries;
UINTN Index;
UINT64 EntryCount[EfiMaxMemoryType];
ZeroMem (EntryCount, sizeof(EntryCount));
Entry = MemoryMap;
NumberOfEntries = MemoryMapSize / DescriptorSize;
for (Index = 0; Index < NumberOfEntries; Index++) {
if (Entry->Type < EfiMaxMemoryType) {
EntryCount[Entry->Type] ++;
}
Entry = NEXT_MEMORY_DESCRIPTOR (Entry, DescriptorSize);
}
if (EntryCount[EfiRuntimeServicesCode] > 1) {
DEBUG ((DEBUG_ERROR, "EfiRuntimeServicesCode entry - %d\n", EntryCount[EfiRuntimeServicesCode]));
}
if (EntryCount[EfiRuntimeServicesData] > 1) {
DEBUG ((DEBUG_ERROR, "EfiRuntimeServicesData entry - %d\n", EntryCount[EfiRuntimeServicesData]));
}
if (EntryCount[EfiACPIMemoryNVS] > 1) {
DEBUG ((DEBUG_ERROR, "EfiACPIMemoryNVS entry - %d\n", EntryCount[EfiACPIMemoryNVS]));
}
if (EntryCount[EfiACPIReclaimMemory] > 1) {
DEBUG ((DEBUG_ERROR, "EfiACPIReclaimMemory entry - %d\n", EntryCount[EfiACPIReclaimMemory]));
}
if ((EntryCount[EfiRuntimeServicesCode] > 1) ||
(EntryCount[EfiRuntimeServicesData] > 1) ||
(EntryCount[EfiACPIReclaimMemory] > 1) ||
(EntryCount[EfiACPIMemoryNVS] > 1) ) {
return FALSE;
} else {
return TRUE;
}
}
VOID
TestPointDumpUefiMemoryMap (
OUT EFI_MEMORY_DESCRIPTOR **UefiMemoryMap, OPTIONAL
OUT UINTN *UefiMemoryMapSize, OPTIONAL
OUT UINTN *UefiDescriptorSize, OPTIONAL
IN BOOLEAN DumpPrint
)
{
EFI_STATUS Status;
UINTN MapKey;
UINT32 DescriptorVersion;
EFI_MEMORY_DESCRIPTOR *MemoryMap;
UINTN MemoryMapSize;
UINTN DescriptorSize;
if (UefiMemoryMap != NULL) {
*UefiMemoryMap = NULL;
*UefiMemoryMapSize = 0;
*UefiDescriptorSize = 0;
}
if (DumpPrint) {
DEBUG ((DEBUG_INFO, "==== TestPointDumpUefiMemoryMap - Enter\n"));
}
MemoryMapSize = 0;
MemoryMap = NULL;
Status = gBS->GetMemoryMap (
&MemoryMapSize,
MemoryMap,
&MapKey,
&DescriptorSize,
&DescriptorVersion
);
ASSERT (Status == EFI_BUFFER_TOO_SMALL);
do {
Status = gBS->AllocatePool (EfiBootServicesData, MemoryMapSize, (VOID **)&MemoryMap);
ASSERT (MemoryMap != NULL);
if (MemoryMap == NULL) {
goto Done ;
}
Status = gBS->GetMemoryMap (
&MemoryMapSize,
MemoryMap,
&MapKey,
&DescriptorSize,
&DescriptorVersion
);
if (EFI_ERROR (Status)) {
gBS->FreePool (MemoryMap);
MemoryMap = NULL;
}
} while (Status == EFI_BUFFER_TOO_SMALL);
if (MemoryMap == NULL) {
goto Done ;
}
if (DumpPrint) {
TestPointDumpMemoryMap (MemoryMap, MemoryMapSize, DescriptorSize);
}
if (UefiMemoryMap != NULL) {
*UefiMemoryMap = AllocateCopyPool (MemoryMapSize, MemoryMap);
*UefiMemoryMapSize = MemoryMapSize;
*UefiDescriptorSize = DescriptorSize;
}
gBS->FreePool (MemoryMap);
Done:
if (DumpPrint) {
DEBUG ((DEBUG_INFO, "==== TestPointDumpUefiMemoryMap - Exit\n"));
}
return ;
}
EFI_STATUS
TestPointCheckUefiMemoryMap (
VOID
)
{
EFI_STATUS Status;
UINTN MapKey;
UINT32 DescriptorVersion;
EFI_MEMORY_DESCRIPTOR *MemoryMap;
UINTN UefiMemoryMapSize;
UINTN UefiDescriptorSize;
BOOLEAN Result;
DEBUG ((DEBUG_INFO, "==== TestPointCheckUefiMemoryMap - Enter\n"));
UefiMemoryMapSize = 0;
MemoryMap = NULL;
Status = gBS->GetMemoryMap (
&UefiMemoryMapSize,
MemoryMap,
&MapKey,
&UefiDescriptorSize,
&DescriptorVersion
);
ASSERT (Status == EFI_BUFFER_TOO_SMALL);
do {
Status = gBS->AllocatePool (EfiBootServicesData, UefiMemoryMapSize, (VOID **)&MemoryMap);
ASSERT (MemoryMap != NULL);
if (MemoryMap == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto Done ;
}
Status = gBS->GetMemoryMap (
&UefiMemoryMapSize,
MemoryMap,
&MapKey,
&UefiDescriptorSize,
&DescriptorVersion
);
if (EFI_ERROR (Status)) {
gBS->FreePool (MemoryMap);
MemoryMap = NULL;
}
} while (Status == EFI_BUFFER_TOO_SMALL);
if (MemoryMap == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto Done ;
}
Result = TestPointCheckUefiMemoryMapEntry (MemoryMap, UefiMemoryMapSize, UefiDescriptorSize);
if (!Result) {
TestPointLibAppendErrorString (
PLATFORM_TEST_POINT_ROLE_PLATFORM_IBV,
NULL,
TEST_POINT_BYTE4_READY_TO_BOOT_MEMORY_TYPE_INFORMATION_FUNCTIONAL_ERROR_CODE \
TEST_POINT_READY_TO_BOOT \
TEST_POINT_BYTE4_READY_TO_BOOT_MEMORY_TYPE_INFORMATION_FUNCTIONAL_ERROR_STRING
);
Status = EFI_INVALID_PARAMETER;
} else {
Status = EFI_SUCCESS;
}
gBS->FreePool (MemoryMap);
Done:
DEBUG ((DEBUG_INFO, "==== TestPointCheckUefiMemoryMap - Exit\n"));
return Status;
}