]> code.delx.au - refind/commitdiff
New files for BIOS-mode boot support under GNU-EFI
authorsrs5694 <srs5694@users.sourceforge.net>
Fri, 9 May 2014 00:33:01 +0000 (20:33 -0400)
committersrs5694 <srs5694@users.sourceforge.net>
Fri, 9 May 2014 00:33:01 +0000 (20:33 -0400)
EfiLib/BdsConnect.c [deleted file]
EfiLib/Console.c [deleted file]
EfiLib/DevicePathUtilities.h [new file with mode: 0644]
EfiLib/LegacyBios.h [new file with mode: 0644]
EfiLib/gnuefi-helper.c [new file with mode: 0644]
EfiLib/gnuefi-helper.h [new file with mode: 0644]

diff --git a/EfiLib/BdsConnect.c b/EfiLib/BdsConnect.c
deleted file mode 100644 (file)
index d168462..0000000
+++ /dev/null
@@ -1,641 +0,0 @@
-/** @file\r
-  BDS Lib functions which relate with connect the device\r
-\r
-Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution.  The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#include "Platform.h"\r
-\r
-\r
-/**\r
-  This function will connect all the system driver to controller\r
-  first, and then special connect the default console, this make\r
-  sure all the system controller available and the platform default\r
-  console connected.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-BdsLibConnectAll (\r
-  VOID\r
-  )\r
-{\r
-  //\r
-  // Connect the platform console first\r
-  //\r
-  BdsLibConnectAllDefaultConsoles ();\r
-\r
-  //\r
-  // Generic way to connect all the drivers\r
-  //\r
-  BdsLibConnectAllDriversToAllControllers ();\r
-\r
-  //\r
-  // Here we have the assumption that we have already had\r
-  // platform default console\r
-  //\r
-  BdsLibConnectAllDefaultConsoles ();\r
-}\r
-\r
-\r
-/**\r
-  This function will connect all the system drivers to all controllers\r
-  first, and then connect all the console devices the system current\r
-  have. After this we should get all the device work and console available\r
-  if the system have console device.\r
-\r
-**/\r
-VOID\r
-BdsLibGenericConnectAll (\r
-  VOID\r
-  )\r
-{\r
-  //\r
-  // Most generic way to connect all the drivers\r
-  //\r
-  BdsLibConnectAllDriversToAllControllers ();\r
-  BdsLibConnectAllConsoles ();\r
-}\r
-\r
-\r
-/**\r
-  This function will create all handles associate with every device\r
-  path node. If the handle associate with one device path node can not\r
-  be created success, then still give one chance to do the dispatch,\r
-  which load the missing drivers if possible.\r
-\r
-  @param  DevicePathToConnect   The device path which will be connected, it can be\r
-                                a multi-instance device path\r
-\r
-  @retval EFI_SUCCESS           All handles associate with every device path  node\r
-                                have been created\r
-  @retval EFI_OUT_OF_RESOURCES  There is no resource to create new handles\r
-  @retval EFI_NOT_FOUND         Create the handle associate with one device  path\r
-                                node failed\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-BdsLibConnectDevicePath (\r
-  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePathToConnect\r
-  )\r
-{\r
-  EFI_STATUS                Status;\r
-  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;\r
-  EFI_DEVICE_PATH_PROTOCOL  *CopyOfDevicePath;\r
-  EFI_DEVICE_PATH_PROTOCOL  *Instance;\r
-  EFI_DEVICE_PATH_PROTOCOL  *RemainingDevicePath;\r
-  EFI_DEVICE_PATH_PROTOCOL  *Next;\r
-  EFI_HANDLE                Handle;\r
-  EFI_HANDLE                PreviousHandle;\r
-  UINTN                     Size;\r
-\r
-  if (DevicePathToConnect == NULL) {\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  DevicePath        = DuplicateDevicePath (DevicePathToConnect);\r
-  if (DevicePath == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-  CopyOfDevicePath  = DevicePath;\r
-  \r
-  do {\r
-    //\r
-    // The outer loop handles multi instance device paths.\r
-    // Only console variables contain multiple instance device paths.\r
-    //\r
-    // After this call DevicePath points to the next Instance\r
-    //\r
-    Instance  = GetNextDevicePathInstance (&DevicePath, &Size);\r
-    if (Instance == NULL) {\r
-      FreePool (CopyOfDevicePath);\r
-      return EFI_OUT_OF_RESOURCES;\r
-    }\r
-    \r
-    Next      = Instance;\r
-    while (!IsDevicePathEndType (Next)) {\r
-      Next = NextDevicePathNode (Next);\r
-    }\r
-\r
-    SetDevicePathEndNode (Next);\r
-\r
-    //\r
-    // Start the real work of connect with RemainingDevicePath\r
-    //\r
-    PreviousHandle = NULL;\r
-    do {\r
-      //\r
-      // Find the handle that best matches the Device Path. If it is only a\r
-      // partial match the remaining part of the device path is returned in\r
-      // RemainingDevicePath.\r
-      //\r
-      RemainingDevicePath = Instance;\r
-      Status              = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &RemainingDevicePath, &Handle);\r
-\r
-      if (!EFI_ERROR (Status)) {\r
-        if (Handle == PreviousHandle) {\r
-          //\r
-          // If no forward progress is made try invoking the Dispatcher.\r
-          // A new FV may have been added to the system an new drivers\r
-          // may now be found.\r
-          // Status == EFI_SUCCESS means a driver was dispatched\r
-          // Status == EFI_NOT_FOUND means no new drivers were dispatched\r
-          //\r
-          Status = gDS->Dispatch ();\r
-        }\r
-\r
-        if (!EFI_ERROR (Status)) {\r
-          PreviousHandle = Handle;\r
-          //\r
-          // Connect all drivers that apply to Handle and RemainingDevicePath,\r
-          // the Recursive flag is FALSE so only one level will be expanded.\r
-          //\r
-          // Do not check the connect status here, if the connect controller fail,\r
-          // then still give the chance to do dispatch, because partial\r
-          // RemainingDevicepath may be in the new FV\r
-          //\r
-          // 1. If the connect fail, RemainingDevicepath and handle will not\r
-          //    change, so next time will do the dispatch, then dispatch's status\r
-          //    will take effect\r
-          // 2. If the connect success, the RemainingDevicepath and handle will\r
-          //    change, then avoid the dispatch, we have chance to continue the\r
-          //    next connection\r
-          //\r
-          gBS->ConnectController (Handle, NULL, RemainingDevicePath, FALSE);\r
-        }\r
-      }\r
-      //\r
-      // Loop until RemainingDevicePath is an empty device path\r
-      //\r
-    } while (!EFI_ERROR (Status) && !IsDevicePathEnd (RemainingDevicePath));\r
-\r
-  } while (DevicePath != NULL);\r
-\r
-  if (CopyOfDevicePath != NULL) {\r
-    FreePool (CopyOfDevicePath);\r
-  }\r
-  //\r
-  // All handle with DevicePath exists in the handle database\r
-  //\r
-  return Status;\r
-}\r
-\r
-\r
-/**\r
-  This function will connect all current system handles recursively. \r
-  \r
-  gBS->ConnectController() service is invoked for each handle exist in system handler buffer.\r
-  If the handle is bus type handler, all childrens also will be connected recursively\r
-  by gBS->ConnectController().\r
-\r
-  @retval EFI_SUCCESS           All handles and it's child handle have been connected\r
-  @retval EFI_STATUS            Error status returned by of gBS->LocateHandleBuffer().\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-BdsLibConnectAllEfi (\r
-  VOID\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-  UINTN       HandleCount;\r
-  EFI_HANDLE  *HandleBuffer;\r
-  UINTN       Index;\r
-\r
-  Status = gBS->LocateHandleBuffer (\r
-                  AllHandles,\r
-                  NULL,\r
-                  NULL,\r
-                  &HandleCount,\r
-                  &HandleBuffer\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  for (Index = 0; Index < HandleCount; Index++) {\r
-    Status = gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);\r
-  }\r
-\r
-  if (HandleBuffer != NULL) {\r
-    FreePool (HandleBuffer);\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
-  This function will disconnect all current system handles. \r
-  \r
-  gBS->DisconnectController() is invoked for each handle exists in system handle buffer.\r
-  If handle is a bus type handle, all childrens also are disconnected recursively by\r
-  gBS->DisconnectController().\r
-\r
-  @retval EFI_SUCCESS           All handles have been disconnected\r
-  @retval EFI_STATUS            Error status returned by of gBS->LocateHandleBuffer().\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-BdsLibDisconnectAllEfi (\r
-  VOID\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-  UINTN       HandleCount;\r
-  EFI_HANDLE  *HandleBuffer;\r
-  UINTN       Index;\r
-\r
-  //\r
-  // Disconnect all\r
-  //\r
-  Status = gBS->LocateHandleBuffer (\r
-                  AllHandles,\r
-                  NULL,\r
-                  NULL,\r
-                  &HandleCount,\r
-                  &HandleBuffer\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  for (Index = 0; Index < HandleCount; Index++) {\r
-    Status = gBS->DisconnectController (HandleBuffer[Index], NULL, NULL);\r
-  }\r
-\r
-  if (HandleBuffer != NULL) {\r
-    FreePool (HandleBuffer);\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS ScanDeviceHandles(EFI_HANDLE ControllerHandle,\r
-                             UINTN *HandleCount,\r
-                             EFI_HANDLE **HandleBuffer,\r
-                             UINT32 **HandleType)\r
-{\r
-  EFI_STATUS                          Status;\r
-  UINTN                               HandleIndex;\r
-  EFI_GUID                            **ProtocolGuidArray;\r
-  UINTN                               ArrayCount;\r
-  UINTN                               ProtocolIndex;\r
-  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfo;\r
-  UINTN                               OpenInfoCount;\r
-  UINTN                               OpenInfoIndex;\r
-  UINTN                               ChildIndex;\r
-  \r
-  *HandleCount  = 0;\r
-  *HandleBuffer = NULL;\r
-  *HandleType   = NULL;\r
-  \r
-  //\r
-  // Retrieve the list of all handles from the handle database\r
-  //\r
-  Status = gBS->LocateHandleBuffer (AllHandles, NULL, NULL, HandleCount, HandleBuffer);\r
-  if (EFI_ERROR (Status)) goto Error;\r
-  \r
-  *HandleType = AllocatePool (*HandleCount * sizeof (UINT32));\r
-  if (*HandleType == NULL) goto Error;\r
-    \r
-  for (HandleIndex = 0; HandleIndex < *HandleCount; HandleIndex++) {\r
-    (*HandleType)[HandleIndex] = EFI_HANDLE_TYPE_UNKNOWN;\r
-    //\r
-    // Retrieve the list of all the protocols on each handle\r
-    //\r
-    Status = gBS->ProtocolsPerHandle (\r
-                  (*HandleBuffer)[HandleIndex],\r
-                  &ProtocolGuidArray,\r
-                  &ArrayCount\r
-                  );\r
-    if (!EFI_ERROR (Status)) {      \r
-      for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) \r
-      {\r
-        \r
-        if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiLoadedImageProtocolGuid))\r
-        {\r
-          (*HandleType)[HandleIndex] |= EFI_HANDLE_TYPE_IMAGE_HANDLE;\r
-        }\r
-        \r
-        if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverBindingProtocolGuid))\r
-        {\r
-          (*HandleType)[HandleIndex] |= EFI_HANDLE_TYPE_DRIVER_BINDING_HANDLE;\r
-        }\r
-        \r
-        if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverConfigurationProtocolGuid)) \r
-        {\r
-          (*HandleType)[HandleIndex] |= EFI_HANDLE_TYPE_DRIVER_CONFIGURATION_HANDLE;\r
-        }\r
-        \r
-        if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDriverDiagnosticsProtocolGuid)) \r
-        {\r
-          (*HandleType)[HandleIndex] |= EFI_HANDLE_TYPE_DRIVER_DIAGNOSTICS_HANDLE;\r
-        }\r
-        \r
-        if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiComponentName2ProtocolGuid)) \r
-        {\r
-          (*HandleType)[HandleIndex] |= EFI_HANDLE_TYPE_COMPONENT_NAME_HANDLE;\r
-        }\r
-        \r
-        if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiComponentNameProtocolGuid) ) \r
-        {\r
-          (*HandleType)[HandleIndex] |= EFI_HANDLE_TYPE_COMPONENT_NAME_HANDLE;\r
-        }\r
-        \r
-        if (CompareGuid (ProtocolGuidArray[ProtocolIndex], &gEfiDevicePathProtocolGuid)) \r
-        {\r
-          (*HandleType)[HandleIndex] |= EFI_HANDLE_TYPE_DEVICE_HANDLE;\r
-        }\r
-        \r
-        //\r
-        // Retrieve the list of agents that have opened each protocol\r
-        //\r
-        Status = gBS->OpenProtocolInformation (\r
-                                               (*HandleBuffer)[HandleIndex],\r
-                                               ProtocolGuidArray[ProtocolIndex],\r
-                                               &OpenInfo,\r
-                                               &OpenInfoCount\r
-                                               );\r
-        if (!EFI_ERROR (Status)) {\r
-          \r
-          for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {\r
-            \r
-            if (OpenInfo[OpenInfoIndex].ControllerHandle == ControllerHandle)\r
-            {\r
-              if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) == EFI_OPEN_PROTOCOL_BY_DRIVER) \r
-              {\r
-                for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) \r
-                {\r
-                  if ((*HandleBuffer)[ChildIndex] == OpenInfo[OpenInfoIndex].AgentHandle) \r
-                  {\r
-                    (*HandleType)[ChildIndex] |= EFI_HANDLE_TYPE_DEVICE_DRIVER;\r
-                  }\r
-                }\r
-              }\r
-              \r
-              if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) == EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER)\r
-              {\r
-                (*HandleType)[HandleIndex] |= EFI_HANDLE_TYPE_PARENT_HANDLE;\r
-                for (ChildIndex = 0; ChildIndex < *HandleCount; ChildIndex++) \r
-                {\r
-                  if ((*HandleBuffer)[ChildIndex] == OpenInfo[OpenInfoIndex].AgentHandle) \r
-                  {\r
-                    (*HandleType)[ChildIndex] |= EFI_HANDLE_TYPE_BUS_DRIVER;\r
-                  }\r
-                }\r
-              }\r
-            }\r
-          }\r
-          \r
-          FreePool (OpenInfo);\r
-        }\r
-      }\r
-      \r
-      FreePool (ProtocolGuidArray);\r
-    }\r
-  }\r
-  \r
-  return EFI_SUCCESS;\r
-  \r
-Error:\r
-  if (*HandleType != NULL) {\r
-    FreePool (*HandleType);\r
-  }\r
-  \r
-  if (*HandleBuffer != NULL) {\r
-    FreePool (*HandleBuffer);\r
-  }\r
-  \r
-  *HandleCount  = 0;\r
-  *HandleBuffer = NULL;\r
-  *HandleType   = NULL;\r
-  \r
-  return Status;\r
-}\r
-\r
-\r
-\r
-EFI_STATUS BdsLibConnectMostlyAllEfi()\r
-{\r
-       EFI_STATUS                              Status;\r
-       UINTN             AllHandleCount;\r
-       EFI_HANDLE                              *AllHandleBuffer;\r
-       UINTN             Index;\r
-       UINTN             HandleCount;\r
-       EFI_HANDLE                              *HandleBuffer;\r
-       UINT32            *HandleType;\r
-       UINTN             HandleIndex;\r
-       BOOLEAN           Parent;\r
-       BOOLEAN           Device;\r
-       EFI_PCI_IO_PROTOCOL*    PciIo;\r
-       PCI_TYPE00                              Pci;\r
-  \r
-  \r
-       Status = gBS->LocateHandleBuffer (AllHandles, NULL, NULL, &AllHandleCount, &AllHandleBuffer);\r
-       if (CheckError(Status, L"locating handle buffer")) \r
-               return Status;\r
-  \r
-       for (Index = 0; Index < AllHandleCount; Index++) \r
-       {\r
-               Status = ScanDeviceHandles(AllHandleBuffer[Index], &HandleCount, &HandleBuffer, &HandleType);\r
-    \r
-               if (EFI_ERROR (Status))\r
-                       goto Done;\r
-    \r
-               Device = TRUE;\r
-               \r
-               if (HandleType[Index] & EFI_HANDLE_TYPE_DRIVER_BINDING_HANDLE)\r
-                       Device = FALSE;\r
-               if (HandleType[Index] & EFI_HANDLE_TYPE_IMAGE_HANDLE)\r
-                       Device = FALSE;\r
-    \r
-               if (Device) \r
-               {                                       \r
-                       Parent = FALSE;\r
-                       for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) \r
-                       {\r
-                               if (HandleType[HandleIndex] & EFI_HANDLE_TYPE_PARENT_HANDLE)\r
-                                       Parent = TRUE;\r
-                       }\r
-      \r
-                       if (!Parent) \r
-                       {\r
-                               if (HandleType[Index] & EFI_HANDLE_TYPE_DEVICE_HANDLE) \r
-                               {\r
-                                       Status = gBS->HandleProtocol (AllHandleBuffer[Index], &gEfiPciIoProtocolGuid, (VOID*)&PciIo);\r
-                                       if (!EFI_ERROR (Status)) \r
-                                       {\r
-                                               Status = PciIo->Pci.Read (PciIo,EfiPciIoWidthUint32, 0, sizeof (Pci) / sizeof (UINT32), &Pci);\r
-                                               if (!EFI_ERROR (Status))\r
-                                               {\r
-                                                       if(IS_PCI_VGA(&Pci)==TRUE)\r
-                                                       {\r
-                                                               gBS->DisconnectController(AllHandleBuffer[Index], NULL, NULL);\r
-                                                       }\r
-                                               }\r
-                                       }\r
-                                       Status = gBS->ConnectController(AllHandleBuffer[Index], NULL, NULL, TRUE);\r
-                               }\r
-                       }\r
-               }\r
-    \r
-               FreePool (HandleBuffer);\r
-               FreePool (HandleType);\r
-       }\r
-  \r
-Done:\r
-       FreePool (AllHandleBuffer);\r
-       return Status;\r
-}\r
-\r
-\r
-\r
-/**\r
-  Connects all drivers to all controllers.\r
-  This function make sure all the current system driver will manage\r
-  the correspoinding controllers if have. And at the same time, make\r
-  sure all the system controllers have driver to manage it if have.\r
-\r
-**/\r
-VOID\r
-EFIAPI\r
-BdsLibConnectAllDriversToAllControllers (\r
-  VOID\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-\r
-  do {\r
-    //\r
-    // Connect All EFI 1.10 drivers following EFI 1.10 algorithm\r
-    //\r
-    //BdsLibConnectAllEfi ();\r
-    BdsLibConnectMostlyAllEfi ();\r
-\r
-    //\r
-    // Check to see if it's possible to dispatch an more DXE drivers.\r
-    // The BdsLibConnectAllEfi () may have made new DXE drivers show up.\r
-    // If anything is Dispatched Status == EFI_SUCCESS and we will try\r
-    // the connect again.\r
-    //\r
-    Status = gDS->Dispatch ();\r
-\r
-  } while (!EFI_ERROR (Status));\r
-\r
-}\r
-\r
-\r
-/**\r
-  Connect the specific Usb device which match the short form device path,\r
-  and whose bus is determined by Host Controller (Uhci or Ehci).\r
-\r
-  @param  HostControllerPI      Uhci (0x00) or Ehci (0x20) or Both uhci and ehci\r
-                                (0xFF)\r
-  @param  RemainingDevicePath   a short-form device path that starts with the first\r
-                                element  being a USB WWID or a USB Class device\r
-                                path\r
-\r
-  @return EFI_INVALID_PARAMETER  RemainingDevicePath is NULL pointer.\r
-                                 RemainingDevicePath is not a USB device path.\r
-                                 Invalid HostControllerPI type.\r
-  @return EFI_SUCCESS            Success to connect USB device\r
-  @return EFI_NOT_FOUND          Fail to find handle for USB controller to connect.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-BdsLibConnectUsbDevByShortFormDP(\r
-  IN UINT8                      HostControllerPI,\r
-  IN EFI_DEVICE_PATH_PROTOCOL   *RemainingDevicePath\r
-  )\r
-{\r
-  EFI_STATUS                            Status;\r
-  EFI_HANDLE                            *HandleArray;\r
-  UINTN                                 HandleArrayCount;\r
-  UINTN                                 Index;\r
-  EFI_PCI_IO_PROTOCOL                   *PciIo;\r
-  UINT8                                 Class[3];\r
-  BOOLEAN                               AtLeastOneConnected;\r
-\r
-  //\r
-  // Check the passed in parameters\r
-  //\r
-  if (RemainingDevicePath == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if ((DevicePathType (RemainingDevicePath) != MESSAGING_DEVICE_PATH) ||\r
-      ((DevicePathSubType (RemainingDevicePath) != MSG_USB_CLASS_DP)\r
-      && (DevicePathSubType (RemainingDevicePath) != MSG_USB_WWID_DP)\r
-      )) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  if (HostControllerPI != 0xFF &&\r
-      HostControllerPI != 0x00 &&\r
-      HostControllerPI != 0x10 &&\r
-      HostControllerPI != 0x20 &&\r
-      HostControllerPI != 0x30) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // Find the usb host controller firstly, then connect with the remaining device path\r
-  //\r
-  AtLeastOneConnected = FALSE;\r
-  Status = gBS->LocateHandleBuffer (\r
-                  ByProtocol,\r
-                  &gEfiPciIoProtocolGuid,\r
-                  NULL,\r
-                  &HandleArrayCount,\r
-                  &HandleArray\r
-                  );\r
-  if (!EFI_ERROR (Status)) {\r
-    for (Index = 0; Index < HandleArrayCount; Index++) {\r
-      Status = gBS->HandleProtocol (\r
-                      HandleArray[Index],\r
-                      &gEfiPciIoProtocolGuid,\r
-                      (VOID **)&PciIo\r
-                      );\r
-      if (!EFI_ERROR (Status)) {\r
-        //\r
-        // Check whether the Pci device is the wanted usb host controller\r
-        //\r
-        Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, 0x09, 3, &Class);\r
-        if (!EFI_ERROR (Status)) {\r
-          if ((PCI_CLASS_SERIAL == Class[2]) &&\r
-              (PCI_CLASS_SERIAL_USB == Class[1])) {\r
-            if (HostControllerPI == Class[0] || HostControllerPI == 0xFF) {\r
-              Status = gBS->ConnectController (\r
-                              HandleArray[Index],\r
-                              NULL,\r
-                              RemainingDevicePath,\r
-                              FALSE\r
-                              );\r
-              if (!EFI_ERROR(Status)) {\r
-                AtLeastOneConnected = TRUE;\r
-              }\r
-            }\r
-          }\r
-        }\r
-      }\r
-    }\r
-\r
-    if (AtLeastOneConnected) {\r
-      return EFI_SUCCESS;\r
-    }\r
-  }\r
-\r
-  return EFI_NOT_FOUND;\r
-}\r
diff --git a/EfiLib/Console.c b/EfiLib/Console.c
deleted file mode 100644 (file)
index b5cf03f..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-/* $Id: Console.c $ */
-/** @file
- * Console.c - VirtualBox Console control emulation
- */
-
-/*
- * Copyright (C) 2010 Oracle Corporation
- *
- * This file is part of VirtualBox Open Source Edition (OSE), as
- * available from http://www.virtualbox.org. This file is free software;
- * you can redistribute it and/or modify it under the terms of the GNU
- * General Public License (GPL) as published by the Free Software
- * Foundation, in version 2 as it comes in the "COPYING" file of the
- * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
- * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
- */
-
-#include "Platform.h"
-extern EFI_RUNTIME_SERVICES*  gRS;
-static EFI_CONSOLE_CONTROL_SCREEN_MODE CurrentMode = EfiConsoleControlScreenText;
-
-EFI_STATUS EFIAPI
-GetModeImpl(
-  IN  EFI_CONSOLE_CONTROL_PROTOCOL      *This,
-  OUT EFI_CONSOLE_CONTROL_SCREEN_MODE   *Mode,
-  OUT BOOLEAN                           *GopUgaExists,  OPTIONAL
-  OUT BOOLEAN                           *StdInLocked    OPTIONAL
-  )
-{
-  *Mode = CurrentMode; 
-  // EfiConsoleControlScreenText;
-  // EfiConsoleControlScreenGraphics;
-
-    if (GopUgaExists)
-        *GopUgaExists = TRUE;
-    if (StdInLocked)
-        *StdInLocked = FALSE;
-    return EFI_SUCCESS;
-}
-
-EFI_STATUS EFIAPI
-SetModeImpl(
-  IN  EFI_CONSOLE_CONTROL_PROTOCOL      *This,
-  IN  EFI_CONSOLE_CONTROL_SCREEN_MODE   Mode
-  )
-{
-  CurrentMode = Mode;
-    return EFI_SUCCESS;
-}
-
-EFI_STATUS EFIAPI
-LockStdInImpl(
-  IN  EFI_CONSOLE_CONTROL_PROTOCOL      *This,
-  IN CHAR16                             *Password
-  )
-{
-    return EFI_SUCCESS;
-}
-
-
-EFI_CONSOLE_CONTROL_PROTOCOL gConsoleController =
-{
-    GetModeImpl,
-    SetModeImpl,
-    LockStdInImpl
-};
-
-EFI_GUID gEfiConsoleControlProtocolGuid = EFI_CONSOLE_CONTROL_PROTOCOL_GUID;
-
-EFI_STATUS
-EFIAPI
-InitializeConsoleSim ()
-{
-  EFI_STATUS              Status;
-//  EG_PIXEL           BackgroundClear = {0, 0, 0, 0};
-//     CHAR16*                 bgc = L"BackgroundClear";
-//     UINTN                   dataSize = sizeof(BackgroundClear);
-  
-  
-  Status = gBS->InstallMultipleProtocolInterfaces (
-      &gImageHandle,
-      &gEfiConsoleControlProtocolGuid,
-      &gConsoleController,
-      NULL
-                                                   );
-  
-  // get background clear
-//     Status = gRS->GetVariable(bgc, &gEfiAppleNvramGuid, 0, &dataSize, &BackgroundClear);
-//     if(!EFI_ERROR(Status))
-//             return Status;
-  
-//     Status = gRS->SetVariable(bgc, &gEfiAppleBootGuid,
-//                            EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
-//                            sizeof(BackgroundClear), &BackgroundClear);
-  
-  ASSERT_EFI_ERROR (Status);
-
-  return Status;
-}
diff --git a/EfiLib/DevicePathUtilities.h b/EfiLib/DevicePathUtilities.h
new file mode 100644 (file)
index 0000000..b559671
--- /dev/null
@@ -0,0 +1,233 @@
+/*++\r
+\r
+Copyright (c) 2006 - 2007, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials                          \r
+are licensed and made available under the terms and conditions of the BSD License         \r
+which accompanies this distribution.  The full text of the license may be found at        \r
+http://opensource.org/licenses/bsd-license.php                                            \r
+                                                                                          \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+\r
+Module Name:\r
+\r
+  DevicePathUtilities.h\r
+\r
+Abstract:\r
+\r
+--*/\r
+\r
+#ifndef _DEVICE_PATH_UTILITIES_PROTOCOL_H_\r
+#define _DEVICE_PATH_UTILITIES_PROTOCOL_H_\r
+\r
+//\r
+// Device Path Utilities protocol\r
+//\r
+#define EFI_DEVICE_PATH_UTILITIES_PROTOCOL_GUID \\r
+  { \\r
+    0x379be4e, 0xd706, 0x437d, {0xb0, 0x37, 0xed, 0xb8, 0x2f, 0xb7, 0x72, 0xa4}  \\r
+  }\r
+\r
+typedef\r
+UINTN\r
+EFIAPI\r
+(EFIAPI *EFI_DEVICE_PATH_UTILS_GET_DEVICE_PATH_SIZE) (\r
+  IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Returns the size of the device path, in bytes.\r
+\r
+  Arguments:\r
+    DevicePath  -   Points to the start of the EFI device path.\r
+\r
+  Returns:\r
+    Size        -   Size of the specified device path, in bytes, including the end-of-path tag.\r
+\r
+--*/\r
+;\r
+\r
+typedef\r
+EFI_DEVICE_PATH_PROTOCOL*\r
+EFIAPI\r
+(EFIAPI *EFI_DEVICE_PATH_UTILS_DUP_DEVICE_PATH) (\r
+  IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Create a duplicate of the specified path.\r
+\r
+  Arguments:\r
+    DevicePath  -   Points to the source EFI device path.\r
+\r
+  Returns:\r
+    Pointer     -   A pointer to the duplicate device path.\r
+    NULL        -   Insufficient memory.\r
+\r
+--*/\r
+;\r
+\r
+typedef\r
+EFI_DEVICE_PATH_PROTOCOL*\r
+EFIAPI\r
+(EFIAPI *EFI_DEVICE_PATH_UTILS_APPEND_PATH) (\r
+  IN CONST EFI_DEVICE_PATH_PROTOCOL *Src1,\r
+  IN CONST EFI_DEVICE_PATH_PROTOCOL *Src2\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Create a new path by appending the second device path to the first.\r
+\r
+  Arguments:\r
+    Src1      -   Points to the first device path. If NULL, then it is ignored.\r
+    Src2      -   Points to the second device path. If NULL, then it is ignored.\r
+\r
+  Returns:\r
+    Pointer   -   A pointer to the newly created device path.\r
+    NULL      -   Memory could not be allocated\r
+                  or either DevicePath or DeviceNode is NULL.\r
+\r
+--*/\r
+;\r
+\r
+typedef\r
+EFI_DEVICE_PATH_PROTOCOL*\r
+EFIAPI\r
+(EFIAPI *EFI_DEVICE_PATH_UTILS_APPEND_NODE) (\r
+  IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
+  IN CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Creates a new path by appending the device node to the device path.\r
+\r
+  Arguments:\r
+    DevicePath   -   Points to the device path.\r
+    DeviceNode   -   Points to the device node.\r
+\r
+  Returns:\r
+    Pointer      -   A pointer to the allocated device node.\r
+    NULL         -   Memory could not be allocated\r
+                     or either DevicePath or DeviceNode is NULL.\r
+\r
+--*/\r
+;\r
+\r
+typedef\r
+EFI_DEVICE_PATH_PROTOCOL*\r
+EFIAPI\r
+(EFIAPI *EFI_DEVICE_PATH_UTILS_APPEND_INSTANCE) (\r
+  IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
+  IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Creates a new path by appending the specified device path instance to the specified device path.\r
+\r
+  Arguments:\r
+    DevicePath           -   Points to the device path. If NULL, then ignored.\r
+    DevicePathInstance   -   Points to the device path instance.\r
+\r
+  Returns:\r
+    Pointer              -   A pointer to the newly created device path\r
+    NULL                 -   Memory could not be allocated or DevicePathInstance is NULL.\r
+\r
+--*/\r
+;\r
+\r
+typedef\r
+EFI_DEVICE_PATH_PROTOCOL*\r
+EFIAPI\r
+(EFIAPI *EFI_DEVICE_PATH_UTILS_GET_NEXT_INSTANCE) (\r
+  IN  OUT EFI_DEVICE_PATH_PROTOCOL  **DevicePathInstance,\r
+  OUT UINTN                         *DevicePathInstanceSize\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Creates a copy of the current device path instance and returns a pointer to the next device path instance.\r
+\r
+  Arguments:\r
+    DevicePathInstance       -   On input, this holds the pointer to the current device path\r
+                                 instance. On output, this holds the pointer to the next\r
+                                 device path instance or NULL if there are no more device\r
+                                 path instances in the device path.\r
+    DevicePathInstanceSize   -   On output, this holds the size of the device path instance,\r
+                                 in bytes or zero, if DevicePathInstance is zero.\r
+\r
+  Returns:\r
+    Pointer                  -   A pointer to the copy of the current device path instance.\r
+    NULL                     -   DevicePathInstace was NULL on entry or there was insufficient memory.\r
+\r
+--*/\r
+;\r
+\r
+typedef\r
+BOOLEAN\r
+EFIAPI\r
+(EFIAPI *EFI_DEVICE_PATH_UTILS_IS_MULTI_INSTANCE) (\r
+  IN CONST EFI_DEVICE_PATH_PROTOCOL         *DevicePath\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Returns whether a device path is multi-instance.\r
+\r
+  Arguments:\r
+    DevicePath  -   Points to the device path. If NULL, then ignored.\r
+\r
+  Returns:\r
+    TRUE        -   The device path has more than one instance\r
+    FALSE       -   The device path is empty or contains only a single instance.\r
+\r
+--*/\r
+;\r
+\r
+typedef\r
+EFI_DEVICE_PATH_PROTOCOL*\r
+EFIAPI\r
+(EFIAPI *EFI_DEVICE_PATH_UTILS_CREATE_NODE) (\r
+  IN UINT8                          NodeType,\r
+  IN UINT8                          NodeSubType,\r
+  IN UINT16                         NodeLength\r
+  )\r
+/*++\r
+\r
+  Routine Description:\r
+    Creates a device node\r
+\r
+  Arguments:\r
+    NodeType     -    NodeType is the device node type (EFI_DEVICE_PATH.Type) for\r
+                      the new device node.\r
+    NodeSubType  -    NodeSubType is the device node sub-type\r
+                      EFI_DEVICE_PATH.SubType) for the new device node.\r
+    NodeLength   -    NodeLength is the length of the device node\r
+                      (EFI_DEVICE_PATH.Length) for the new device node.\r
+\r
+  Returns:\r
+    Pointer      -    A pointer to the newly created device node.\r
+    NULL         -    NodeLength is less than\r
+                      the size of the header or there was insufficient memory.\r
+\r
+--*/\r
+;\r
+\r
+typedef struct {\r
+  EFI_DEVICE_PATH_UTILS_GET_DEVICE_PATH_SIZE GetDevicePathSize;\r
+  EFI_DEVICE_PATH_UTILS_DUP_DEVICE_PATH      DuplicateDevicePath;\r
+  EFI_DEVICE_PATH_UTILS_APPEND_PATH          AppendDevicePath;\r
+  EFI_DEVICE_PATH_UTILS_APPEND_NODE          AppendDeviceNode;\r
+  EFI_DEVICE_PATH_UTILS_APPEND_INSTANCE      AppendDevicePathInstance;\r
+  EFI_DEVICE_PATH_UTILS_GET_NEXT_INSTANCE    GetNextDevicePathInstance;\r
+  EFI_DEVICE_PATH_UTILS_IS_MULTI_INSTANCE    IsDevicePathMultiInstance;\r
+  EFI_DEVICE_PATH_UTILS_CREATE_NODE          CreateDeviceNode;\r
+} EFI_DEVICE_PATH_UTILITIES_PROTOCOL;\r
+\r
+extern EFI_GUID gEfiDevicePathUtilitiesProtocolGuid;\r
+\r
+#endif\r
diff --git a/EfiLib/LegacyBios.h b/EfiLib/LegacyBios.h
new file mode 100644 (file)
index 0000000..88f5980
--- /dev/null
@@ -0,0 +1,1498 @@
+/** @file\r
+  The EFI Legacy BIOS Protocol is used to abstract legacy Option ROM usage\r
+  under EFI and Legacy OS boot.  This file also includes all the related\r
+  COMPATIBILIY16 structures and defintions.\r
+\r
+  Note: The names for EFI_IA32_REGISTER_SET elements were picked to follow\r
+  well known naming conventions.\r
+\r
+  Thunk is the code that switches from 32-bit protected environment into the 16-bit real-mode\r
+       environment. Reverse thunk is the code that does the opposite.\r
+\r
+Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials are licensed and made available under \r
+the terms and conditions of the BSD License that accompanies this distribution.  \r
+The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php.                                          \r
+    \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+  @par Revision Reference:\r
+  This protocol is defined in Framework for EFI Compatibility Support Module spec\r
+  Version 0.97.\r
+\r
+**/\r
+\r
+#ifndef _EFI_LEGACY_BIOS_H_\r
+#define _EFI_LEGACY_BIOS_H_\r
+\r
+///\r
+/// \r
+///\r
+#pragma pack(1)\r
+\r
+typedef UINT8                       SERIAL_MODE;\r
+typedef UINT8                       PARALLEL_MODE;\r
+\r
+#define EFI_COMPATIBILITY16_TABLE_SIGNATURE SIGNATURE_32 ('I', 'F', 'E', '$')\r
+\r
+///\r
+/// There is a table located within the traditional BIOS in either the 0xF000:xxxx or 0xE000:xxxx\r
+/// physical address range. It is located on a 16-byte boundary and provides the physical address of the\r
+/// entry point for the Compatibility16 functions. These functions provide the platform-specific\r
+/// information that is required by the generic EfiCompatibility code. The functions are invoked via\r
+/// thunking by using EFI_LEGACY_BIOS_PROTOCOL.FarCall86() with the 32-bit physical\r
+/// entry point.\r
+///\r
+typedef struct {\r
+  ///\r
+  /// The string "$EFI" denotes the start of the EfiCompatibility table. Byte 0 is "I," byte\r
+  /// 1 is "F," byte 2 is "E," and byte 3 is "$" and is normally accessed as a DWORD or UINT32.\r
+  ///\r
+  UINT32                            Signature;\r
+  \r
+  ///\r
+  /// The value required such that byte checksum of TableLength equals zero.\r
+  ///\r
+  UINT8                             TableChecksum;\r
+  \r
+  ///\r
+  /// The length of this table.\r
+  ///\r
+  UINT8                             TableLength;\r
+  \r
+  ///\r
+  /// The major EFI revision for which this table was generated.\r
+  /// \r
+  UINT8                             EfiMajorRevision;\r
+  \r
+  ///\r
+  /// The minor EFI revision for which this table was generated.\r
+  ///\r
+  UINT8                             EfiMinorRevision;\r
+  \r
+  ///\r
+  /// The major revision of this table.\r
+  ///\r
+  UINT8                             TableMajorRevision;\r
+  \r
+  ///\r
+  /// The minor revision of this table.\r
+  ///\r
+  UINT8                             TableMinorRevision;\r
+  \r
+  ///\r
+  /// Reserved for future usage.\r
+  ///\r
+  UINT16                            Reserved;\r
+  \r
+  ///\r
+  /// The segment of the entry point within the traditional BIOS for Compatibility16 functions.\r
+  ///\r
+  UINT16                            Compatibility16CallSegment;\r
+  \r
+  ///\r
+  /// The offset of the entry point within the traditional BIOS for Compatibility16 functions.\r
+  ///\r
+  UINT16                            Compatibility16CallOffset;\r
+  \r
+  ///\r
+  /// The segment of the entry point within the traditional BIOS for EfiCompatibility \r
+  /// to invoke the PnP installation check.\r
+  ///\r
+  UINT16                            PnPInstallationCheckSegment;\r
+  \r
+  ///\r
+  /// The Offset of the entry point within the traditional BIOS for EfiCompatibility \r
+  /// to invoke the PnP installation check.\r
+  ///\r
+  UINT16                            PnPInstallationCheckOffset;\r
+  \r
+  ///\r
+  /// EFI system resources table. Type EFI_SYSTEM_TABLE is defined in the IntelPlatform \r
+  ///Innovation Framework for EFI Driver Execution Environment Core Interface Specification (DXE CIS).\r
+  ///\r
+  UINT32                            EfiSystemTable; \r
+  \r
+  ///\r
+  /// The address of an OEM-provided identifier string. The string is null terminated.\r
+  ///\r
+  UINT32                            OemIdStringPointer;\r
+  \r
+  ///\r
+  /// The 32-bit physical address where ACPI RSD PTR is stored within the traditional\r
+  /// BIOS. The remained of the ACPI tables are located at their EFI addresses. The size\r
+  /// reserved is the maximum for ACPI 2.0. The EfiCompatibility will fill in the ACPI\r
+  /// RSD PTR with either the ACPI 1.0b or 2.0 values.\r
+  ///\r
+  UINT32                            AcpiRsdPtrPointer;\r
+  \r
+  ///\r
+  /// The OEM revision number. Usage is undefined but provided for OEM module usage.\r
+  ///\r
+  UINT16                            OemRevision;\r
+  \r
+  ///\r
+  /// The 32-bit physical address where INT15 E820 data is stored within the traditional\r
+  /// BIOS. The EfiCompatibility code will fill in the E820Pointer value and copy the\r
+  /// data to the indicated area.\r
+  ///\r
+  UINT32                            E820Pointer;\r
+  \r
+  ///\r
+  /// The length of the E820 data and is filled in by the EfiCompatibility code.\r
+  ///\r
+  UINT32                            E820Length;\r
+  \r
+  ///\r
+  /// The 32-bit physical address where the $PIR table is stored in the traditional BIOS.\r
+  /// The EfiCompatibility code will fill in the IrqRoutingTablePointer value and\r
+  /// copy the data to the indicated area.\r
+  ///\r
+  UINT32                            IrqRoutingTablePointer;\r
+  \r
+  ///\r
+  /// The length of the $PIR table and is filled in by the EfiCompatibility code.\r
+  ///\r
+  UINT32                            IrqRoutingTableLength;\r
+  \r
+  ///\r
+  /// The 32-bit physical address where the MP table is stored in the traditional BIOS.\r
+  /// The EfiCompatibility code will fill in the MpTablePtr value and copy the data \r
+  /// to the indicated area.\r
+  ///\r
+  UINT32                            MpTablePtr;\r
+  \r
+  ///\r
+  /// The length of the MP table and is filled in by the EfiCompatibility code.\r
+  ///\r
+  UINT32                            MpTableLength;\r
+  \r
+  ///\r
+  /// The segment of the OEM-specific INT table/code.\r
+  /// \r
+  UINT16                            OemIntSegment;\r
+  \r
+  ///\r
+  /// The offset of the OEM-specific INT table/code.\r
+  ///\r
+  UINT16                            OemIntOffset;\r
+  \r
+  ///\r
+  /// The segment of the OEM-specific 32-bit table/code.\r
+  ///\r
+  UINT16                            Oem32Segment;\r
+  \r
+  ///\r
+  /// The offset of the OEM-specific 32-bit table/code.\r
+  ///\r
+  UINT16                            Oem32Offset;\r
+  \r
+  ///\r
+  /// The segment of the OEM-specific 16-bit table/code.\r
+  ///\r
+  UINT16                            Oem16Segment;\r
+  \r
+  ///\r
+  /// The offset of the OEM-specific 16-bit table/code.\r
+  ///\r
+  UINT16                            Oem16Offset;\r
+  \r
+  ///\r
+  /// The segment of the TPM binary passed to 16-bit CSM.\r
+  ///\r
+  UINT16                            TpmSegment;\r
+  \r
+  ///\r
+  /// The offset of the TPM binary passed to 16-bit CSM.\r
+  ///\r
+  UINT16                            TpmOffset;\r
+  \r
+  ///\r
+  /// A pointer to a string identifying the independent BIOS vendor.\r
+  ///\r
+  UINT32                            IbvPointer;\r
+  \r
+  ///\r
+  /// This field is NULL for all systems not supporting PCI Express. This field is the base\r
+  /// value of the start of the PCI Express memory-mapped configuration registers and\r
+  /// must be filled in prior to EfiCompatibility code issuing the Compatibility16 function\r
+  /// Compatibility16InitializeYourself().\r
+  /// Compatibility16InitializeYourself() is defined in Compatability16\r
+  /// Functions.\r
+  ///\r
+  UINT32                            PciExpressBase;\r
+  \r
+  ///\r
+  /// Maximum PCI bus number assigned.\r
+  ///\r
+  UINT8                             LastPciBus;\r
+} EFI_COMPATIBILITY16_TABLE;\r
+\r
+///\r
+/// Functions provided by the CSM binary which communicate between the EfiCompatibility \r
+/// and Compatability16 code.\r
+///\r
+/// Inconsistent with the specification here: \r
+/// The member's name started with "Compatibility16" [defined in Intel Framework \r
+/// Compatibility Support Module Specification / 0.97 version] \r
+/// has been changed to "Legacy16" since keeping backward compatible.\r
+///\r
+typedef enum {\r
+  ///\r
+  /// Causes the Compatibility16 code to do any internal initialization required.\r
+  /// Input:\r
+  ///   AX = Compatibility16InitializeYourself\r
+  ///   ES:BX = Pointer to EFI_TO_COMPATIBILITY16_INIT_TABLE\r
+  /// Return:\r
+  ///   AX = Return Status codes\r
+  ///\r
+  Legacy16InitializeYourself    = 0x0000,\r
+  \r
+  ///\r
+  /// Causes the Compatibility16 BIOS to perform any drive number translations to match the boot sequence.\r
+  /// Input:\r
+  ///   AX = Compatibility16UpdateBbs\r
+  ///   ES:BX = Pointer to EFI_TO_COMPATIBILITY16_BOOT_TABLE\r
+  /// Return:\r
+  ///   AX = Returned status codes\r
+  ///\r
+  Legacy16UpdateBbs             = 0x0001,\r
+  \r
+  ///\r
+  /// Allows the Compatibility16 code to perform any final actions before booting. The Compatibility16\r
+  /// code is read/write.\r
+  /// Input:\r
+  ///   AX = Compatibility16PrepareToBoot\r
+  ///   ES:BX = Pointer to EFI_TO_COMPATIBILITY16_BOOT_TABLE structure  \r
+  /// Return:\r
+  ///   AX = Returned status codes\r
+  ///\r
+  Legacy16PrepareToBoot         = 0x0002,\r
+  \r
+  ///\r
+  /// Causes the Compatibility16 BIOS to boot. The Compatibility16 code is Read/Only.\r
+  /// Input:\r
+  ///   AX = Compatibility16Boot\r
+  /// Output:\r
+  ///   AX = Returned status codes\r
+  ///\r
+  Legacy16Boot                  = 0x0003,\r
+  \r
+  ///\r
+  /// Allows the Compatibility16 code to get the last device from which a boot was attempted. This is\r
+  /// stored in CMOS and is the priority number of the last attempted boot device.\r
+  /// Input:\r
+  ///   AX = Compatibility16RetrieveLastBootDevice\r
+  /// Output:\r
+  ///   AX = Returned status codes\r
+  ///   BX = Priority number of the boot device.\r
+  ///\r
+  Legacy16RetrieveLastBootDevice = 0x0004,\r
+  \r
+  ///\r
+  /// Allows the Compatibility16 code rehook INT13, INT18, and/or INT19 after dispatching a legacy OpROM.\r
+  /// Input:\r
+  ///   AX = Compatibility16DispatchOprom\r
+  ///   ES:BX = Pointer to EFI_DISPATCH_OPROM_TABLE\r
+  /// Output:\r
+  ///   AX = Returned status codes\r
+  ///   BX = Number of non-BBS-compliant devices found. Equals 0 if BBS compliant.\r
+  ///\r
+  Legacy16DispatchOprom         = 0x0005,\r
+  \r
+  ///\r
+  /// Finds a free area in the 0xFxxxx or 0xExxxx region of the specified length and returns the address\r
+  /// of that region.\r
+  /// Input:\r
+  ///   AX = Compatibility16GetTableAddress\r
+  ///   BX = Allocation region\r
+  ///       00 = Allocate from either 0xE0000 or 0xF0000 64 KB blocks.\r
+  ///       Bit 0 = 1 Allocate from 0xF0000 64 KB block\r
+  ///       Bit 1 = 1 Allocate from 0xE0000 64 KB block\r
+  ///   CX = Requested length in bytes.\r
+  ///   DX = Required address alignment. Bit mapped. First non-zero bit from the right is the alignment.\r
+  /// Output:\r
+  ///   AX = Returned status codes\r
+  ///   DS:BX = Address of the region\r
+  ///\r
+  Legacy16GetTableAddress       = 0x0006,\r
+  \r
+  ///\r
+  /// Enables the EfiCompatibility module to do any nonstandard processing of keyboard LEDs or state.\r
+  /// Input:\r
+  ///   AX = Compatibility16SetKeyboardLeds\r
+  ///   CL = LED status.\r
+  ///     Bit 0  Scroll Lock 0 = Off\r
+  ///     Bit 1  NumLock\r
+  ///     Bit 2  Caps Lock\r
+  /// Output:\r
+  ///     AX = Returned status codes\r
+  ///\r
+  Legacy16SetKeyboardLeds       = 0x0007,\r
+  \r
+  ///\r
+  /// Enables the EfiCompatibility module to install an interrupt handler for PCI mass media devices that\r
+  /// do not have an OpROM associated with them. An example is SATA.\r
+  /// Input:\r
+  ///   AX = Compatibility16InstallPciHandler\r
+  ///   ES:BX = Pointer to EFI_LEGACY_INSTALL_PCI_HANDLER structure\r
+  /// Output:\r
+  ///   AX = Returned status codes\r
+  ///\r
+  Legacy16InstallPciHandler     = 0x0008\r
+} EFI_COMPATIBILITY_FUNCTIONS;\r
+\r
+\r
+///\r
+/// EFI_DISPATCH_OPROM_TABLE\r
+///\r
+typedef struct {\r
+  UINT16  PnPInstallationCheckSegment;  ///< A pointer to the PnpInstallationCheck data structure.\r
+  UINT16  PnPInstallationCheckOffset;   ///< A pointer to the PnpInstallationCheck data structure.\r
+  UINT16  OpromSegment;                 ///< The segment where the OpROM was placed. Offset is assumed to be 3.\r
+  UINT8   PciBus;                       ///< The PCI bus.\r
+  UINT8   PciDeviceFunction;            ///< The PCI device * 0x08 | PCI function.\r
+  UINT8   NumberBbsEntries;             ///< The number of valid BBS table entries upon entry and exit. The IBV code may\r
+                                        ///< increase this number, if BBS-compliant devices also hook INTs in order to force the\r
+                                        ///< OpROM BIOS Setup to be executed.\r
+  UINT32  BbsTablePointer;              ///< A pointer to the BBS table.\r
+  UINT16  RuntimeSegment;               ///< The segment where the OpROM can be relocated to. If this value is 0x0000, this\r
+                                        ///< means that the relocation of this run time code is not supported.\r
+                                        ///< Inconsistent with specification here: \r
+                                        ///< The member's name "OpromDestinationSegment" [defined in Intel Framework Compatibility Support Module Specification / 0.97 version] \r
+                                        ///< has been changed to "RuntimeSegment" since keeping backward compatible.\r
+\r
+} EFI_DISPATCH_OPROM_TABLE;\r
+\r
+///\r
+/// EFI_TO_COMPATIBILITY16_INIT_TABLE\r
+///\r
+typedef struct {\r
+  ///\r
+  /// Starting address of memory under 1 MB. The ending address is assumed to be 640 KB or 0x9FFFF.\r
+  ///\r
+  UINT32                            BiosLessThan1MB;\r
+  \r
+  ///\r
+  /// The starting address of the high memory block.\r
+  ///\r
+  UINT32                            HiPmmMemory;\r
+  \r
+  ///\r
+  /// The length of high memory block.\r
+  ///\r
+  UINT32                            HiPmmMemorySizeInBytes;\r
+  \r
+  ///\r
+  /// The segment of the reverse thunk call code.\r
+  ///\r
+  UINT16                            ReverseThunkCallSegment;\r
+  \r
+  ///\r
+  /// The offset of the reverse thunk call code.\r
+  ///\r
+  UINT16                            ReverseThunkCallOffset;\r
+  \r
+  ///\r
+  /// The number of E820 entries copied to the Compatibility16 BIOS.\r
+  ///\r
+  UINT32                            NumberE820Entries;\r
+  \r
+  ///\r
+  /// The amount of usable memory above 1 MB, e.g., E820 type 1 memory.\r
+  ///\r
+  UINT32                            OsMemoryAbove1Mb;\r
+  \r
+  ///\r
+  /// The start of thunk code in main memory. Memory cannot be used by BIOS or PMM.\r
+  ///\r
+  UINT32                            ThunkStart;\r
+  \r
+  ///\r
+  /// The size of the thunk code.\r
+  ///\r
+  UINT32                            ThunkSizeInBytes;\r
+  \r
+  ///\r
+  /// Starting address of memory under 1 MB.\r
+  ///\r
+  UINT32                            LowPmmMemory;\r
+  \r
+  ///\r
+  /// The length of low Memory block.\r
+  ///\r
+  UINT32                            LowPmmMemorySizeInBytes;\r
+} EFI_TO_COMPATIBILITY16_INIT_TABLE;\r
+\r
+///\r
+/// DEVICE_PRODUCER_SERIAL.\r
+///\r
+typedef struct {\r
+  UINT16                            Address;    ///< I/O address assigned to the serial port.\r
+  UINT8                             Irq;        ///< IRQ assigned to the serial port.\r
+  SERIAL_MODE                       Mode;       ///< Mode of serial port. Values are defined below.\r
+} DEVICE_PRODUCER_SERIAL;\r
+\r
+///\r
+/// DEVICE_PRODUCER_SERIAL's modes.\r
+///@{\r
+#define DEVICE_SERIAL_MODE_NORMAL               0x00\r
+#define DEVICE_SERIAL_MODE_IRDA                 0x01\r
+#define DEVICE_SERIAL_MODE_ASK_IR               0x02\r
+#define DEVICE_SERIAL_MODE_DUPLEX_HALF          0x00\r
+#define DEVICE_SERIAL_MODE_DUPLEX_FULL          0x10\r
+///@)\r
+\r
+///\r
+/// DEVICE_PRODUCER_PARALLEL.\r
+///\r
+typedef struct {\r
+  UINT16                            Address;  ///< I/O address assigned to the parallel port.\r
+  UINT8                             Irq;      ///< IRQ assigned to the parallel port.\r
+  UINT8                             Dma;      ///< DMA assigned to the parallel port.\r
+  PARALLEL_MODE                     Mode;     ///< Mode of the parallel port. Values are defined below.\r
+} DEVICE_PRODUCER_PARALLEL;\r
+\r
+///\r
+/// DEVICE_PRODUCER_PARALLEL's modes.\r
+///@{\r
+#define DEVICE_PARALLEL_MODE_MODE_OUTPUT_ONLY   0x00\r
+#define DEVICE_PARALLEL_MODE_MODE_BIDIRECTIONAL 0x01\r
+#define DEVICE_PARALLEL_MODE_MODE_EPP           0x02\r
+#define DEVICE_PARALLEL_MODE_MODE_ECP           0x03\r
+///@}\r
+\r
+///\r
+/// DEVICE_PRODUCER_FLOPPY\r
+///\r
+typedef struct {\r
+  UINT16                            Address;          ///< I/O address assigned to the floppy.\r
+  UINT8                             Irq;              ///< IRQ assigned to the floppy.\r
+  UINT8                             Dma;              ///< DMA assigned to the floppy.\r
+  UINT8                             NumberOfFloppy;   ///< Number of floppies in the system.\r
+} DEVICE_PRODUCER_FLOPPY;\r
+\r
+///\r
+/// LEGACY_DEVICE_FLAGS\r
+///\r
+typedef struct {\r
+  UINT32                            A20Kybd : 1;      ///< A20 controller by keyboard controller.\r
+  UINT32                            A20Port90 : 1;    ///< A20 controlled by port 0x92.\r
+  UINT32                            Reserved : 30;    ///< Reserved for future usage.\r
+} LEGACY_DEVICE_FLAGS;\r
+\r
+///\r
+/// DEVICE_PRODUCER_DATA_HEADER\r
+///\r
+typedef struct {\r
+  DEVICE_PRODUCER_SERIAL            Serial[4];      ///< Data for serial port x. Type DEVICE_PRODUCER_SERIAL is defined below.\r
+  DEVICE_PRODUCER_PARALLEL          Parallel[3];    ///< Data for parallel port x. Type DEVICE_PRODUCER_PARALLEL is defined below.\r
+  DEVICE_PRODUCER_FLOPPY            Floppy;         ///< Data for floppy. Type DEVICE_PRODUCER_FLOPPY is defined below.\r
+  UINT8                             MousePresent;   ///< Flag to indicate if mouse is present.\r
+  LEGACY_DEVICE_FLAGS               Flags;          ///< Miscellaneous Boolean state information passed to CSM.\r
+} DEVICE_PRODUCER_DATA_HEADER;\r
+\r
+///\r
+/// ATAPI_IDENTIFY\r
+///\r
+typedef struct {\r
+  UINT16                            Raw[256];     ///< Raw data from the IDE IdentifyDrive command.\r
+} ATAPI_IDENTIFY;\r
+\r
+///\r
+/// HDD_INFO\r
+///\r
+typedef struct {\r
+  ///\r
+  /// Status of IDE device. Values are defined below. There is one HDD_INFO structure\r
+  /// per IDE controller. The IdentifyDrive is per drive. Index 0 is master and index\r
+  /// 1 is slave.\r
+  ///\r
+  UINT16                            Status;   \r
+  \r
+  ///\r
+  /// PCI bus of IDE controller.\r
+  ///\r
+  UINT32                            Bus;\r
+  \r
+  ///\r
+  /// PCI device of IDE controller.\r
+  ///\r
+  UINT32                            Device;\r
+  \r
+  ///\r
+  /// PCI function of IDE controller.\r
+  ///\r
+  UINT32                            Function;\r
+  \r
+  ///\r
+  /// Command ports base address.\r
+  ///\r
+  UINT16                            CommandBaseAddress;\r
+  \r
+  ///\r
+  /// Control ports base address.\r
+  ///\r
+  UINT16                            ControlBaseAddress;\r
+  \r
+  ///\r
+  /// Bus master address.\r
+  ///\r
+  UINT16                            BusMasterAddress;\r
+  \r
+  UINT8                             HddIrq;\r
+  \r
+  ///\r
+  /// Data that identifies the drive data; one per possible attached drive.\r
+  ///\r
+  ATAPI_IDENTIFY                    IdentifyDrive[2];\r
+} HDD_INFO;\r
+\r
+///\r
+/// HDD_INFO status bits\r
+///\r
+#define HDD_PRIMARY               0x01\r
+#define HDD_SECONDARY             0x02\r
+#define HDD_MASTER_ATAPI_CDROM    0x04\r
+#define HDD_SLAVE_ATAPI_CDROM     0x08\r
+#define HDD_MASTER_IDE            0x20\r
+#define HDD_SLAVE_IDE             0x40\r
+#define HDD_MASTER_ATAPI_ZIPDISK  0x10\r
+#define HDD_SLAVE_ATAPI_ZIPDISK   0x80\r
+\r
+///\r
+/// BBS_STATUS_FLAGS;\.\r
+///\r
+typedef struct {\r
+  UINT16                            OldPosition : 4;    ///< Prior priority.\r
+  UINT16                            Reserved1 : 4;      ///< Reserved for future use.\r
+  UINT16                            Enabled : 1;        ///< If 0, ignore this entry.\r
+  UINT16                            Failed : 1;         ///< 0 = Not known if boot failure occurred.\r
+                                                        ///< 1 = Boot attempted failed.\r
+  \r
+  ///\r
+  /// State of media present.\r
+  ///   00 = No bootable media is present in the device.\r
+  ///   01 = Unknown if a bootable media present.\r
+  ///   10 = Media is present and appears bootable.\r
+  ///   11 = Reserved.\r
+  ///\r
+  UINT16                            MediaPresent : 2;\r
+  UINT16                            Reserved2 : 4;      ///< Reserved for future use.\r
+} BBS_STATUS_FLAGS;\r
+\r
+///\r
+/// BBS_TABLE, device type values & boot priority values.\r
+///\r
+typedef struct {\r
+  ///\r
+  /// The boot priority for this boot device. Values are defined below.\r
+  ///\r
+  UINT16                            BootPriority;\r
+  \r
+  ///\r
+  /// The PCI bus for this boot device.\r
+  ///\r
+  UINT32                            Bus;\r
+  \r
+  ///\r
+  /// The PCI device for this boot device.\r
+  ///\r
+  UINT32                            Device;\r
+  \r
+  ///\r
+  /// The PCI function for the boot device.\r
+  ///\r
+  UINT32                            Function;\r
+  \r
+  ///\r
+  /// The PCI class for this boot device.\r
+  ///\r
+  UINT8                             Class;\r
+  \r
+  ///\r
+  /// The PCI Subclass for this boot device.\r
+  ///\r
+  UINT8                             SubClass;\r
+  \r
+  ///\r
+  /// Segment:offset address of an ASCIIZ description string describing the manufacturer.\r
+  ///\r
+  UINT16                            MfgStringOffset;\r
+  \r
+  ///\r
+  /// Segment:offset address of an ASCIIZ description string describing the manufacturer.\r
+  ///  \r
+  UINT16                            MfgStringSegment;\r
+  \r
+  ///\r
+  /// BBS device type. BBS device types are defined below.\r
+  ///\r
+  UINT16                            DeviceType;\r
+  \r
+  ///\r
+  /// Status of this boot device. Type BBS_STATUS_FLAGS is defined below.\r
+  ///\r
+  BBS_STATUS_FLAGS                  StatusFlags;\r
+  \r
+  ///\r
+  /// Segment:Offset address of boot loader for IPL devices or install INT13 handler for\r
+  /// BCV devices.\r
+  ///\r
+  UINT16                            BootHandlerOffset;\r
+  \r
+  ///\r
+  /// Segment:Offset address of boot loader for IPL devices or install INT13 handler for\r
+  /// BCV devices.\r
+  ///  \r
+  UINT16                            BootHandlerSegment;\r
+  \r
+  ///\r
+  /// Segment:offset address of an ASCIIZ description string describing this device.\r
+  ///\r
+  UINT16                            DescStringOffset;\r
+\r
+  ///\r
+  /// Segment:offset address of an ASCIIZ description string describing this device.\r
+  ///\r
+  UINT16                            DescStringSegment;\r
+  \r
+  ///\r
+  /// Reserved.\r
+  ///\r
+  UINT32                            InitPerReserved;\r
+  \r
+  ///\r
+  /// The use of these fields is IBV dependent. They can be used to flag that an OpROM\r
+  /// has hooked the specified IRQ. The OpROM may be BBS compliant as some SCSI\r
+  /// BBS-compliant OpROMs also hook IRQ vectors in order to run their BIOS Setup\r
+  ///\r
+  UINT32                            AdditionalIrq13Handler;\r
+  \r
+  ///\r
+  /// The use of these fields is IBV dependent. They can be used to flag that an OpROM\r
+  /// has hooked the specified IRQ. The OpROM may be BBS compliant as some SCSI\r
+  /// BBS-compliant OpROMs also hook IRQ vectors in order to run their BIOS Setup\r
+  ///  \r
+  UINT32                            AdditionalIrq18Handler;\r
+  \r
+  ///\r
+  /// The use of these fields is IBV dependent. They can be used to flag that an OpROM\r
+  /// has hooked the specified IRQ. The OpROM may be BBS compliant as some SCSI\r
+  /// BBS-compliant OpROMs also hook IRQ vectors in order to run their BIOS Setup\r
+  ///  \r
+  UINT32                            AdditionalIrq19Handler;\r
+  \r
+  ///\r
+  /// The use of these fields is IBV dependent. They can be used to flag that an OpROM\r
+  /// has hooked the specified IRQ. The OpROM may be BBS compliant as some SCSI\r
+  /// BBS-compliant OpROMs also hook IRQ vectors in order to run their BIOS Setup\r
+  ///  \r
+  UINT32                            AdditionalIrq40Handler;\r
+  UINT8                             AssignedDriveNumber;\r
+  UINT32                            AdditionalIrq41Handler;\r
+  UINT32                            AdditionalIrq46Handler;\r
+  UINT32                            IBV1;\r
+  UINT32                            IBV2;\r
+} BBS_TABLE;\r
+\r
+///\r
+/// BBS device type values\r
+///@{\r
+#define BBS_FLOPPY              0x01\r
+#define BBS_HARDDISK            0x02\r
+#define BBS_CDROM               0x03\r
+#define BBS_PCMCIA              0x04\r
+#define BBS_USB                 0x05\r
+#define BBS_EMBED_NETWORK       0x06\r
+#define BBS_BEV_DEVICE          0x80\r
+#define BBS_UNKNOWN             0xff\r
+///@}\r
+\r
+///\r
+/// BBS boot priority values\r
+///@{\r
+#define BBS_DO_NOT_BOOT_FROM    0xFFFC\r
+#define BBS_LOWEST_PRIORITY     0xFFFD\r
+#define BBS_UNPRIORITIZED_ENTRY 0xFFFE\r
+#define BBS_IGNORE_ENTRY        0xFFFF\r
+///@}\r
+\r
+///\r
+/// SMM_ATTRIBUTES\r
+///\r
+typedef struct {\r
+  ///\r
+  /// Access mechanism used to generate the soft SMI. Defined types are below. The other\r
+  /// values are reserved for future usage.\r
+  ///\r
+  UINT16                            Type : 3;\r
+  \r
+  ///\r
+  /// The size of "port" in bits. Defined values are below.\r
+  ///\r
+  UINT16                            PortGranularity : 3;\r
+  \r
+  ///\r
+  /// The size of data in bits. Defined values are below.\r
+  ///\r
+  UINT16                            DataGranularity : 3;\r
+  \r
+  ///\r
+  /// Reserved for future use.\r
+  ///\r
+  UINT16                            Reserved : 7;\r
+} SMM_ATTRIBUTES;\r
+\r
+///\r
+/// SMM_ATTRIBUTES type values.\r
+///@{\r
+#define STANDARD_IO       0x00\r
+#define STANDARD_MEMORY   0x01\r
+///@}\r
+\r
+///\r
+/// SMM_ATTRIBUTES port size constants.\r
+///@{\r
+#define PORT_SIZE_8       0x00\r
+#define PORT_SIZE_16      0x01\r
+#define PORT_SIZE_32      0x02\r
+#define PORT_SIZE_64      0x03\r
+///@}\r
+\r
+///\r
+/// SMM_ATTRIBUTES data size constants.\r
+///@{\r
+#define DATA_SIZE_8       0x00\r
+#define DATA_SIZE_16      0x01\r
+#define DATA_SIZE_32      0x02\r
+#define DATA_SIZE_64      0x03\r
+///@}\r
+\r
+///\r
+/// SMM_FUNCTION & relating constants.\r
+///\r
+typedef struct {\r
+  UINT16                            Function : 15;\r
+  UINT16                            Owner : 1;\r
+} SMM_FUNCTION;\r
+\r
+///\r
+/// SMM_FUNCTION Function constants.\r
+///@{\r
+#define INT15_D042        0x0000\r
+#define GET_USB_BOOT_INFO 0x0001\r
+#define DMI_PNP_50_57     0x0002\r
+///@}\r
+\r
+///\r
+/// SMM_FUNCTION Owner constants.\r
+///@{\r
+#define STANDARD_OWNER    0x0\r
+#define OEM_OWNER         0x1\r
+///@}\r
+\r
+///\r
+/// This structure assumes both port and data sizes are 1. SmmAttribute must be\r
+/// properly to reflect that assumption.\r
+///\r
+typedef struct {\r
+  ///\r
+  /// Describes the access mechanism, SmmPort, and SmmData sizes. Type\r
+  /// SMM_ATTRIBUTES is defined below.\r
+  ///\r
+  SMM_ATTRIBUTES                    SmmAttributes;\r
+  \r
+  ///\r
+  /// Function Soft SMI is to perform. Type SMM_FUNCTION is defined below.\r
+  ///\r
+  SMM_FUNCTION                      SmmFunction;\r
+  \r
+  ///\r
+  /// SmmPort size depends upon SmmAttributes and ranges from2 bytes to 16 bytes.\r
+  ///\r
+  UINT8                             SmmPort;\r
+  \r
+  ///\r
+  /// SmmData size depends upon SmmAttributes and ranges from2 bytes to 16 bytes.\r
+  ///\r
+  UINT8                             SmmData;\r
+} SMM_ENTRY;\r
+\r
+///\r
+/// SMM_TABLE\r
+///\r
+typedef struct {\r
+  UINT16                            NumSmmEntries;    ///< Number of entries represented by SmmEntry.\r
+  SMM_ENTRY                         SmmEntry;         ///< One entry per function. Type SMM_ENTRY is defined below.\r
+} SMM_TABLE;\r
+\r
+///\r
+/// UDC_ATTRIBUTES\r
+///\r
+typedef struct {\r
+  ///\r
+  /// This bit set indicates that the ServiceAreaData is valid.\r
+  ///\r
+  UINT8                             DirectoryServiceValidity : 1;\r
+  \r
+  ///\r
+  /// This bit set indicates to use the Reserve Area Boot Code Address (RACBA) only if\r
+  /// DirectoryServiceValidity is 0.\r
+  ///\r
+  UINT8                             RabcaUsedFlag : 1;\r
+  \r
+  ///\r
+  /// This bit set indicates to execute hard disk diagnostics.\r
+  ///\r
+  UINT8                             ExecuteHddDiagnosticsFlag : 1;\r
+  \r
+  ///\r
+  /// Reserved for future use. Set to 0.\r
+  ///\r
+  UINT8                             Reserved : 5;\r
+} UDC_ATTRIBUTES;\r
+\r
+///\r
+/// UD_TABLE\r
+///\r
+typedef struct {\r
+  ///\r
+  /// This field contains the bit-mapped attributes of the PARTIES information. Type\r
+  /// UDC_ATTRIBUTES is defined below.\r
+  ///\r
+  UDC_ATTRIBUTES                    Attributes;\r
+  \r
+  ///\r
+  /// This field contains the zero-based device on which the selected\r
+  /// ServiceDataArea is present. It is 0 for master and 1 for the slave device.  \r
+  ///\r
+  UINT8                             DeviceNumber;\r
+  \r
+  ///\r
+  /// This field contains the zero-based index into the BbsTable for the parent device.\r
+  /// This index allows the user to reference the parent device information such as PCI\r
+  /// bus, device function.\r
+  ///\r
+  UINT8                             BbsTableEntryNumberForParentDevice;\r
+  \r
+  ///\r
+  /// This field contains the zero-based index into the BbsTable for the boot entry.\r
+  ///\r
+  UINT8                             BbsTableEntryNumberForBoot;\r
+  \r
+  ///\r
+  /// This field contains the zero-based index into the BbsTable for the HDD diagnostics entry.\r
+  ///\r
+  UINT8                             BbsTableEntryNumberForHddDiag;\r
+  \r
+  ///\r
+  /// The raw Beer data.\r
+  ///\r
+  UINT8                             BeerData[128];\r
+  \r
+  ///\r
+  /// The raw data of selected service area.\r
+  ///\r
+  UINT8                             ServiceAreaData[64];\r
+} UD_TABLE;\r
+\r
+#define EFI_TO_LEGACY_MAJOR_VERSION 0x02\r
+#define EFI_TO_LEGACY_MINOR_VERSION 0x00\r
+#define MAX_IDE_CONTROLLER          8\r
+\r
+///\r
+/// EFI_TO_COMPATIBILITY16_BOOT_TABLE\r
+///\r
+typedef struct {\r
+  UINT16                            MajorVersion;                 ///< The EfiCompatibility major version number.\r
+  UINT16                            MinorVersion;                 ///< The EfiCompatibility minor version number.\r
+  UINT32                            AcpiTable;                    ///< The location of the RSDT ACPI table. < 4G range.\r
+  UINT32                            SmbiosTable;                  ///< The location of the SMBIOS table in EFI memory. < 4G range.\r
+  UINT32                            SmbiosTableLength;\r
+  //\r
+  // Legacy SIO state\r
+  //\r
+  DEVICE_PRODUCER_DATA_HEADER       SioData;                      ///< Standard traditional device information.\r
+  UINT16                            DevicePathType;               ///< The default boot type.\r
+  UINT16                            PciIrqMask;                   ///< Mask of which IRQs have been assigned to PCI.\r
+  UINT32                            NumberE820Entries;            ///< Number of E820 entries. The number can change from the\r
+                                                                  ///< Compatibility16InitializeYourself() function.\r
+  //\r
+  // Controller & Drive Identify[2] per controller information\r
+  //\r
+  HDD_INFO                          HddInfo[MAX_IDE_CONTROLLER];  ///< Hard disk drive information, including raw Identify Drive data.\r
+  UINT32                            NumberBbsEntries;             ///< Number of entries in the BBS table\r
+  UINT32                            BbsTable;                     ///< A pointer to the BBS table. Type BBS_TABLE is defined below.\r
+  UINT32                            SmmTable;                     ///< A pointer to the SMM table. Type SMM_TABLE is defined below.\r
+  UINT32                            OsMemoryAbove1Mb;             ///< The amount of usable memory above 1 MB, i.e. E820 type 1 memory. This value can\r
+                                                                  ///< differ from the value in EFI_TO_COMPATIBILITY16_INIT_TABLE as more\r
+                                                                  ///< memory may have been discovered.\r
+  UINT32                            UnconventionalDeviceTable;    ///< Information to boot off an unconventional device like a PARTIES partition. Type\r
+                                                                  ///< UD_TABLE is defined below.\r
+} EFI_TO_COMPATIBILITY16_BOOT_TABLE;\r
+\r
+///\r
+/// EFI_LEGACY_INSTALL_PCI_HANDLER\r
+///\r
+typedef struct {\r
+  UINT8                             PciBus;             ///< The PCI bus of the device.\r
+  UINT8                             PciDeviceFun;       ///< The PCI device in bits 7:3 and function in bits 2:0.\r
+  UINT8                             PciSegment;         ///< The PCI segment of the device.\r
+  UINT8                             PciClass;           ///< The PCI class code of the device.\r
+  UINT8                             PciSubclass;        ///< The PCI subclass code of the device.\r
+  UINT8                             PciInterface;       ///< The PCI interface code of the device.\r
+  //\r
+  // Primary section\r
+  //\r
+  UINT8                             PrimaryIrq;         ///< The primary device IRQ.\r
+  UINT8                             PrimaryReserved;    ///< Reserved.\r
+  UINT16                            PrimaryControl;     ///< The primary device control I/O base.\r
+  UINT16                            PrimaryBase;        ///< The primary device I/O base.\r
+  UINT16                            PrimaryBusMaster;   ///< The primary device bus master I/O base.\r
+  //\r
+  // Secondary Section\r
+  //\r
+  UINT8                             SecondaryIrq;       ///< The secondary device IRQ.\r
+  UINT8                             SecondaryReserved;  ///< Reserved.\r
+  UINT16                            SecondaryControl;   ///< The secondary device control I/O base.\r
+  UINT16                            SecondaryBase;      ///< The secondary device I/O base.\r
+  UINT16                            SecondaryBusMaster; ///< The secondary device bus master I/O base.\r
+} EFI_LEGACY_INSTALL_PCI_HANDLER;\r
+\r
+//\r
+// Restore default pack value\r
+//\r
+#pragma pack()\r
+\r
+#define EFI_LEGACY_BIOS_PROTOCOL_GUID \\r
+  { \\r
+    0xdb9a1e3d, 0x45cb, 0x4abb, {0x85, 0x3b, 0xe5, 0x38, 0x7f, 0xdb, 0x2e, 0x2d } \\r
+  }\r
+\r
+typedef struct _EFI_LEGACY_BIOS_PROTOCOL EFI_LEGACY_BIOS_PROTOCOL;\r
+\r
+///\r
+/// Flags returned by CheckPciRom().\r
+///\r
+#define NO_ROM            0x00\r
+#define ROM_FOUND         0x01\r
+#define VALID_LEGACY_ROM  0x02\r
+#define ROM_WITH_CONFIG   0x04     ///< Not defined in the Framework CSM Specification.\r
+\r
+///\r
+/// The following macros do not appear in the Framework CSM Specification and \r
+/// are kept for backward compatibility only.  They convert 32-bit address (_Adr) \r
+/// to Segment:Offset 16-bit form.\r
+///\r
+///@{\r
+#define EFI_SEGMENT(_Adr)     (UINT16) ((UINT16) (((UINTN) (_Adr)) >> 4) & 0xf000)\r
+#define EFI_OFFSET(_Adr)      (UINT16) (((UINT16) ((UINTN) (_Adr))) & 0xffff)\r
+///@}\r
+\r
+#define CARRY_FLAG            0x01\r
+\r
+///\r
+/// EFI_EFLAGS_REG\r
+///\r
+typedef struct {\r
+  UINT32 CF:1;\r
+  UINT32 Reserved1:1;\r
+  UINT32 PF:1;\r
+  UINT32 Reserved2:1;\r
+  UINT32 AF:1;\r
+  UINT32 Reserved3:1;\r
+  UINT32 ZF:1;\r
+  UINT32 SF:1;\r
+  UINT32 TF:1;\r
+  UINT32 IF:1;\r
+  UINT32 DF:1;\r
+  UINT32 OF:1;\r
+  UINT32 IOPL:2;\r
+  UINT32 NT:1;\r
+  UINT32 Reserved4:2;\r
+  UINT32 VM:1;\r
+  UINT32 Reserved5:14;\r
+} EFI_EFLAGS_REG;\r
+\r
+///\r
+/// EFI_DWORD_REGS\r
+///\r
+typedef struct {\r
+    UINT32           EAX;\r
+    UINT32           EBX;\r
+    UINT32           ECX;\r
+    UINT32           EDX;\r
+    UINT32           ESI;\r
+    UINT32           EDI;\r
+    EFI_EFLAGS_REG   EFlags;\r
+    UINT16           ES;\r
+    UINT16           CS;\r
+    UINT16           SS;\r
+    UINT16           DS;\r
+    UINT16           FS;\r
+    UINT16           GS;\r
+    UINT32           EBP;\r
+    UINT32           ESP;\r
+} EFI_DWORD_REGS;\r
+\r
+///\r
+/// EFI_FLAGS_REG\r
+///\r
+typedef struct {\r
+  UINT16     CF:1;\r
+  UINT16     Reserved1:1;\r
+  UINT16     PF:1;\r
+  UINT16     Reserved2:1;\r
+  UINT16     AF:1;\r
+  UINT16     Reserved3:1;\r
+  UINT16     ZF:1;\r
+  UINT16     SF:1;\r
+  UINT16     TF:1;\r
+  UINT16     IF:1;\r
+  UINT16     DF:1;\r
+  UINT16     OF:1;\r
+  UINT16     IOPL:2;\r
+  UINT16     NT:1;\r
+  UINT16     Reserved4:1;\r
+} EFI_FLAGS_REG;\r
+\r
+///\r
+/// EFI_WORD_REGS\r
+///\r
+typedef struct {\r
+    UINT16           AX;\r
+    UINT16           ReservedAX;\r
+    UINT16           BX;\r
+    UINT16           ReservedBX;\r
+    UINT16           CX;\r
+    UINT16           ReservedCX;\r
+    UINT16           DX;\r
+    UINT16           ReservedDX;\r
+    UINT16           SI;\r
+    UINT16           ReservedSI;\r
+    UINT16           DI;\r
+    UINT16           ReservedDI;\r
+    EFI_FLAGS_REG    Flags;\r
+    UINT16           ReservedFlags;\r
+    UINT16           ES;\r
+    UINT16           CS;\r
+    UINT16           SS;\r
+    UINT16           DS;\r
+    UINT16           FS;\r
+    UINT16           GS;\r
+    UINT16           BP;\r
+    UINT16           ReservedBP;\r
+    UINT16           SP;\r
+    UINT16           ReservedSP;\r
+} EFI_WORD_REGS;\r
+\r
+///\r
+/// EFI_BYTE_REGS\r
+///\r
+typedef struct {\r
+    UINT8   AL, AH;\r
+    UINT16  ReservedAX;\r
+    UINT8   BL, BH;\r
+    UINT16  ReservedBX;\r
+    UINT8   CL, CH;\r
+    UINT16  ReservedCX;\r
+    UINT8   DL, DH;\r
+    UINT16  ReservedDX;\r
+} EFI_BYTE_REGS;\r
+\r
+///\r
+/// EFI_IA32_REGISTER_SET\r
+///\r
+typedef union {\r
+  EFI_DWORD_REGS  E;\r
+  EFI_WORD_REGS   X;\r
+  EFI_BYTE_REGS   H;\r
+} EFI_IA32_REGISTER_SET;\r
+\r
+/**\r
+  Thunk to 16-bit real mode and execute a software interrupt with a vector\r
+  of BiosInt. Regs will contain the 16-bit register context on entry and\r
+  exit.\r
+\r
+  @param[in]     This      The protocol instance pointer.\r
+  @param[in]     BiosInt   The processor interrupt vector to invoke.\r
+  @param[in,out] Reg       Register contexted passed into (and returned) from thunk to\r
+                           16-bit mode.\r
+\r
+  @retval TRUE                Thunk completed with no BIOS errors in the target code. See Regs for status.  \r
+  @retval FALSE                  There was a BIOS error in the target code.\r
+**/\r
+typedef\r
+BOOLEAN\r
+(EFIAPI *EFI_LEGACY_BIOS_INT86)(\r
+  IN     EFI_LEGACY_BIOS_PROTOCOL  *This,\r
+  IN     UINT8                     BiosInt,\r
+  IN OUT EFI_IA32_REGISTER_SET     *Regs\r
+  );\r
+\r
+/**\r
+  Thunk to 16-bit real mode and call Segment:Offset. Regs will contain the\r
+  16-bit register context on entry and exit. Arguments can be passed on\r
+  the Stack argument\r
+\r
+  @param[in] This        The protocol instance pointer.\r
+  @param[in] Segment     The segemnt of 16-bit mode call.\r
+  @param[in] Offset      The offset of 16-bit mdoe call.\r
+  @param[in] Reg         Register contexted passed into (and returned) from thunk to\r
+                         16-bit mode.\r
+  @param[in] Stack       The caller allocated stack used to pass arguments.\r
+  @param[in] StackSize   The size of Stack in bytes.\r
+\r
+  @retval FALSE                 Thunk completed with no BIOS errors in the target code.                                See Regs for status.  @retval TRUE                  There was a BIOS error in the target code.\r
+**/\r
+typedef\r
+BOOLEAN\r
+(EFIAPI *EFI_LEGACY_BIOS_FARCALL86)(\r
+  IN EFI_LEGACY_BIOS_PROTOCOL  *This,\r
+  IN UINT16                    Segment,\r
+  IN UINT16                    Offset,\r
+  IN EFI_IA32_REGISTER_SET     *Regs,\r
+  IN VOID                      *Stack,\r
+  IN UINTN                     StackSize\r
+  );\r
+\r
+/**\r
+  Test to see if a legacy PCI ROM exists for this device. Optionally return\r
+  the Legacy ROM instance for this PCI device.\r
+\r
+  @param[in]  This        The protocol instance pointer.\r
+  @param[in]  PciHandle   The PCI PC-AT OPROM from this devices ROM BAR will be loaded\r
+  @param[out] RomImage    Return the legacy PCI ROM for this device.\r
+  @param[out] RomSize     The size of ROM Image.\r
+  @param[out] Flags       Indicates if ROM found and if PC-AT. Multiple bits can be set as follows:\r
+                            - 00 = No ROM.\r
+                            - 01 = ROM Found.\r
+                            - 02 = ROM is a valid legacy ROM.\r
+\r
+  @retval EFI_SUCCESS       The Legacy Option ROM availible for this device\r
+  @retval EFI_UNSUPPORTED   The Legacy Option ROM is not supported.\r
+\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *EFI_LEGACY_BIOS_CHECK_ROM)(\r
+  IN  EFI_LEGACY_BIOS_PROTOCOL  *This,\r
+  IN  EFI_HANDLE                PciHandle,\r
+  OUT VOID                      **RomImage, OPTIONAL\r
+  OUT UINTN                     *RomSize, OPTIONAL\r
+  OUT UINTN                     *Flags\r
+  );\r
+\r
+/**\r
+  Load a legacy PC-AT OPROM on the PciHandle device. Return information\r
+  about how many disks were added by the OPROM and the shadow address and\r
+  size. DiskStart & DiskEnd are INT 13h drive letters. Thus 0x80 is C:\r
+\r
+  @param[in]  This               The protocol instance pointer.\r
+  @param[in]  PciHandle          The PCI PC-AT OPROM from this devices ROM BAR will be loaded.\r
+                                 This value is NULL if RomImage is non-NULL. This is the normal\r
+                                 case.\r
+  @param[in]  RomImage           A PCI PC-AT ROM image. This argument is non-NULL if there is\r
+                                 no hardware associated with the ROM and thus no PciHandle,\r
+                                 otherwise is must be NULL.\r
+                                 Example is PXE base code.\r
+  @param[out] Flags              The type of ROM discovered. Multiple bits can be set, as follows:\r
+                                   - 00 = No ROM.\r
+                                   - 01 = ROM found.\r
+                                   - 02 = ROM is a valid legacy ROM.\r
+  @param[out] DiskStart          The disk number of first device hooked by the ROM. If DiskStart\r
+                                 is the same as DiskEnd no disked were hooked.\r
+  @param[out] DiskEnd            disk number of the last device hooked by the ROM.\r
+  @param[out] RomShadowAddress   Shadow address of PC-AT ROM.\r
+  @param[out] RomShadowSize      Size of RomShadowAddress in bytes.\r
+\r
+  @retval EFI_SUCCESS             Thunk completed, see Regs for status.\r
+  @retval EFI_INVALID_PARAMETER   PciHandle not found\r
+\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *EFI_LEGACY_BIOS_INSTALL_ROM)(\r
+  IN  EFI_LEGACY_BIOS_PROTOCOL  *This,\r
+  IN  EFI_HANDLE                PciHandle,\r
+  IN  VOID                      **RomImage,\r
+  OUT UINTN                     *Flags,\r
+  OUT UINT8                     *DiskStart, OPTIONAL\r
+  OUT UINT8                     *DiskEnd, OPTIONAL\r
+  OUT VOID                      **RomShadowAddress, OPTIONAL\r
+  OUT UINT32                    *ShadowedRomSize OPTIONAL\r
+  );\r
+\r
+/**\r
+  This function attempts to traditionally boot the specified BootOption. If the EFI context has\r
+  been compromised, this function will not return. This procedure is not used for loading an EFI-aware\r
+  OS off a traditional device. The following actions occur:\r
+  - Get EFI SMBIOS data structures, convert them to a traditional format, and copy to\r
+    Compatibility16.\r
+  - Get a pointer to ACPI data structures and copy the Compatibility16 RSD PTR to F0000 block.\r
+  - Find the traditional SMI handler from a firmware volume and register the traditional SMI\r
+    handler with the EFI SMI handler.\r
+  - Build onboard IDE information and pass this information to the Compatibility16 code.\r
+  - Make sure all PCI Interrupt Line registers are programmed to match 8259.\r
+  - Reconfigure SIO devices from EFI mode (polled) into traditional mode (interrupt driven).\r
+  - Shadow all PCI ROMs.\r
+  - Set up BDA and EBDA standard areas before the legacy boot.\r
+  - Construct the Compatibility16 boot memory map and pass it to the Compatibility16 code.\r
+  - Invoke the Compatibility16 table function Compatibility16PrepareToBoot(). This\r
+    invocation causes a thunk into the Compatibility16 code, which sets all appropriate internal\r
+    data structures. The boot device list is a parameter.\r
+  - Invoke the Compatibility16 Table function Compatibility16Boot(). This invocation\r
+    causes a thunk into the Compatibility16 code, which does an INT19.\r
+  - If the Compatibility16Boot() function returns, then the boot failed in a graceful\r
+    manner--meaning that the EFI code is still valid. An ungraceful boot failure causes a reset because the state\r
+    of EFI code is unknown.\r
+\r
+  @param[in] This             The protocol instance pointer.\r
+  @param[in] BootOption       The EFI Device Path from BootXXXX variable.\r
+  @param[in] LoadOptionSize   The size of LoadOption in size.\r
+  @param[in] LoadOption       LThe oadOption from BootXXXX variable.\r
+\r
+  @retval EFI_DEVICE_ERROR      Failed to boot from any boot device and memory is uncorrupted.                                Note: This function normally does not returns. It will either boot the                                OS or reset the system if memory has been "corrupted" by loading                                a boot sector and passing control to it.\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *EFI_LEGACY_BIOS_BOOT)(\r
+  IN EFI_LEGACY_BIOS_PROTOCOL  *This,\r
+  IN BBS_BBS_DEVICE_PATH       *BootOption,\r
+  IN UINT32                    LoadOptionsSize,\r
+  IN VOID                      *LoadOptions\r
+  );\r
+\r
+/**\r
+  This function takes the Leds input parameter and sets/resets the BDA accordingly. \r
+  Leds is also passed to Compatibility16 code, in case any special processing is required. \r
+  This function is normally called from EFI Setup drivers that handle user-selectable\r
+  keyboard options such as boot with NUM LOCK on/off. This function does not\r
+  touch the keyboard or keyboard LEDs but only the BDA.\r
+\r
+  @param[in] This   The protocol instance pointer.\r
+  @param[in] Leds   The status of current Scroll, Num & Cap lock LEDS:\r
+                      - Bit 0 is Scroll Lock 0 = Not locked.\r
+                      - Bit 1 is Num Lock.\r
+                      - Bit 2 is Caps Lock.\r
+\r
+  @retval EFI_SUCCESS   The BDA was updated successfully.\r
+\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *EFI_LEGACY_BIOS_UPDATE_KEYBOARD_LED_STATUS)(\r
+  IN EFI_LEGACY_BIOS_PROTOCOL  *This,\r
+  IN UINT8                     Leds\r
+  );\r
+\r
+/**\r
+  Retrieve legacy BBS info and assign boot priority.\r
+\r
+  @param[in]     This       The protocol instance pointer.\r
+  @param[out]    HddCount   The number of HDD_INFO structures.\r
+  @param[out]    HddInfo    Onboard IDE controller information.\r
+  @param[out]    BbsCount   The number of BBS_TABLE structures.\r
+  @param[in,out] BbsTable   Points to List of BBS_TABLE.\r
+\r
+  @retval EFI_SUCCESS   Tables were returned.\r
+\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *EFI_LEGACY_BIOS_GET_BBS_INFO)(\r
+  IN     EFI_LEGACY_BIOS_PROTOCOL  *This,\r
+  OUT    UINT16                    *HddCount,\r
+  OUT    HDD_INFO                  **HddInfo,\r
+  OUT    UINT16                    *BbsCount,\r
+  IN OUT BBS_TABLE                 **BbsTable\r
+  );\r
+\r
+/**\r
+  Assign drive number to legacy HDD drives prior to booting an EFI\r
+  aware OS so the OS can access drives without an EFI driver.\r
+\r
+  @param[in]  This       The protocol instance pointer.\r
+  @param[out] BbsCount   The number of BBS_TABLE structures\r
+  @param[out] BbsTable   List of BBS entries\r
+\r
+  @retval EFI_SUCCESS   Drive numbers assigned.\r
+\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *EFI_LEGACY_BIOS_PREPARE_TO_BOOT_EFI)(\r
+  IN  EFI_LEGACY_BIOS_PROTOCOL  *This,\r
+  OUT UINT16                    *BbsCount,\r
+  OUT BBS_TABLE                 **BbsTable\r
+  );\r
+\r
+/**\r
+  To boot from an unconventional device like parties and/or execute\r
+  HDD diagnostics.\r
+\r
+  @param[in]  This              The protocol instance pointer.\r
+  @param[in]  Attributes        How to interpret the other input parameters.\r
+  @param[in]  BbsEntry          The 0-based index into the BbsTable for the parent\r
+                                device.\r
+  @param[in]  BeerData          A pointer to the 128 bytes of ram BEER data.\r
+  @param[in]  ServiceAreaData   A pointer to the 64 bytes of raw Service Area data. The\r
+                                caller must provide a pointer to the specific Service\r
+                                Area and not the start all Service Areas.\r
+\r
+  @retval EFI_INVALID_PARAMETER   If error. Does NOT return if no error.\r
+\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *EFI_LEGACY_BIOS_BOOT_UNCONVENTIONAL_DEVICE)(\r
+  IN EFI_LEGACY_BIOS_PROTOCOL  *This,\r
+  IN UDC_ATTRIBUTES            Attributes,\r
+  IN UINTN                     BbsEntry,\r
+  IN VOID                      *BeerData,\r
+  IN VOID                      *ServiceAreaData\r
+  );\r
+\r
+/**\r
+  Shadow all legacy16 OPROMs that haven't been shadowed.\r
+  Warning: Use this with caution. This routine disconnects all EFI\r
+  drivers. If used externally, then  the caller must re-connect EFI\r
+  drivers.\r
+  \r
+  @param[in]  This   The protocol instance pointer.\r
+  \r
+  @retval EFI_SUCCESS   OPROMs were shadowed.\r
+\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *EFI_LEGACY_BIOS_SHADOW_ALL_LEGACY_OPROMS)(\r
+  IN EFI_LEGACY_BIOS_PROTOCOL  *This\r
+  );\r
+\r
+/**\r
+  Get a region from the LegacyBios for S3 usage.\r
+\r
+  @param[in]  This                  The protocol instance pointer.\r
+  @param[in]  LegacyMemorySize      The size of required region.\r
+  @param[in]  Region                The region to use.\r
+                                    00 = Either 0xE0000 or 0xF0000 block.\r
+                                      - Bit0 = 1 0xF0000 block.\r
+                                      - Bit1 = 1 0xE0000 block.\r
+  @param[in]  Alignment             Address alignment. Bit mapped. The first non-zero\r
+                                    bit from right is alignment.\r
+  @param[out] LegacyMemoryAddress   The Region Assigned\r
+\r
+  @retval EFI_SUCCESS           The Region was assigned.\r
+  @retval EFI_ACCESS_DENIED     The function was previously invoked.\r
+  @retval Other                 The Region was not assigned.\r
+\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *EFI_LEGACY_BIOS_GET_LEGACY_REGION)(\r
+  IN  EFI_LEGACY_BIOS_PROTOCOL  *This,\r
+  IN  UINTN                     LegacyMemorySize,\r
+  IN  UINTN                     Region,\r
+  IN  UINTN                     Alignment,\r
+  OUT VOID                      **LegacyMemoryAddress\r
+  );\r
+\r
+/**\r
+  Get a region from the LegacyBios for Tiano usage. Can only be invoked once.\r
+\r
+  @param[in]  This                        The protocol instance pointer.\r
+  @param[in]  LegacyMemorySize            The size of data to copy.\r
+  @param[in]  LegacyMemoryAddress         The Legacy Region destination address.\r
+                                          Note: must be in region assigned by\r
+                                          LegacyBiosGetLegacyRegion.\r
+  @param[in]  LegacyMemorySourceAddress   The source of the data to copy.\r
+\r
+  @retval EFI_SUCCESS           The Region assigned.\r
+  @retval EFI_ACCESS_DENIED     Destination was outside an assigned region.\r
+\r
+**/\r
+typedef\r
+EFI_STATUS\r
+(EFIAPI *EFI_LEGACY_BIOS_COPY_LEGACY_REGION)(\r
+  IN EFI_LEGACY_BIOS_PROTOCOL  *This,\r
+  IN UINTN                     LegacyMemorySize,\r
+  IN VOID                      *LegacyMemoryAddress,\r
+  IN VOID                      *LegacyMemorySourceAddress\r
+  );\r
+\r
+///\r
+/// Abstracts the traditional BIOS from the rest of EFI. The LegacyBoot()\r
+/// member function allows the BDS to support booting a traditional OS.\r
+/// EFI thunks drivers that make EFI bindings for BIOS INT services use\r
+/// all the other member functions.\r
+///\r
+struct _EFI_LEGACY_BIOS_PROTOCOL {\r
+  ///\r
+  /// Performs traditional software INT. See the Int86() function description.\r
+  ///\r
+  EFI_LEGACY_BIOS_INT86                       Int86;\r
+  \r
+  ///\r
+  /// Performs a far call into Compatibility16 or traditional OpROM code.\r
+  ///\r
+  EFI_LEGACY_BIOS_FARCALL86                   FarCall86;\r
+  \r
+  ///\r
+  /// Checks if a traditional OpROM exists for this device.\r
+  ///\r
+  EFI_LEGACY_BIOS_CHECK_ROM                   CheckPciRom;\r
+  \r
+  ///\r
+  /// Loads a traditional OpROM in traditional OpROM address space.\r
+  ///\r
+  EFI_LEGACY_BIOS_INSTALL_ROM                 InstallPciRom;\r
+  \r
+  ///\r
+  /// Boots a traditional OS.\r
+  ///\r
+  EFI_LEGACY_BIOS_BOOT                        LegacyBoot;\r
+  \r
+  ///\r
+  /// Updates BDA to reflect the current EFI keyboard LED status.\r
+  ///\r
+  EFI_LEGACY_BIOS_UPDATE_KEYBOARD_LED_STATUS  UpdateKeyboardLedStatus;\r
+  \r
+  ///\r
+  /// Allows an external agent, such as BIOS Setup, to get the BBS data.\r
+  ///\r
+  EFI_LEGACY_BIOS_GET_BBS_INFO                GetBbsInfo;\r
+  \r
+  ///\r
+  /// Causes all legacy OpROMs to be shadowed.\r
+  ///\r
+  EFI_LEGACY_BIOS_SHADOW_ALL_LEGACY_OPROMS    ShadowAllLegacyOproms;\r
+  \r
+  ///\r
+  /// Performs all actions prior to boot. Used when booting an EFI-aware OS\r
+  /// rather than a legacy OS.  \r
+  ///\r
+  EFI_LEGACY_BIOS_PREPARE_TO_BOOT_EFI         PrepareToBootEfi;\r
+  \r
+  ///\r
+  /// Allows EFI to reserve an area in the 0xE0000 or 0xF0000 block.\r
+  ///\r
+  EFI_LEGACY_BIOS_GET_LEGACY_REGION           GetLegacyRegion;\r
+  \r
+  ///\r
+  /// Allows EFI to copy data to the area specified by GetLegacyRegion.\r
+  ///\r
+  EFI_LEGACY_BIOS_COPY_LEGACY_REGION          CopyLegacyRegion;\r
+  \r
+  ///\r
+  /// Allows the user to boot off an unconventional device such as a PARTIES partition.\r
+  ///\r
+  EFI_LEGACY_BIOS_BOOT_UNCONVENTIONAL_DEVICE  BootUnconventionalDevice;\r
+};\r
+\r
+extern EFI_GUID gEfiLegacyBiosProtocolGuid;\r
+\r
+#endif\r
diff --git a/EfiLib/gnuefi-helper.c b/EfiLib/gnuefi-helper.c
new file mode 100644 (file)
index 0000000..368246d
--- /dev/null
@@ -0,0 +1,310 @@
+/*
+ * EfiLib/gnuefi.h
+ * GNU-EFI support in legacy boot code
+ *
+ * Copyright (c) 2014 Roderick W. Smith
+ * With extensive borrowing from other sources (mostly Tianocore)
+ *
+ * This software is licensed under the terms of the GNU GPLv3,
+ * a copy of which should come with this file.
+ *
+ */
+
+#include "gnuefi-helper.h"
+#include "DevicePathUtilities.h"
+#include "refit_call_wrapper.h"
+#include "LegacyBios.h"
+
+EFI_GUID gEfiDevicePathUtilitiesProtocolGuid = { 0x09576E91, 0x6D3F, 0x11D2, { 0x8E, 0x39, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B }};
+EFI_GUID gEfiGlobalVariableGuid = { 0x8BE4DF61, 0x93CA, 0x11D2, { 0xAA, 0x0D, 0x00, 0xE0, 0x98, 0x03, 0x2B, 0x8C }};
+EFI_GUID gEfiLegacyBiosProtocolGuid = { 0xdb9a1e3d, 0x45cb, 0x4abb, { 0x85, 0x3b, 0xe5, 0x38, 0x7f, 0xdb, 0x2e, 0x2d }};
+
+/**
+  Convert a Null-terminated Unicode string to a Null-terminated 
+  ASCII string and returns the ASCII string.
+
+  This function converts the content of the Unicode string Source 
+  to the ASCII string Destination by copying the lower 8 bits of 
+  each Unicode character. It returns Destination. The function terminates 
+  the ASCII string Destination  by appending a Null-terminator character 
+  at the end. The caller is responsible to make sure Destination points 
+  to a buffer with size equal or greater than (StrLen (Source) + 1) in bytes.
+
+  If Destination is NULL, then ASSERT().
+  If Source is NULL, then ASSERT().
+  If Source is not aligned on a 16-bit boundary, then ASSERT().
+  If Source and Destination overlap, then ASSERT().
+
+  If any Unicode characters in Source contain non-zero value in 
+  the upper 8 bits, then ASSERT().
+
+  If PcdMaximumUnicodeStringLength is not zero, and Source contains 
+  more than PcdMaximumUnicodeStringLength Unicode characters not including 
+  the Null-terminator, then ASSERT().
+
+  If PcdMaximumAsciiStringLength is not zero, and Source contains more 
+  than PcdMaximumAsciiStringLength Unicode characters not including the 
+  Null-terminator, then ASSERT().
+
+  @param  Source        Pointer to a Null-terminated Unicode string.
+  @param  Destination   Pointer to a Null-terminated ASCII string.
+
+  @reture Destination
+
+**/
+CHAR8 *
+UnicodeStrToAsciiStr (
+  IN      CHAR16              *Source,
+  OUT     CHAR8               *Destination
+  )
+{
+  ASSERT (Destination != NULL);
+  ASSERT (Source != NULL);
+  ASSERT (((UINTN) Source & 0x01) == 0);
+
+  //
+  // Source and Destination should not overlap
+  //
+  ASSERT ((UINTN) ((CHAR16 *) Destination -  Source) > StrLen (Source));
+  ASSERT ((UINTN) ((CHAR8 *) Source - Destination) > StrLen (Source));
+
+//   //
+//   // If PcdMaximumUnicodeStringLength is not zero,
+//   // length of Source should not more than PcdMaximumUnicodeStringLength
+//   //
+//   if (PcdGet32 (PcdMaximumUnicodeStringLength) != 0) {
+//     ASSERT (StrLen (Source) < PcdGet32 (PcdMaximumUnicodeStringLength));
+//   }
+
+  while (*Source != '\0') {
+    //
+    // If any Unicode characters in Source contain 
+    // non-zero value in the upper 8 bits, then ASSERT().
+    //
+    ASSERT (*Source < 0x100);
+    *(Destination++) = (CHAR8) *(Source++);
+  }
+
+  *Destination = '\0';
+
+  return Destination;
+}
+
+/**
+  Returns the length of a Null-terminated ASCII string.
+
+  This function returns the number of ASCII characters in the Null-terminated
+  ASCII string specified by String.
+
+  If String is NULL, then ASSERT().
+  If PcdMaximumAsciiStringLength is not zero and String contains more than
+  PcdMaximumAsciiStringLength ASCII characters not including the Null-terminator,
+  then ASSERT().
+
+  @param  String  Pointer to a Null-terminated ASCII string.
+
+  @return The length of String.
+
+**/
+UINTN
+AsciiStrLen (
+  IN      CONST CHAR8               *String
+  )
+{
+  UINTN                             Length;
+
+  ASSERT (String != NULL);
+
+  for (Length = 0; *String != '\0'; String++, Length++) {
+//     //
+//     // If PcdMaximumUnicodeStringLength is not zero,
+//     // length should not more than PcdMaximumUnicodeStringLength
+//     //
+//     if (PcdGet32 (PcdMaximumAsciiStringLength) != 0) {
+//       ASSERT (Length < PcdGet32 (PcdMaximumAsciiStringLength));
+//     }
+  }
+  return Length;
+}
+
+/**
+  Determine whether a given device path is valid.
+  If DevicePath is NULL, then ASSERT().
+
+  @param  DevicePath  A pointer to a device path data structure.
+  @param  MaxSize     The maximum size of the device path data structure.
+
+  @retval TRUE        DevicePath is valid.
+  @retval FALSE       The length of any node node in the DevicePath is less
+                      than sizeof (EFI_DEVICE_PATH_PROTOCOL).
+  @retval FALSE       If MaxSize is not zero, the size of the DevicePath
+                      exceeds MaxSize.
+  @retval FALSE       If PcdMaximumDevicePathNodeCount is not zero, the node
+                      count of the DevicePath exceeds PcdMaximumDevicePathNodeCount.
+**/
+BOOLEAN
+EFIAPI
+IsDevicePathValid (
+  IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+  IN       UINTN                    MaxSize
+  )
+{
+  UINTN Count;
+  UINTN Size;
+  UINTN NodeLength;
+
+  ASSERT (DevicePath != NULL);
+
+  for (Count = 0, Size = 0; !IsDevicePathEnd (DevicePath); DevicePath = NextDevicePathNode (DevicePath)) {
+    NodeLength = DevicePathNodeLength (DevicePath);
+    if (NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
+      return FALSE;
+    }
+
+    if (MaxSize > 0) {
+      Size += NodeLength;
+      if (Size + END_DEVICE_PATH_LENGTH > MaxSize) {
+        return FALSE;
+      }
+    }
+
+//     if (PcdGet32 (PcdMaximumDevicePathNodeCount) > 0) {
+//       Count++;
+//       if (Count >= PcdGet32 (PcdMaximumDevicePathNodeCount)) {
+//         return FALSE;
+//       }
+//     }
+  }
+
+  //
+  // Only return TRUE when the End Device Path node is valid.
+  //
+  return (BOOLEAN) (DevicePathNodeLength (DevicePath) == END_DEVICE_PATH_LENGTH);
+}
+
+/**
+  Returns the size of a device path in bytes.
+
+  This function returns the size, in bytes, of the device path data structure 
+  specified by DevicePath including the end of device path node.
+  If DevicePath is NULL or invalid, then 0 is returned.
+
+  @param  DevicePath  A pointer to a device path data structure.
+
+  @retval 0           If DevicePath is NULL or invalid.
+  @retval Others      The size of a device path in bytes.
+
+**/
+UINTN
+EFIAPI
+GetDevicePathSize (
+  IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath
+  )
+{
+  CONST EFI_DEVICE_PATH_PROTOCOL  *Start;
+
+  if (DevicePath == NULL) {
+    return 0;
+  }
+
+  if (!IsDevicePathValid (DevicePath, 0)) {
+    return 0;
+  }
+
+  //
+  // Search for the end of the device path structure
+  //
+  Start = DevicePath;
+  while (!IsDevicePathEnd (DevicePath)) {
+    DevicePath = NextDevicePathNode (DevicePath);
+  }
+
+  //
+  // Compute the size and add back in the size of the end device path structure
+  //
+  return ((UINTN) DevicePath - (UINTN) Start) + DevicePathNodeLength (DevicePath);
+}
+
+/**
+  Creates a copy of the current device path instance and returns a pointer to the next device path
+  instance.
+
+  This function creates a copy of the current device path instance. It also updates 
+  DevicePath to point to the next device path instance in the device path (or NULL 
+  if no more) and updates Size to hold the size of the device path instance copy.
+  If DevicePath is NULL, then NULL is returned.
+  If DevicePath points to a invalid device path, then NULL is returned.
+  If there is not enough memory to allocate space for the new device path, then 
+  NULL is returned.  
+  The memory is allocated from EFI boot services memory. It is the responsibility 
+  of the caller to free the memory allocated.
+  If Size is NULL, then ASSERT().
+  @param  DevicePath                 On input, this holds the pointer to the current 
+                                     device path instance. On output, this holds 
+                                     the pointer to the next device path instance 
+                                     or NULL if there are no more device path
+                                     instances in the device path pointer to a 
+                                     device path data structure.
+  @param  Size                       On output, this holds the size of the device 
+                                     path instance, in bytes or zero, if DevicePath 
+                                     is NULL.
+
+  @return A pointer to the current device path instance.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+GetNextDevicePathInstance (
+  IN OUT EFI_DEVICE_PATH_PROTOCOL    **DevicePath,
+  OUT UINTN                          *Size
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL  *DevPath;
+  EFI_DEVICE_PATH_PROTOCOL  *ReturnValue;
+  UINT8                     Temp;
+
+  ASSERT (Size != NULL);
+
+  if (DevicePath == NULL || *DevicePath == NULL) {
+    *Size = 0;
+    return NULL;
+  }
+
+  if (!IsDevicePathValid (*DevicePath, 0)) {
+    return NULL;
+  }
+
+  //
+  // Find the end of the device path instance
+  //
+  DevPath = *DevicePath;
+  while (!IsDevicePathEndType (DevPath)) {
+    DevPath = NextDevicePathNode (DevPath);
+  }
+
+  //
+  // Compute the size of the device path instance
+  //
+  *Size = ((UINTN) DevPath - (UINTN) (*DevicePath)) + sizeof (EFI_DEVICE_PATH_PROTOCOL);
+  //
+  // Make a copy and return the device path instance
+  //
+  Temp              = DevPath->SubType;
+  DevPath->SubType  = END_ENTIRE_DEVICE_PATH_SUBTYPE;
+  ReturnValue       = DuplicateDevicePath (*DevicePath);
+  DevPath->SubType  = Temp;
+
+  //
+  // If DevPath is the end of an entire device path, then another instance
+  // does not follow, so *DevicePath is set to NULL.
+  //
+  if (DevicePathSubType (DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE) {
+    *DevicePath = NULL;
+  } else {
+    *DevicePath = NextDevicePathNode (DevPath);
+  }
+
+  return ReturnValue;
+}
\ No newline at end of file
diff --git a/EfiLib/gnuefi-helper.h b/EfiLib/gnuefi-helper.h
new file mode 100644 (file)
index 0000000..1a17497
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ * EfiLib/gnuefi.h
+ * Header file for GNU-EFI support in legacy boot code
+ *
+ * Copyright (c) 2014 Roderick W. Smith
+ * With extensive borrowing from other sources (mostly Tianocore)
+ *
+ * This software is licensed under the terms of the GNU GPLv3,
+ * a copy of which should come with this file.
+ *
+ */
+/*
+ * THIS FILE SHOULD NOT BE INCLUDED WHEN COMPILING UNDER TIANOCORE'S TOOLKIT!
+ */
+
+#ifndef __EFILIB_GNUEFI_H
+#define __EFILIB_GNUEFI_H
+
+#include "efi.h"
+#include "efilib.h"
+
+#define EFI_DEVICE_PATH_PROTOCOL EFI_DEVICE_PATH
+#define UnicodeSPrint SPrint
+#define gRT RT
+#define gBS BS
+#define CONST
+#define ASSERT_EFI_ERROR(status)  ASSERT(!EFI_ERROR(status))
+
+CHAR8 *
+UnicodeStrToAsciiStr (
+   IN       CHAR16              *Source,
+   OUT      CHAR8               *Destination
+);
+
+UINTN
+AsciiStrLen (
+   IN      CONST CHAR8               *String
+);
+
+UINTN
+EFIAPI
+GetDevicePathSize (
+   IN CONST EFI_DEVICE_PATH_PROTOCOL  *DevicePath
+);
+
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+GetNextDevicePathInstance (
+   IN OUT EFI_DEVICE_PATH_PROTOCOL    **DevicePath,
+   OUT UINTN                          *Size
+);
+
+#endif
\ No newline at end of file