/** @file

Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>

This program and the accompanying materials
are licensed and made available under the terms and conditions
of the BSD License which accompanies this distribution.  The
full text of the license may be found at
http://opensource.org/licenses/bsd-license.php

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "LegacyBiosInterface.h"
#include <IndustryStandard/Pci.h>

#define BOOT_LEGACY_OS              0
#define BOOT_EFI_OS                 1
#define BOOT_UNCONVENTIONAL_DEVICE  2

UINT32              mLoadOptionsSize    = 0;
UINTN               mBootMode           = BOOT_LEGACY_OS;
VOID                *mLoadOptions       = NULL;
BBS_BBS_DEVICE_PATH *mBbsDevicePathPtr  = NULL;
BBS_BBS_DEVICE_PATH mBbsDevicePathNode;
UDC_ATTRIBUTES      mAttributes         = { 0, 0, 0, 0 };
UINTN               mBbsEntry           = 0;
VOID                *mBeerData          = NULL;
VOID                *mServiceAreaData   = NULL;
UINT64              mLowWater           = 0xffffffffffffffffULL;

extern BBS_TABLE           *mBbsTable;

extern VOID                  *mRuntimeSmbiosEntryPoint;
extern EFI_PHYSICAL_ADDRESS  mReserveSmbiosEntryPoint;
extern EFI_PHYSICAL_ADDRESS  mStructureTableAddress;

/**
  Print the BBS Table.

  @param BbsTable   The BBS table.


**/
VOID
PrintBbsTable (
  IN BBS_TABLE *BbsTable
  )
{
  UINT16 Index;
  UINT16 SubIndex;
  CHAR8  *String;

  DEBUG ((EFI_D_INFO, "\n"));
  DEBUG ((EFI_D_INFO, " NO  Prio bb/dd/ff cl/sc Type Stat segm:offs mfgs:mfgo dess:deso\n"));
  DEBUG ((EFI_D_INFO, "=================================================================\n"));
  for (Index = 0; Index < MAX_BBS_ENTRIES; Index++) {
    //
    // Filter
    //
    if (BbsTable[Index].BootPriority == BBS_IGNORE_ENTRY) {
      continue;
    }

    DEBUG ((
      EFI_D_INFO,
      " %02x: %04x %02x/%02x/%02x %02x/%02x %04x %04x",
      (UINTN) Index,
      (UINTN) BbsTable[Index].BootPriority,
      (UINTN) BbsTable[Index].Bus,
      (UINTN) BbsTable[Index].Device,
      (UINTN) BbsTable[Index].Function,
      (UINTN) BbsTable[Index].Class,
      (UINTN) BbsTable[Index].SubClass,
      (UINTN) BbsTable[Index].DeviceType,
      (UINTN) * (UINT16 *) &BbsTable[Index].StatusFlags
      ));
    DEBUG ((
      EFI_D_INFO,
      " %04x:%04x %04x:%04x %04x:%04x",
      (UINTN) BbsTable[Index].BootHandlerSegment,
      (UINTN) BbsTable[Index].BootHandlerOffset,
      (UINTN) BbsTable[Index].MfgStringSegment,
      (UINTN) BbsTable[Index].MfgStringOffset,
      (UINTN) BbsTable[Index].DescStringSegment,
      (UINTN) BbsTable[Index].DescStringOffset
      ));

    //
    // Print DescString
    //
    String = (CHAR8 *)(UINTN)((BbsTable[Index].DescStringSegment << 4) + BbsTable[Index].DescStringOffset);
    if (String != NULL) {
      DEBUG ((EFI_D_INFO," ("));
      for (SubIndex = 0; String[SubIndex] != 0; SubIndex++) {
        DEBUG ((EFI_D_INFO, "%c", String[SubIndex]));
      }
      DEBUG ((EFI_D_INFO,")"));
    }
    DEBUG ((EFI_D_INFO,"\n"));
  }

  DEBUG ((EFI_D_INFO, "\n"));

  return ;
}

/**
  Print the BBS Table.

  @param HddInfo   The HddInfo table.


**/
VOID
PrintHddInfo (
  IN HDD_INFO *HddInfo
  )
{
  UINTN Index;

  DEBUG ((EFI_D_INFO, "\n"));
  for (Index = 0; Index < MAX_IDE_CONTROLLER; Index++) {
    DEBUG ((EFI_D_INFO, "Index - %04x\n", Index));
    DEBUG ((EFI_D_INFO, "  Status    - %04x\n", (UINTN)HddInfo[Index].Status));
    DEBUG ((EFI_D_INFO, "  B/D/F     - %02x/%02x/%02x\n", (UINTN)HddInfo[Index].Bus, (UINTN)HddInfo[Index].Device, (UINTN)HddInfo[Index].Function));
    DEBUG ((EFI_D_INFO, "  Command   - %04x\n", HddInfo[Index].CommandBaseAddress));
    DEBUG ((EFI_D_INFO, "  Control   - %04x\n", HddInfo[Index].ControlBaseAddress));
    DEBUG ((EFI_D_INFO, "  BusMaster - %04x\n", HddInfo[Index].BusMasterAddress));
    DEBUG ((EFI_D_INFO, "  HddIrq    - %02x\n", HddInfo[Index].HddIrq));
    DEBUG ((EFI_D_INFO, "  IdentifyDrive[0].Raw[0] - %x\n", HddInfo[Index].IdentifyDrive[0].Raw[0]));
    DEBUG ((EFI_D_INFO, "  IdentifyDrive[1].Raw[0] - %x\n", HddInfo[Index].IdentifyDrive[1].Raw[0]));
  }

  DEBUG ((EFI_D_INFO, "\n"));

  return ;
}

/**
  Print the PCI Interrupt Line and Interrupt Pin registers.
**/
VOID
PrintPciInterruptRegister (
  VOID
  )
{
  EFI_STATUS                  Status;
  UINTN                       Index;
  EFI_HANDLE                  *Handles;
  UINTN                       HandleNum;
  EFI_PCI_IO_PROTOCOL         *PciIo;
  UINT8                       Interrupt[2];
  UINTN                       Segment;
  UINTN                       Bus;
  UINTN                       Device;
  UINTN                       Function;

  gBS->LocateHandleBuffer (
         ByProtocol,
         &gEfiPciIoProtocolGuid,
         NULL,
         &HandleNum,
         &Handles
         );

  Bus      = 0;
  Device   = 0;
  Function = 0;

  DEBUG ((EFI_D_INFO, "\n"));
  DEBUG ((EFI_D_INFO, " bb/dd/ff interrupt line interrupt pin\n"));
  DEBUG ((EFI_D_INFO, "======================================\n"));
  for (Index = 0; Index < HandleNum; Index++) {
    Status = gBS->HandleProtocol (Handles[Index], &gEfiPciIoProtocolGuid, (VOID **) &PciIo);
    if (!EFI_ERROR (Status)) {
      Status = PciIo->Pci.Read (
                            PciIo,
                            EfiPciIoWidthUint8,
                            PCI_INT_LINE_OFFSET,
                            2,
                            Interrupt
                            );
    }
    if (!EFI_ERROR (Status)) {
      Status = PciIo->GetLocation (
                        PciIo,
                        &Segment,
                        &Bus,
                        &Device,
                        &Function
                        );
    }
    if (!EFI_ERROR (Status)) {
      DEBUG ((EFI_D_INFO, " %02x/%02x/%02x 0x%02x           0x%02x\n",
              Bus, Device, Function, Interrupt[0], Interrupt[1]));
    }
  }
  DEBUG ((EFI_D_INFO, "\n"));

  if (Handles != NULL) {
    FreePool (Handles);
  }
}

/**
  Identify drive data must be updated to actual parameters before boot.

  @param  IdentifyDriveData       ATA Identify Data

**/
VOID
UpdateIdentifyDriveData (
  IN  UINT8     *IdentifyDriveData
  );

