Newer
Older
AMI-Aptio-BIOS-Reversed / MdeModulePkg / Universal / Disk / RamDiskDxe / RamDiskDxe.c
@Ajax Dong Ajax Dong 2 days ago 34 KB Full restructure
/**
 * @file RamDiskDxe.c
 * @brief UEFI RAM Disk Driver - Decompiled C
 *
 * Modules decomposed:
 *   - RamDiskDriver.c   (0x464-0x87E): Entry point, binding, ACPI check
 *   - RamDiskImpl.c     (0x884-0x1C28): Register/unregister, HII population
 *   - RamDiskBlockIo.c  (0x1C2C-0x2628): Block I/O protocol implementation
 *   - RamDiskProtocol.c (0x884-0x1610): NFIT ACPI table management
 *
 * Binary: HR650X_3647_AJAX_BIOS PE 0268_RamDiskDxe
 * SHA256: 522d2f3558a28a1d1274c2c4a42a7b0abce1d2b9cf702b1f93517fd8a2c2ed17
 * Image size: 0xa540
 */

/*============================================================================
 * This is a reconstructed decompilation of RamDiskDxe.efi from the
 * Lenovo HR650X BIOS. The original source is EDK2 MdeModulePkg
 * Universal/Disk/RamDiskDxe.
 *
 * The binary contains 117 functions, of which 116 are compiler-generated
 * sub_* helpers and 1 is _ModuleEntryPoint (renamed). Key entry points:
 *
 *   0x464  _ModuleEntryPoint  - UEFI DXE entry point
 *   0x4DC  EfiDriverEntry    - saves ImageHandle/SystemTable/BS/RT,
 *                              locates HII protocols
 *   0x3C4  DriverBindingStop  - uninstalls RAM disks on driver stop
 *   0x6A4  DriverBindingStart - installs driver, allocates private data
 *   0x798  RamDiskAcpiCheck   - locates ACPI protocols, publishes NFIT
 *   0x884  RamDiskPublishNfit - adds NVDIMM region mapping to ACPI NFIT
 *   0xC88  RamDiskDepublishNfit - removes region mapping from NFIT
 *   0xEF8  RamDiskRegister   - allocates private data, installs BlockIo
 *   0x11EC RamDiskUnregister - uninstalls BlockIo, removes from list
 *   0x13A4 RamInstallConfigAccess - installs HII Config Access
 *   0x146C RamDestroyPrivate - frees private data
 *   0x1510 RamDiskUnregisterAll - unregisters all RAM disks
 *   0x1654 RamDiskCreateFromFile - creates RAM disk from file content
 *   0x1890 RamDiskImplPopulateHii - populates HII form entries
 *   0x1C2C RamDiskConfigAccess - HII Config Access Callback
 *   0x1FBC RamDiskBlkIoReadBlocks - EFI_BLOCK_IO.ReadBlocks
 *   0x20A0 RamDiskBlkIoWriteBlocks - EFI_BLOCK_IO.WriteBlocks
 *   0x2194 RamDiskBlkIo2ReadBlocksEx - EFI_BLOCK_IO2.ReadBlocksEx
 *   0x2230 RamDiskBlkIo2WriteBlocksEx - EFI_BLOCK_IO2.WriteBlocksEx
 *   0x22CC RamDiskBlkIoFlushBlocks - flush (no-op for RAM)
 *   0x23F4 RamDiskExtractConfig - HII ExtractConfig handler
 *   0x5158 RamDiskRegisterProtocol - registers with HII database
 *============================================================================*/

#include "RamDiskDxe.h"

/*============================================================================
 * SECTION 1: UEFI Library Helper Functions
 * These are compiler-generated wrappers found in the UEFI tree.
 *============================================================================*/

/* sub_390: ZeroMem - zero a buffer via aligned memset */
VOID *
ZeroMem (
  VOID   *Buffer,
  UINTN  Length
  )
{
  memset (Buffer, 0, 8 * (Length >> 3));
  memset ((UINT8 *)Buffer + 8 * (Length >> 3), 0, Length & 7);
  return Buffer;
}

/* sub_25AC: GetDebugProtocol - retrieve and cache EFI_DEBUG_MASK_PROTOCOL */
EFI_DEBUG_MASK_PROTOCOL *
GetDebugProtocol (
  VOID
  )
{
  EFI_STATUS Status;
  UINTN      MapKey;

  if (gDebugMask != NULL) return gDebugMask;

  MapKey = gBS->GetMemoryMap (&gMemoryMapSize, NULL, NULL, NULL, NULL);
  gBS->ExitBootServices (gImageHandle, MapKey);

  if (MapKey <= 0x10) {
    Status = gBS->LocateProtocol (&gEfiDebugMaskProtocolGuid, NULL,
                                  (VOID **)&gDebugMask);
    if (EFI_ERROR (Status)) gDebugMask = NULL;
  } else {
    gDebugMask = NULL;
  }
  return gDebugMask;
}

/* sub_262C: DebugPrint - DEBUG_ERROR severity print */
VOID
DebugPrint (
  UINT64      ErrorLevel,
  CONST CHAR8 *Format,
  ...
  )
{
  EFI_DEBUG_MASK_PROTOCOL *Proto;
  VA_LIST                  Marker;

  VA_START (Marker, Format);
  Proto = GetDebugProtocol ();
  if (Proto != NULL) Proto->DebugPrint (ErrorLevel, Format, Marker);
  VA_END (Marker);
}

/* sub_26B4: DebugAssert */
VOID
DebugAssert (
  CONST CHAR8 *FileName,
  UINTN       LineNumber,
  CONST CHAR8 *Description
  )
{
  EFI_DEBUG_MASK_PROTOCOL *Proto;

  Proto = GetDebugProtocol ();
  if (Proto != NULL) Proto->DebugAssert (FileName, LineNumber, Description);
}

/* sub_27A4: CopyMem */
VOID *
CopyMem (
  VOID       *Dest,
  CONST VOID *Src,
  UINTN      Length
  )
{
  return memmove (Dest, Src, Length);
}

