Correct some typos (discovered with the codespell utility) Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Thomas Huth <thuth@redhat.com> Reviewed-by: Laszlo Ersek <lersek@redhat.com> Cc: Jordan Justen <jordan.l.justen@intel.com> Cc: Thomas Huth <thuth@redhat.com> Reviewed-by: Jordan Justen <jordan.l.justen@intel.com>
		
			
				
	
	
		
			1067 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1067 lines
		
	
	
		
			36 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  Legacy BIOS Platform support
 | 
						|
 | 
						|
  Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
 | 
						|
 | 
						|
  This program and the accompanying materials are
 | 
						|
  licensed and made available under the terms and conditions of the BSD License
 | 
						|
  which accompanies this distribution.  The full text of the license may be found at
 | 
						|
  http://opensource.org/licenses/bsd-license.php
 | 
						|
 | 
						|
  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | 
						|
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | 
						|
 | 
						|
**/
 | 
						|
 | 
						|
#include "LegacyPlatform.h"
 | 
						|
 | 
						|
EFI_SETUP_BBS_MAP mSetupBbsMap[] = {
 | 
						|
  { 1, 2,     1, 1 },     // ATA HardDrive
 | 
						|
  { 2, 3,     1, 1 },     // ATAPI CDROM
 | 
						|
  { 3, 0x80,  2, 0 },     // PXE
 | 
						|
  { 4, 1,     0, 6 },     // USB Floppy
 | 
						|
  { 4, 2,     0, 6 },     // USB HDD
 | 
						|
  { 4, 3,     0, 6 },     // USB CD
 | 
						|
  { 4, 1,     0, 0 },     // USB ZIP Bugbug since Class/SubClass code is uninitialized
 | 
						|
  { 4, 2,     0, 0 }      // USB ZIP Bugbug since Class/SubClass code is uninitialized
 | 
						|
};
 | 
						|
 | 
						|
//
 | 
						|
// Global variables for System ROMs
 | 
						|
//
 | 
						|
#define SYSTEM_ROM_FILE_GUID \
 | 
						|
{ 0x1547B4F3, 0x3E8A, 0x4FEF, { 0x81, 0xC8, 0x32, 0x8E, 0xD6, 0x47, 0xAB, 0x1A } }
 | 
						|
 | 
						|