/**
  Update SIO data.

  @param  Private                 Legacy BIOS Instance data

  @retval EFI_SUCCESS             Removable media not present

**/
EFI_STATUS
UpdateSioData (
  IN  LEGACY_BIOS_INSTANCE      *Private
  )
{
  EFI_STATUS                          Status;
  UINTN                               Index;
  UINTN                               Index1;
  UINT8                               LegacyInterrupts[16];
  EFI_LEGACY_IRQ_ROUTING_ENTRY        *RoutingTable;
  UINTN                               RoutingTableEntries;
  EFI_LEGACY_IRQ_PRIORITY_TABLE_ENTRY *IrqPriorityTable;
  UINTN                               NumberPriorityEntries;
  EFI_TO_COMPATIBILITY16_BOOT_TABLE   *EfiToLegacy16BootTable;
  UINT8                               HddIrq;
  UINT16                              LegacyInt;
  UINT16                              LegMask;
  UINT32                              Register;
  UINTN                               HandleCount;
  EFI_HANDLE                          *HandleBuffer;
  EFI_ISA_IO_PROTOCOL                 *IsaIo;

  LegacyInt               = 0;
  HandleBuffer            = NULL;

  EfiToLegacy16BootTable  = &Private->IntThunk->EfiToLegacy16BootTable;
  LegacyBiosBuildSioData (Private);
  SetMem (LegacyInterrupts, sizeof (LegacyInterrupts), 0);

  //
  // Create list of legacy interrupts.
  //
  for (Index = 0; Index < 4; Index++) {
    LegacyInterrupts[Index] = EfiToLegacy16BootTable->SioData.Serial[Index].Irq;
  }

  for (Index = 4; Index < 7; Index++) {
    LegacyInterrupts[Index] = EfiToLegacy16BootTable->SioData.Parallel[Index - 4].Irq;
  }

  LegacyInterrupts[7] = EfiToLegacy16BootTable->SioData.Floppy.Irq;

  //
  // Get Legacy Hdd IRQs. If native mode treat as PCI
  //
  for (Index = 0; Index < 2; Index++) {
    HddIrq = EfiToLegacy16BootTable->HddInfo[Index].HddIrq;
    if ((HddIrq != 0) && ((HddIrq == 15) || (HddIrq == 14))) {
      LegacyInterrupts[Index + 8] = HddIrq;
    }
  }

  Private->LegacyBiosPlatform->GetRoutingTable (
                                Private->LegacyBiosPlatform,
                                (VOID *) &RoutingTable,
                                &RoutingTableEntries,
                                NULL,
                                NULL,
                                (VOID **) &IrqPriorityTable,
                                &NumberPriorityEntries
                                );
  //
  // Remove legacy interrupts from the list of PCI interrupts available.
  //
  for (Index = 0; Index <= 0x0b; Index++) {
    for (Index1 = 0; Index1 <= NumberPriorityEntries; Index1++) {
      if (LegacyInterrupts[Index] != 0) {
        LegacyInt = (UINT16) (LegacyInt | (1 << LegacyInterrupts[Index]));
        if (LegacyInterrupts[Index] == IrqPriorityTable[Index1].Irq) {
          IrqPriorityTable[Index1].Used = LEGACY_USED;
        }
      }
    }
  }

  Private->Legacy8259->GetMask (
                        Private->Legacy8259,
                        &LegMask,
                        NULL,
                        NULL,
                        NULL
                        );

  //
  // Set SIO interrupts and disable mouse. Let mouse driver
  // re-enable it.
  //
  LegMask = (UINT16) ((LegMask &~LegacyInt) | 0x1000);
  Private->Legacy8259->SetMask (
                        Private->Legacy8259,
                        &LegMask,
                        NULL,
                        NULL,
                        NULL
                        );

  //
  // Disable mouse in keyboard controller
  //
  Register = 0xA7;
  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiIsaIoProtocolGuid,
                  NULL,
                  &HandleCount,
                  &HandleBuffer
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  for (Index = 0; Index < HandleCount; Index++) {
    Status = gBS->HandleProtocol (
                    HandleBuffer[Index],
                    &gEfiIsaIoProtocolGuid,
                    (VOID **) &IsaIo
                    );
    ASSERT_EFI_ERROR (Status);
    IsaIo->Io.Write (IsaIo, EfiIsaIoWidthUint8, 0x64, 1, &Register);

  }

  if (HandleBuffer != NULL) {
    FreePool (HandleBuffer);
  }

  return EFI_SUCCESS;

}

/**
  Identify drive data must be updated to actual parameters before boot.
  This requires updating the checksum, if it exists.

  @param  IdentifyDriveData       ATA Identify Data
  @param  Checksum                checksum of the ATA Identify Data

  @retval EFI_SUCCESS             checksum calculated
  @retval EFI_SECURITY_VIOLATION  IdentifyData invalid

**/
EFI_STATUS
CalculateIdentifyDriveChecksum (
  IN  UINT8     *IdentifyDriveData,
  OUT UINT8     *Checksum
  )
{
  UINTN Index;
  UINT8 LocalChecksum;
  LocalChecksum = 0;
  *Checksum     = 0;
  if (IdentifyDriveData[510] != 0xA5) {
    return EFI_SECURITY_VIOLATION;
  }

  for (Index = 0; Index < 512; Index++) {
    LocalChecksum = (UINT8) (LocalChecksum + IdentifyDriveData[Index]);
  }

  *Checksum = LocalChecksum;
  return EFI_SUCCESS;
}


/**
  Identify drive data must be updated to actual parameters before boot.

  @param  IdentifyDriveData       ATA Identify Data


**/
VOID
UpdateIdentifyDriveData (
  IN  UINT8     *IdentifyDriveData
  )
{
  UINT16          NumberCylinders;
  UINT16          NumberHeads;
  UINT16          NumberSectorsTrack;
  UINT32          CapacityInSectors;
  UINT8           OriginalChecksum;
  UINT8           FinalChecksum;
  EFI_STATUS      Status;
  ATAPI_IDENTIFY  *ReadInfo;

  //
  // Status indicates if Integrity byte is correct. Checksum should be
  // 0 if valid.
  //
  ReadInfo  = (ATAPI_IDENTIFY *) IdentifyDriveData;
  Status    = CalculateIdentifyDriveChecksum (IdentifyDriveData, &OriginalChecksum);
  if (OriginalChecksum != 0) {
    Status = EFI_SECURITY_VIOLATION;
  }
  //
  // If NumberCylinders = 0 then do data(Controller present but don drive attached).
  //
  NumberCylinders = ReadInfo->Raw[1];
  if (NumberCylinders != 0) {
    ReadInfo->Raw[54]   = NumberCylinders;

    NumberHeads         = ReadInfo->Raw[3];
    ReadInfo->Raw[55]   = NumberHeads;

    NumberSectorsTrack  = ReadInfo->Raw[6];
    ReadInfo->Raw[56]   = NumberSectorsTrack;

    //
    // Copy Multisector info and set valid bit.
    //
    ReadInfo->Raw[59] = (UINT16) (ReadInfo->Raw[47] + 0x100);
    CapacityInSectors = (UINT32) ((UINT32) (NumberCylinders) * (UINT32) (NumberHeads) * (UINT32) (NumberSectorsTrack));
    ReadInfo->Raw[57] = (UINT16) (CapacityInSectors >> 16);
    ReadInfo->Raw[58] = (UINT16) (CapacityInSectors & 0xffff);
    if (Status == EFI_SUCCESS) {
      //
      // Forece checksum byte to 0 and get new checksum.
      //
      ReadInfo->Raw[255] &= 0xff;
      CalculateIdentifyDriveChecksum (IdentifyDriveData, &FinalChecksum);

      //
      // Force new checksum such that sum is 0.
      //
      FinalChecksum = (UINT8) ((UINT8)0 - FinalChecksum);
      ReadInfo->Raw[255] = (UINT16) (ReadInfo->Raw[255] | (FinalChecksum << 8));
    }
  }
}

/**
  Identify drive data must be updated to actual parameters before boot.
  Do for all drives.

  @param  Private                 Legacy BIOS Instance data


**/
VOID
UpdateAllIdentifyDriveData (
  IN LEGACY_BIOS_INSTANCE                 *Private
  )
{
  UINTN     Index;
  HDD_INFO  *HddInfo;

  HddInfo = &Private->IntThunk->EfiToLegacy16BootTable.HddInfo[0];

  for (Index = 0; Index < MAX_IDE_CONTROLLER; Index++) {
    //
    // Each controller can have 2 devices. Update for each device
    //
    if ((HddInfo[Index].Status & HDD_MASTER_IDE) != 0) {
      UpdateIdentifyDriveData ((UINT8 *) (&HddInfo[Index].IdentifyDrive[0].Raw[0]));
    }

    if ((HddInfo[Index].Status & HDD_SLAVE_IDE) != 0) {
      UpdateIdentifyDriveData ((UINT8 *) (&HddInfo[Index].IdentifyDrive[1].Raw[0]));
    }
  }
}

/**
  Enable ide controller.  This gets disabled when LegacyBoot.c is about
  to run the Option ROMs.

  @param  Private        Legacy BIOS Instance data


**/
VOID
EnableIdeController (
  IN LEGACY_BIOS_INSTANCE              *Private
  )
{
  EFI_PCI_IO_PROTOCOL *PciIo;
  EFI_STATUS          Status;
  EFI_HANDLE          IdeController;
  UINT8               ByteBuffer;
  UINTN               HandleCount;
  EFI_HANDLE          *HandleBuffer;

  Status = Private->LegacyBiosPlatform->GetPlatformHandle (
                                          Private->LegacyBiosPlatform,
                                          EfiGetPlatformIdeHandle,
                                          0,
                                          &HandleBuffer,
                                          &HandleCount,
                                          NULL
                                          );
  if (!EFI_ERROR (Status)) {
    IdeController = HandleBuffer[0];
    Status = gBS->HandleProtocol (
                    IdeController,
                    &gEfiPciIoProtocolGuid,
                    (VOID **) &PciIo
                    );
    ByteBuffer = 0x1f;
    if (!EFI_ERROR (Status)) {
      PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 0x04, 1, &ByteBuffer);
    }
  }
}


/**
  Enable ide controller.  This gets disabled when LegacyBoot.c is about
  to run the Option ROMs.

  @param  Private                 Legacy BIOS Instance data


**/
VOID
EnableAllControllers (
  IN LEGACY_BIOS_INSTANCE              *Private
  )
{
  UINTN               HandleCount;
  EFI_HANDLE          *HandleBuffer;
  UINTN               Index;
  EFI_PCI_IO_PROTOCOL *PciIo;
  PCI_TYPE01          PciConfigHeader;
  EFI_STATUS          Status;

  //
  //
  //
  EnableIdeController (Private);

  //
  // Assumption is table is built from low bus to high bus numbers.
  //
  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiPciIoProtocolGuid,
                  NULL,
                  &HandleCount,
                  &HandleBuffer
                  );
  ASSERT_EFI_ERROR (Status);

  for (Index = 0; Index < HandleCount; Index++) {
    Status = gBS->HandleProtocol (
                    HandleBuffer[Index],
                    &gEfiPciIoProtocolGuid,
                    (VOID **) &PciIo
                    );
    ASSERT_EFI_ERROR (Status);

    PciIo->Pci.Read (
                PciIo,
                EfiPciIoWidthUint32,
                0,
                sizeof (PciConfigHeader) / sizeof (UINT32),
                &PciConfigHeader
                );

    //
    // We do not enable PPB here. This is for HotPlug Consideration.
    // The Platform HotPlug Driver is responsible for Padding enough hot plug
    // resources. It is also responsible for enable this bridge. If it
    // does not pad it. It will cause some early Windows fail to installation.
    // If the platform driver does not pad resource for PPB, PPB should be in
    // un-enabled state to let Windows know that this PPB is not configured by
    // BIOS. So Windows will allocate default resource for PPB.
    //
    // The reason for why we enable the command register is:
    // The CSM will use the IO bar to detect some IRQ status, if the command
    // is disabled, the IO resource will be out of scope.
    // For example:
    // We installed a legacy IRQ handle for a PCI IDE controller. When IRQ
    // comes up, the handle will check the IO space to identify is the
    // controller generated the IRQ source.
    // If the IO command is not enabled, the IRQ handler will has wrong
    // information. It will cause IRQ storm when the correctly IRQ handler fails
    // to run.
    //
    if (!(IS_PCI_VGA (&PciConfigHeader)     ||
          IS_PCI_OLD_VGA (&PciConfigHeader) ||
          IS_PCI_IDE (&PciConfigHeader)     ||
          IS_PCI_P2P (&PciConfigHeader)     ||
          IS_PCI_P2P_SUB (&PciConfigHeader) ||
          IS_PCI_LPC (&PciConfigHeader)     )) {

      PciConfigHeader.Hdr.Command |= 0x1f;

      PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, 4, 1, &PciConfigHeader.Hdr.Command);
    }
  }
}