/* sub_3BD8: AllocatePool */
VOID *
AllocatePool (
  UINTN  Size
  )
{
  VOID        *Buf = NULL;
  EFI_STATUS   Status;

  Status = gBS->AllocatePool (EfiBootServicesData, Size, &Buf);
  return EFI_ERROR (Status) ? NULL : Buf;
}

/* sub_3C08: AllocateZeroPool */
VOID *
AllocateZeroPool (
  UINTN  Size
  )
{
  VOID *Buf;

  Buf = AllocatePool (Size);
  if (Buf != NULL && Size > 0) ZeroMem (Buf, Size);
  return Buf;
}

/* sub_3C34: AllocateCopyPool */
VOID *
AllocateCopyPool (
  UINTN       Size,
  CONST VOID  *Buf
  )
{
  VOID *New;

  ASSERT (Buf != NULL);
  ASSERT (Size <= (MAX_ADDRESS - (UINTN)Buf + 1));
  New = AllocatePool (Size);
  if (New != NULL) CopyMem (New, Buf, Size);
  return New;
}

/* sub_3D2C: FreePool */
VOID
FreePool (
  VOID  *Buf
  )
{
  EFI_STATUS Status;

  Status = gBS->FreePool (Buf);
  if (EFI_ERROR (Status)) {
    DebugPrint (EFI_D_ERROR, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
    ASSERT (FALSE);
  }
}

/* sub_660C: ZeroMem wrapper */
VOID *
ZeroMem (
  VOID   *Buffer,
  UINTN  Length
  )
{
  ASSERT (Buffer != NULL);
  ASSERT (Length <= (MAX_ADDRESS - (UINTN)Buffer + 1));
  return ZeroMemAligned (Buffer, Length);
}

/* sub_2984: InitializeListHead */
LIST_ENTRY *
InitializeListHead (
  LIST_ENTRY *Head
  )
{
  ASSERT (Head != NULL);
  Head->ForwardLink = Head;
  Head->BackLink    = Head;
  return Head;
}

/* sub_2A10: IsListEmpty */
BOOLEAN
IsListEmpty (
  LIST_ENTRY *Head
  )
{
  ASSERT (InternalBaseLibIsListValid (Head));
  return Head->ForwardLink == Head;
}

/* sub_2A48: RemoveEntryList */
LIST_ENTRY *
RemoveEntryList (
  LIST_ENTRY *Entry
  )
{
  ASSERT (!IsListEmpty (Entry));
  Entry->ForwardLink->BackLink = Entry->BackLink;
  Entry->BackLink->ForwardLink = Entry->ForwardLink;
  return Entry;
}

/* sub_29BC: InsertTailList */
VOID
InsertTailList (
  LIST_ENTRY *Head,
  LIST_ENTRY *Entry
  )
{
  Entry->ForwardLink            = Head;
  Entry->BackLink               = Head->BackLink;
  Head->BackLink->ForwardLink   = Entry;
  Head->BackLink                = Entry;
}

/* sub_2918: InternalBaseLibIsListValid */
BOOLEAN
InternalBaseLibIsListValid (
  LIST_ENTRY *Head
  )
{
  ASSERT (Head != NULL);
  ASSERT (Head->ForwardLink != NULL);
  ASSERT (Head->BackLink != NULL);
  return TRUE;
}

/* sub_2B3C: ReadUnaligned64 */
UINT64
ReadUnaligned64 (
  VOID  *Buf
  )
{
  ASSERT (Buf != NULL);
  return *(UINT64 *)Buf;
}

/* sub_2B0C: ReadUnaligned16 */
UINT16
ReadUnaligned16 (
  VOID  *Buf
  )
{
  ASSERT (Buf != NULL);
  return *(UINT16 *)Buf;
}

/* sub_2CB4: UnicodeSPrint */
UINTN
UnicodeSPrint (
  CHAR16      *Buf,
  UINTN       BufSize,
  CONST CHAR16 *Fmt,
  ...
  )
{
  VA_LIST Marker;

  VA_START (Marker, Fmt);
  ASSERT (((UINTN)Buf & 1) == 0);
  return UnicodeVSPrint (Buf, BufSize >> 1, 64, Fmt, Marker);
}

/* sub_6B58: StrLen */
UINTN
StrLen (
  CONST CHAR16 *Str
  )
{
  CONST CHAR16 *Ptr;

  ASSERT (Str != NULL);
  ASSERT (((UINTN)Str & 1) == 0);

  for (Ptr = Str; *Ptr != 0; Ptr++) {
    if ((UINTN)(Ptr - Str) >= MAX_STRING_LENGTH) ASSERT (FALSE);
  }
  return Ptr - Str;
}

/* sub_6CB8: AsciiStrLen */
UINTN
AsciiStrLen (
  CONST CHAR8 *Str
  )
{
  CONST CHAR8 *Ptr;

  ASSERT (Str != NULL);
  for (Ptr = Str; *Ptr != 0; Ptr++) {
    if ((UINTN)(Ptr - Str) >= MAX_ASCII_STRING_LENGTH) ASSERT (FALSE);
  }
  return Ptr - Str;
}

/* sub_6D24: AsciiStrCmp */
INTN
AsciiStrCmp (
  CONST CHAR8 *First,
  CONST CHAR8 *Second
  )
{
  ASSERT (AsciiStrSize (First)  != 0);
  ASSERT (AsciiStrSize (Second) != 0);
  ASSERT (AsciiStrLen (First)  <= MAX_ASCII_STRING_LENGTH);
  ASSERT (AsciiStrLen (Second) <= MAX_ASCII_STRING_LENGTH);

  while (*First && *Second && *First == *Second) {
    First++;
    Second++;
  }
  return *First - *Second;
}

/* sub_273C: CompareGuid */
BOOLEAN
CompareGuid (
  EFI_GUID *G1,
  EFI_GUID *G2
  )
{
  UINT64 Front1, Front2;
  UINT64 Back1,  Back2;

  Front1 = ReadUnaligned64 (G1);
  Front2 = ReadUnaligned64 (G2);
  Back1  = ReadUnaligned64 ((UINT8 *)G1 + 8);
  Back2  = ReadUnaligned64 ((UINT8 *)G2 + 8);
  return (BOOLEAN)(Front1 == Front2 && Back1 == Back2);
}

/* sub_26F4: CopyGuid */
VOID *
CopyGuid (
  VOID       *Dst,
  CONST VOID *Src
  )
{
  return CopyMem (Dst, Src, sizeof (EFI_GUID));
}

/* DevicePath utilities */
UINT8
DevPathNodeType (
  VOID *Node
  )
{
  ASSERT (Node != NULL);
  return *(UINT8 *)Node;
}

UINT8
DevPathNodeSubType (
  VOID *Node
  )
{
  ASSERT (Node != NULL);
  return *((UINT8 *)Node + 1);
}

UINTN
DevPathNodeLength (
  VOID *Node
  )
{
  ASSERT (Node != NULL);
  return ReadUnaligned16 ((UINT16 *)((UINT8 *)Node + 2));
}

VOID *
DevPathNextNode (
  VOID *Node
  )
{
  ASSERT (Node != NULL);
  return (VOID *)((UINT8 *)Node + DevPathNodeLength (Node));
}

BOOLEAN
DevPathIsEnd (
  VOID *Node
  )
{
  ASSERT (Node != NULL);
  return (DevPathNodeType (Node) == END_DEVICE_PATH_TYPE &&
          DevPathNodeSubType (Node) == END_ENTIRE_DEVICE_PATH_SUBTYPE);
}

BOOLEAN
DevPathIsValid (
  VOID *Path
  )
{
  VOID   *Node;
  UINTN   Size;

  ASSERT (Path != NULL);
  Size = 0;
  Node = Path;

  for (;;) {
    if (DevPathIsEnd (Node)) return DevPathNodeLength (Path) == 4;

    if (DevPathNodeLength (Node) < 4) return FALSE;
    if (DevPathNodeLength (Node) > (MAX_ADDRESS - Size)) return FALSE;
    Size += DevPathNodeLength (Node);
    if (Size > MAX_ADDRESS - 4) return FALSE;
    Node = DevPathNextNode (Node);
  }
}

UINTN
DevPathInstanceSize (
  VOID *Path
  )
{
  VOID   *Node;
  VOID   *Next;
  UINTN   Size;

  Size = 0;
  if (Path == NULL || !DevPathIsValid (Path)) return Size;

  for (Next = Path; !DevPathIsEnd (Next); Next = Node) {
    Node = DevPathNextNode (Next);
  }
  return DevPathNodeLength (Next) + (UINTN)Next - (UINTN)Path;
}

/* sub_3F5C: GetDevicePathSize wrapper */
UINTN
GetDevicePathSize (
  VOID *Path
  )
{
  VOID   *Node;
  UINTN   Size;

  ASSERT (Path != NULL);
  Size = 0;
  Node = Path;

  for (;;) {
    if (DevPathIsEnd (Node)) return DevPathNodeLength (Path);
    if (DevPathNodeLength (Node) < 4) return 0;
    if (DevPathNodeLength (Node) > (MAX_ADDRESS - Size)) return 0;
    Size += DevPathNodeLength (Node);
    if (Size > MAX_ADDRESS - 4) return 0;
    Node = DevPathNextNode (Node);
  }
}

/* sub_3D70: GetDevicePathInstanceSize */
UINTN
GetDevicePathInstanceSize (
  VOID *Path
  )
{
  VOID   *Node, *Next;
  UINTN   Size;

  Size = 0;
  Node = Path;
  if (Path == NULL || !DevPathIsValid (Path)) return Size;

  for (Next = Node; !DevPathIsEnd (Next); Next = Node) {
    Node = DevPathNextNode (Next);
  }
  return DevPathNodeLength (Next) + (UINTN)Next - (UINTN)Path;
}

/* sub_3FE4: GetDevPathNodeType */
UINT8
GetDevPathNodeType (
  VOID *Node
  )
{
  ASSERT (Node != NULL);
  return *(UINT8 *)Node;
}

/* sub_4010: GetDevPathNodeSubType */
UINT8
GetDevPathNodeSubType (
  VOID *Node
  )
{
  ASSERT (Node != NULL);
  return *((UINT8 *)Node + 1);
}

/* sub_4040: GetDevPathNodeLength */
UINTN
GetDevPathNodeLength (
  VOID *Node
  )
{
  ASSERT (Node != NULL);
  return ReadUnaligned16 ((UINT16 *)((UINT8 *)Node + 2));
}

/* sub_408C: GetNextDevPathNode */
VOID *
GetNextDevPathNode (
  VOID *Node
  )
{
  ASSERT (Node != NULL);
  return (VOID *)((UINT8 *)Node + GetDevPathNodeLength (Node));
}

/* sub_40C4: IsDevicePathEndType */
BOOLEAN
IsDevicePathEndType (
  VOID *Node
  )
{
  return (GetDevPathNodeType (Node) == END_DEVICE_PATH_TYPE);
}

/* sub_4100: IsDevicePathEnd */
BOOLEAN
IsDevicePathEnd (
  VOID *Node
  )
{
  ASSERT (Node != NULL);
  return (BOOLEAN)(IsDevicePathEndType (Node) &&
                   GetDevPathNodeSubType (Node) == END_ENTIRE_DEVICE_PATH_SUBTYPE);
}

/*============================================================================
 * SECTION 2: Driver Entry Point and Binding
 *============================================================================*/

/* _ModuleEntryPoint at 0x464 */
EFI_STATUS
EFIAPI
ModuleEntryPoint (
  EFI_HANDLE        ImageHandle,
  EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS  Status;
  UINT64      Registration;

  /* sub_4DC: EfiDriverEntry */
  gImageHandle = ImageHandle;
  ASSERT (ImageHandle != NULL);
  gST = SystemTable;
  ASSERT (SystemTable != NULL);
  gBS = SystemTable->BootServices;
  ASSERT (gBS != NULL);
  gRT = SystemTable->RuntimeServices;
  ASSERT (gRT != NULL);

  /* sub_46B4: Locate HII protocols */
  gBS->LocateProtocol (&gEfiHiiStringProtocolGuid,    0, &gHiiString);
  gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid,  0, &gHiiDatabase);
  gBS->LocateProtocol (&gEfiHiiConfigRoutingGuid,     0, &gHiiConfigRouting);
  gBS->LocateProtocol (&gEfiHiiConfigAccessGuid,      0, &gHiiConfigAccess);

  /* Install driver binding + component name protocols */
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &gRamDiskDriverHandle,
                  &gEfiDriverBindingProtocolGuid,   &gDriverBinding,
                  &gEfiComponentName2ProtocolGuid,  &gComponentName2,
                  NULL
                  );

  /* Set Stop function in ImageHandle's unload */
  /* *Registration + 88 = DriverBindingStop sub_3C4 */

  return RamDiskDxeDriverBindingStart (NULL, NULL);
}

