示例#1
0
文件: DebugMp.c 项目: baranee/edk2
/**
  Check the next pending breaking CPU.

  @retval others      There is at least one processor broken, the minimum
                      index number of Processor returned.
  @retval -1          No any processor broken.

**/
UINT32
FindNextPendingBreakCpu (
  VOID
  )
{
  UINT32               Index;

  for (Index = 0; Index < DEBUG_CPU_MAX_COUNT / 8; Index ++) {
    if (mDebugMpContext.CpuBreakMask[Index] != 0) {
      return  (UINT32) LowBitSet32 (mDebugMpContext.CpuBreakMask[Index]) + Index * 8;
    }
  }
  return (UINT32)-1;
}
示例#2
0
文件: SecMain.c 项目: baranee/edk2
INTN
EFIAPI
main (
  IN  INTN  Argc,
  IN  CHAR8 **Argv,
  IN  CHAR8 **Envp
  )
/*++

Routine Description:
  Main entry point to SEC for WinNt. This is a Windows program

Arguments:
  Argc - Number of command line arguments
  Argv - Array of command line argument strings
  Envp - Array of environment variable strings

Returns:
  0 - Normal exit
  1 - Abnormal exit

--*/
{
  EFI_STATUS            Status;
  HANDLE                Token;
  TOKEN_PRIVILEGES      TokenPrivileges;
  EFI_PHYSICAL_ADDRESS  InitialStackMemory;
  UINT64                InitialStackMemorySize;
  UINTN                 Index;
  UINTN                 Index1;
  UINTN                 Index2;
  CHAR16                *FileName;
  CHAR16                *FileNamePtr;
  BOOLEAN               Done;
  VOID                  *PeiCoreFile;
  CHAR16                *MemorySizeStr;
  CHAR16                *FirmwareVolumesStr;
  UINTN                 *StackPointer;
  UINT32                ProcessAffinityMask;
  UINT32                SystemAffinityMask;
  INT32                 LowBit;


  //
  // Enable the privilege so that RTC driver can successfully run SetTime()
  //
  OpenProcessToken (GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &Token);
  if (LookupPrivilegeValue(NULL, SE_TIME_ZONE_NAME, &TokenPrivileges.Privileges[0].Luid)) {
    TokenPrivileges.PrivilegeCount = 1;
    TokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    AdjustTokenPrivileges(Token, FALSE, &TokenPrivileges, 0, (PTOKEN_PRIVILEGES) NULL, 0);
  }

  MemorySizeStr      = (CHAR16 *) PcdGetPtr (PcdWinNtMemorySizeForSecMain);
  FirmwareVolumesStr = (CHAR16 *) PcdGetPtr (PcdWinNtFirmwareVolume);

  SecPrint ("\nEDK II SEC Main NT Emulation Environment from www.TianoCore.org\n");

  //
  // Determine the first thread available to this process.
  //
  if (GetProcessAffinityMask (GetCurrentProcess (), &ProcessAffinityMask, &SystemAffinityMask)) {
    LowBit = (INT32)LowBitSet32 (ProcessAffinityMask);
    if (LowBit != -1) {
      //
      // Force the system to bind the process to a single thread to work
      // around odd semaphore type crashes.
      //
      SetProcessAffinityMask (GetCurrentProcess (), (INTN)(BIT0 << LowBit));
    }
  }

  //
  // Make some Windows calls to Set the process to the highest priority in the
  //  idle class. We need this to have good performance.
  //
  SetPriorityClass (GetCurrentProcess (), IDLE_PRIORITY_CLASS);
  SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST);

  //
  // Allocate space for gSystemMemory Array
  //
  gSystemMemoryCount  = CountSeparatorsInString (MemorySizeStr, '!') + 1;
  gSystemMemory       = calloc (gSystemMemoryCount, sizeof (NT_SYSTEM_MEMORY));
  if (gSystemMemory == NULL) {
    SecPrint ("ERROR : Can not allocate memory for %S.  Exiting.\n", MemorySizeStr);
    exit (1);
  }
  //
  // Allocate space for gSystemMemory Array
  //
  gFdInfoCount  = CountSeparatorsInString (FirmwareVolumesStr, '!') + 1;
  gFdInfo       = calloc (gFdInfoCount, sizeof (NT_FD_INFO));
  if (gFdInfo == NULL) {
    SecPrint ("ERROR : Can not allocate memory for %S.  Exiting.\n", FirmwareVolumesStr);
    exit (1);
  }
  //
  // Setup Boot Mode. If BootModeStr == "" then BootMode = 0 (BOOT_WITH_FULL_CONFIGURATION)
  //
  SecPrint ("  BootMode 0x%02x\n", PcdGet32 (PcdWinNtBootMode));

  //
  //  Allocate 128K memory to emulate temp memory for PEI.
  //  on a real platform this would be SRAM, or using the cache as RAM.
  //  Set InitialStackMemory to zero so WinNtOpenFile will allocate a new mapping
  //
  InitialStackMemorySize  = STACK_SIZE;
  InitialStackMemory = (EFI_PHYSICAL_ADDRESS) (UINTN) VirtualAlloc (NULL, (SIZE_T) (InitialStackMemorySize), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  if (InitialStackMemory == 0) {
    SecPrint ("ERROR : Can not allocate enough space for SecStack\n");
    exit (1);
  }

  for (StackPointer = (UINTN*) (UINTN) InitialStackMemory;
       StackPointer < (UINTN*) ((UINTN)InitialStackMemory + (SIZE_T) InitialStackMemorySize);
       StackPointer ++) {
    *StackPointer = 0x5AA55AA5;
  }
  
  SecPrint ("  SEC passing in %d bytes of temp RAM to PEI\n", InitialStackMemorySize);

  //
  // Open All the firmware volumes and remember the info in the gFdInfo global
  //
  FileNamePtr = (CHAR16 *)malloc (StrLen ((CHAR16 *)FirmwareVolumesStr) * sizeof(CHAR16));
  if (FileNamePtr == NULL) {
    SecPrint ("ERROR : Can not allocate memory for firmware volume string\n");
    exit (1);
  }

  StrCpy (FileNamePtr, (CHAR16*)FirmwareVolumesStr);

  for (Done = FALSE, Index = 0, PeiCoreFile = NULL; !Done; Index++) {
    FileName = FileNamePtr;
    for (Index1 = 0; (FileNamePtr[Index1] != '!') && (FileNamePtr[Index1] != 0); Index1++)
      ;
    if (FileNamePtr[Index1] == 0) {
      Done = TRUE;
    } else {
      FileNamePtr[Index1]  = '\0';
      FileNamePtr = FileNamePtr + Index1 + 1;
    }

    //
    // Open the FD and remember where it got mapped into our processes address space
    //
    Status = WinNtOpenFile (
              FileName,
              0,
              OPEN_EXISTING,
              &gFdInfo[Index].Address,
              &gFdInfo[Index].Size
              );
    if (EFI_ERROR (Status)) {
      SecPrint ("ERROR : Can not open Firmware Device File %S (0x%X).  Exiting.\n", FileName, Status);
      exit (1);
    }

    SecPrint ("  FD loaded from");
    //
    // printf can't print filenames directly as the \ gets interpreted as an
    //  escape character.
    //
    for (Index2 = 0; FileName[Index2] != '\0'; Index2++) {
      SecPrint ("%c", FileName[Index2]);
    }

    if (PeiCoreFile == NULL) {
      //
      // Assume the beginning of the FD is an FV and look for the PEI Core.
      // Load the first one we find.
      //
      Status = SecFfsFindPeiCore ((EFI_FIRMWARE_VOLUME_HEADER *) (UINTN) gFdInfo[Index].Address, &PeiCoreFile);
      if (!EFI_ERROR (Status)) {
        SecPrint (" contains SEC Core");
      }
    }

    SecPrint ("\n");
  }
  //
  // Calculate memory regions and store the information in the gSystemMemory
  //  global for later use. The autosizing code will use this data to
  //  map this memory into the SEC process memory space.
  //
  for (Index = 0, Done = FALSE; !Done; Index++) {
    //
    // Save the size of the memory and make a Unicode filename SystemMemory00, ...
    //
    gSystemMemory[Index].Size = _wtoi (MemorySizeStr) * 0x100000;

    //
    // Find the next region
    //
    for (Index1 = 0; MemorySizeStr[Index1] != '!' && MemorySizeStr[Index1] != 0; Index1++)
      ;
    if (MemorySizeStr[Index1] == 0) {
      Done = TRUE;
    }

    MemorySizeStr = MemorySizeStr + Index1 + 1;
  }

  SecPrint ("\n");

  //
  // Hand off to PEI Core
  //
  SecLoadFromCore ((UINTN) InitialStackMemory, (UINTN) InitialStackMemorySize, (UINTN) gFdInfo[0].Address, PeiCoreFile);

  //
  // If we get here, then the PEI Core returned. This is an error as PEI should
  //  always hand off to DXE.
  //
  SecPrint ("ERROR : PEI Core returned\n");
  exit (1);
}
示例#3
0
文件: WinHost.c 项目: MattDevo/edk2
INTN
EFIAPI
main (
  IN  INTN  Argc,
  IN  CHAR8 **Argv,
  IN  CHAR8 **Envp
  )