/**
  The following routines are identical in operation, so combine
  for code compaction:
  EfiGetPlatformBinaryGetMpTable
  EfiGetPlatformBinaryGetOemIntData
  EfiGetPlatformBinaryGetOem32Data
  EfiGetPlatformBinaryGetOem16Data

  @param  This                    Protocol instance pointer.
  @param  Id                      Table/Data identifier

  @retval EFI_SUCCESS             Success
  @retval EFI_INVALID_PARAMETER   Invalid ID
  @retval EFI_OUT_OF_RESOURCES    no resource to get data or table

**/
EFI_STATUS
LegacyGetDataOrTable (
  IN EFI_LEGACY_BIOS_PROTOCOL         *This,
  IN EFI_GET_PLATFORM_INFO_MODE       Id
  )
{
  VOID                              *Table;
  UINT32                            TablePtr;
  UINTN                             TableSize;
  UINTN                             Alignment;
  UINTN                             Location;
  EFI_STATUS                        Status;
  EFI_LEGACY_BIOS_PLATFORM_PROTOCOL *LegacyBiosPlatform;
  EFI_COMPATIBILITY16_TABLE         *Legacy16Table;
  EFI_IA32_REGISTER_SET             Regs;
  LEGACY_BIOS_INSTANCE              *Private;

  Private             = LEGACY_BIOS_INSTANCE_FROM_THIS (This);

  LegacyBiosPlatform  = Private->LegacyBiosPlatform;
  Legacy16Table       = Private->Legacy16Table;

  //
  // Phase 1 - get an address allocated in 16-bit code
  //
  while (TRUE) {
    switch (Id) {
    case EfiGetPlatformBinaryMpTable:
    case EfiGetPlatformBinaryOemIntData:
    case EfiGetPlatformBinaryOem32Data:
    case EfiGetPlatformBinaryOem16Data:
      {
        Status = LegacyBiosPlatform->GetPlatformInfo (
                                      LegacyBiosPlatform,
                                      Id,
                                      (VOID *) &Table,
                                      &TableSize,
                                      &Location,
                                      &Alignment,
                                      0,
                                      0
                                      );
        DEBUG ((EFI_D_INFO, "LegacyGetDataOrTable - ID: %x, %r\n", (UINTN)Id, Status));
        DEBUG ((EFI_D_INFO, "  Table - %x, Size - %x, Location - %x, Alignment - %x\n", (UINTN)Table, (UINTN)TableSize, (UINTN)Location, (UINTN)Alignment));
        break;
      }

    default:
      {
        return EFI_INVALID_PARAMETER;
      }
    }

    if (EFI_ERROR (Status)) {
      return Status;
    }

    ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET));
    Regs.X.AX = Legacy16GetTableAddress;
    Regs.X.CX = (UINT16) TableSize;
    Regs.X.BX = (UINT16) Location;
    Regs.X.DX = (UINT16) Alignment;
    Private->LegacyBios.FarCall86 (
      This,
      Private->Legacy16CallSegment,
      Private->Legacy16CallOffset,
      &Regs,
      NULL,
      0
      );

    if (Regs.X.AX != 0) {
      DEBUG ((EFI_D_ERROR, "Table ID %x length insufficient\n", Id));
      return EFI_OUT_OF_RESOURCES;
    } else {
      break;
    }
  }
  //
  // Phase 2 Call routine second time with address to allow address adjustment
  //
  Status = LegacyBiosPlatform->GetPlatformInfo (
                                LegacyBiosPlatform,
                                Id,
                                (VOID *) &Table,
                                &TableSize,
                                &Location,
                                &Alignment,
                                Regs.X.DS,
                                Regs.X.BX
                                );
  switch (Id) {
  case EfiGetPlatformBinaryMpTable:
    {
      Legacy16Table->MpTablePtr     = (UINT32) (Regs.X.DS * 16 + Regs.X.BX);
      Legacy16Table->MpTableLength  = (UINT32)TableSize;
      DEBUG ((EFI_D_INFO, "MP table in legacy region - %x\n", (UINTN)Legacy16Table->MpTablePtr));
      break;
    }

  case EfiGetPlatformBinaryOemIntData:
    {

      Legacy16Table->OemIntSegment  = Regs.X.DS;
      Legacy16Table->OemIntOffset   = Regs.X.BX;
      DEBUG ((EFI_D_INFO, "OemInt table in legacy region - %04x:%04x\n", (UINTN)Legacy16Table->OemIntSegment, (UINTN)Legacy16Table->OemIntOffset));
      break;
    }

  case EfiGetPlatformBinaryOem32Data:
    {
      Legacy16Table->Oem32Segment = Regs.X.DS;
      Legacy16Table->Oem32Offset  = Regs.X.BX;
      DEBUG ((EFI_D_INFO, "Oem32 table in legacy region - %04x:%04x\n", (UINTN)Legacy16Table->Oem32Segment, (UINTN)Legacy16Table->Oem32Offset));
      break;
    }

  case EfiGetPlatformBinaryOem16Data:
    {
      //
      //          Legacy16Table->Oem16Segment = Regs.X.DS;
      //          Legacy16Table->Oem16Offset  = Regs.X.BX;
      DEBUG ((EFI_D_INFO, "Oem16 table in legacy region - %04x:%04x\n", (UINTN)Legacy16Table->Oem16Segment, (UINTN)Legacy16Table->Oem16Offset));
      break;
    }

  default:
    {
      return EFI_INVALID_PARAMETER;
    }
  }

  if (EFI_ERROR (Status)) {
    return Status;
  }
  //
  // Phase 3 Copy table to final location
  //
  TablePtr = (UINT32) (Regs.X.DS * 16 + Regs.X.BX);

  CopyMem (
    (VOID *) (UINTN)TablePtr,
    Table,
    TableSize
    );

  return EFI_SUCCESS;
}

/**
  Copy SMBIOS table to EfiReservedMemoryType of memory for legacy boot.

**/
VOID
CreateSmbiosTableInReservedMemory (
  VOID
  )
{
  SMBIOS_TABLE_ENTRY_POINT    *EntryPointStructure;
  
  if ((mRuntimeSmbiosEntryPoint == NULL) || 
      (mReserveSmbiosEntryPoint == 0) || 
      (mStructureTableAddress == 0)) {
    return;
  }
  
  EntryPointStructure = (SMBIOS_TABLE_ENTRY_POINT *) mRuntimeSmbiosEntryPoint;
  
  //
  // Copy SMBIOS Entry Point Structure
  //
  CopyMem (
    (VOID *)(UINTN) mReserveSmbiosEntryPoint,
    EntryPointStructure,
    EntryPointStructure->EntryPointLength
  );
  
  //
  // Copy SMBIOS Structure Table into EfiReservedMemoryType memory
  //
  CopyMem (
    (VOID *)(UINTN) mStructureTableAddress,
    (VOID *)(UINTN) EntryPointStructure->TableAddress,
    EntryPointStructure->TableLength
  );
  
  //
  // Update TableAddress in Entry Point Structure
  //
  EntryPointStructure = (SMBIOS_TABLE_ENTRY_POINT *)(UINTN) mReserveSmbiosEntryPoint;
  EntryPointStructure->TableAddress = (UINT32)(UINTN) mStructureTableAddress;
  
  //
  // Fixup checksums in the Entry Point Structure
  //
  EntryPointStructure->IntermediateChecksum = 0;
  EntryPointStructure->EntryPointStructureChecksum = 0;

  EntryPointStructure->IntermediateChecksum = 
    CalculateCheckSum8 (
      (UINT8 *) EntryPointStructure + OFFSET_OF (SMBIOS_TABLE_ENTRY_POINT, IntermediateAnchorString), 
      EntryPointStructure->EntryPointLength - OFFSET_OF (SMBIOS_TABLE_ENTRY_POINT, IntermediateAnchorString)
      );
  EntryPointStructure->EntryPointStructureChecksum =
    CalculateCheckSum8 ((UINT8 *) EntryPointStructure, EntryPointStructure->EntryPointLength);
}