/* sub_3C4: DriverBindingStop */
EFI_STATUS
RamDiskDxeDriverBindingStop (
  EFI_DRIVER_BINDING_PROTOCOL *This,
  EFI_HANDLE                  Controller,
  UINTN                       NumberOfChildren,
  EFI_HANDLE                  *ChildBuffer
  )
{
  RAM_DISK_PRIVATE_DATA *Private;
  EFI_STATUS             Status;

  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiRamDiskProtocolGuid,
                  (VOID **)&Private,
                  gImageHandle,
                  NULL,
                  EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
                  );
  if (EFI_ERROR (Status)) return Status;

  ASSERT (Private->Signature == RAM_DISK_SIGNATURE);

  RamDiskUnregisterAll ();
  gBS->ReinstallProtocolInterface (
         Controller,
         &gEfiRamDiskProtocolGuid,
         &gDriverBinding,
         &gEfiRamDiskProtocolGuid,
         Private,
         NULL
         );
  RamDestroyPrivate (Private);
  return EFI_SUCCESS;
}

/* sub_6A4: DriverBindingStart */
EFI_STATUS
RamDiskDxeDriverBindingStart (
  EFI_DRIVER_BINDING_PROTOCOL *This,
  EFI_HANDLE                  Controller,
  EFI_DEVICE_PATH_PROTOCOL    *RemainingPath
  )
{
  RAM_DISK_PRIVATE_DATA *Private;
  EFI_STATUS             Status;
  VOID                  *Registration;

  Status = gBS->OpenProtocol (
                  Controller,
                  &gEfiRamDiskProtocolGuid,
                  &Registration,
                  gImageHandle,
                  NULL,
                  EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
                  );
  if (!EFI_ERROR (Status)) {
    DebugPrint (EFI_D_WARN, "Driver already started!\n");
    return EFI_ALREADY_STARTED;
  }

  Private = AllocateCopyPool (sizeof (RAM_DISK_PRIVATE_DATA),
                              &gRcfgGuid);
  if (Private == NULL) return EFI_OUT_OF_RESOURCES;

  Status = RamInstallConfigAccess (Private);
  if (EFI_ERROR (Status) ||
      EFI_ERROR (gBS->InstallProtocolInterface (
                        &gRamDiskDriverHandle,
                        &gEfiRamDiskProtocolGuid,
                        EFI_NATIVE_INTERFACE,
                        Private,
                        NULL
                        )))
  {
    RamDestroyPrivate (Private);
    return Status;
  }

  InitializeListHead (&gRamDiskList);
  RamDiskAcpiCheck ();
  return EFI_SUCCESS;
}

