/** @file
|
|
Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
**/
|
|
#include <Uefi.h>
|
#include <PiDxe.h>
|
#include <Library/UefiBootServicesTableLib.h>
|
#include <Library/TestPointCheckLib.h>
|
#include <Library/TestPointLib.h>
|
#include <Library/DebugLib.h>
|
#include <Library/PrintLib.h>
|
#include <Library/UefiLib.h>
|
#include <Library/BaseMemoryLib.h>
|
#include <Library/MemoryAllocationLib.h>
|
|
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;
|
}
|