/**
  Assign drive number to legacy HDD drives prior to booting an EFI
  aware OS so the OS can access drives without an EFI driver.
  Note: BBS compliant drives ARE NOT available until this call by
  either shell or EFI.

  @param  This                    Protocol instance pointer.

  @retval EFI_SUCCESS             Drive numbers assigned

**/
EFI_STATUS
GenericLegacyBoot (
  IN EFI_LEGACY_BIOS_PROTOCOL           *This
  )
{
  EFI_STATUS                        Status;
  LEGACY_BIOS_INSTANCE              *Private;
  EFI_IA32_REGISTER_SET             Regs;
  EFI_TO_COMPATIBILITY16_BOOT_TABLE *EfiToLegacy16BootTable;
  EFI_LEGACY_BIOS_PLATFORM_PROTOCOL *LegacyBiosPlatform;
  UINTN                             CopySize;
  VOID                              *AcpiPtr;
  HDD_INFO                          *HddInfo;
  HDD_INFO                          *LocalHddInfo;
  UINTN                             Index;
  EFI_COMPATIBILITY16_TABLE         *Legacy16Table;
  UINT32                            *BdaPtr;
  UINT16                            HddCount;
  UINT16                            BbsCount;
  BBS_TABLE                         *LocalBbsTable;
  UINT32                            *BaseVectorMaster;
  EFI_TIME                          BootTime;
  UINT32                            LocalTime;
  EFI_HANDLE                        IdeController;
  UINTN                             HandleCount;
  EFI_HANDLE                        *HandleBuffer;
  VOID                              *AcpiTable;
  UINTN                             ShadowAddress;
  UINT32                            Granularity;

  LocalHddInfo  = NULL;
  HddCount      = 0;
  BbsCount      = 0;
  LocalBbsTable = NULL;

  Private       = LEGACY_BIOS_INSTANCE_FROM_THIS (This);
  DEBUG_CODE (
    DEBUG ((EFI_D_ERROR, "Start of legacy boot\n"));
  );

  Legacy16Table                         = Private->Legacy16Table;
  EfiToLegacy16BootTable                = &Private->IntThunk->EfiToLegacy16BootTable;
  HddInfo = &EfiToLegacy16BootTable->HddInfo[0];

  LegacyBiosPlatform = Private->LegacyBiosPlatform;

  EfiToLegacy16BootTable->MajorVersion = EFI_TO_LEGACY_MAJOR_VERSION;
  EfiToLegacy16BootTable->MinorVersion = EFI_TO_LEGACY_MINOR_VERSION;
  
  //
  // If booting to a legacy OS then force HDD drives to the appropriate
  // boot mode by calling GetIdeHandle.
  // A reconnect -r can force all HDDs back to native mode.
  //
  IdeController = NULL;
  if ((mBootMode == BOOT_LEGACY_OS) || (mBootMode == BOOT_UNCONVENTIONAL_DEVICE)) {
    Status = LegacyBiosPlatform->GetPlatformHandle (
                                  Private->LegacyBiosPlatform,
                                  EfiGetPlatformIdeHandle,
                                  0,
                                  &HandleBuffer,
                                  &HandleCount,
                                  NULL
                                  );
    if (!EFI_ERROR (Status)) {
      IdeController = HandleBuffer[0];
    }   
  }
  //
  // Unlock the Legacy BIOS region
  //
  Private->LegacyRegion->UnLock (
                           Private->LegacyRegion,
                           0xE0000,
                           0x20000,
                           &Granularity
                           );

  //
  // Reconstruct the Legacy16 boot memory map
  //
  LegacyBiosBuildE820 (Private, &CopySize);
  if (CopySize > Private->Legacy16Table->E820Length) {
    ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET));
    Regs.X.AX = Legacy16GetTableAddress;
    Regs.X.CX = (UINT16) CopySize;
    Private->LegacyBios.FarCall86 (
      &Private->LegacyBios,
      Private->Legacy16Table->Compatibility16CallSegment,
      Private->Legacy16Table->Compatibility16CallOffset,
      &Regs,
      NULL,
      0
      );

    Private->Legacy16Table->E820Pointer = (UINT32) (Regs.X.DS * 16 + Regs.X.BX);
    Private->Legacy16Table->E820Length  = (UINT32) CopySize;
    if (Regs.X.AX != 0) {
      DEBUG ((EFI_D_ERROR, "Legacy16 E820 length insufficient\n"));
    } else {
      CopyMem (
        (VOID *)(UINTN) Private->Legacy16Table->E820Pointer,
        Private->E820Table,
        CopySize
        );
    }
  } else {
    CopyMem (
      (VOID *)(UINTN) Private->Legacy16Table->E820Pointer,
      Private->E820Table,
      CopySize
      );
    Private->Legacy16Table->E820Length = (UINT32) CopySize;
  }

  //
  // We do not ASSERT if SmbiosTable not found. It is possbile that a platform does not produce SmbiosTable.
  //
  if (mReserveSmbiosEntryPoint == 0) {
    DEBUG ((EFI_D_INFO, "Smbios table is not found!\n"));
  }
  CreateSmbiosTableInReservedMemory ();
  EfiToLegacy16BootTable->SmbiosTable = (UINT32)(UINTN)mReserveSmbiosEntryPoint;

  AcpiTable = NULL;
  Status = EfiGetSystemConfigurationTable (
             &gEfiAcpi20TableGuid,
             &AcpiTable
             );
  if (EFI_ERROR (Status)) {
    Status = EfiGetSystemConfigurationTable (
               &gEfiAcpi10TableGuid,
               &AcpiTable
               );
  }
  //
  // We do not ASSERT if AcpiTable not found. It is possbile that a platform does not produce AcpiTable.
  //
  if (AcpiTable == NULL) {
    DEBUG ((EFI_D_INFO, "ACPI table is not found!\n"));
  }
  EfiToLegacy16BootTable->AcpiTable = (UINT32)(UINTN)AcpiTable;

  //
  // Get RSD Ptr table rev at offset 15 decimal
  // Rev = 0 Length is 20 decimal
  // Rev != 0 Length is UINT32 at offset 20 decimal
  //
  if (AcpiTable != NULL) {

    AcpiPtr = AcpiTable;
    if (*((UINT8 *) AcpiPtr + 15) == 0) {
      CopySize = 20;
    } else {
      AcpiPtr   = ((UINT8 *) AcpiPtr + 20);
      CopySize  = (*(UINT32 *) AcpiPtr);
    }

    CopyMem (
      (VOID *)(UINTN) Private->Legacy16Table->AcpiRsdPtrPointer,
      AcpiTable,
      CopySize
      );
  }
  //
  // Make sure all PCI Interrupt Line register are programmed to match 8259
  //
  PciProgramAllInterruptLineRegisters (Private);

  //
  // Unlock the Legacy BIOS region as PciProgramAllInterruptLineRegisters
  // can lock it.
  //
  Private->LegacyRegion->UnLock (
                           Private->LegacyRegion,
                           Private->BiosStart,
                           Private->LegacyBiosImageSize,
                           &Granularity
                           );

  //
  // Configure Legacy Device Magic
  //
  // Only do this code if booting legacy OS
  //
  if ((mBootMode == BOOT_LEGACY_OS) || (mBootMode == BOOT_UNCONVENTIONAL_DEVICE)) {
    UpdateSioData (Private);
  }
  //
  // Setup BDA and EBDA standard areas before Legacy Boot
  //
  LegacyBiosCompleteBdaBeforeBoot (Private);
  LegacyBiosCompleteStandardCmosBeforeBoot (Private);

  //
  // We must build IDE data, if it hasn't been done, before PciShadowRoms
  // to insure EFI drivers are connected.
  //
  LegacyBiosBuildIdeData (Private, &HddInfo, 1);
  UpdateAllIdentifyDriveData (Private);

  //
  // Clear IO BAR, if IDE controller in legacy mode.
  //
  InitLegacyIdeController (IdeController);

  //
  // Generate number of ticks since midnight for BDA. DOS requires this
  // for its time. We have to make assumptions as to how long following
  // code takes since after PciShadowRoms PciIo is gone. Place result in
  // 40:6C-6F
  //
  // Adjust value by 1 second.
  //
  gRT->GetTime (&BootTime, NULL);
  LocalTime = BootTime.Hour * 3600 + BootTime.Minute * 60 + BootTime.Second;
  LocalTime += 1;

  //
  // Multiply result by 18.2 for number of ticks since midnight.
  // Use 182/10 to avoid floating point math.
  //
  LocalTime = (LocalTime * 182) / 10;
  BdaPtr    = (UINT32 *) (UINTN)0x46C;
  *BdaPtr   = LocalTime;

  //
  // Shadow PCI ROMs. We must do this near the end since this will kick
  // of Native EFI drivers that may be needed to collect info for Legacy16
  //
  //  WARNING: PciIo is gone after this call.
  //
  PciShadowRoms (Private);

  //
  // Shadow PXE base code, BIS etc.
  //
  Private->LegacyRegion->UnLock (Private->LegacyRegion, 0xc0000, 0x40000, &Granularity);
  ShadowAddress = Private->OptionRom;
  Private->LegacyBiosPlatform->PlatformHooks (
                                 Private->LegacyBiosPlatform,
                                 EfiPlatformHookShadowServiceRoms,
                                 0,
                                 0,
                                 &ShadowAddress,
                                 Legacy16Table,
                                 NULL
                                 );
  Private->OptionRom = (UINT32)ShadowAddress;
  //
  // Register Legacy SMI Handler
  //
  LegacyBiosPlatform->SmmInit (
                        LegacyBiosPlatform,
                        EfiToLegacy16BootTable
                        );

  //
  // Let platform code know the boot options
  //
  LegacyBiosGetBbsInfo (
    This,
    &HddCount,
    &LocalHddInfo,
    &BbsCount,
    &LocalBbsTable
    );

  DEBUG_CODE (
    PrintPciInterruptRegister ();
    PrintBbsTable (LocalBbsTable);
    PrintHddInfo (LocalHddInfo);
    );
  //
  // If drive wasn't spun up then BuildIdeData may have found new drives.
  // Need to update BBS boot priority.
  //
  for (Index = 0; Index < MAX_IDE_CONTROLLER; Index++) {
    if ((LocalHddInfo[Index].IdentifyDrive[0].Raw[0] != 0) &&
        (LocalBbsTable[2 * Index + 1].BootPriority == BBS_IGNORE_ENTRY)
        ) {
      LocalBbsTable[2 * Index + 1].BootPriority = BBS_UNPRIORITIZED_ENTRY;
    }

    if ((LocalHddInfo[Index].IdentifyDrive[1].Raw[0] != 0) &&
        (LocalBbsTable[2 * Index + 2].BootPriority == BBS_IGNORE_ENTRY)
        ) {
      LocalBbsTable[2 * Index + 2].BootPriority = BBS_UNPRIORITIZED_ENTRY;
    }
  }

  Private->LegacyRegion->UnLock (
                           Private->LegacyRegion,
                           0xc0000,
                           0x40000,
                           &Granularity
                           );

  LegacyBiosPlatform->PrepareToBoot (
                        LegacyBiosPlatform,
                        mBbsDevicePathPtr,
                        mBbsTable,
                        mLoadOptionsSize,
                        mLoadOptions,
                        (VOID *) &Private->IntThunk->EfiToLegacy16BootTable
                        );

  //
  // If no boot device return to BDS
  //
  if ((mBootMode == BOOT_LEGACY_OS) || (mBootMode == BOOT_UNCONVENTIONAL_DEVICE)) {
    for (Index = 0; Index < BbsCount; Index++){
      if ((LocalBbsTable[Index].BootPriority != BBS_DO_NOT_BOOT_FROM) &&
          (LocalBbsTable[Index].BootPriority != BBS_UNPRIORITIZED_ENTRY) &&
          (LocalBbsTable[Index].BootPriority != BBS_IGNORE_ENTRY)) {
        break;
      }
    }
    if (Index == BbsCount) {
      return EFI_DEVICE_ERROR;
    }
  }
  //
  // Let the Legacy16 code know the device path type for legacy boot
  //
  EfiToLegacy16BootTable->DevicePathType = mBbsDevicePathPtr->DeviceType;

  //
  // Copy MP table, if it exists.
  //
  LegacyGetDataOrTable (This, EfiGetPlatformBinaryMpTable);

  if (!Private->LegacyBootEntered) {
    //
    // Copy OEM INT Data, if it exists. Note: This code treats any data
    // as a bag of bits and knows nothing of the contents nor cares.
    // Contents are IBV specific.
    //
    LegacyGetDataOrTable (This, EfiGetPlatformBinaryOemIntData);

    //
    // Copy OEM16 Data, if it exists.Note: This code treats any data
    // as a bag of bits and knows nothing of the contents nor cares.
    // Contents are IBV specific.
    //
    LegacyGetDataOrTable (This, EfiGetPlatformBinaryOem16Data);

    //
    // Copy OEM32 Data, if it exists.Note: This code treats any data
    // as a bag of bits and knows nothing of the contents nor cares.
    // Contents are IBV specific.
    //
    LegacyGetDataOrTable (This, EfiGetPlatformBinaryOem32Data);
  }

  //
  // Call into Legacy16 code to prepare for INT 19h
  //
  ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET));
  Regs.X.AX = Legacy16PrepareToBoot;

  //
  // Pass in handoff data
  //
  Regs.X.ES = NORMALIZE_EFI_SEGMENT ((UINTN)EfiToLegacy16BootTable);
  Regs.X.BX = NORMALIZE_EFI_OFFSET ((UINTN)EfiToLegacy16BootTable);

  Private->LegacyBios.FarCall86 (
    This,
    Private->Legacy16CallSegment,
    Private->Legacy16CallOffset,
    &Regs,
    NULL,
    0
    );

  if (Regs.X.AX != 0) {
    return EFI_DEVICE_ERROR;
  }
  //
  // Lock the Legacy BIOS region
  //
  Private->LegacyRegion->Lock (
                           Private->LegacyRegion,
                           0xc0000,
                           0x40000,
                           &Granularity
                           );
  //
  // Lock attributes of the Legacy Region if chipset supports
  //
  Private->LegacyRegion->BootLock (
                           Private->LegacyRegion,
                           0xc0000,
                           0x40000,
                           &Granularity
                           );

  //
  // Call into Legacy16 code to do the INT 19h
  //
  EnableAllControllers (Private);
  if ((mBootMode == BOOT_LEGACY_OS) || (mBootMode == BOOT_UNCONVENTIONAL_DEVICE)) {
    //
    // Report Status Code to indicate legacy boot event will be signalled
    //
    REPORT_STATUS_CODE (
      EFI_PROGRESS_CODE,
      (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_LEGACY_BOOT_EVENT)
      );

    //
    // Signal all the events that are waiting on EVT_SIGNAL_LEGACY_BOOT
    //
    EfiSignalEventLegacyBoot ();
    DEBUG ((EFI_D_INFO, "Legacy INT19 Boot...\n"));

    //
    // Disable DXE Timer while executing in real mode
    //
    Private->Timer->SetTimerPeriod (Private->Timer, 0);
    
    //
    // Save and disable interrupt of debug timer
    //
    SaveAndSetDebugTimerInterrupt (FALSE);


    //
    // Put the 8259 into its legacy mode by reprogramming the vector bases
    //
    Private->Legacy8259->SetVectorBase (Private->Legacy8259, LEGACY_MODE_BASE_VECTOR_MASTER, LEGACY_MODE_BASE_VECTOR_SLAVE);
    //
    // PC History
    //   The original PC used INT8-F for master PIC. Since these mapped over
    //   processor exceptions TIANO moved the master PIC to INT68-6F.
    // We need to set these back to the Legacy16 unexpected interrupt(saved
    // in LegacyBios.c) since some OS see that these have values different from
    // what is expected and invoke them. Since the legacy OS corrupts EFI
    // memory, there is no handler for these interrupts and OS blows up.
    //
    // We need to save the TIANO values for the rare case that the Legacy16
    // code cannot boot but knows memory hasn't been destroyed.
    //
    // To compound the problem, video takes over one of these INTS and must be
    // be left.
    // @bug - determine if video hooks INT(in which case we must find new
    //          set of TIANO vectors) or takes it over.
    //
    //
    BaseVectorMaster = (UINT32 *) (sizeof (UINT32) * PROTECTED_MODE_BASE_VECTOR_MASTER);
    for (Index = 0; Index < 8; Index++) {
      Private->ThunkSavedInt[Index] = BaseVectorMaster[Index];
      if (Private->ThunkSeg == (UINT16) (BaseVectorMaster[Index] >> 16)) {
        BaseVectorMaster[Index] = (UINT32) (Private->BiosUnexpectedInt);
      }
    }

    ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET));
    Regs.X.AX = Legacy16Boot;

    Private->LegacyBios.FarCall86 (
      This,
      Private->Legacy16CallSegment,
      Private->Legacy16CallOffset,
      &Regs,
      NULL,
      0
      );

    BaseVectorMaster = (UINT32 *) (sizeof (UINT32) * PROTECTED_MODE_BASE_VECTOR_MASTER);
    for (Index = 0; Index < 8; Index++) {
      BaseVectorMaster[Index] = Private->ThunkSavedInt[Index];
    }
  }
  Private->LegacyBootEntered = TRUE;
  if ((mBootMode == BOOT_LEGACY_OS) || (mBootMode == BOOT_UNCONVENTIONAL_DEVICE)) {
    //
    // Should never return unless never passed control to 0:7c00(first stage
    // OS loader) and only then if no bootable device found.
    //
    return EFI_DEVICE_ERROR;
  } else {
    //
    // If boot to EFI then expect to return to caller
    //
    return EFI_SUCCESS;
  }
}