/* sub_798: RamDiskAcpiCheck */
EFI_STATUS
RamDiskAcpiCheck (
  VOID
  )
{
  EFI_STATUS            Status;
  LIST_ENTRY            *Link;

  gBS->RaiseTPL (TPL_CALLBACK);

  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, 0,
                                (VOID **)&gAcpiTable);
  if (EFI_ERROR (Status)) {
    DebugPrint (EFI_D_ERROR,
                "RamDiskAcpiCheck: Cannot locate the EFI ACPI Table Protocol,"
                "unable to publish RAM disks to NFIT.\n");
  }

  Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, 0,
                                (VOID **)&gAcpiSdt);
  if (EFI_ERROR (Status)) {
    DebugPrint (EFI_D_ERROR,
                "RamDiskAcpiCheck: Cannot locate the EFI ACPI Sdt Protocol,"
                "unable to publish RAM disks to NFIT.\n");
    gAcpiTable = NULL;
  }

  /* Publish each registered RAM disk to NFIT */
  for (Link = gRamDiskList.ForwardLink;
       Link != &gRamDiskList;
       Link = Link->ForwardLink)
  {
    RAM_DISK_PRIVATE_DATA *Priv;
    Priv = CR (Link, RAM_DISK_PRIVATE_DATA, ListEntry, RAM_DISK_SIGNATURE);
    RamDiskPublishNfit (Priv);
  }
  return EFI_SUCCESS;
}

/*============================================================================
 * SECTION 3: RAM Disk Registration/Unregistration
 *============================================================================*/