/*++

Routine Description:
  Main entry point to SEC for WinNt. This is a Windows program

Arguments:
  Argc - Number of command line arguments
  Argv - Array of command line argument strings
  Envp - Array of environment variable strings

Returns:
  0 - Normal exit
  1 - Abnormal exit

--*/
{
  EFI_STATUS            Status;
  HANDLE                Token;
  TOKEN_PRIVILEGES      TokenPrivileges;
  VOID                  *TemporaryRam;
  UINT32                TemporaryRamSize;
  VOID                  *EmuMagicPage;
  UINTN                 Index;
  UINTN                 Index1;
  CHAR16                *FileName;
  CHAR16                *FileNamePtr;
  BOOLEAN               Done;
  EFI_PEI_FILE_HANDLE   FileHandle;
  VOID                  *SecFile;
  CHAR16                *MemorySizeStr;
  CHAR16                *FirmwareVolumesStr;
  UINT32                ProcessAffinityMask;
  UINT32                SystemAffinityMask;
  INT32                 LowBit;

  //
  // Enable the privilege so that RTC driver can successfully run SetTime()
  //
  OpenProcessToken (GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY, &Token);
  if (LookupPrivilegeValue(NULL, SE_TIME_ZONE_NAME, &TokenPrivileges.Privileges[0].Luid)) {
    TokenPrivileges.PrivilegeCount = 1;
    TokenPrivileges.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    AdjustTokenPrivileges(Token, FALSE, &TokenPrivileges, 0, (PTOKEN_PRIVILEGES) NULL, 0);
  }

  MemorySizeStr      = (CHAR16 *) PcdGetPtr (PcdEmuMemorySize);
  FirmwareVolumesStr = (CHAR16 *) PcdGetPtr (PcdEmuFirmwareVolume);

  SecPrint ("\nEDK II WIN Host Emulation Environment from http://www.tianocore.org/edk2/\n");

  //
  // Determine the first thread available to this process.
  //
  if (GetProcessAffinityMask (GetCurrentProcess (), &ProcessAffinityMask, &SystemAffinityMask)) {
    LowBit = (INT32)LowBitSet32 (ProcessAffinityMask);
    if (LowBit != -1) {
      //
      // Force the system to bind the process to a single thread to work
      // around odd semaphore type crashes.
      //
      SetProcessAffinityMask (GetCurrentProcess (), (INTN)(BIT0 << LowBit));
    }
  }

  //
  // Make some Windows calls to Set the process to the highest priority in the
  //  idle class. We need this to have good performance.
  //
  SetPriorityClass (GetCurrentProcess (), IDLE_PRIORITY_CLASS);
  SetThreadPriority (GetCurrentThread (), THREAD_PRIORITY_HIGHEST);

  SecInitializeThunk ();
  //
  // PPIs pased into PEI_CORE
  //
  AddThunkPpi (EFI_PEI_PPI_DESCRIPTOR_PPI, &gEmuThunkPpiGuid, &mSecEmuThunkPpi);

  //
  // Emulator Bus Driver Thunks
  //
  AddThunkProtocol (&mWinNtWndThunkIo, (CHAR16 *)PcdGetPtr (PcdEmuGop), TRUE);
  AddThunkProtocol (&mWinNtFileSystemThunkIo, (CHAR16 *)PcdGetPtr (PcdEmuFileSystem), TRUE);
  AddThunkProtocol (&mWinNtBlockIoThunkIo, (CHAR16 *)PcdGetPtr (PcdEmuVirtualDisk), TRUE);

  //
  // Allocate space for gSystemMemory Array
  //
  gSystemMemoryCount  = CountSeparatorsInString (MemorySizeStr, '!') + 1;
  gSystemMemory       = calloc (gSystemMemoryCount, sizeof (NT_SYSTEM_MEMORY));
  if (gSystemMemory == NULL) {
    SecPrint ("ERROR : Can not allocate memory for %S.  Exiting.\n", MemorySizeStr);
    exit (1);
  }

  //
  // Allocate space for gSystemMemory Array
  //
  gFdInfoCount  = CountSeparatorsInString (FirmwareVolumesStr, '!') + 1;
  gFdInfo       = calloc (gFdInfoCount, sizeof (NT_FD_INFO));
  if (gFdInfo == NULL) {
    SecPrint ("ERROR : Can not allocate memory for %S.  Exiting.\n", FirmwareVolumesStr);
    exit (1);
  }
  //
  // Setup Boot Mode.
  //
  SecPrint ("  BootMode 0x%02x\n", PcdGet32 (PcdEmuBootMode));

  //
  //  Allocate 128K memory to emulate temp memory for PEI.
  //  on a real platform this would be SRAM, or using the cache as RAM.
  //  Set TemporaryRam to zero so WinNtOpenFile will allocate a new mapping
  //
  TemporaryRamSize = TEMPORARY_RAM_SIZE;
  TemporaryRam     = VirtualAlloc (NULL, (SIZE_T) (TemporaryRamSize), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  if (TemporaryRam == NULL) {
    SecPrint ("ERROR : Can not allocate enough space for SecStack\n");
    exit (1);
  }
  SetMem32 (TemporaryRam, TemporaryRamSize, PcdGet32 (PcdInitValueInTempStack));

  SecPrint ("  OS Emulator passing in %u KB of temp RAM at 0x%08lx to SEC\n",
    TemporaryRamSize / SIZE_1KB,
    TemporaryRam
    );

  //
  // If enabled use the magic page to communicate between modules
  // This replaces the PI PeiServicesTable pointer mechanism that
  // deos not work in the emulator. It also allows the removal of
  // writable globals from SEC, PEI_CORE (libraries), PEIMs
  //
  EmuMagicPage = (VOID *)(UINTN)(FixedPcdGet64 (PcdPeiServicesTablePage) & MAX_UINTN);
  if (EmuMagicPage != NULL) {
    UINT64  Size;
    Status = WinNtOpenFile (
              NULL,
              SIZE_4KB,
              0,
              &EmuMagicPage,
              &Size
              );
    if (EFI_ERROR (Status)) {
      SecPrint ("ERROR : Could not allocate PeiServicesTablePage @ %p\n", EmuMagicPage);
      return EFI_DEVICE_ERROR;
    }
  }

  //
  // Open All the firmware volumes and remember the info in the gFdInfo global
  // Meanwhile, find the SEC Core.
  //
  FileNamePtr = AllocateCopyPool (StrSize (FirmwareVolumesStr), FirmwareVolumesStr);
  if (FileNamePtr == NULL) {
    SecPrint ("ERROR : Can not allocate memory for firmware volume string\n");
    exit (1);
  }

  for (Done = FALSE, Index = 0, SecFile = NULL; !Done; Index++) {
    FileName = FileNamePtr;
    for (Index1 = 0; (FileNamePtr[Index1] != '!') && (FileNamePtr[Index1] != 0); Index1++)
      ;
    if (FileNamePtr[Index1] == 0) {
      Done = TRUE;
    } else {
      FileNamePtr[Index1]  = '\0';
      FileNamePtr = &FileNamePtr[Index1 + 1];
    }

    //
    // Open the FD and remember where it got mapped into our processes address space
    //
    Status = WinNtOpenFile (
              FileName,
              0,
              OPEN_EXISTING,
              &gFdInfo[Index].Address,
              &gFdInfo[Index].Size
              );
    if (EFI_ERROR (Status)) {
      SecPrint ("ERROR : Can not open Firmware Device File %S (0x%X).  Exiting.\n", FileName, Status);
      exit (1);
    }

    SecPrint ("  FD loaded from %S\n", FileName);

    if (SecFile == NULL) {
      //
      // Assume the beginning of the FD is an FV and look for the SEC Core.
      // Load the first one we find.
      //
      FileHandle = NULL;
      Status = PeiServicesFfsFindNextFile (
                  EFI_FV_FILETYPE_SECURITY_CORE,
                  (EFI_PEI_FV_HANDLE)gFdInfo[Index].Address,
                  &FileHandle
                  );
      if (!EFI_ERROR (Status)) {
        Status = PeiServicesFfsFindSectionData (EFI_SECTION_PE32, FileHandle, &SecFile);
        if (!EFI_ERROR (Status)) {
          SecPrint (" contains SEC Core");
        }
      }
    }

    SecPrint ("\n");
  }
  //
  // Calculate memory regions and store the information in the gSystemMemory
  //  global for later use. The autosizing code will use this data to
  //  map this memory into the SEC process memory space.
  //
  for (Index = 0, Done = FALSE; !Done; Index++) {
    //
    // Save the size of the memory and make a Unicode filename SystemMemory00, ...
    //
    gSystemMemory[Index].Size = _wtoi (MemorySizeStr) * SIZE_1MB;

    //
    // Find the next region
    //
    for (Index1 = 0; MemorySizeStr[Index1] != '!' && MemorySizeStr[Index1] != 0; Index1++)
      ;
    if (MemorySizeStr[Index1] == 0) {
      Done = TRUE;
    }

    MemorySizeStr = MemorySizeStr + Index1 + 1;
  }

  SecPrint ("\n");

  //
  // Hand off to SEC Core
  //
  SecLoadSecCore ((UINTN)TemporaryRam, TemporaryRamSize, gFdInfo[0].Address, gFdInfo[0].Size, SecFile);

  //
  // If we get here, then the SEC Core returned. This is an error as SEC should
  //  always hand off to PEI Core and then on to DXE Core.
  //
  SecPrint ("ERROR : SEC returned\n");
  exit (1);
}
示例#4
0
/**
  Initialize the KeyData and Key[] in the EFI_BOOT_MANAGER_KEY_OPTION.
**/
EFI_STATUS
InitializeKeyFields (
  IN UINT32                       Modifier,
  IN VA_LIST                      Args,
  OUT EFI_BOOT_MANAGER_KEY_OPTION *KeyOption
  )
{
  EFI_INPUT_KEY                   *Key;
  UINTN                           KeyCount;

  if (KeyOption == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  KeyOption->KeyData = 0;

  for (KeyCount = 0; KeyCount < sizeof (KeyOption->Keys) / sizeof (KeyOption->Keys[0]); KeyCount++) {
    Key = VA_ARG (Args, EFI_INPUT_KEY *);
    if (Key == NULL) {
      break;
    }
    CopyMem (
      &KeyOption->Keys[KeyCount],
      Key,
      sizeof (EFI_INPUT_KEY)
      );
  }
  if (KeyCount == sizeof (KeyOption->Keys) / sizeof (KeyOption->Keys[0])) {
    //
    // Too many keys
    //
    return EFI_INVALID_PARAMETER;
  } else {
    KeyOption->KeyData |= KeyCount << LowBitSet32 (EFI_KEY_OPTION_INPUT_KEY_COUNT_MASK);
  }

  if ((Modifier & ~(EFI_BOOT_MANAGER_SHIFT_PRESSED
                 | EFI_BOOT_MANAGER_CONTROL_PRESSED
                 | EFI_BOOT_MANAGER_ALT_PRESSED
                 | EFI_BOOT_MANAGER_LOGO_PRESSED
                 | EFI_BOOT_MANAGER_MENU_KEY_PRESSED
                 | EFI_BOOT_MANAGER_SYS_REQ_PRESSED
                 )) != 0) {
    return EFI_INVALID_PARAMETER;
  }

  if (BitSet (Modifier, EFI_BOOT_MANAGER_SHIFT_PRESSED)) {
    KeyOption->KeyData |= EFI_KEY_OPTION_SHIFT_PRESSED_MASK;
  }
  if (BitSet (Modifier, EFI_BOOT_MANAGER_CONTROL_PRESSED)) {
    KeyOption->KeyData |= EFI_KEY_OPTION_CONTROL_PRESSED_MASK;
  }
  if (BitSet (Modifier, EFI_BOOT_MANAGER_ALT_PRESSED)) {
    KeyOption->KeyData |= EFI_KEY_OPTION_ALT_PRESSED_MASK;
  }
  if (BitSet (Modifier, EFI_BOOT_MANAGER_LOGO_PRESSED)) {
    KeyOption->KeyData |= EFI_KEY_OPTION_LOGO_PRESSED_MASK;
  }
  if (BitSet (Modifier, EFI_BOOT_MANAGER_MENU_KEY_PRESSED)) {
    KeyOption->KeyData |= EFI_KEY_OPTION_MENU_PRESSED_MASK;
  }
  if (BitSet (Modifier, EFI_BOOT_MANAGER_SYS_REQ_PRESSED)) {
    KeyOption->KeyData |= EFI_KEY_OPTION_SYS_REQ_PRESSED_MASK;
  }

  return EFI_SUCCESS;
}
示例#5
0
文件: LegacySio.c 项目: MattDevo/edk2
/**
  Collect EFI Info about legacy devices through Super IO interface.

  @param  SioPtr       Pointer to SIO data.

  @retval EFI_SUCCESS   When SIO data is got successfully.
  @retval EFI_NOT_FOUND When ISA IO interface is absent.

**/
EFI_STATUS
LegacyBiosBuildSioDataFromSio (
  IN DEVICE_PRODUCER_DATA_HEADER             *SioPtr
  )
{
  EFI_STATUS                                 Status;
  DEVICE_PRODUCER_SERIAL                     *SioSerial;
  DEVICE_PRODUCER_PARALLEL                   *SioParallel;
  DEVICE_PRODUCER_FLOPPY                     *SioFloppy;
  UINTN                                      HandleCount;
  EFI_HANDLE                                 *HandleBuffer;
  UINTN                                      Index;
  UINTN                                      ChildIndex;
  EFI_SIO_PROTOCOL                           *Sio;
  ACPI_RESOURCE_HEADER_PTR                   Resources;
  EFI_ACPI_IO_PORT_DESCRIPTOR                *IoResource;
  EFI_ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR *FixedIoResource;
  EFI_ACPI_DMA_DESCRIPTOR                    *DmaResource;
  EFI_ACPI_IRQ_NOFLAG_DESCRIPTOR             *IrqResource;
  UINT16                                     Address;
  UINT8                                      Dma;
  UINT8                                      Irq;
  UINTN                                      EntryCount;
  EFI_OPEN_PROTOCOL_INFORMATION_ENTRY        *OpenInfoBuffer;
  EFI_BLOCK_IO_PROTOCOL                      *BlockIo;
  EFI_SERIAL_IO_PROTOCOL                     *SerialIo;
  EFI_DEVICE_PATH_PROTOCOL                   *DevicePath;
  ACPI_HID_DEVICE_PATH                       *Acpi;

  //
  // Get the list of ISA controllers in the system
  //
  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiSioProtocolGuid,
                  NULL,
                  &HandleCount,
                  &HandleBuffer
                  );
  if (EFI_ERROR (Status)) {
    return EFI_NOT_FOUND;
  }
  //
  // Collect legacy information from each of the ISA controllers in the system
  //
  for (Index = 0; Index < HandleCount; Index++) {
    Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiSioProtocolGuid, (VOID **) &Sio);
    if (EFI_ERROR (Status)) {
      continue;
    }

    Address = MAX_UINT16;
    Dma     = MAX_UINT8;
    Irq     = MAX_UINT8;
    Status = Sio->GetResources (Sio, &Resources);
    if (!EFI_ERROR (Status)) {
      //
      // Get the base address information from ACPI resource descriptor.
      //
      while (Resources.SmallHeader->Byte != ACPI_END_TAG_DESCRIPTOR) {
        switch (Resources.SmallHeader->Byte) {
        case ACPI_IO_PORT_DESCRIPTOR:
          IoResource = (EFI_ACPI_IO_PORT_DESCRIPTOR *) Resources.SmallHeader;
          Address = IoResource->BaseAddressMin;
          break;

        case ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR:
          FixedIoResource = (EFI_ACPI_FIXED_LOCATION_IO_PORT_DESCRIPTOR *) Resources.SmallHeader;
          Address = FixedIoResource->BaseAddress;
          break;

        case ACPI_DMA_DESCRIPTOR:
          DmaResource = (EFI_ACPI_DMA_DESCRIPTOR *) Resources.SmallHeader;
          Dma = (UINT8) LowBitSet32 (DmaResource->ChannelMask);
          break;

        case ACPI_IRQ_DESCRIPTOR:
        case ACPI_IRQ_NOFLAG_DESCRIPTOR:
          IrqResource = (EFI_ACPI_IRQ_NOFLAG_DESCRIPTOR *) Resources.SmallHeader;
          Irq = (UINT8) LowBitSet32 (IrqResource->Mask);
          break;

        default:
          break;
        }

        if (Resources.SmallHeader->Bits.Type == 0) {
          Resources.SmallHeader = (ACPI_SMALL_RESOURCE_HEADER *) ((UINT8 *) Resources.SmallHeader
                                                                  + Resources.SmallHeader->Bits.Length
                                                                  + sizeof (*Resources.SmallHeader));
        } else {
          Resources.LargeHeader = (ACPI_LARGE_RESOURCE_HEADER *) ((UINT8 *) Resources.LargeHeader
                                                                  + Resources.LargeHeader->Length
                                                                  + sizeof (*Resources.LargeHeader));
        }
      }
    }

    DEBUG ((EFI_D_INFO, "LegacySio: Address/Dma/Irq = %x/%d/%d\n", Address, Dma, Irq));

    DevicePath = DevicePathFromHandle (HandleBuffer[Index]);
    if (DevicePath == NULL) {
      continue;
    }

    Acpi = NULL;
    while (!IsDevicePathEnd (DevicePath)) {
      Acpi = (ACPI_HID_DEVICE_PATH *) DevicePath;
      DevicePath = NextDevicePathNode (DevicePath);
    }

    if ((Acpi == NULL) || (DevicePathType (Acpi) != ACPI_DEVICE_PATH) ||
        ((DevicePathSubType (Acpi) != ACPI_DP) && (DevicePathSubType (Acpi) != ACPI_EXTENDED_DP))
        ) {
      continue;
    }

    //
    // See if this is an ISA serial port
    //
    // Ignore DMA resource since it is always returned NULL
    //
    if (Acpi->HID == EISA_PNP_ID (0x500) || Acpi->HID == EISA_PNP_ID (0x501)) {

      if (Acpi->UID < 4 && Address != MAX_UINT16 && Irq != MAX_UINT8) {
        //
        // Get the handle of the child device that has opened the Super I/O Protocol
        //
        Status = gBS->OpenProtocolInformation (
                        HandleBuffer[Index],
                        &gEfiSioProtocolGuid,
                        &OpenInfoBuffer,
                        &EntryCount
                        );
        if (EFI_ERROR (Status)) {
          continue;
        }
        for (ChildIndex = 0; ChildIndex < EntryCount; ChildIndex++) {
          if ((OpenInfoBuffer[ChildIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
            Status = gBS->HandleProtocol (OpenInfoBuffer[ChildIndex].ControllerHandle, &gEfiSerialIoProtocolGuid, (VOID **) &SerialIo);
            if (!EFI_ERROR (Status)) {
              SioSerial           = &SioPtr->Serial[Acpi->UID];
              SioSerial->Address  = Address;
              SioSerial->Irq      = Irq;
              SioSerial->Mode     = DEVICE_SERIAL_MODE_NORMAL | DEVICE_SERIAL_MODE_DUPLEX_HALF;
              break;
            }
          }
        }

        FreePool (OpenInfoBuffer);
      }
    }
    //
    // See if this is an ISA parallel port
    //
    // Ignore DMA resource since it is always returned NULL, port
    // only used in output mode.
    //
    if (Acpi->HID == EISA_PNP_ID (0x400) || Acpi->HID == EISA_PNP_ID (0x401)) {
      if (Acpi->UID < 3 && Address != MAX_UINT16 && Irq != MAX_UINT8 && Dma != MAX_UINT8) {
        SioParallel           = &SioPtr->Parallel[Acpi->UID];
        SioParallel->Address  = Address;
        SioParallel->Irq      = Irq;
        SioParallel->Dma      = Dma;
        SioParallel->Mode     = DEVICE_PARALLEL_MODE_MODE_OUTPUT_ONLY;
      }
    }
    //
    // See if this is an ISA floppy controller
    //
    if (Acpi->HID == EISA_PNP_ID (0x604)) {
      if (Address != MAX_UINT16 && Irq != MAX_UINT8 && Dma != MAX_UINT8) {
        Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiBlockIoProtocolGuid, (VOID **) &BlockIo);
        if (!EFI_ERROR (Status)) {
          SioFloppy           = &SioPtr->Floppy;
          SioFloppy->Address  = Address;
          SioFloppy->Irq      = Irq;
          SioFloppy->Dma      = Dma;
          SioFloppy->NumberOfFloppy++;
        }
      }
    }
    //
    // See if this is a mouse
    // Always set mouse found so USB hot plug will work
    //
    // Ignore lower byte of HID. Pnp0fxx is any type of mouse.
    //
    //    Hid = ResourceList->Device.HID & 0xff00ffff;
    //    PnpId = EISA_PNP_ID(0x0f00);
    //    if (Hid == PnpId) {
    //      if (ResourceList->Device.UID == 1) {
    //        Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiSimplePointerProtocolGuid, &SimplePointer);
    //      if (!EFI_ERROR (Status)) {
    //
    SioPtr->MousePresent = 0x01;
    //
    //        }
    //      }
    //    }
    //
  }

  FreePool (HandleBuffer);
  return EFI_SUCCESS;

}