/**
  Assign drive number to legacy HDD drives prior to booting an EFI
  aware OS so the OS can access drives without an EFI driver.
  Note: BBS compliant drives ARE NOT available until this call by
  either shell or EFI.

  @param  This                    Protocol instance pointer.
  @param  BbsCount                Number of BBS_TABLE structures
  @param  BbsTable                List BBS entries

  @retval EFI_SUCCESS             Drive numbers assigned

**/
EFI_STATUS
EFIAPI
LegacyBiosPrepareToBootEfi (
  IN EFI_LEGACY_BIOS_PROTOCOL         *This,
  OUT UINT16                          *BbsCount,
  OUT BBS_TABLE                       **BbsTable
  )
{
  EFI_STATUS                        Status;
  EFI_TO_COMPATIBILITY16_BOOT_TABLE *EfiToLegacy16BootTable;
  LEGACY_BIOS_INSTANCE              *Private;

  Private                 = LEGACY_BIOS_INSTANCE_FROM_THIS (This);
  EfiToLegacy16BootTable  = &Private->IntThunk->EfiToLegacy16BootTable;
  mBootMode               = BOOT_EFI_OS;
  mBbsDevicePathPtr       = NULL;
  Status                  = GenericLegacyBoot (This);
  *BbsTable               = (BBS_TABLE*)(UINTN)EfiToLegacy16BootTable->BbsTable;
  *BbsCount               = (UINT16) (sizeof (Private->IntThunk->BbsTable) / sizeof (BBS_TABLE));
  return Status;
}