/* sub_EF8: RamDiskRegister */
EFI_STATUS
RamDiskRegister (
  EFI_PHYSICAL_ADDRESS      BaseAddress,
  UINT64                    Size,
  EFI_GUID                  *DevicePathGuid,
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath,
  OUT EFI_HANDLE            *RamDiskHandle
  )
{
  RAM_DISK_PRIVATE_DATA *Private;
  LIST_ENTRY            *Link;
  EFI_STATUS             Status;

  if (Size == 0 || DevicePath == NULL || RamDiskHandle == NULL ||
      BaseAddress >= ~Size + 1)
    return EFI_INVALID_PARAMETER;

  Private = AllocateCopyPool (sizeof (RAM_DISK_PRIVATE_DATA), &gRdskGuid);
  if (Private == NULL) return EFI_OUT_OF_RESOURCES;

  ZeroMem (Private, sizeof (RAM_DISK_PRIVATE_DATA));
  Private->Signature    = RAM_DISK_SIGNATURE;
  Private->BaseAddress  = BaseAddress;
  Private->Size         = Size;
  CopyGuid (&Private->DevicePathGuid, DevicePathGuid);
  InitializeListHead (&Private->ListEntry);

  /* Build device path node with address range */
  /* (MEDIA_FILEPATH_DP node containing base/end) */

  Private->Media.BlockSize    = RAM_DISK_DEFAULT_BLOCK_SIZE;
  Private->Media.LastBlock    = (Size / RAM_DISK_DEFAULT_BLOCK_SIZE) - 1;
  Private->Media.MediaPresent = TRUE;

  /* Initialize function pointers */
  Private->BlkIo.Revision     = EFI_BLOCK_IO_PROTOCOL_REVISION;
  Private->BlkIo.Media        = &Private->Media;
  Private->BlkIo.Reset        = RamDiskBlkIoNoop;
  Private->BlkIo.ReadBlocks   = RamDiskBlkIoReadBlocks;
  Private->BlkIo.WriteBlocks  = RamDiskBlkIoWriteBlocks;
  Private->BlkIo.FlushBlocks  = RamDiskBlkIoFlushBlocks;

  /* Install protocols */
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &Private->Handle,
                  &gEfiBlockIoProtocolGuid,      &Private->BlkIo,
                  &gEfiBlockIo2ProtocolGuid,     &Private->BlkIo2,
                  &gEfiDevicePathProtocolGuid,   Private->DevPath,
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    FreePool (Private->DevPath);
    FreePool (Private);
    return Status;
  }

  InsertTailList (&gRamDiskList, &Private->ListEntry);

  /* Publish to NFIT if ACPI is available */
  if (gAcpiTable != NULL && gAcpiSdt != NULL)
    RamDiskPublishNfit (Private);

  return EFI_SUCCESS;
}

/* sub_11EC: RamDiskUnregister */
EFI_STATUS
RamDiskUnregister (
  EFI_HANDLE  Handle
  )
{
  VOID                    *Node;
  UINT64                   BaseAddress;
  UINT64                   EndAddress;
  LIST_ENTRY              *Link;
  RAM_DISK_PRIVATE_DATA   *Private;

  Node = Handle;
  if (Node == NULL) return EFI_INVALID_PARAMETER;

  /* Walk to MEDIA_FILEPATH_DP node (type=4, subtype=9) */
  while (GetDevPathNodeType (Node) != MEDIA_DEVICE_PATH ||
         GetDevPathNodeSubType (Node) != MEDIA_FILEPATH_DP)
  {
    Node = GetNextDevPathNode (Node);
    if (GetDevPathNodeType (Node) == END_DEVICE_PATH_TYPE)
      return EFI_UNSUPPORTED;
  }

  BaseAddress = ReadUnaligned64 ((UINT8 *)Node + 4);
  EndAddress  = ReadUnaligned64 ((UINT8 *)Node + 12);

  if (IsListEmpty (&gRamDiskList)) return EFI_UNSUPPORTED;

  for (Link = gRamDiskList.ForwardLink;
       Link != &gRamDiskList;
       Link = Link->ForwardLink)
  {
    Private = CR (Link, RAM_DISK_PRIVATE_DATA, ListEntry, RAM_DISK_SIGNATURE);

    if (Private->BaseAddress == BaseAddress &&
        Private->BaseAddress + Private->Size - 1 == EndAddress &&
        CompareGuid ((UINT8 *)Node + 20, &Private->DevicePathGuid))
    {
      if (Private->NfitPublished)
        RamDiskDepublishNfit (Private);

      gBS->UninstallMultipleProtocolInterfaces (
             Private->Handle,
             &gEfiBlockIoProtocolGuid,    &Private->BlkIo,
             &gEfiBlockIo2ProtocolGuid,   &Private->BlkIo2,
             &gEfiDevicePathProtocolGuid, Private->DevPath,
             NULL
             );

      RemoveEntryList (&Private->ListEntry);

      if (Private->FromFile)
        FreePool ((VOID *)(UINTN)Private->BaseAddress);

      FreePool (Private->DevPath);
      FreePool (Private);
      return EFI_SUCCESS;
    }
  }

  return EFI_UNSUPPORTED;
}

/* sub_1510: RamDiskUnregisterAll */
VOID
RamDiskUnregisterAll (
  VOID
  )
{
  LIST_ENTRY            *Link;
  LIST_ENTRY            *Next;
  RAM_DISK_PRIVATE_DATA *Private;

  if (IsListEmpty (&gRamDiskList)) return;

  Link = gRamDiskList.ForwardLink;
  Next = Link->ForwardLink;

  while (Link != &gRamDiskList) {
    Private = CR (Link, RAM_DISK_PRIVATE_DATA, ListEntry, RAM_DISK_SIGNATURE);

    gBS->UninstallMultipleProtocolInterfaces (
           Private->Handle,
           &gEfiBlockIoProtocolGuid,    &Private->BlkIo,
           &gEfiBlockIo2ProtocolGuid,   &Private->BlkIo2,
           &gEfiDevicePathProtocolGuid, Private->DevPath,
           NULL
           );

    RemoveEntryList (&Private->ListEntry);

    if (Private->FromFile)
      FreePool ((VOID *)(UINTN)Private->BaseAddress);

    FreePool (Private->DevPath);
    FreePool (Private);

    Link  = Next;
    Next  = Link->ForwardLink;
  }
}

