mirror of
https://github.com/tianocore/edk2.git
synced 2025-08-26 13:14:41 +00:00

Add the OvmfPkg MemDebugLogPei PEI Module which is responsible for allocating and initializing the main memory log buffer. Cc: Gerd Hoffmann <kraxel@redhat.com> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Jiewen Yao <jiewen.yao@intel.com> Signed-off-by: Aaron Young <aaron.young@oracle.com>
151 lines
4.2 KiB
C
151 lines
4.2 KiB
C
/** @file
|
|
|
|
Memory Debug Log PEIM
|
|
|
|
Copyright (C) 2025, Oracle and/or its affiliates.
|
|
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
|
**/
|
|
|
|
#include <Library/BaseMemoryLib.h>
|
|
#include <Library/DebugLib.h>
|
|
#include <Library/HobLib.h>
|
|
#include <Library/MemoryAllocationLib.h>
|
|
#include <Library/PeiServicesLib.h>
|
|
#include <Library/PeimEntryPoint.h>
|
|
#include <Library/PcdLib.h>
|
|
#include <Library/MemDebugLogLib.h>
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
MemDebugLogMemAvailCB (
|
|
IN EFI_PEI_SERVICES **PeiServices,
|
|
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
|
|
IN VOID *Ppi
|
|
);
|
|
|
|
CONST EFI_PEI_NOTIFY_DESCRIPTOR mMemAvailNotifyList[] = {
|
|
{
|
|
(EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
|
|
&gEfiPeiMemoryDiscoveredPpiGuid,
|
|
MemDebugLogMemAvailCB
|
|
}
|
|
};
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
MemDebugLogMemAvailCB (
|
|
IN EFI_PEI_SERVICES **PeiServices,
|
|
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
|
|
IN VOID *Ppi
|
|
)
|
|
{
|
|
UINT32 MemDebugLogBufPages;
|
|
EFI_PHYSICAL_ADDRESS MemDebugLogBufAddr;
|
|
EFI_HOB_GUID_TYPE *GuidHob;
|
|
MEM_DEBUG_LOG_HOB_DATA *HobData;
|
|
EFI_STATUS Status;
|
|
|
|
MemDebugLogBufPages = MemDebugLogPages ();
|
|
|
|
//
|
|
// Buffer size of 0 disables memory debug logging.
|
|
//
|
|
if (!MemDebugLogBufPages) {
|
|
MemDebugLogBufAddr = 0;
|
|
Status = EFI_SUCCESS;
|
|
goto done;
|
|
}
|
|
|
|
//
|
|
// Allocate the memory debug log buffer.
|
|
// NOTE: We allocate the buffer as type EfiRuntimeServicesData
|
|
// as this seems to allow the buffer to persist and be
|
|
// accessible/modifiable throughout runtime (i.e. and avoid
|
|
// being locked down by the MemoryAttributesTable code).
|
|
//
|
|
Status = PeiServicesAllocatePages (
|
|
EfiRuntimeServicesData,
|
|
MemDebugLogBufPages,
|
|
&MemDebugLogBufAddr
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "%a: Failed to allocate Memory Debug Log buffer: %r. Logging disabled\n", __func__, Status));
|
|
MemDebugLogBufAddr = 0;
|
|
goto done;
|
|
}
|
|
|
|
//
|
|
// Init the debug log buffer
|
|
//
|
|
Status = MemDebugLogInit (MemDebugLogBufAddr, (UINT32)EFI_PAGES_TO_SIZE ((UINTN)MemDebugLogBufPages));
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "%a: Failed to init Memory Debug Log buffer: %r. Logging disabled\n", __func__, Status));
|
|
PeiServicesFreePages (MemDebugLogBufAddr, MemDebugLogBufPages);
|
|
MemDebugLogBufAddr = 0;
|
|
goto done;
|
|
}
|
|
|
|
//
|
|
// Copy over the messages from the Early Debug Log buffer.
|
|
//
|
|
if (FixedPcdGet32 (PcdOvmfEarlyMemDebugLogBase) != 0) {
|
|
MemDebugLogCopy (MemDebugLogBufAddr, (EFI_PHYSICAL_ADDRESS)(UINTN)FixedPcdGet32 (PcdOvmfEarlyMemDebugLogBase));
|
|
}
|
|
|
|
done:
|
|
//
|
|
// Zero the early buffer if we successfully
|
|
// created the main memory log buffer.
|
|
//
|
|
if ((Status == EFI_SUCCESS) && (FixedPcdGet32 (PcdOvmfEarlyMemDebugLogBase) != 0)) {
|
|
ZeroMem (
|
|
(VOID *)(UINTN)FixedPcdGet32 (PcdOvmfEarlyMemDebugLogBase),
|
|
(UINT32)FixedPcdGet32 (PcdOvmfEarlyMemDebugLogSize)
|
|
);
|
|
}
|
|
|
|
//
|
|
// Create HOB to pass mem debug log buffer addr
|
|
//
|
|
Status = PeiServicesCreateHob (
|
|
EFI_HOB_TYPE_GUID_EXTENSION,
|
|
(UINT16)(sizeof (EFI_HOB_GUID_TYPE) + sizeof (MEM_DEBUG_LOG_HOB_DATA)),
|
|
(VOID **)&GuidHob
|
|
);
|
|
if (EFI_ERROR (Status)) {
|
|
if (MemDebugLogBufAddr) {
|
|
PeiServicesFreePages (MemDebugLogBufAddr, MemDebugLogBufPages);
|
|
}
|
|
} else {
|
|
//
|
|
// Populate the HOB
|
|
//
|
|
CopyGuid (&GuidHob->Name, &gMemDebugLogHobGuid);
|
|
HobData = (MEM_DEBUG_LOG_HOB_DATA *)GET_GUID_HOB_DATA (GuidHob);
|
|
HobData->MemDebugLogBufAddr = MemDebugLogBufAddr;
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
EFI_STATUS
|
|
EFIAPI
|
|
MemDebugLogEntry (
|
|
IN EFI_PEI_FILE_HANDLE FileHandle,
|
|
IN CONST EFI_PEI_SERVICES **PeiServices
|
|
)
|
|
{
|
|
EFI_STATUS Status;
|
|
|
|
//
|
|
// Setup callback for memory available notification
|
|
//
|
|
Status = PeiServicesNotifyPpi (mMemAvailNotifyList);
|
|
if (EFI_ERROR (Status)) {
|
|
DEBUG ((DEBUG_ERROR, "%a: Failed to create MemDebugLog PEIM Callback: %r. Logging disabled\n", __func__, Status));
|
|
}
|
|
|
|
return Status;
|
|
}
|