/**
  To boot from an unconventional device like parties and/or execute HDD diagnostics.

  @param  This            Protocol instance pointer.
  @param  Attributes      How to interpret the other input parameters
  @param  BbsEntry        The 0-based index into the BbsTable for the parent
                          device.
  @param  BeerData        Pointer to the 128 bytes of ram BEER data.
  @param  ServiceAreaData Pointer to the 64 bytes of raw Service Area data. The
                          caller must provide a pointer to the specific Service
                          Area and not the start all Service Areas.

  @retval EFI_INVALID_PARAMETER if error. Does NOT return if no error.

***/
EFI_STATUS
EFIAPI
LegacyBiosBootUnconventionalDevice (
  IN EFI_LEGACY_BIOS_PROTOCOL         *This,
  IN UDC_ATTRIBUTES                   Attributes,
  IN UINTN                            BbsEntry,
  IN VOID                             *BeerData,
  IN VOID                             *ServiceAreaData
  )
{
  EFI_STATUS                        Status;
  EFI_TO_COMPATIBILITY16_BOOT_TABLE *EfiToLegacy16BootTable;
  LEGACY_BIOS_INSTANCE              *Private;
  UD_TABLE                          *UcdTable;
  UINTN                             Index;
  UINT16                            BootPriority;
  BBS_TABLE                         *BbsTable;

  BootPriority = 0;
  Private = LEGACY_BIOS_INSTANCE_FROM_THIS (This);
  mBootMode = BOOT_UNCONVENTIONAL_DEVICE;
  mBbsDevicePathPtr = &mBbsDevicePathNode;
  mAttributes = Attributes;
  mBbsEntry = BbsEntry;
  mBeerData = BeerData, mServiceAreaData = ServiceAreaData;

  EfiToLegacy16BootTable = &Private->IntThunk->EfiToLegacy16BootTable;

  //
  // Do input parameter checking
  //
  if ((Attributes.DirectoryServiceValidity == 0) &&
      (Attributes.RabcaUsedFlag == 0) &&
      (Attributes.ExecuteHddDiagnosticsFlag == 0)
      ) {
    return EFI_INVALID_PARAMETER;
  }

  if (((Attributes.DirectoryServiceValidity != 0) && (ServiceAreaData == NULL)) ||
      (((Attributes.DirectoryServiceValidity | Attributes.RabcaUsedFlag) != 0) && (BeerData == NULL))
      ) {
    return EFI_INVALID_PARAMETER;
  }

  UcdTable = (UD_TABLE *) AllocatePool (
														sizeof (UD_TABLE)
														);
  if (NULL == UcdTable) {
    return EFI_OUT_OF_RESOURCES;
  }

  EfiToLegacy16BootTable->UnconventionalDeviceTable = (UINT32)(UINTN)UcdTable;
  UcdTable->Attributes = Attributes;
  UcdTable->BbsTableEntryNumberForParentDevice = (UINT8) BbsEntry;
  //
  // Force all existing BBS entries to DoNotBoot. This allows 16-bit CSM
  // to assign drive numbers but bot boot from. Only newly created entries
  // will be valid.
  //
  BbsTable = (BBS_TABLE*)(UINTN)EfiToLegacy16BootTable->BbsTable;
  for (Index = 0; Index < EfiToLegacy16BootTable->NumberBbsEntries; Index++) {
    BbsTable[Index].BootPriority = BBS_DO_NOT_BOOT_FROM;
  }
  //
  // If parent is onboard IDE then assign controller & device number
  // else they are 0.
  //
  if (BbsEntry < MAX_IDE_CONTROLLER * 2) {
    UcdTable->DeviceNumber = (UINT8) ((BbsEntry - 1) % 2);
  }

  if (BeerData != NULL) {
    CopyMem (
      (VOID *) UcdTable->BeerData,
      BeerData,
      (UINTN) 128
      );
  }

  if (ServiceAreaData != NULL) {
    CopyMem (
      (VOID *) UcdTable->ServiceAreaData,
      ServiceAreaData,
      (UINTN) 64
      );
  }
  //
  // For each new entry do the following:
  //   1. Increment current number of BBS entries
  //   2. Copy parent entry to new entry.
  //   3. Zero out BootHandler Offset & segment
  //   4. Set appropriate device type. BEV(0x80) for HDD diagnostics
  //      and Floppy(0x01) for PARTIES boot.
  //   5. Assign new priority.
  //
  if ((Attributes.ExecuteHddDiagnosticsFlag) != 0) {
    EfiToLegacy16BootTable->NumberBbsEntries += 1;

    CopyMem (
      (VOID *) &BbsTable[EfiToLegacy16BootTable->NumberBbsEntries].BootPriority,
      (VOID *) &BbsTable[BbsEntry].BootPriority,
      sizeof (BBS_TABLE)
      );

    BbsTable[EfiToLegacy16BootTable->NumberBbsEntries].BootHandlerOffset  = 0;
    BbsTable[EfiToLegacy16BootTable->NumberBbsEntries].BootHandlerSegment = 0;
    BbsTable[EfiToLegacy16BootTable->NumberBbsEntries].DeviceType         = 0x80;

    UcdTable->BbsTableEntryNumberForHddDiag = (UINT8) (EfiToLegacy16BootTable->NumberBbsEntries - 1);

    BbsTable[EfiToLegacy16BootTable->NumberBbsEntries].BootPriority = BootPriority;
    BootPriority += 1;

    //
    // Set device type as BBS_TYPE_DEV for PARTIES diagnostic
    //
    mBbsDevicePathNode.DeviceType = BBS_TYPE_BEV;
  }

  if (((Attributes.DirectoryServiceValidity | Attributes.RabcaUsedFlag)) != 0) {
    EfiToLegacy16BootTable->NumberBbsEntries += 1;
    CopyMem (
      (VOID *) &BbsTable[EfiToLegacy16BootTable->NumberBbsEntries].BootPriority,
      (VOID *) &BbsTable[BbsEntry].BootPriority,
      sizeof (BBS_TABLE)
      );

    BbsTable[EfiToLegacy16BootTable->NumberBbsEntries].BootHandlerOffset  = 0;
    BbsTable[EfiToLegacy16BootTable->NumberBbsEntries].BootHandlerSegment = 0;
    BbsTable[EfiToLegacy16BootTable->NumberBbsEntries].DeviceType         = 0x01;
    UcdTable->BbsTableEntryNumberForBoot = (UINT8) (EfiToLegacy16BootTable->NumberBbsEntries - 1);
    BbsTable[EfiToLegacy16BootTable->NumberBbsEntries].BootPriority = BootPriority;

    //
    // Set device type as BBS_TYPE_FLOPPY for PARTIES boot as floppy
    //
    mBbsDevicePathNode.DeviceType = BBS_TYPE_FLOPPY;
  }
  //
  // Build the BBS Device Path for this boot selection
  //
  mBbsDevicePathNode.Header.Type    = BBS_DEVICE_PATH;
  mBbsDevicePathNode.Header.SubType = BBS_BBS_DP;
  SetDevicePathNodeLength (&mBbsDevicePathNode.Header, sizeof (BBS_BBS_DEVICE_PATH));
  mBbsDevicePathNode.StatusFlag = 0;
  mBbsDevicePathNode.String[0]  = 0;

  Status                        = GenericLegacyBoot (This);
  return Status;
}

/**
  Attempt to legacy boot the BootOption. If the EFI contexted has been
  compromised this function will not return.

  @param  This             Protocol instance pointer.
  @param  BbsDevicePath    EFI Device Path from BootXXXX variable.
  @param  LoadOptionsSize  Size of LoadOption in size.
  @param  LoadOptions      LoadOption from BootXXXX variable

  @retval EFI_SUCCESS      Removable media not present

**/
EFI_STATUS
EFIAPI
LegacyBiosLegacyBoot (
  IN EFI_LEGACY_BIOS_PROTOCOL           *This,
  IN  BBS_BBS_DEVICE_PATH               *BbsDevicePath,
  IN  UINT32                            LoadOptionsSize,
  IN  VOID                              *LoadOptions
  )
{
  EFI_STATUS  Status;

  mBbsDevicePathPtr = BbsDevicePath;
  mLoadOptionsSize  = LoadOptionsSize;
  mLoadOptions      = LoadOptions;
  mBootMode         = BOOT_LEGACY_OS;
  Status            = GenericLegacyBoot (This);

  return Status;
}

/**
  Convert EFI Memory Type to E820 Memory Type.

  @param  Type  EFI Memory Type

  @return ACPI Memory Type for EFI Memory Type

**/
EFI_ACPI_MEMORY_TYPE
EfiMemoryTypeToE820Type (
  IN  UINT32    Type
  )
{
  switch (Type) {
  case EfiLoaderCode:
  case EfiLoaderData:
  case EfiBootServicesCode:
  case EfiBootServicesData:
  case EfiConventionalMemory:
  case EfiRuntimeServicesCode:
  case EfiRuntimeServicesData:
    return EfiAcpiAddressRangeMemory;

  case EfiACPIReclaimMemory:
    return EfiAcpiAddressRangeACPI;

  case EfiACPIMemoryNVS:
    return EfiAcpiAddressRangeNVS;

  //
  // All other types map to reserved.
  // Adding the code just waists FLASH space.
  //
  //  case  EfiReservedMemoryType:
  //  case  EfiUnusableMemory:
  //  case  EfiMemoryMappedIO:
  //  case  EfiMemoryMappedIOPortSpace:
  //  case  EfiPalCode:
  //
  default:
    return EfiAcpiAddressRangeReserved;
  }
}