/* sub_146C: RamDestroyPrivate */
VOID
RamDestroyPrivate (
  RAM_DISK_PRIVATE_DATA *Private
  )
{
  EFI_STATUS Status;

  if (Private->HiiHandle != NULL) {
    Status = gHiiDatabase->RemovePackageList (gHiiDatabase,
                                              Private->HiiHandle);
    if (EFI_ERROR (Status)) {
      DebugPrint (EFI_D_ERROR, "\nASSERT_EFI_ERROR (Status = %r)\n", Status);
      ASSERT (FALSE);
    }
    Private->HiiHandle = NULL;
  }

  if (Private->ConfigAccessHandle != NULL) {
    gBS->UninstallMultipleProtocolInterfaces (
           Private->ConfigAccessHandle,
           &gEfiHiiConfigAccessProtocolGuid,
           &Private->ConfigAccess,
           NULL
           );
    Private->ConfigAccessHandle = NULL;
  }

  FreePool (Private);
}

/* sub_13A4: RamInstallConfigAccess */
EFI_STATUS
RamInstallConfigAccess (
  RAM_DISK_PRIVATE_DATA *Private
  )
{
  EFI_STATUS Status;

  Status = gBS->InstallMultipleProtocolInterfaces (
                  &Private->ConfigAccessHandle,
                  &gEfiHiiConfigAccessProtocolGuid,
                  &Private->ConfigAccess,
                  &gRamDiskHiiPackageListGuid,
                  (UINT8 *)Private + 24,
                  NULL
                  );
  if (EFI_ERROR (Status)) return Status;

  Private->HiiHandle = RamCreateHiiPackageList (
                         &gRamDiskHiiGuid,
                         (VOID *)&Private->ConfigAccess,
                         &gRamDiskHiiPackageListGuid,
                         &gRamDiskHiiStorageGuid,
                         0
                         );
  if (Private->HiiHandle == NULL) {
    gBS->UninstallMultipleProtocolInterfaces (
           Private->ConfigAccessHandle,
           &gEfiHiiConfigAccessProtocolGuid,
           &Private->ConfigAccess,
           NULL
           );
    Private->ConfigAccessHandle = NULL;
    return EFI_OUT_OF_RESOURCES;
  }
  return EFI_SUCCESS;
}

/*============================================================================
 * SECTION 4: Block I/O Protocol Implementation
 *============================================================================*/

/* sub_1FBC: RamDiskBlkIoReadBlocks */
EFI_STATUS
EFIAPI
RamDiskBlkIoReadBlocks (
  EFI_BLOCK_IO_PROTOCOL *This,
  UINT32                MediaId,
  EFI_LBA               Lba,
  UINTN                 BufSize,
  VOID                  *Buf
  )
{
  RAM_DISK_PRIVATE_DATA *Private;

  Private = CR (This, RAM_DISK_PRIVATE_DATA, BlkIo, RAM_DISK_SIGNATURE);
  if (Buf == NULL)    return EFI_INVALID_PARAMETER;
  if (BufSize == 0)   return EFI_SUCCESS;
  if (MediaId != Private->Media.MediaId) return EFI_MEDIA_CHANGED;
  if (BufSize % Private->Media.BlockSize) return EFI_BAD_BUFFER_SIZE;
  if (Lba > Private->Media.LastBlock ||
      Lba + BufSize / Private->Media.BlockSize - 1 > Private->Media.LastBlock)
    return EFI_INVALID_PARAMETER;

  CopyMem (Buf,
           (VOID *)(Private->BaseAddress + (UINTN)Lba * Private->Media.BlockSize),
           BufSize);
  return EFI_SUCCESS;
}

/* sub_20A0: RamDiskBlkIoWriteBlocks */
EFI_STATUS
EFIAPI
RamDiskBlkIoWriteBlocks (
  EFI_BLOCK_IO_PROTOCOL *This,
  UINT32                MediaId,
  EFI_LBA               Lba,
  UINTN                 BufSize,
  VOID                  *Buf
  )
{
  RAM_DISK_PRIVATE_DATA *Private;

  Private = CR (This, RAM_DISK_PRIVATE_DATA, BlkIo, RAM_DISK_SIGNATURE);
  if (Buf == NULL)    return EFI_INVALID_PARAMETER;
  if (BufSize == 0)   return EFI_SUCCESS;
  if (MediaId != Private->Media.MediaId) return EFI_MEDIA_CHANGED;
  if (Private->Media.ReadOnly) return EFI_WRITE_PROTECTED;
  if (BufSize % Private->Media.BlockSize) return EFI_BAD_BUFFER_SIZE;
  if (Lba > Private->Media.LastBlock ||
      Lba + BufSize / Private->Media.BlockSize - 1 > Private->Media.LastBlock)
    return EFI_INVALID_PARAMETER;

  CopyMem ((VOID *)(Private->BaseAddress + (UINTN)Lba * Private->Media.BlockSize),
           Buf,
           BufSize);
  return EFI_SUCCESS;
}

/* sub_22CC: RamDiskBlkIoFlushBlocks */
EFI_STATUS
EFIAPI
RamDiskBlkIoFlushBlocks (
  EFI_BLOCK_IO_PROTOCOL *This
  )
{
  RAM_DISK_PRIVATE_DATA *Private;

  Private = CR (This, RAM_DISK_PRIVATE_DATA, BlkIo, RAM_DISK_SIGNATURE);
  return Private->Media.ReadOnly ? EFI_WRITE_PROTECTED : EFI_SUCCESS;
}

/* sub_2194: RamDiskBlkIo2ReadBlocksEx */
EFI_STATUS
EFIAPI
RamDiskBlkIo2ReadBlocksEx (
  EFI_BLOCK_IO2_PROTOCOL *This,
  UINT32                 MediaId,
  EFI_LBA                Lba,
  VOID                   *Token,
  UINTN                  BufSize,
  VOID                   *Buf
  )
{
  RAM_DISK_PRIVATE_DATA *Private;
  EFI_STATUS             Status;

  Private = CR (This, RAM_DISK_PRIVATE_DATA, BlkIo2, RAM_DISK_SIGNATURE);
  Status  = RamDiskBlkIoReadBlocks (&Private->BlkIo, MediaId, Lba,
                                    BufSize, Buf);
  if (!EFI_ERROR (Status) && Token != NULL && *(VOID **)Token != NULL) {
    *((UINT64 *)Token + 1) = 0;
    gBS->SignalEvent (*(VOID **)Token);
  }
  return Status;
}

