/** @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;
}