/**
  Build the E820 table.

  @param  Private  Legacy BIOS Instance data
  @param  Size     Size of E820 Table

  @retval EFI_SUCCESS  It should always work.

**/
EFI_STATUS
LegacyBiosBuildE820 (
  IN  LEGACY_BIOS_INSTANCE    *Private,
  OUT UINTN                   *Size
  )
{
  EFI_STATUS                  Status;
  EFI_E820_ENTRY64            *E820Table;
  EFI_MEMORY_DESCRIPTOR       *EfiMemoryMap;
  EFI_MEMORY_DESCRIPTOR       *EfiMemoryMapEnd;
  EFI_MEMORY_DESCRIPTOR       *EfiEntry;
  EFI_MEMORY_DESCRIPTOR       *NextEfiEntry;
  EFI_MEMORY_DESCRIPTOR       TempEfiEntry;
  UINTN                       EfiMemoryMapSize;
  UINTN                       EfiMapKey;
  UINTN                       EfiDescriptorSize;
  UINT32                      EfiDescriptorVersion;
  UINTN                       Index;
  EFI_PEI_HOB_POINTERS        Hob;
  EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob;
  UINTN                       TempIndex;
  UINTN                       IndexSort;
  UINTN                       TempNextIndex;
  EFI_E820_ENTRY64            TempE820;
  EFI_ACPI_MEMORY_TYPE        TempType;
  BOOLEAN                     ChangedFlag;
  UINTN                       Above1MIndex;
  UINT64                      MemoryBlockLength;

  E820Table = (EFI_E820_ENTRY64 *) Private->E820Table;

  //
  // Get the EFI memory map.
  //
  EfiMemoryMapSize  = 0;
  EfiMemoryMap      = NULL;
  Status = gBS->GetMemoryMap (
                  &EfiMemoryMapSize,
                  EfiMemoryMap,
                  &EfiMapKey,
                  &EfiDescriptorSize,
                  &EfiDescriptorVersion
                  );
  ASSERT (Status == EFI_BUFFER_TOO_SMALL);

  do {
    //
    // Use size returned back plus 1 descriptor for the AllocatePool.
    // We don't just multiply by 2 since the "for" loop below terminates on
    // EfiMemoryMapEnd which is dependent upon EfiMemoryMapSize. Otherwize
    // we process bogus entries and create bogus E820 entries.
    //
    EfiMemoryMap = (EFI_MEMORY_DESCRIPTOR *) AllocatePool (EfiMemoryMapSize);
    ASSERT (EfiMemoryMap != NULL);
    Status = gBS->GetMemoryMap (
                    &EfiMemoryMapSize,
                    EfiMemoryMap,
                    &EfiMapKey,
                    &EfiDescriptorSize,
                    &EfiDescriptorVersion
                    );
    if (EFI_ERROR (Status)) {
      FreePool (EfiMemoryMap);
    }
  } while (Status == EFI_BUFFER_TOO_SMALL);

  ASSERT_EFI_ERROR (Status);

  //
  // Punch in the E820 table for memory less than 1 MB.
  // Assume ZeroMem () has been done on data structure.
  //
  //
  // First entry is 0 to (640k - EBDA)
  //
  E820Table[0].BaseAddr  = 0;
  E820Table[0].Length    = (UINT64) ((*(UINT16 *) (UINTN)0x40E) << 4);
  E820Table[0].Type      = EfiAcpiAddressRangeMemory;

  //
  // Second entry is (640k - EBDA) to 640k
  //
  E820Table[1].BaseAddr  = E820Table[0].Length;
  E820Table[1].Length    = (UINT64) ((640 * 1024) - E820Table[0].Length);
  E820Table[1].Type      = EfiAcpiAddressRangeReserved;

  //
  // Third Entry is legacy BIOS
  // DO NOT CLAIM region from 0xA0000-0xDFFFF. OS can use free areas
  // to page in memory under 1MB.
  // Omit region from 0xE0000 to start of BIOS, if any. This can be
  // used for a multiple reasons including OPROMS.
  //

  //
  // The CSM binary image size is not the actually size that CSM binary used,
  // to avoid memory corrupt, we declare the 0E0000 - 0FFFFF is used by CSM binary.
  //
  E820Table[2].BaseAddr  = 0xE0000;
  E820Table[2].Length    = 0x20000;
  E820Table[2].Type      = EfiAcpiAddressRangeReserved;

  Above1MIndex = 2;

  //
  // Process the EFI map to produce E820 map;
  //

  //
  // Sort memory map from low to high
  //
  EfiEntry        = EfiMemoryMap;
  NextEfiEntry    = NEXT_MEMORY_DESCRIPTOR (EfiEntry, EfiDescriptorSize);
  EfiMemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) EfiMemoryMap + EfiMemoryMapSize);
  while (EfiEntry < EfiMemoryMapEnd) {
    while (NextEfiEntry < EfiMemoryMapEnd) {
      if (EfiEntry->PhysicalStart > NextEfiEntry->PhysicalStart) {
        CopyMem (&TempEfiEntry, EfiEntry, sizeof (EFI_MEMORY_DESCRIPTOR));
        CopyMem (EfiEntry, NextEfiEntry, sizeof (EFI_MEMORY_DESCRIPTOR));
        CopyMem (NextEfiEntry, &TempEfiEntry, sizeof (EFI_MEMORY_DESCRIPTOR));
      }

      NextEfiEntry = NEXT_MEMORY_DESCRIPTOR (NextEfiEntry, EfiDescriptorSize);
    }

    EfiEntry      = NEXT_MEMORY_DESCRIPTOR (EfiEntry, EfiDescriptorSize);
    NextEfiEntry  = NEXT_MEMORY_DESCRIPTOR (EfiEntry, EfiDescriptorSize);
  }

  EfiEntry        = EfiMemoryMap;
  EfiMemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) EfiMemoryMap + EfiMemoryMapSize);
  for (Index = Above1MIndex; (EfiEntry < EfiMemoryMapEnd) && (Index < EFI_MAX_E820_ENTRY - 1); ) {
    MemoryBlockLength = (UINT64) (LShiftU64 (EfiEntry->NumberOfPages, 12));
    if ((EfiEntry->PhysicalStart + MemoryBlockLength) < 0x100000) {
      //
      // Skip the memory block is under 1MB
      //
    } else {
      if (EfiEntry->PhysicalStart < 0x100000) {
        //
        // When the memory block spans below 1MB, ensure the memory block start address is at least 1MB
        //
        MemoryBlockLength       -= 0x100000 - EfiEntry->PhysicalStart;
        EfiEntry->PhysicalStart =  0x100000;
      }

      //
      // Convert memory type to E820 type
      //
      TempType = EfiMemoryTypeToE820Type (EfiEntry->Type);

      if ((E820Table[Index].Type == TempType) && (EfiEntry->PhysicalStart == (E820Table[Index].BaseAddr + E820Table[Index].Length))) {
        //
        // Grow an existing entry
        //
        E820Table[Index].Length += MemoryBlockLength;
      } else {
        //
        // Make a new entry
        //
        ++Index;
        E820Table[Index].BaseAddr  = EfiEntry->PhysicalStart;
        E820Table[Index].Length    = MemoryBlockLength;
        E820Table[Index].Type      = TempType;
      }
    }
    EfiEntry = NEXT_MEMORY_DESCRIPTOR (EfiEntry, EfiDescriptorSize);
  }

  FreePool (EfiMemoryMap);

  //
  // Process the reserved memory map to produce E820 map ;
  //
  for (Hob.Raw = GetHobList (); !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {
    if (Hob.Raw != NULL && GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
      ResourceHob = Hob.ResourceDescriptor;
      if (((ResourceHob->ResourceType == EFI_RESOURCE_MEMORY_MAPPED_IO) ||
          (ResourceHob->ResourceType == EFI_RESOURCE_FIRMWARE_DEVICE)  ||
          (ResourceHob->ResourceType == EFI_RESOURCE_MEMORY_RESERVED)    ) &&
          (ResourceHob->PhysicalStart > 0x100000) &&
          (Index < EFI_MAX_E820_ENTRY - 1)) {
        ++Index;
        E820Table[Index].BaseAddr  = ResourceHob->PhysicalStart;
        E820Table[Index].Length    = ResourceHob->ResourceLength;
        E820Table[Index].Type      = EfiAcpiAddressRangeReserved;
      }
    }
  }

  Index ++;
  Private->IntThunk->EfiToLegacy16InitTable.NumberE820Entries = (UINT32)Index;
  Private->IntThunk->EfiToLegacy16BootTable.NumberE820Entries = (UINT32)Index;
  Private->NumberE820Entries = (UINT32)Index;
  *Size = (UINTN) (Index * sizeof (EFI_E820_ENTRY64));

  //
  // Sort E820Table from low to high
  //
  for (TempIndex = 0; TempIndex < Index; TempIndex++) {
    ChangedFlag = FALSE;
    for (TempNextIndex = 1; TempNextIndex < Index - TempIndex; TempNextIndex++) {
      if (E820Table[TempNextIndex - 1].BaseAddr > E820Table[TempNextIndex].BaseAddr) {
        ChangedFlag                       = TRUE;
        TempE820.BaseAddr                 = E820Table[TempNextIndex - 1].BaseAddr;
        TempE820.Length                   = E820Table[TempNextIndex - 1].Length;
        TempE820.Type                     = E820Table[TempNextIndex - 1].Type;

        E820Table[TempNextIndex - 1].BaseAddr  = E820Table[TempNextIndex].BaseAddr;
        E820Table[TempNextIndex - 1].Length    = E820Table[TempNextIndex].Length;
        E820Table[TempNextIndex - 1].Type      = E820Table[TempNextIndex].Type;

        E820Table[TempNextIndex].BaseAddr      = TempE820.BaseAddr;
        E820Table[TempNextIndex].Length        = TempE820.Length;
        E820Table[TempNextIndex].Type          = TempE820.Type;
      }
    }

    if (!ChangedFlag) {
      break;
    }
  }

  //
  // Remove the overlap range
  //
  for (TempIndex = 1; TempIndex < Index; TempIndex++) {
    if (E820Table[TempIndex - 1].BaseAddr <= E820Table[TempIndex].BaseAddr &&
        ((E820Table[TempIndex - 1].BaseAddr + E820Table[TempIndex - 1].Length) >=
         (E820Table[TempIndex].BaseAddr +E820Table[TempIndex].Length))) {
        //
        //Overlap range is found
        //
        ASSERT (E820Table[TempIndex - 1].Type == E820Table[TempIndex].Type);

        if (TempIndex == Index - 1) {
          E820Table[TempIndex].BaseAddr = 0;
          E820Table[TempIndex].Length   = 0;
          E820Table[TempIndex].Type     = (EFI_ACPI_MEMORY_TYPE) 0;
          Index--;
          break;
        } else {
          for (IndexSort = TempIndex; IndexSort < Index - 1; IndexSort ++) {
            E820Table[IndexSort].BaseAddr = E820Table[IndexSort + 1].BaseAddr;
            E820Table[IndexSort].Length   = E820Table[IndexSort + 1].Length;
            E820Table[IndexSort].Type     = E820Table[IndexSort + 1].Type;
          }
          Index--;
       }
    }
  }



  Private->IntThunk->EfiToLegacy16InitTable.NumberE820Entries = (UINT32)Index;
  Private->IntThunk->EfiToLegacy16BootTable.NumberE820Entries = (UINT32)Index;
  Private->NumberE820Entries = (UINT32)Index;
  *Size = (UINTN) (Index * sizeof (EFI_E820_ENTRY64));

  //
  // Determine OS usable memory above 1Mb
  //
  Private->IntThunk->EfiToLegacy16BootTable.OsMemoryAbove1Mb = 0x0000;
  for (TempIndex = Above1MIndex; TempIndex < Index; TempIndex++) {
    if (E820Table[TempIndex].BaseAddr >= 0x100000 && E820Table[TempIndex].BaseAddr < 0x100000000ULL) { // not include above 4G memory
      //
      // ACPIReclaimMemory is also usable memory for ACPI OS, after OS dumps all ACPI tables.
      //
      if ((E820Table[TempIndex].Type == EfiAcpiAddressRangeMemory) || (E820Table[TempIndex].Type == EfiAcpiAddressRangeACPI)) {
        Private->IntThunk->EfiToLegacy16BootTable.OsMemoryAbove1Mb += (UINT32) (E820Table[TempIndex].Length);
      } else {
        break; // break at first not normal memory, because SMM may use reserved memory.
      }
    }
  }

  Private->IntThunk->EfiToLegacy16InitTable.OsMemoryAbove1Mb = Private->IntThunk->EfiToLegacy16BootTable.OsMemoryAbove1Mb;

  //
  // Print DEBUG information
  //
  for (TempIndex = 0; TempIndex < Index; TempIndex++) {
    DEBUG((EFI_D_INFO, "E820[%2d]: 0x%16lx ---- 0x%16lx, Type = 0x%x \n",
      TempIndex,
      E820Table[TempIndex].BaseAddr,
      (E820Table[TempIndex].BaseAddr + E820Table[TempIndex].Length),
      E820Table[TempIndex].Type
      ));
  }

  return EFI_SUCCESS;
}