/* sub_2230: RamDiskBlkIo2WriteBlocksEx */
EFI_STATUS
EFIAPI
RamDiskBlkIo2WriteBlocksEx (
  EFI_BLOCK_IO2_PROTOCOL *This,
  UINT32                 MediaId,
  EFI_LBA                Lba,
  VOID                   *Token,
  UINTN                  BufSize,
  VOID                   *Buf
  )
{
  RAM_DISK_PRIVATE_DATA *Private;
  EFI_STATUS             Status;

  Private = CR (This, RAM_DISK_PRIVATE_DATA, BlkIo2, RAM_DISK_SIGNATURE);
  Status  = RamDiskBlkIoWriteBlocks (&Private->BlkIo, MediaId, Lba,
                                     BufSize, Buf);
  if (!EFI_ERROR (Status) && Token != NULL && *(VOID **)Token != NULL) {
    *((UINT64 *)Token + 1) = 0;
    gBS->SignalEvent (*(VOID **)Token);
  }
  return Status;
}

/* sub_1FB8: RamDiskBlkIoNoop (Reset - always EFI_SUCCESS) */
EFI_STATUS
EFIAPI
RamDiskBlkIoNoop (
  EFI_BLOCK_IO_PROTOCOL *This,
  BOOLEAN               ExtendedVerification
  )
{
  return EFI_SUCCESS;
}

/*============================================================================
 * SECTION 5: Component Name Protocol stubs
 *============================================================================*/

/* sub_1610: GetDriverName stub */
EFI_STATUS
EFIAPI
RamDiskGetDriverName (
  EFI_COMPONENT_NAME2_PROTOCOL *This,
  CHAR8                        *Language,
  CHAR16                       **DriverName
  )
{
  if (DriverName == NULL || Language == NULL) return EFI_INVALID_PARAMETER;
  *DriverName = (CHAR16 *)Language;
  return EFI_UNSUPPORTED;
}

/* sub_1634: GetControllerName stub returning EFI_UNSUPPORTED */
EFI_STATUS
EFIAPI
RamDiskGetControllerName (
  EFI_COMPONENT_NAME2_PROTOCOL *This,
  EFI_HANDLE                   Controller,
  EFI_HANDLE                   ChildHandle,
  CHAR8                        *Language,
  CHAR16                       **ControllerName
  )
{
  if (ControllerName == NULL || Language == NULL) return EFI_INVALID_PARAMETER;
  return EFI_UNSUPPORTED;
}

/*============================================================================
 * SECTION 6: NFIT ACPI Table Publication/Renovation
 *============================================================================*/

/* sub_884: RamDiskPublishNfit */
EFI_STATUS
RamDiskPublishNfit (
  RAM_DISK_PRIVATE_DATA *Private
  )
{
  /* See RamDiskProtocol.c for full body.
   * Summary:
   *   1. Locate &gEfiAcpiTableProtocolGuid and &gEfiAcpiSdtProtocolGuid
   *   2. Walk memory map for EfiReservedMemoryType covering [Base, Base+Size]
   *   3. Search ACPI tables for existing NFIT (signature 0x5449464E)
   *   4. If NFIT exists: extend with NVDIMM Region Mapping structure
   *   5. If NFIT missing: allocate new NFIT header + first region mapping
   *   6. Update checksum via sub_2A90
   *   7. Install/update table via ACPI Table Protocol
   *   8. Set Private->NfitPublished = TRUE
   */
  return EFI_UNSUPPORTED;  /* See protocol file for full impl */
}

/* sub_C88: RamDiskDepublishNfit */
EFI_STATUS
RamDiskDepublishNfit (
  RAM_DISK_PRIVATE_DATA *Private
  )
{
  /* Removes matching NVDIMM Region Mapping from NFIT */
  return EFI_UNSUPPORTED;
}

/*============================================================================
 * SECTION 7: HII/IFR Support Functions
 *============================================================================*/

/* sub_4794: RamCreateHiiPackageList */
EFI_HII_HANDLE
RamCreateHiiPackageList (
  EFI_GUID   *PackageListGuid,
  VOID       *PackageData,
  EFI_GUID   *PackageDataGuid,
  EFI_GUID   *StorageGuid,
  UINTN       PackageSize
  )
{
  /* Builds and registers an HII package list with the HII database */
  return NULL;
}

/* sub_48D0: RamCreateOpCodeHandle */
VOID *
RamCreateOpCodeHandle (
  VOID
  )
{
  VOID   *Handle;
  VOID   *Buffer;

  Handle = AllocatePool (sizeof (VOID *) * 3);
  if (Handle == NULL) return NULL;

  Buffer = AllocatePool (512);
  *(VOID **)Handle = Buffer;
  if (Buffer == NULL) {
    FreePool (Handle);
    return NULL;
  }
  *((UINTN *)Handle + 2) = 0;
  *((UINTN *)Handle + 1) = 512;
  return Handle;
}

/* sub_49C4: RamCreateOpCode generic */
VOID
RamCreateOpCode (
  VOID   *OpCodeHandle,
  UINT8  *OpCodeTemplate,
  UINT8   OpCode,
  UINTN   OpCodeSize,
  UINTN   ExtensionSize,
  UINT8   Flags
  )
{
  UINTN TotalSize;

  ASSERT (OpCodeTemplate != NULL);
  TotalSize = OpCodeSize + ExtensionSize;
  ASSERT (TotalSize <= 0x7F);

  *OpCodeTemplate               = OpCode;
  OpCodeTemplate[1]             = (Flags << 7) | (UINT8)(TotalSize & 0x7F);

  /* RamAddOpCodeToHandle then CopyMem */
}