#define NULL_ROM_FILE_GUID \
 | 
						|
{ 0x00000000, 0x0000, 0x0000, { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
 | 
						|
 | 
						|
SYSTEM_ROM_TABLE mSystemRomTable[] = {
 | 
						|
  { SYSTEM_ROM_FILE_GUID,  1 },
 | 
						|
  { NULL_ROM_FILE_GUID,    0 }
 | 
						|
};
 | 
						|
 | 
						|
EFI_HANDLE  mVgaHandles[0x20];
 | 
						|
EFI_HANDLE  mDiskHandles[0x20];
 | 
						|
EFI_HANDLE  mIsaHandles[0x20];
 | 
						|
 | 
						|
EFI_LEGACY_IRQ_PRIORITY_TABLE_ENTRY IrqPriorityTable[MAX_IRQ_PRIORITY_ENTRIES] = {
 | 
						|
  {0x0B,0},
 | 
						|
  {0x09,0},
 | 
						|
  {0x0A,0},
 | 
						|
  {0x05,0},
 | 
						|
  {0x07,0},
 | 
						|
  {0x00,0},
 | 
						|
  {0x00,0}
 | 
						|
};
 | 
						|
 | 
						|
//
 | 
						|
// PIRQ Table
 | 
						|
// - Slot numbering will be used to update the bus number and determine bridge
 | 
						|
//   to check to get bus number.  The Slot number - 1 is an index into a decode
 | 
						|
//   table to get the bridge information.
 | 
						|
//
 | 
						|
EFI_LEGACY_PIRQ_TABLE PirqTableHead = {
 | 
						|
  {
 | 
						|
    EFI_LEGACY_PIRQ_TABLE_SIGNATURE, // UINT32  Signature
 | 
						|
    0x00,             // UINT8   MinorVersion
 | 
						|
    0x01,             // UINT8   MajorVersion
 | 
						|
    0x0000,           // UINT16  TableSize
 | 
						|
    0x00,             // UINT8   Bus
 | 
						|
    0x08,             // UINT8   DevFun
 | 
						|
    0x0000,           // UINT16  PciOnlyIrq
 | 
						|
    0x8086,           // UINT16  CompatibleVid
 | 
						|
    0x122e,           // UINT16  CompatibleDid
 | 
						|
    0x00000000,       // UINT32  Miniport
 | 
						|
    {                 // UINT8   Reserved[11]
 | 
						|
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 | 
						|
      0x00, 0x00, 0x00
 | 
						|
    },
 | 
						|
    0x00,             // UINT8   Checksum
 | 
						|
  },
 | 
						|
  {
 | 
						|
    //           -- Pin 1 --   -- Pin 2 --   -- Pin 3 --   -- Pin 4 --
 | 
						|
    // Bus  Dev   Reg   Map     Reg   Map     Reg   Map     Reg   Map
 | 
						|
    //
 | 
						|
    {0x00,0x08,{{0x60,0xDEB8},{0x61,0xDEB8},{0x62,0xDEB8},{0x63,0xDEB8}},0x00,0x00},
 | 
						|
    {0x00,0x10,{{0x61,0xDEB8},{0x62,0xDEB8},{0x63,0xDEB8},{0x60,0xDEB8}},0x01,0x00},
 | 
						|
    {0x00,0x18,{{0x62,0xDEB8},{0x63,0xDEB8},{0x60,0xDEB8},{0x61,0xDEB8}},0x02,0x00},
 | 
						|
    {0x00,0x20,{{0x63,0xDEB8},{0x60,0xDEB8},{0x61,0xDEB8},{0x62,0xDEB8}},0x03,0x00},
 | 
						|
    {0x00,0x28,{{0x60,0xDEB8},{0x61,0xDEB8},{0x62,0xDEB8},{0x63,0xDEB8}},0x04,0x00},
 | 
						|
    {0x00,0x30,{{0x61,0xDEB8},{0x62,0xDEB8},{0x63,0xDEB8},{0x60,0xDEB8}},0x05,0x00},
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
LEGACY_BIOS_PLATFORM_INSTANCE       mPrivateData;
 | 
						|
EFI_HANDLE                          mImageHandle = NULL;
 | 
						|
 | 
						|
/**
 | 
						|
  Return the handles and assorted information for the specified PCI Class code
 | 
						|
 | 
						|
  @param[in]     PciClasses    Array of PCI_CLASS_RECORD to find terminated with ClassCode 0xff
 | 
						|
  @param[in,out] DeviceTable   Table to place handles etc in.
 | 
						|
  @param[in,out] DeviceIndex   Number of devices found
 | 
						|
  @param[in]     DeviceFlags   FALSE if a valid legacy ROM is required, TRUE otherwise.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS     One or more devices found
 | 
						|
  @retval EFI_NOT_FOUND   No device found
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
FindAllDeviceTypes (
 | 
						|
  IN       PCI_CLASS_RECORD      *PciClasses,
 | 
						|
  IN OUT   DEVICE_STRUCTURE      *DeviceTable,
 | 
						|
  IN OUT   UINT16                *DeviceIndex,
 | 
						|
  IN       BOOLEAN               DeviceFlags
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINTN                       HandleCount;
 | 
						|
  EFI_HANDLE                  *HandleBuffer;
 | 
						|
  UINTN                       Index;
 | 
						|
  UINTN                       StartIndex;
 | 
						|
  PCI_TYPE00                  PciConfigHeader;
 | 
						|
  EFI_PCI_IO_PROTOCOL         *PciIo;
 | 
						|
  EFI_LEGACY_BIOS_PROTOCOL    *LegacyBios;
 | 
						|
  UINTN                       Flags;
 | 
						|
  EFI_STATUS                  Status;
 | 
						|
  UINTN                       Index2;
 | 
						|
 | 
						|
  //
 | 
						|
  // Get legacy BIOS protocol as it is required to deal with Option ROMs.
 | 
						|
  //
 | 
						|
  StartIndex = *DeviceIndex;
 | 
						|
  Status = gBS->LocateProtocol (
 | 
						|
                  &gEfiLegacyBiosProtocolGuid,
 | 
						|
                  NULL,
 | 
						|
                  (VOID**)&LegacyBios
 | 
						|
                  );
 | 
						|
  ASSERT_EFI_ERROR (Status);
 | 
						|
 | 
						|
  //
 | 
						|
  // Get all PCI handles and check them to generate a list of matching devices.
 | 
						|
  //
 | 
						|
  gBS->LocateHandleBuffer (
 | 
						|
         ByProtocol,
 | 
						|
         &gEfiPciIoProtocolGuid,
 | 
						|
         NULL,
 | 
						|
         &HandleCount,
 | 
						|
         &HandleBuffer
 | 
						|
         );
 | 
						|
  for (Index = 0; Index < HandleCount; Index++) {
 | 
						|
    gBS->HandleProtocol (
 | 
						|
           HandleBuffer[Index],
 | 
						|
           &gEfiPciIoProtocolGuid,
 | 
						|
           (VOID**)&PciIo
 | 
						|
           );
 | 
						|
    PciIo->Pci.Read (
 | 
						|
                 PciIo,
 | 
						|
                 EfiPciIoWidthUint32,
 | 
						|
                 0,
 | 
						|
                 sizeof (PciConfigHeader) / sizeof (UINT32),
 | 
						|
                 &PciConfigHeader
 | 
						|
                 );
 | 
						|
    for (Index2 = 0; PciClasses[Index2].Class != 0xff; Index2++) {
 | 
						|
        if ((PciConfigHeader.Hdr.ClassCode[2] == PciClasses[Index2].Class) &&
 | 
						|
            (PciConfigHeader.Hdr.ClassCode[1] == PciClasses[Index2].SubClass)) {
 | 
						|
        LegacyBios->CheckPciRom (
 | 
						|
                      LegacyBios,
 | 
						|
                      HandleBuffer[Index],
 | 
						|
                      NULL,
 | 
						|
                      NULL,
 | 
						|
                      &Flags
 | 
						|
                      );
 | 
						|
 | 
						|
        //
 | 
						|
        // Verify that results of OPROM check match request.
 | 
						|
        // The two valid requests are:
 | 
						|
        //   DeviceFlags = 0 require a valid legacy ROM
 | 
						|
        //   DeviceFlags = 1 require either no ROM or a valid legacy ROM
 | 
						|
        //
 | 
						|
        if (
 | 
						|
            ((DeviceFlags != 0) && (Flags == NO_ROM)) ||
 | 
						|
            ((Flags & (ROM_FOUND | VALID_LEGACY_ROM)) == (ROM_FOUND | VALID_LEGACY_ROM))
 | 
						|
           ) {
 | 
						|
          DeviceTable->Handle = HandleBuffer[Index];
 | 
						|
          DeviceTable->Vid    = PciConfigHeader.Hdr.VendorId;
 | 
						|
          DeviceTable->Did    = PciConfigHeader.Hdr.DeviceId;
 | 
						|
          DeviceTable->SvId   = PciConfigHeader.Device.SubsystemVendorID;
 | 
						|
          DeviceTable->SysId  = PciConfigHeader.Device.SubsystemID;
 | 
						|
          ++ *DeviceIndex;
 | 
						|
          DeviceTable++;
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Free any allocated buffers
 | 
						|
  //
 | 
						|
  gBS->FreePool (HandleBuffer);
 | 
						|
 | 
						|
  if (*DeviceIndex != StartIndex) {
 | 
						|
    return EFI_SUCCESS;
 | 
						|
  } else {
 | 
						|
    return EFI_NOT_FOUND;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Load and initialize the Legacy BIOS SMM handler.
 | 
						|
 | 
						|
  @param  This                   The protocol instance pointer.
 | 
						|
  @param  EfiToLegacy16BootTable A pointer to Legacy16 boot table.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           SMM code loaded.
 | 
						|
  @retval EFI_DEVICE_ERROR      SMM code failed to load
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
SmmInit (
 | 
						|
  IN  EFI_LEGACY_BIOS_PLATFORM_PROTOCOL           *This,
 | 
						|
  IN  VOID                                        *EfiToLegacy16BootTable
 | 
						|
  )
 | 
						|
{
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Finds the device path that should be used as the primary display adapter.
 | 
						|
 | 
						|
  @param  VgaHandle - The handle of the video device
 | 
						|
 | 
						|
**/
 | 
						|
VOID
 | 
						|
GetSelectedVgaDeviceInfo (
 | 
						|
  OUT EFI_HANDLE                *VgaHandle
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                Status;
 | 
						|
  UINTN                     HandleCount;
 | 
						|
  EFI_HANDLE                *HandleBuffer;
 | 
						|
  UINTN                     Index;
 | 
						|
  EFI_PCI_IO_PROTOCOL       *PciIo;
 | 
						|
  PCI_TYPE00                Pci;
 | 
						|
  UINT8                     MinBus;
 | 
						|
  UINT8                     MaxBus;
 | 
						|
  UINTN                     Segment;
 | 
						|
  UINTN                     Bus;
 | 
						|
  UINTN                     Device;
 | 
						|
  UINTN                     Function;
 | 
						|
  UINTN                     SelectedAddress;
 | 
						|
  UINTN                     CurrentAddress;
 | 
						|
 | 
						|
  //
 | 
						|
  // Initialize return to 'not found' state
 | 
						|
  //
 | 
						|
  *VgaHandle = NULL;
 | 
						|
 | 
						|
  //
 | 
						|
  // Initialize variable states.  This is important for selecting the VGA
 | 
						|
  // device if multiple devices exist behind a single bridge.
 | 
						|
  //
 | 
						|
  HandleCount = 0;
 | 
						|
  HandleBuffer = NULL;
 | 
						|
  SelectedAddress = PCI_LIB_ADDRESS(0xff, 0x1f, 0x7, 0);
 | 
						|
 | 
						|
  //
 | 
						|
  // The bus range to search for a VGA device in.
 | 
						|
  //
 | 
						|
  MinBus = MaxBus = 0;
 | 
						|
 | 
						|
  //
 | 
						|
  // Start to check all the pci io to find all possible VGA device
 | 
						|
  //
 | 
						|
  HandleCount = 0;
 | 
						|
  HandleBuffer = NULL;
 | 
						|
  Status = gBS->LocateHandleBuffer (
 | 
						|
                  ByProtocol,
 | 
						|
                  &gEfiPciIoProtocolGuid,
 | 
						|
                  NULL,
 | 
						|
                  &HandleCount,
 | 
						|
                  &HandleBuffer
 | 
						|
                  );
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  for (Index = 0; Index < HandleCount; Index++) {
 | 
						|
    Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiPciIoProtocolGuid, (VOID**)&PciIo);
 | 
						|
    if (!EFI_ERROR (Status)) {
 | 
						|
      //
 | 
						|
      // Detemine if this is in the correct bus range.
 | 
						|
      //
 | 
						|
      Status = PciIo->GetLocation (PciIo, &Segment, &Bus, &Device, &Function);
 | 
						|
      if (EFI_ERROR(Status) || (Bus < MinBus || Bus > MaxBus)) {
 | 
						|
        continue;
 | 
						|
      }
 | 
						|
 | 
						|
      //
 | 
						|
      // Read device information.
 | 
						|
      //
 | 
						|
      Status = PciIo->Pci.Read (
 | 
						|
                        PciIo,
 | 
						|
                        EfiPciIoWidthUint32,
 | 
						|
                        0,
 | 
						|
                        sizeof (Pci) / sizeof (UINT32),
 | 
						|
                        &Pci
 | 
						|
                        );
 | 
						|
      if (EFI_ERROR (Status)) {
 | 
						|
        continue;
 | 
						|
      }
 | 
						|
 | 
						|
      //
 | 
						|
      // Make sure the device is a VGA device.
 | 
						|
      //
 | 
						|
      if (!IS_PCI_VGA (&Pci)) {
 | 
						|
        continue;
 | 
						|
      }
 | 
						|
      DEBUG ((EFI_D_INFO,
 | 
						|
        "PCI VGA: 0x%04x:0x%04x\n",
 | 
						|
        Pci.Hdr.VendorId,
 | 
						|
        Pci.Hdr.DeviceId
 | 
						|
        ));
 | 
						|
 | 
						|
      //
 | 
						|
      // Currently we use the lowest numbered bus/device/function if multiple
 | 
						|
      // devices are found in the target bus range.
 | 
						|
      //
 | 
						|
      CurrentAddress = PCI_LIB_ADDRESS(Bus, Device, Function, 0);
 | 
						|
      if (CurrentAddress < SelectedAddress) {
 | 
						|
        SelectedAddress = CurrentAddress;
 | 
						|
        *VgaHandle = HandleBuffer[Index];
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  FreePool (HandleBuffer);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Returns a buffer of handles for the requested subfunction.
 | 
						|
 | 
						|
  @param  This                  The protocol instance pointer.
 | 
						|
  @param  Mode                  Specifies what handle to return. See EFI_GET_PLATFORM_HANDLE_MODE enum.
 | 
						|
  @param  Type                  Mode specific. See EFI_GET_PLATFORM_HANDLE_MODE enum.
 | 
						|
  @param  HandleBuffer          Mode specific. See EFI_GET_PLATFORM_HANDLE_MODE enum.
 | 
						|
  @param  HandleCount           Mode specific. See EFI_GET_PLATFORM_HANDLE_MODE enum.
 | 
						|
  @param  AdditionalData        Mode specific. See EFI_GET_PLATFORM_HANDLE_MODE enum.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           Handle is valid.
 | 
						|
  @retval EFI_UNSUPPORTED       Mode is not supported on the platform.
 | 
						|
  @retval EFI_NOT_FOUND         Handle is not known.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
GetPlatformHandle (
 | 
						|
  IN  EFI_LEGACY_BIOS_PLATFORM_PROTOCOL           *This,
 | 
						|
  IN  EFI_GET_PLATFORM_HANDLE_MODE                Mode,
 | 
						|
  IN  UINT16                                      Type,
 | 
						|
  OUT EFI_HANDLE                                  **HandleBuffer,
 | 
						|
  OUT UINTN                                       *HandleCount,
 | 
						|
  OUT VOID                                        **AdditionalData OPTIONAL
 | 
						|
  )
 | 
						|
{
 | 
						|
  DEVICE_STRUCTURE    LocalDevice[0x40];
 | 
						|
  UINT32              LocalIndex;
 | 
						|
  UINT32              Index;
 | 
						|
  DEVICE_STRUCTURE    TempDevice;
 | 
						|
  EFI_STATUS          Status;
 | 
						|
  EFI_PCI_IO_PROTOCOL *PciIo;
 | 
						|
  UINTN               Segment;
 | 
						|
  UINTN               Bus;
 | 
						|
  UINTN               Device;
 | 
						|
  UINTN               Function;
 | 
						|
  HDD_INFO            *HddInfo;
 | 
						|
  PCI_TYPE00          PciConfigHeader;
 | 
						|
  UINT32              HddIndex;
 | 
						|
  EFI_HANDLE          IdeHandle;
 | 
						|
  EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;
 | 
						|
  PCI_CLASS_RECORD    ClassLists[10];
 | 
						|
  UINTN               PriorityIndex;
 | 
						|
 | 
						|
  static BOOLEAN      bConnected = FALSE;
 | 
						|
 | 
						|
  LocalIndex  = 0x00;
 | 
						|
  HddInfo     = NULL;
 | 
						|
  HddIndex    = 0;
 | 
						|
 | 
						|
  Status = gBS->LocateProtocol (
 | 
						|
                  &gEfiLegacyBiosProtocolGuid,
 | 
						|
                  NULL,
 | 
						|
                  (VOID**)&LegacyBios
 | 
						|
                  );
 | 
						|
 | 
						|
  //
 | 
						|
  // Process mode specific operations
 | 
						|
  //
 | 
						|
  switch (Mode) {
 | 
						|
    case EfiGetPlatformVgaHandle:
 | 
						|
      //
 | 
						|
      // Get the handle for the currently selected VGA device.
 | 
						|
      //
 | 
						|
      GetSelectedVgaDeviceInfo (&mVgaHandles[0]);
 | 
						|
      *HandleBuffer = &mVgaHandles[0];
 | 
						|
      *HandleCount  = (mVgaHandles[0] != NULL) ? 1 : 0;
 | 
						|
      return EFI_SUCCESS;
 | 
						|
    case EfiGetPlatformIdeHandle:
 | 
						|
      IdeHandle  = NULL;
 | 
						|
      if (AdditionalData != NULL) {
 | 
						|
        HddInfo = (HDD_INFO *) *AdditionalData;
 | 
						|
      }
 | 
						|
 | 
						|
      //
 | 
						|
      // Locate all found block io devices
 | 
						|
      //
 | 
						|
      ClassLists[0].Class    = PCI_CLASS_MASS_STORAGE;
 | 
						|
      ClassLists[0].SubClass = PCI_CLASS_MASS_STORAGE_SCSI;
 | 
						|
      ClassLists[1].Class    = PCI_CLASS_MASS_STORAGE;
 | 
						|
      ClassLists[1].SubClass = PCI_CLASS_MASS_STORAGE_IDE;
 | 
						|
      ClassLists[2].Class    = PCI_CLASS_MASS_STORAGE;
 | 
						|
      ClassLists[2].SubClass = PCI_CLASS_MASS_STORAGE_RAID;
 | 
						|
      ClassLists[3].Class    = PCI_CLASS_MASS_STORAGE;
 | 
						|
      ClassLists[3].SubClass = PCI_CLASS_MASS_STORAGE_SATADPA;
 | 
						|
      ClassLists[4].Class    = 0xff;
 | 
						|
      FindAllDeviceTypes (ClassLists, LocalDevice, (UINT16 *) &LocalIndex, TRUE);
 | 
						|
      if (LocalIndex == 0) {
 | 
						|
        return EFI_NOT_FOUND;
 | 
						|
      }
 | 
						|
 | 
						|
      //
 | 
						|
      // Make sure all IDE controllers are connected. This is necessary
 | 
						|
      // in NO_CONFIG_CHANGE boot path to ensure IDE controller is correctly
 | 
						|
      // initialized and all IDE drives are enumerated
 | 
						|
      //
 | 
						|
      if (!bConnected) {
 | 
						|
        for (Index = 0; Index < LocalIndex; Index++) {
 | 
						|
          gBS->ConnectController (LocalDevice[Index].Handle, NULL, NULL, TRUE);
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      //
 | 
						|
      // Locate onboard controllers.
 | 
						|
      //
 | 
						|
      for (Index = 0; Index < LocalIndex; Index++) {
 | 
						|
        if (LocalDevice[Index].Vid == V_INTEL_VENDOR_ID) {
 | 
						|
          if (LocalDevice[Index].Did == V_PIIX4_IDE_DEVICE_ID) {
 | 
						|
            IdeHandle = LocalDevice[Index].Handle;
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      //
 | 
						|
      // Set the IDE contorller as primary devices.
 | 
						|
      //
 | 
						|
      PriorityIndex = 0;
 | 
						|
      for (Index = 0; Index < LocalIndex; Index++) {
 | 
						|
        if (LocalDevice[Index].Handle == IdeHandle && PriorityIndex == 0) {
 | 
						|
          TempDevice = LocalDevice[PriorityIndex];
 | 
						|
          LocalDevice[PriorityIndex] = LocalDevice[Index];
 | 
						|
          LocalDevice[Index] = TempDevice;
 | 
						|
          PriorityIndex++;
 | 
						|
          break;
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      //
 | 
						|
      // Copy over handles and update return values.
 | 
						|
      //
 | 
						|
      for (Index = 0; Index < LocalIndex; Index++) {
 | 
						|
        mDiskHandles[Index] = LocalDevice[Index].Handle;
 | 
						|
      }
 | 
						|
      *HandleBuffer = &mDiskHandles[0];
 | 
						|
      *HandleCount  = LocalIndex;
 | 
						|
 | 
						|
      //
 | 
						|
      // We have connected all IDE controllers once. No more needed
 | 
						|
      //
 | 
						|
      bConnected = TRUE;
 | 
						|
 | 
						|
      //
 | 
						|
      // Log all onboard controllers.
 | 
						|
      //
 | 
						|
      for (Index = 0; (Index < LocalIndex) && (AdditionalData != NULL); Index++) {
 | 
						|
        if ((LocalDevice[Index].Handle != NULL) &&
 | 
						|
            (LocalDevice[Index].Handle == IdeHandle)) {
 | 
						|
          Status = gBS->HandleProtocol (
 | 
						|
                          LocalDevice[Index].Handle,
 | 
						|
                          &gEfiPciIoProtocolGuid,
 | 
						|
                          (VOID **) &PciIo
 | 
						|
                          );
 | 
						|
          PciIo->Pci.Read (
 | 
						|
                       PciIo,
 | 
						|
                       EfiPciIoWidthUint32,
 | 
						|
                       0,
 | 
						|
                       sizeof (PciConfigHeader) / sizeof (UINT32),
 | 
						|
                       &PciConfigHeader
 | 
						|
                       );
 | 
						|
          if (!EFI_ERROR (Status)) {
 | 
						|
            PciIo->GetLocation (
 | 
						|
                     PciIo,
 | 
						|
                     &Segment,
 | 
						|
                     &Bus,
 | 
						|
                     &Device,
 | 
						|
                     &Function
 | 
						|
                     );
 | 
						|
 | 
						|
            //
 | 
						|
            // Be sure to only fill out correct information based on platform
 | 
						|
            // configureation.
 | 
						|
            //
 | 
						|
            HddInfo[HddIndex].Status        |= HDD_PRIMARY;
 | 
						|
            HddInfo[HddIndex].Bus           = (UINT32)Bus;
 | 
						|
            HddInfo[HddIndex].Device        = (UINT32)Device;
 | 
						|
            HddInfo[HddIndex].Function      = (UINT32)Function;
 | 
						|
            HddInfo[HddIndex + 1].Status    |= HDD_SECONDARY;
 | 
						|
            HddInfo[HddIndex + 1].Bus       = (UINT32)Bus;
 | 
						|
            HddInfo[HddIndex + 1].Device    = (UINT32)Device;
 | 
						|
            HddInfo[HddIndex + 1].Function  = (UINT32)Function;
 | 
						|
 | 
						|
            //
 | 
						|
            // Primary controller data
 | 
						|
            //
 | 
						|
            if ((PciConfigHeader.Hdr.ClassCode[0] & 0x01) != 0) {
 | 
						|
              HddInfo[HddIndex].CommandBaseAddress =
 | 
						|
                (UINT16)(PciConfigHeader.Device.Bar[0] & 0xfffc);
 | 
						|
              HddInfo[HddIndex].ControlBaseAddress =
 | 
						|
                (UINT16)((PciConfigHeader.Device.Bar[1] & 0xfffc)+2);
 | 
						|
              HddInfo[HddIndex].BusMasterAddress =
 | 
						|
                (UINT16)(PciConfigHeader.Device.Bar[4] & 0xfffc);
 | 
						|
              HddInfo[HddIndex].HddIrq = PciConfigHeader.Device.InterruptLine;
 | 
						|
            } else {
 | 
						|
              HddInfo[HddIndex].HddIrq = 14;
 | 
						|
              HddInfo[HddIndex].CommandBaseAddress = 0x1f0;
 | 
						|
              HddInfo[HddIndex].ControlBaseAddress = 0x3f6;
 | 
						|
              HddInfo[HddIndex].BusMasterAddress = 0;
 | 
						|
            }
 | 
						|
            HddIndex++;
 | 
						|
 | 
						|
            //
 | 
						|
            // Secondary controller data
 | 
						|
            //
 | 
						|
            if ((PciConfigHeader.Hdr.ClassCode[0] & 0x04) != 0) {
 | 
						|
              HddInfo[HddIndex].CommandBaseAddress =
 | 
						|
                (UINT16)(PciConfigHeader.Device.Bar[2] & 0xfffc);
 | 
						|
              HddInfo[HddIndex].ControlBaseAddress =
 | 
						|
                (UINT16)((PciConfigHeader.Device.Bar[3] & 0xfffc)+2);
 | 
						|
              HddInfo[HddIndex].BusMasterAddress =
 | 
						|
                (UINT16)(HddInfo[HddIndex].BusMasterAddress + 8);
 | 
						|
              HddInfo[HddIndex].HddIrq = PciConfigHeader.Device.InterruptLine;
 | 
						|
            } else {
 | 
						|
              HddInfo[HddIndex].HddIrq = 15;
 | 
						|
              HddInfo[HddIndex].CommandBaseAddress = 0x170;
 | 
						|
              HddInfo[HddIndex].ControlBaseAddress = 0x376;
 | 
						|
              HddInfo[HddIndex].BusMasterAddress = 0;
 | 
						|
            }
 | 
						|
            HddIndex++;
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
      return EFI_SUCCESS;
 | 
						|
    case EfiGetPlatformIsaBusHandle:
 | 
						|
      ClassLists[0].Class    = (UINT8) PCI_CLASS_BRIDGE;
 | 
						|
      ClassLists[0].SubClass = (UINT8) PCI_CLASS_BRIDGE_ISA_PDECODE;
 | 
						|
      ClassLists[1].Class    = (UINT8) PCI_CLASS_BRIDGE;
 | 
						|
      ClassLists[1].SubClass = (UINT8) PCI_CLASS_BRIDGE_ISA;
 | 
						|
      ClassLists[2].Class    = 0xff;
 | 
						|
 | 
						|
      //
 | 
						|
      // Locate all found block io devices
 | 
						|
      //
 | 
						|
      FindAllDeviceTypes (ClassLists, LocalDevice, (UINT16 *) (&LocalIndex), TRUE);
 | 
						|
      if (LocalIndex == 0) {
 | 
						|
        return EFI_NOT_FOUND;
 | 
						|
      }
 | 
						|
 | 
						|
      //
 | 
						|
      // Find our ISA bridge.
 | 
						|
      //
 | 
						|
      for (Index = 0; Index < LocalIndex; Index++) {
 | 
						|
        if (LocalDevice[Index].Vid == V_INTEL_VENDOR_ID) {
 | 
						|
          TempDevice          = LocalDevice[0];
 | 
						|
          LocalDevice[0]      = LocalDevice[Index];
 | 
						|
          LocalDevice[Index]  = TempDevice;
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      //
 | 
						|
      // Perform copy and update return values.
 | 
						|
      //
 | 
						|
      for (Index = 0; Index < LocalIndex; Index++) {
 | 
						|
        mIsaHandles[Index] = LocalDevice[Index].Handle;
 | 
						|
      }
 | 
						|
      *HandleBuffer = &mIsaHandles[0];
 | 
						|
      *HandleCount  = LocalIndex;
 | 
						|
      return EFI_SUCCESS;
 | 
						|
    case EfiGetPlatformUsbHandle:
 | 
						|
    default:
 | 
						|
      return EFI_UNSUPPORTED;
 | 
						|
  };
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Allows platform to perform any required action after a LegacyBios operation.
 | 
						|
  Invokes the specific sub function specified by Mode.
 | 
						|
 | 
						|
  @param  This                  The protocol instance pointer.
 | 
						|
  @param  Mode                  Specifies what handle to return. See EFI_GET_PLATFORM_HOOK_MODE enum.
 | 
						|
  @param  Type                  Mode specific.  See EFI_GET_PLATFORM_HOOK_MODE enum.
 | 
						|
  @param  DeviceHandle          Mode specific.  See EFI_GET_PLATFORM_HOOK_MODE enum.
 | 
						|
  @param  ShadowAddress         Mode specific.  See EFI_GET_PLATFORM_HOOK_MODE enum.
 | 
						|
  @param  Compatibility16Table  Mode specific.  See EFI_GET_PLATFORM_HOOK_MODE enum.
 | 
						|
  @param  AdditionalData        Mode specific.  See EFI_GET_PLATFORM_HOOK_MODE enum.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           The operation performed successfully. Mode specific.
 | 
						|
  @retval EFI_UNSUPPORTED       Mode is not supported on the platform.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
PlatformHooks (
 | 
						|
  IN       EFI_LEGACY_BIOS_PLATFORM_PROTOCOL     *This,
 | 
						|
  IN       EFI_GET_PLATFORM_HOOK_MODE            Mode,
 | 
						|
  IN       UINT16                                Type,
 | 
						|
     OUT   EFI_HANDLE                            DeviceHandle, OPTIONAL
 | 
						|
  IN OUT   UINTN                                 *Shadowaddress, OPTIONAL
 | 
						|
  IN       EFI_COMPATIBILITY16_TABLE             *Compatibility16Table, OPTIONAL
 | 
						|
     OUT   VOID                                  **AdditionalData OPTIONAL
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_IA32_REGISTER_SET     Regs;
 | 
						|
  EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;
 | 
						|
  EFI_STATUS                Status;
 | 
						|
 | 
						|
  switch (Mode) {
 | 
						|
    case EfiPlatformHookPrepareToScanRom:
 | 
						|
      Status = gBS->LocateProtocol (
 | 
						|
                      &gEfiLegacyBiosProtocolGuid,
 | 
						|
                      NULL,
 | 
						|
                      (VOID**)&LegacyBios
 | 
						|
                      );
 | 
						|
 | 
						|
      //
 | 
						|
      // Set the 80x25 Text VGA Mode
 | 
						|
      //
 | 
						|
      Regs.H.AH = 0x00;
 | 
						|
      Regs.H.AL = 0x03;
 | 
						|
      Status = LegacyBios->Int86 (LegacyBios, 0x10, &Regs);
 | 
						|
      return Status;
 | 
						|
    case EfiPlatformHookShadowServiceRoms:
 | 
						|
      return EFI_SUCCESS;
 | 
						|
    case EfiPlatformHookAfterRomInit:
 | 
						|
    default:
 | 
						|
      return EFI_UNSUPPORTED;
 | 
						|
  };
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Returns information associated with PCI IRQ routing.
 | 
						|
  This function returns the following information associated with PCI IRQ routing:
 | 
						|
    * An IRQ routing table and number of entries in the table.
 | 
						|
    * The $PIR table and its size.
 | 
						|
    * A list of PCI IRQs and the priority order to assign them.
 | 
						|
 | 
						|
  @param  This                    The protocol instance pointer.
 | 
						|
  @param  RoutingTable            The pointer to PCI IRQ Routing table.
 | 
						|
                                  This location is the $PIR table minus the header.
 | 
						|
  @param  RoutingTableEntries     The number of entries in table.
 | 
						|
  @param  LocalPirqTable          $PIR table.
 | 
						|
  @param  PirqTableSize           $PIR table size.
 | 
						|
  @param  LocalIrqPriorityTable   A list of interrupts in priority order to assign.
 | 
						|
  @param  IrqPriorityTableEntries The number of entries in the priority table.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           Data was successfully returned.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
GetRoutingTable (
 | 
						|
  IN  EFI_LEGACY_BIOS_PLATFORM_PROTOCOL           *This,
 | 
						|
  OUT VOID                                        **RoutingTable,
 | 
						|
  OUT UINTN                                       *RoutingTableEntries,
 | 
						|
  OUT VOID                                        **LocalPirqTable, OPTIONAL
 | 
						|
  OUT UINTN                                       *PirqTableSize, OPTIONAL
 | 
						|
  OUT VOID                                        **LocalIrqPriorityTable, OPTIONAL
 | 
						|
  OUT UINTN                                       *IrqPriorityTableEntries OPTIONAL
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT16                        PTableSize;
 | 
						|
  UINT32                        Index;
 | 
						|
  UINT8                         Bus;
 | 
						|
  UINT8                         Device;
 | 
						|
  UINT8                         Function;
 | 
						|
  UINT8                         Checksum;
 | 
						|
  UINT8                         *Ptr;
 | 
						|
  EFI_STATUS                    Status;
 | 
						|
  EFI_LEGACY_INTERRUPT_PROTOCOL *LegacyInterrupt;
 | 
						|
 | 
						|
  Checksum = 0;
 | 
						|
 | 
						|
  if (LocalPirqTable != NULL) {
 | 
						|
    PTableSize = sizeof (EFI_LEGACY_PIRQ_TABLE_HEADER) +
 | 
						|
                 sizeof (EFI_LEGACY_IRQ_ROUTING_ENTRY) * MAX_IRQ_ROUTING_ENTRIES;
 | 
						|
 | 
						|
    Status = gBS->LocateProtocol (
 | 
						|
                    &gEfiLegacyInterruptProtocolGuid,
 | 
						|
                    NULL,
 | 
						|
                    (VOID**)&LegacyInterrupt
 | 
						|
                    );
 | 
						|
    ASSERT_EFI_ERROR (Status);
 | 
						|
    LegacyInterrupt->GetLocation (
 | 
						|
                       LegacyInterrupt,
 | 
						|
                       &Bus,
 | 
						|
                       &Device,
 | 
						|
                       &Function
 | 
						|
                       );
 | 
						|
 | 
						|
    //
 | 
						|
    // Update fields in $PIR table header
 | 
						|
    //
 | 
						|
    PirqTableHead.PirqTable.TableSize = PTableSize;
 | 
						|
    PirqTableHead.PirqTable.Bus       = Bus;
 | 
						|
    PirqTableHead.PirqTable.DevFun    = (UINT8) ((Device << 3) + Function);
 | 
						|
    Ptr = (UINT8 *) (&PirqTableHead);
 | 
						|
 | 
						|
    //
 | 
						|
    // Calculate checksum.
 | 
						|
    //
 | 
						|
    for (Index = 0; Index < PTableSize; Index++) {
 | 
						|
      Checksum = (UINT8) (Checksum + (UINT8) *Ptr);
 | 
						|
      Ptr += 1;
 | 
						|
    }
 | 
						|
    Checksum                          = (UINT8) (0x00 - Checksum);
 | 
						|
    PirqTableHead.PirqTable.Checksum  = Checksum;
 | 
						|
 | 
						|
    //
 | 
						|
    // Update return values.
 | 
						|
    //
 | 
						|
    *LocalPirqTable                   = (VOID *) (&PirqTableHead);
 | 
						|
    *PirqTableSize                    = PTableSize;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // More items to return.
 | 
						|
  //
 | 
						|
  *RoutingTable         = PirqTableHead.IrqRoutingEntry;
 | 
						|
  *RoutingTableEntries  = MAX_IRQ_ROUTING_ENTRIES;
 | 
						|
  if (LocalIrqPriorityTable != NULL) {
 | 
						|
    *LocalIrqPriorityTable    = IrqPriorityTable;
 | 
						|
    *IrqPriorityTableEntries  = MAX_IRQ_PRIORITY_ENTRIES;
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Finds the binary data or other platform information.
 | 
						|
 | 
						|
  @param  This                  The protocol instance pointer.
 | 
						|
  @param  Mode                  Specifies what data to return. See See EFI_GET_PLATFORM_INFO_MODE enum.
 | 
						|
  @param  Table                 Mode specific.  See EFI_GET_PLATFORM_INFO_MODE enum.
 | 
						|
  @param  TableSize             Mode specific.  See EFI_GET_PLATFORM_INFO_MODE enum.
 | 
						|
  @param  Location              Mode specific.  See EFI_GET_PLATFORM_INFO_MODE enum.
 | 
						|
  @param  Alignment             Mode specific.  See EFI_GET_PLATFORM_INFO_MODE enum.
 | 
						|
  @param  LegacySegment         Mode specific.  See EFI_GET_PLATFORM_INFO_MODE enum.
 | 
						|
  @param  LegacyOffset          Mode specific.  See EFI_GET_PLATFORM_INFO_MODE enum.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           Data returned successfully.
 | 
						|
  @retval EFI_UNSUPPORTED       Mode is not supported on the platform.
 | 
						|
  @retval EFI_NOT_FOUND         Binary image or table not found.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
GetPlatformInfo (
 | 
						|
  IN  EFI_LEGACY_BIOS_PLATFORM_PROTOCOL           *This,
 | 
						|
  IN  EFI_GET_PLATFORM_INFO_MODE                  Mode,
 | 
						|
  OUT VOID                                        **Table,
 | 
						|
  OUT UINTN                                       *TableSize,
 | 
						|
  OUT UINTN                                       *Location,
 | 
						|
  OUT UINTN                                       *Alignment,
 | 
						|
  IN  UINT16                                      LegacySegment,
 | 
						|
  IN  UINT16                                      LegacyOffset
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                    Status;
 | 
						|
  UINTN                         Index;
 | 
						|
 | 
						|
  switch (Mode) {
 | 
						|
    case EfiGetPlatformBinarySystemRom:
 | 
						|
      //
 | 
						|
      // Loop through table of System rom descriptions
 | 
						|
      //
 | 
						|
      for (Index = 0; mSystemRomTable[Index].Valid != 0; Index++) {
 | 
						|
        Status = GetSectionFromFv (
 | 
						|
                   &mSystemRomTable[Index].FileName,
 | 
						|
                   EFI_SECTION_RAW,
 | 
						|
                   0,
 | 
						|
                   Table,
 | 
						|
                   (UINTN *) TableSize
 | 
						|
                   );
 | 
						|
        if (EFI_ERROR (Status)) {
 | 
						|
          continue;
 | 
						|
        }
 | 
						|
        return EFI_SUCCESS;
 | 
						|
      }
 | 
						|
 | 
						|
      return EFI_NOT_FOUND;
 | 
						|
    case EfiGetPlatformBinaryOem16Data:
 | 
						|
    case EfiGetPlatformBinaryMpTable:
 | 
						|
    case EfiGetPlatformBinaryOemIntData:
 | 
						|
    case EfiGetPlatformBinaryOem32Data:
 | 
						|
    case EfiGetPlatformBinaryTpmBinary:
 | 
						|
    case EfiGetPlatformPciExpressBase:
 | 
						|
    default:
 | 
						|
      return EFI_UNSUPPORTED;
 | 
						|
  };
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  Translates the given PIRQ accounting for bridge.
 | 
						|
  This function translates the given PIRQ back through all buses, if required,
 | 
						|
  and returns the true PIRQ and associated IRQ.
 | 
						|
 | 
						|
  @param  This                  The protocol instance pointer.
 | 
						|
  @param  PciBus                The PCI bus number for this device.
 | 
						|
  @param  PciDevice             The PCI device number for this device.
 | 
						|
  @param  PciFunction           The PCI function number for this device.
 | 
						|
  @param  Pirq                  Input is PIRQ reported by device, and output is true PIRQ.
 | 
						|
  @param  PciIrq                The IRQ already assigned to the PIRQ, or the IRQ to be
 | 
						|
                                assigned to the PIRQ.
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           The PIRQ was translated.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
TranslatePirq (
 | 
						|
  IN        EFI_LEGACY_BIOS_PLATFORM_PROTOCOL           *This,
 | 
						|
  IN        UINTN                                       PciBus,
 | 
						|
  IN        UINTN                                       PciDevice,
 | 
						|
  IN        UINTN                                       PciFunction,
 | 
						|
  IN  OUT   UINT8                                       *Pirq,
 | 
						|
      OUT   UINT8                                       *PciIrq
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_LEGACY_INTERRUPT_PROTOCOL      *LegacyInterrupt;
 | 
						|
  EFI_STATUS                         Status;
 | 
						|
  UINTN                              Index;
 | 
						|
  UINTN                              Index1;
 | 
						|
  UINT8                              LocalPirq;
 | 
						|
  UINT8                              PirqData;
 | 
						|
  UINT8                              MatchData;
 | 
						|
 | 
						|
  Status = gBS->LocateProtocol (
 | 
						|
                  &gEfiLegacyInterruptProtocolGuid,
 | 
						|
                  NULL,
 | 
						|
                  (VOID**)&LegacyInterrupt
 | 
						|
                  );
 | 
						|
  ASSERT_EFI_ERROR (Status);
 | 
						|
  LocalPirq = (UINT8) (*Pirq);
 | 
						|
 | 
						|
  for (Index = 0; Index < MAX_IRQ_ROUTING_ENTRIES; Index++) {
 | 
						|
    if ((PirqTableHead.IrqRoutingEntry[Index].Bus == PciBus) &&
 | 
						|
        (PirqTableHead.IrqRoutingEntry[Index].Device == PciDevice)) {
 | 
						|
      LocalPirq = (UINT8) (PirqTableHead.IrqRoutingEntry[Index].PirqEntry[LocalPirq].Pirq & 0x0f);
 | 
						|
      if (LocalPirq > 4) {
 | 
						|
        LocalPirq -= 4;
 | 
						|
      }
 | 
						|
 | 
						|
      LegacyInterrupt->ReadPirq (LegacyInterrupt, LocalPirq, &PirqData);
 | 
						|
      MatchData = PCI_UNUSED;
 | 
						|
      while (PirqData == 0) {
 | 
						|
        for (Index1 = 0; Index1 < MAX_IRQ_PRIORITY_ENTRIES; Index1++) {
 | 
						|
          if ((IrqPriorityTable[Index1].Used == MatchData) &&
 | 
						|
              (IrqPriorityTable[Index1].Irq != 0)) {
 | 
						|
            PirqData = IrqPriorityTable[Index1].Irq;
 | 
						|
            IrqPriorityTable[Index1].Used = 0xff;
 | 
						|
            LegacyInterrupt->WritePirq (
 | 
						|
                               LegacyInterrupt,
 | 
						|
                               LocalPirq,
 | 
						|
                               PirqData
 | 
						|
                               );
 | 
						|
            break;
 | 
						|
          }
 | 
						|
        }
 | 
						|
 | 
						|
        if (PirqData == 0) {
 | 
						|
 | 
						|
          //
 | 
						|
          // No unused interrpts, so start reusing them.
 | 
						|
          //
 | 
						|
          MatchData = (UINT8) (~MatchData);
 | 
						|
        }
 | 
						|
      }
 | 
						|
 | 
						|
      *PciIrq = PirqData;
 | 
						|
      *Pirq   = LocalPirq;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Attempt to legacy boot the BootOption. If the EFI contexted has been
 | 
						|
  compromised this function will not return.
 | 
						|
 | 
						|
  @param  This                   The protocol instance pointer.
 | 
						|
  @param  BbsDevicePath          The EFI Device Path from BootXXXX variable.
 | 
						|
  @param  BbsTable               The Internal BBS table.
 | 
						|
  @param  LoadOptionSize         The size of LoadOption in size.
 | 
						|
  @param  LoadOption             The LoadOption from BootXXXX variable
 | 
						|
  @param  EfiToLegacy16BootTable A pointer to BootTable structure
 | 
						|
 | 
						|
  @retval EFI_SUCCESS           Ready to boot.
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
PrepareToBoot (
 | 
						|
  IN  EFI_LEGACY_BIOS_PLATFORM_PROTOCOL           *This,
 | 
						|
  IN  BBS_BBS_DEVICE_PATH                         *BbsDevicePath,
 | 
						|
  IN  VOID                                        *BbsTable,
 | 
						|
  IN  UINT32                                      LoadOptionsSize,
 | 
						|
  IN  VOID                                        *LoadOptions,
 | 
						|
  IN  VOID                                        *EfiToLegacy16BootTable
 | 
						|
  )
 | 
						|
{
 | 
						|
  BBS_TABLE                           *LocalBbsTable;
 | 
						|
  EFI_TO_COMPATIBILITY16_BOOT_TABLE   *Legacy16BootTable;
 | 
						|
  DEVICE_PRODUCER_DATA_HEADER         *SioPtr;
 | 
						|
  UINT16                              DevicePathType;
 | 
						|
  UINT16                              Index;
 | 
						|
  UINT16                              Priority;
 | 
						|
 | 
						|
  //
 | 
						|
  // Initialize values
 | 
						|
  //
 | 
						|
  Priority = 0;
 | 
						|
  Legacy16BootTable = (EFI_TO_COMPATIBILITY16_BOOT_TABLE*) EfiToLegacy16BootTable;
 | 
						|
 | 
						|
  //
 | 
						|
  // Set how Gate A20 is gated by hardware
 | 
						|
  //
 | 
						|
  SioPtr                  = &Legacy16BootTable->SioData;
 | 
						|
  SioPtr->Flags.A20Kybd   = 1;
 | 
						|
  SioPtr->Flags.A20Port90 = 1;
 | 
						|
  SioPtr->MousePresent    = 1;
 | 
						|
 | 
						|
  LocalBbsTable           = BbsTable;
 | 
						|
 | 
						|
  //
 | 
						|
  // There are 2 cases that must be covered.
 | 
						|
  // Case 1: Booting to a legacy OS - BbsDevicePath is non-NULL.
 | 
						|
  // Case 2: Booting to an EFI aware OS - BbsDevicePath is NULL.
 | 
						|
  //         We need to perform the PrepareToBoot function to assign
 | 
						|
  //         drive numbers to HDD devices to allow the shell or EFI
 | 
						|
  //         to access them.
 | 
						|
  //
 | 
						|
  if (BbsDevicePath != NULL) {
 | 
						|
    DevicePathType = BbsDevicePath->DeviceType;
 | 
						|
  } else {
 | 
						|
    DevicePathType = BBS_HARDDISK;
 | 
						|
  }
 | 
						|
 | 
						|
  //
 | 
						|
  // Skip the boot devices where priority is set by BDS and set the next one
 | 
						|
  //
 | 
						|
  for (Index = 0; Index < Legacy16BootTable->NumberBbsEntries; Index++) {
 | 
						|
    if ((LocalBbsTable[Index].BootPriority != BBS_UNPRIORITIZED_ENTRY) &&
 | 
						|
        (LocalBbsTable[Index].BootPriority != BBS_IGNORE_ENTRY) &&
 | 
						|
        (LocalBbsTable[Index].BootPriority != BBS_LOWEST_PRIORITY) &&
 | 
						|
        (Priority <= LocalBbsTable[Index].BootPriority)) {
 | 
						|
      Priority = (UINT16) (LocalBbsTable[Index].BootPriority + 1);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  switch (DevicePathType) {
 | 
						|
    case BBS_FLOPPY:
 | 
						|
    case BBS_HARDDISK:
 | 
						|
    case BBS_CDROM:
 | 
						|
    case BBS_EMBED_NETWORK:
 | 
						|
      for (Index = 0; Index < Legacy16BootTable->NumberBbsEntries; Index++) {
 | 
						|
        if ((LocalBbsTable[Index].BootPriority == BBS_UNPRIORITIZED_ENTRY) &&
 | 
						|
            (LocalBbsTable[Index].DeviceType == DevicePathType)) {
 | 
						|
          LocalBbsTable[Index].BootPriority = Priority;
 | 
						|
          ++Priority;
 | 
						|
        }
 | 
						|
      }
 | 
						|
      break;
 | 
						|
    case BBS_BEV_DEVICE:
 | 
						|
      for (Index = 0; Index < Legacy16BootTable->NumberBbsEntries; Index++) {
 | 
						|
        if ((LocalBbsTable[Index].BootPriority == BBS_UNPRIORITIZED_ENTRY) &&
 | 
						|
            (LocalBbsTable[Index].Class == 01) &&
 | 
						|
            (LocalBbsTable[Index].SubClass == 01)) {
 | 
						|
          LocalBbsTable[Index].BootPriority = Priority;
 | 
						|
          ++Priority;
 | 
						|
        }
 | 
						|
      }
 | 
						|
      break;
 | 
						|
    case BBS_USB:
 | 
						|
    case BBS_PCMCIA:
 | 
						|
    case BBS_UNKNOWN:
 | 
						|
    default:
 | 
						|
      break;
 | 
						|
  };
 | 
						|
 | 
						|
  //
 | 
						|
  // Set priority for rest of devices
 | 
						|
  //
 | 
						|
  for (Index = 0; Index < Legacy16BootTable->NumberBbsEntries; Index++) {
 | 
						|
    if (LocalBbsTable[Index].BootPriority == BBS_UNPRIORITIZED_ENTRY) {
 | 
						|
      LocalBbsTable[Index].BootPriority = Priority;
 | 
						|
      ++Priority;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
  Initialize Legacy Platform support
 | 
						|
 | 
						|
  @retval EFI_SUCCESS   Successfully initialized
 | 
						|
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
LegacyBiosPlatformInstall (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS                           Status;
 | 
						|
  LEGACY_BIOS_PLATFORM_INSTANCE        *Private;
 | 
						|
 | 
						|
  mImageHandle = gImageHandle;
 | 
						|
  Private = &mPrivateData;
 | 
						|
 | 
						|
  //
 | 
						|
  // Grab a copy of all the protocols we depend on.
 | 
						|
  //
 | 
						|
  Private->Signature = LEGACY_BIOS_PLATFORM_INSTANCE_SIGNATURE;
 | 
						|
  Private->LegacyBiosPlatform.GetPlatformInfo   = GetPlatformInfo;
 | 
						|
  Private->LegacyBiosPlatform.GetPlatformHandle = GetPlatformHandle;
 | 
						|
  Private->LegacyBiosPlatform.SmmInit           = SmmInit;
 | 
						|
  Private->LegacyBiosPlatform.PlatformHooks     = PlatformHooks;
 | 
						|
  Private->LegacyBiosPlatform.GetRoutingTable   = GetRoutingTable;
 | 
						|
  Private->LegacyBiosPlatform.TranslatePirq     = TranslatePirq;
 | 
						|
  Private->LegacyBiosPlatform.PrepareToBoot     = PrepareToBoot;
 | 
						|
  Private->ImageHandle = gImageHandle;
 | 
						|
 | 
						|
  //
 | 
						|
  // Make a new handle and install the protocol
 | 
						|
  //
 | 
						|
  Private->Handle = NULL;
 | 
						|
  Status = gBS->InstallProtocolInterface (
 | 
						|
                  &Private->Handle,
 | 
						|
                  &gEfiLegacyBiosPlatformProtocolGuid,
 | 
						|
                  EFI_NATIVE_INTERFACE,
 | 
						|
                  &Private->LegacyBiosPlatform
 | 
						|
                  );
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 |