/**
  Fill in the standard BDA and EBDA stuff prior to legacy Boot

  @param  Private      Legacy BIOS Instance data

  @retval EFI_SUCCESS  It should always work.

**/
EFI_STATUS
LegacyBiosCompleteBdaBeforeBoot (
  IN  LEGACY_BIOS_INSTANCE    *Private
  )
{
  BDA_STRUC                   *Bda;
  UINT16                      MachineConfig;
  DEVICE_PRODUCER_DATA_HEADER *SioPtr;

  Bda           = (BDA_STRUC *) ((UINTN) 0x400);
  MachineConfig = 0;

  SioPtr        = &(Private->IntThunk->EfiToLegacy16BootTable.SioData);
  Bda->Com1     = SioPtr->Serial[0].Address;
  Bda->Com2     = SioPtr->Serial[1].Address;
  Bda->Com3     = SioPtr->Serial[2].Address;
  Bda->Com4     = SioPtr->Serial[3].Address;

  if (SioPtr->Serial[0].Address != 0x00) {
    MachineConfig += 0x200;
  }

  if (SioPtr->Serial[1].Address != 0x00) {
    MachineConfig += 0x200;
  }

  if (SioPtr->Serial[2].Address != 0x00) {
    MachineConfig += 0x200;
  }

  if (SioPtr->Serial[3].Address != 0x00) {
    MachineConfig += 0x200;
  }

  Bda->Lpt1 = SioPtr->Parallel[0].Address;
  Bda->Lpt2 = SioPtr->Parallel[1].Address;
  Bda->Lpt3 = SioPtr->Parallel[2].Address;

  if (SioPtr->Parallel[0].Address != 0x00) {
    MachineConfig += 0x4000;
  }

  if (SioPtr->Parallel[1].Address != 0x00) {
    MachineConfig += 0x4000;
  }

  if (SioPtr->Parallel[2].Address != 0x00) {
    MachineConfig += 0x4000;
  }

  Bda->NumberOfDrives = (UINT8) (Bda->NumberOfDrives + Private->IdeDriveCount);
  if (SioPtr->Floppy.NumberOfFloppy != 0x00) {
    MachineConfig     = (UINT16) (MachineConfig + 0x01 + (SioPtr->Floppy.NumberOfFloppy - 1) * 0x40);
    Bda->FloppyXRate  = 0x07;
  }

  Bda->Lpt1_2Timeout  = 0x1414;
  Bda->Lpt3_4Timeout  = 0x1414;
  Bda->Com1_2Timeout  = 0x0101;
  Bda->Com3_4Timeout  = 0x0101;

  //
  // Force VGA and Coprocessor, indicate 101/102 keyboard
  //
  MachineConfig       = (UINT16) (MachineConfig + 0x00 + 0x02 + (SioPtr->MousePresent * 0x04));
  Bda->MachineConfig  = MachineConfig;

  return EFI_SUCCESS;
}

/**
  Fill in the standard BDA for Keyboard LEDs

  @param  This         Protocol instance pointer.
  @param  Leds         Current LED status

  @retval EFI_SUCCESS  It should always work.

**/
EFI_STATUS
EFIAPI
LegacyBiosUpdateKeyboardLedStatus (
  IN EFI_LEGACY_BIOS_PROTOCOL           *This,
  IN  UINT8                             Leds
  )
{
  LEGACY_BIOS_INSTANCE  *Private;
  BDA_STRUC             *Bda;
  UINT8                 LocalLeds;
  EFI_IA32_REGISTER_SET Regs;

  Bda                 = (BDA_STRUC *) ((UINTN) 0x400);

  Private             = LEGACY_BIOS_INSTANCE_FROM_THIS (This);
  LocalLeds           = Leds;
  Bda->LedStatus      = (UINT8) ((Bda->LedStatus &~0x07) | LocalLeds);
  LocalLeds           = (UINT8) (LocalLeds << 4);
  Bda->ShiftStatus    = (UINT8) ((Bda->ShiftStatus &~0x70) | LocalLeds);
  LocalLeds           = (UINT8) (Leds & 0x20);
  Bda->KeyboardStatus = (UINT8) ((Bda->KeyboardStatus &~0x20) | LocalLeds);
  //
  // Call into Legacy16 code to allow it to do any processing
  //
  ZeroMem (&Regs, sizeof (EFI_IA32_REGISTER_SET));
  Regs.X.AX = Legacy16SetKeyboardLeds;
  Regs.H.CL = Leds;

  Private->LegacyBios.FarCall86 (
    &Private->LegacyBios,
    Private->Legacy16Table->Compatibility16CallSegment,
    Private->Legacy16Table->Compatibility16CallOffset,
    &Regs,
    NULL,
    0
    );

  return EFI_SUCCESS;
}


/**
  Fill in the standard CMOS stuff prior to legacy Boot

  @param  Private      Legacy BIOS Instance data

  @retval EFI_SUCCESS  It should always work.

**/
EFI_STATUS
LegacyBiosCompleteStandardCmosBeforeBoot (
  IN  LEGACY_BIOS_INSTANCE    *Private
  )
{
  UINT8   Bda;
  UINT8   Floppy;
  UINT32  Size;

  //
  // Update CMOS locations
  // 10 floppy
  // 12,19,1A - ignore as OS don't use them and there is no standard due
  //            to large capacity drives
  // CMOS 14 = BDA 40:10 plus bit 3(display enabled)
  //
  Bda = (UINT8)(*((UINT8 *)((UINTN)0x410)) | BIT3);

  //
  // Force display enabled
  //
  Floppy = 0x00;
  if ((Bda & BIT0) != 0) {
    Floppy = BIT6;
  }

  //
  // Check if 2.88MB floppy set
  //
  if ((Bda & (BIT7 | BIT6)) != 0) {
    Floppy = (UINT8)(Floppy | BIT1);
  }

  LegacyWriteStandardCmos (CMOS_10, Floppy);
  LegacyWriteStandardCmos (CMOS_14, Bda);

  //
  // Force Status Register A to set rate selection bits and divider
  //
  LegacyWriteStandardCmos (CMOS_0A, 0x26);

  //
  // redo memory size since it can change
  //
  Size = 15 * SIZE_1MB;
  if (Private->IntThunk->EfiToLegacy16InitTable.OsMemoryAbove1Mb < (15 * SIZE_1MB)) {
    Size  = Private->IntThunk->EfiToLegacy16InitTable.OsMemoryAbove1Mb >> 10;
  }

  LegacyWriteStandardCmos (CMOS_17, (UINT8)(Size & 0xFF));
  LegacyWriteStandardCmos (CMOS_30, (UINT8)(Size & 0xFF));
  LegacyWriteStandardCmos (CMOS_18, (UINT8)(Size >> 8));
  LegacyWriteStandardCmos (CMOS_31, (UINT8)(Size >> 8));

  LegacyCalculateWriteStandardCmosChecksum ();

  return EFI_SUCCESS;
}

/**
  Relocate this image under 4G memory for IPF.

  @param  ImageHandle  Handle of driver image.
  @param  SystemTable  Pointer to system table.

  @retval EFI_SUCCESS  Image successfully relocated.
  @retval EFI_ABORTED  Failed to relocate image.

**/
EFI_STATUS
RelocateImageUnder4GIfNeeded (
  IN EFI_HANDLE           ImageHandle,
  IN EFI_SYSTEM_TABLE     *SystemTable
  )
{
  return EFI_SUCCESS;
}