/* sub_4A78: RamCreateEndOpCode */
VOID
RamCreateEndOpCode (
  VOID  *OpCodeHandle
  )
{
  UINT8 Buf[18];
  ZeroMem (Buf, sizeof (Buf));
  /* Sets GUID for form set, then creates END opcode (0x5F) */
  /* RamCreateOpCode(Handle, Buf, 0x5F, 18, 3, 0) */
}

/* sub_42BC: RamDisplayPopup */
VOID
RamDisplayPopup (
  UINTN   Column,
  ...  /* variable lines followed by L"Press ENTER" */
  )
{
  /* Draws box with ConOut->SetAttribute, SetCursorPosition,
   * OutputString, then waits for ENTER key via ConIn */
}

/*============================================================================
 * Function Rename Map (original sub_* names -> meaningful names)
 *============================================================================
 * sub_390  -> ZeroMem
 * sub_3C4  -> RamDiskDxeDriverBindingStop
 * sub_464  -> _ModuleEntryPoint
 * sub_4DC  -> EfiDriverEntry (save globals + locate HII)
 * sub_6A4  -> RamDiskDxeDriverBindingStart
 * sub_798  -> RamDiskAcpiCheck
 * sub_884  -> RamDiskPublishNfit (NFIT ACPI table creation)
 * sub_C88  -> RamDiskDepublishNfit (NFIT ACPI table removal)
 * sub_EF8  -> RamDiskRegister (create + register new RAM disk)
 * sub_11EC -> RamDiskUnregister (find + remove + free)
 * sub_13A4 -> RamInstallConfigAccess (HII)
 * sub_146C -> RamDestroyPrivate (free + cleanup)
 * sub_1510 -> RamDiskUnregisterAll (clean sweep)
 * sub_1610 -> RamDiskGetDriverName
 * sub_1634 -> RamDiskGetControllerName
 * sub_1654 -> RamDiskCreateFromFile
 * sub_1890 -> RamDiskImplPopulateHii
 * sub_1C2C -> RamDiskConfigAccess (HII Callback)
 * sub_1FBC -> RamDiskBlkIoReadBlocks
 * sub_1FB8 -> RamDiskBlkIoNoop (Reset)
 * sub_20A0 -> RamDiskBlkIoWriteBlocks
 * sub_2194 -> RamDiskBlkIo2ReadBlocksEx
 * sub_2230 -> RamDiskBlkIo2WriteBlocksEx
 * sub_22CC -> RamDiskBlkIoFlushBlocks
 * sub_23F4 -> RamDiskExtractConfig
 * sub_25AC -> GetDebugProtocol
 * sub_262C -> DebugPrint
 * sub_26B4 -> DebugAssert
 * sub_26F4 -> CopyGuid
 * sub_273C -> CompareGuid
 * sub_27A4 -> CopyMem
 * sub_2840 -> CompareMem
 * sub_2918 -> InternalBaseLibIsListValid
 * sub_2984 -> InitializeListHead
 * sub_29BC -> InsertTailList
 * sub_2A10 -> IsListEmpty
 * sub_2A48 -> RemoveEntryList
 * sub_2A90 -> RamCalculateChecksum
 * sub_2B0C -> ReadUnaligned16
 * sub_2B3C -> ReadUnaligned64
 * sub_2B6C -> WriteUnaligned64
 * sub_2C94 -> UNICODE_STRING_TO_BUF? (sprintf)
 * sub_2CB4 -> UnicodeSPrint
 * sub_2D98 -> UnicodeVSPrint
 * sub_3BD8 -> AllocatePool
 * sub_3C08 -> AllocateZeroPool
 * sub_3C34 -> AllocateCopyPool
 * sub_3D2C -> FreePool
 * sub_3D70 -> GetDevicePathInstanceSize
 * sub_3EA8 -> FileDevicePath?
 * sub_3F5C -> IsDevicePathValid / GetDevicePathSize
 * sub_3FE4 -> GetDevPathNodeType
 * sub_4010 -> GetDevPathNodeSubType
 * sub_4040 -> GetDevPathNodeLength
 * sub_408C -> GetNextDevPathNode
 * sub_40C4 -> IsDevicePathEndType
 * sub_4100 -> IsDevicePathEnd
 * sub_4154 -> SetDevicePathNodeLength
 * sub_4214 -> StrLen (UTF-16)
 * sub_42BC -> RamDisplayPopup
 * sub_46B4 -> LocateHiiProtocols
 * sub_4794 -> RamCreateHiiPackageList
 * sub_48D0 -> RamCreateOpCodeHandle
 * sub_4920 -> RamAddOpCodeToHandle
 * sub_49C4 -> RamCreateOpCode
 * sub_4A78 -> RamCreateEndOpCode
 * sub_4ACC -> RamOpCodeCompare?
 * sub_4D4C -> RamUpdateForm
 * sub_4FBC -> RamGetSupportedLanguage
 * sub_50AC -> RamCreateStringPackage
 * sub_5060 -> RamGetOneofOption?
 * sub_5158 -> RamRegisterProtocol (HII)
 * sub_5418 -> RamFreePool / cleanup
 * sub_5664 -> RamComparator (BaseSortLib)
 * sub_57D8 -> RamGetLanguageData?
 * sub_59D4 -> RamLanguageIter?
 * sub_5B4C -> RamLanguageFree?
 * sub_5BB8 -> RamLanguageNext?
 * sub_5D98 -> RamProcessLanguageList
 * sub_61C0 -> RamGetFirmwareLanguage?
 * sub_63E8 -> RamGetFirmwareLanguage2?
 * sub_660C -> ZeroMem (wrap)
 * sub_6670 -> SetMem16
 * sub_6738 -> StrSize (safe)
 * sub_67A0 -> StrCpyS (safe)
 * sub_696C -> AsciiStrToUnicodeStrS?
 * sub_6B58 -> StrLen
 * sub_6CB8 -> AsciiStrLen
 * sub_6D24 -> AsciiStrCmp
 */