Example #1
0
/**
  Check if a boot option path is a memory map boot option path or not.

  The device specified by the beginning of the path has to support the BlockIo
  protocol. Furthermore, the remaining part of the path has to be composed of
  a single node of type HARDWARE_DEVICE_PATH and sub-type HW_MEMMAP_DP.

  @param[in]  DevicePath  Complete device path of a boot option.

  @retval  FALSE  The boot option path has not been identified as that of a
                  memory map boot option.
  @retval  TRUE   The boot option path is a a memory map boot option.
**/
BOOLEAN
BdsLoadOptionMemMapIsSupported (
  IN  EFI_DEVICE_PATH  *DevicePath
  )
{
  EFI_STATUS              Status;
  EFI_HANDLE              Handle;
  EFI_DEVICE_PATH        *RemainingDevicePath;
  EFI_BLOCK_IO_PROTOCOL  *BlockIoProtocol;

  Status = BdsConnectDevicePath (DevicePath, &Handle, &RemainingDevicePath);
  if (EFI_ERROR (Status)) {
    return FALSE;
  }

  Status = gBS->HandleProtocol (
                  Handle,
                  &gEfiBlockIoProtocolGuid,
                  (VOID **)(&BlockIoProtocol)
                  );
  if (EFI_ERROR (Status)) {
    return FALSE;
  }

  if (!IS_DEVICE_PATH_NODE (RemainingDevicePath, HARDWARE_DEVICE_PATH, HW_MEMMAP_DP))
    return FALSE;

  return TRUE;
}
Example #2
0
BOOLEAN
BdsLoadOptionPxeIsSupported (
  IN  EFI_DEVICE_PATH  *DevicePath
  )
{
  EFI_STATUS  Status;
  EFI_HANDLE Handle;
  EFI_DEVICE_PATH_PROTOCOL  *RemainingDevicePath;
  EFI_PXE_BASE_CODE_PROTOCOL  *PxeBcProtocol;

  Status = BdsConnectDevicePath (DevicePath, &Handle, &RemainingDevicePath);
  if (EFI_ERROR(Status)) {
    return FALSE;
  }

  if (!IsDevicePathEnd(RemainingDevicePath)) {
    return FALSE;
  }

  Status = gBS->HandleProtocol (Handle, &gEfiPxeBaseCodeProtocolGuid, (VOID **)&PxeBcProtocol);
  if (EFI_ERROR (Status)) {
    return FALSE;
  } else {
    return TRUE;
  }
}
Example #3
0
/**
  Check if a boot option path is a file system boot option path or not.

  The device specified by the beginning of the path has to support the Simple File
  System protocol. Furthermore, the remaining part of the path has to be composed of
  a single node of type MEDIA_DEVICE_PATH and sub-type MEDIA_FILEPATH_DP.

  @param[in]  DevicePath  Complete device path of a boot option.

  @retval  FALSE  The boot option path has not been identified as that of a
                  file system boot option.
  @retval  TRUE   The boot option path is a file system boot option.
**/
BOOLEAN
BdsLoadOptionFileSystemIsSupported (
  IN  EFI_DEVICE_PATH  *DevicePath
  )
{
  EFI_STATUS                        Status;
  EFI_HANDLE                        Handle;
  EFI_DEVICE_PATH                  *RemainingDevicePath;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL  *FileProtocol;

  Status = BdsConnectDevicePath (DevicePath, &Handle, &RemainingDevicePath);
  if (EFI_ERROR (Status)) {
    return FALSE;
  }

  Status = gBS->HandleProtocol (
                   Handle,
                   &gEfiSimpleFileSystemProtocolGuid,
                   (VOID **)(&FileProtocol)
                   );
  if (EFI_ERROR (Status)) {
    return FALSE;
  }

  if (!IS_DEVICE_PATH_NODE (RemainingDevicePath, MEDIA_DEVICE_PATH, MEDIA_FILEPATH_DP))
    return FALSE;

  return TRUE;
}
Example #4
0
EFI_STATUS
BdsLoadImage (
    IN     EFI_DEVICE_PATH       *DevicePath,
    IN     EFI_ALLOCATE_TYPE     Type,
    IN OUT EFI_PHYSICAL_ADDRESS* Image,
    OUT    UINTN                 *FileSize
)
{
    EFI_STATUS      Status;
    EFI_HANDLE      Handle;
    EFI_DEVICE_PATH *RemainingDevicePath;
    BDS_FILE_LOADER*  FileLoader;

    Status = BdsConnectDevicePath (DevicePath, &Handle, &RemainingDevicePath);
    if (EFI_ERROR (Status)) {
        return Status;
    }

    FileLoader = FileLoaders;
    while (FileLoader->Support != NULL) {
        if (FileLoader->Support (DevicePath, Handle, RemainingDevicePath)) {
            return FileLoader->LoadImage (DevicePath, Handle, RemainingDevicePath, Type, Image, FileSize);
        }
        FileLoader++;
    }

    return EFI_UNSUPPORTED;
}
Example #5
0
BOOLEAN
BdsLoadOptionTftpIsSupported (
  IN  EFI_DEVICE_PATH           *DevicePath
  )
{
  EFI_STATUS  Status;
  EFI_HANDLE Handle;
  EFI_DEVICE_PATH  *RemainingDevicePath;
  EFI_DEVICE_PATH  *NextDevicePath;
  EFI_PXE_BASE_CODE_PROTOCOL  *PxeBcProtocol;

  Status = BdsConnectDevicePath (DevicePath, &Handle, &RemainingDevicePath);
  if (EFI_ERROR(Status)) {
    return FALSE;
  }

  // Validate the Remaining Device Path
  if (IsDevicePathEnd(RemainingDevicePath)) {
    return FALSE;
  }
  if (!IS_DEVICE_PATH_NODE(RemainingDevicePath,MESSAGING_DEVICE_PATH,MSG_IPv4_DP) &&
      !IS_DEVICE_PATH_NODE(RemainingDevicePath,MESSAGING_DEVICE_PATH,MSG_IPv6_DP)) {
    return FALSE;
  }
  NextDevicePath = NextDevicePathNode (RemainingDevicePath);
  if (IsDevicePathEnd(NextDevicePath)) {
    return FALSE;
  }
  if (!IS_DEVICE_PATH_NODE(NextDevicePath,MEDIA_DEVICE_PATH,MEDIA_FILEPATH_DP)) {
    return FALSE;
  }

  Status = gBS->HandleProtocol (Handle, &gEfiPxeBaseCodeProtocolGuid, (VOID **)&PxeBcProtocol);
  if (EFI_ERROR (Status)) {
    return FALSE;
  } else {
    return TRUE;
  }
}
Example #6
0
STATIC
EFI_STATUS
InitializeConsolePipe (
  IN EFI_DEVICE_PATH    *ConsoleDevicePaths,
  IN EFI_GUID           *Protocol,
  OUT EFI_HANDLE        *Handle,
  OUT VOID*             *Interface
  )
{
  EFI_STATUS                Status;
  UINTN                     Size;
  UINTN                     NoHandles;
  EFI_HANDLE                *Buffer;
  EFI_DEVICE_PATH_PROTOCOL* DevicePath;

  // Connect all the Device Path Consoles
  while (ConsoleDevicePaths != NULL) {
    DevicePath = GetNextDevicePathInstance (&ConsoleDevicePaths, &Size);

    Status = BdsConnectDevicePath (DevicePath, Handle, NULL);
    DEBUG_CODE_BEGIN();
      if (EFI_ERROR(Status)) {
        // We convert back to the text representation of the device Path
        EFI_DEVICE_PATH_TO_TEXT_PROTOCOL* DevicePathToTextProtocol;
        CHAR16* DevicePathTxt;
        EFI_STATUS Status;

        Status = gBS->LocateProtocol(&gEfiDevicePathToTextProtocolGuid, NULL, (VOID **)&DevicePathToTextProtocol);
        if (!EFI_ERROR(Status)) {
          DevicePathTxt = DevicePathToTextProtocol->ConvertDevicePathToText (DevicePath, TRUE, TRUE);

          DEBUG((EFI_D_ERROR,"Fail to start the console with the Device Path '%s'. (Error '%r')\n", DevicePathTxt, Status));

          FreePool (DevicePathTxt);
        }
      }
    DEBUG_CODE_END();

    // If the console splitter driver is not supported by the platform then use the first Device Path
    // instance for the console interface.
    if (!EFI_ERROR(Status) && (*Interface == NULL)) {
      Status = gBS->HandleProtocol (*Handle, Protocol, Interface);
    }
  }

  // No Device Path has been defined for this console interface. We take the first protocol implementation
  if (*Interface == NULL) {
    Status = gBS->LocateHandleBuffer (ByProtocol, Protocol, NULL, &NoHandles, &Buffer);
    if (EFI_ERROR (Status)) {
      BdsConnectAllDrivers();
      Status = gBS->LocateHandleBuffer (ByProtocol, Protocol, NULL, &NoHandles, &Buffer);
    }

    if (!EFI_ERROR(Status)) {
      *Handle = Buffer[0];
      Status = gBS->HandleProtocol (*Handle, Protocol, Interface);
      ASSERT_EFI_ERROR(Status);
      FreePool (Buffer);
    }
  } else {
    Status = EFI_SUCCESS;
  }

  return Status;
}
Example #7
0
/**
  Connect a Device Path and return the handle of the driver that support this DevicePath

  @param  DevicePath            Device Path of the File to connect
  @param  Handle                Handle of the driver that support this DevicePath
  @param  RemainingDevicePath   Remaining DevicePath nodes that do not match the driver DevicePath

  @retval EFI_SUCCESS           A driver that matches the Device Path has been found
  @retval EFI_NOT_FOUND         No handles match the search.
  @retval EFI_INVALID_PARAMETER DevicePath or Handle is NULL

**/
EFI_STATUS
BdsConnectDevicePath (
    IN  EFI_DEVICE_PATH_PROTOCOL* DevicePath,
    OUT EFI_HANDLE                *Handle,
    OUT EFI_DEVICE_PATH_PROTOCOL  **RemainingDevicePath
)
{
    EFI_DEVICE_PATH*            Remaining;
    EFI_DEVICE_PATH*            NewDevicePath;
    EFI_STATUS                  Status;

    if ((DevicePath == NULL) || (Handle == NULL)) {
        return EFI_INVALID_PARAMETER;
    }

    do {
        Remaining = DevicePath;
        // The LocateDevicePath() function locates all devices on DevicePath that support Protocol and returns
        // the handle to the device that is closest to DevicePath. On output, the device path pointer is modified
        // to point to the remaining part of the device path
        Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &Remaining, Handle);
        if (!EFI_ERROR (Status)) {
            // Recursive = FALSE: We do not want to start all the device tree
            Status = gBS->ConnectController (*Handle, NULL, Remaining, FALSE);
        }

        /*// We need to check if RemainingDevicePath does not point on the last node. Otherwise, calling
        // NextDevicePathNode() will return an undetermined Device Path Node
        if (!IsDevicePathEnd (RemainingDevicePath)) {
          RemainingDevicePath = NextDevicePathNode (RemainingDevicePath);
        }*/
    } while (!EFI_ERROR (Status) && !IsDevicePathEnd (Remaining));

    if (!EFI_ERROR (Status)) {
        // Now, we have got the whole Device Path connected, call again ConnectController to ensure all the supported Driver
        // Binding Protocol are connected (such as DiskIo and SimpleFileSystem)
        Remaining = DevicePath;
        Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid,&Remaining,Handle);
        if (!EFI_ERROR (Status)) {
            Status = gBS->ConnectController (*Handle, NULL, Remaining, FALSE);
            if (EFI_ERROR (Status)) {
                // If the last node is a Memory Map Device Path just return EFI_SUCCESS.
                if ((Remaining->Type == HARDWARE_DEVICE_PATH) && (Remaining->SubType == HW_MEMMAP_DP)) {
                    Status = EFI_SUCCESS;
                }
            }
        }
    } else if (!IsDevicePathEnd (Remaining) && !IsRemovableDevice (Remaining)) {

        /*// If the remaining Device Path is a FilePath or MemoryMap then we consider the Device Path has been loaded correctly
        if ((Remaining->Type == MEDIA_DEVICE_PATH) && (Remaining->SubType == MEDIA_FILEPATH_DP)) {
          Status = EFI_SUCCESS;
        } else if ((Remaining->Type == HARDWARE_DEVICE_PATH) && (Remaining->SubType == HW_MEMMAP_DP)) {
          Status = EFI_SUCCESS;
        }*/

        //TODO: Should we just return success and leave the caller decide if it is the expected RemainingPath
        Status = EFI_SUCCESS;
    } else {
        Status = TryRemovableDevice (DevicePath, Handle, &NewDevicePath);
        if (!EFI_ERROR (Status)) {
            return BdsConnectDevicePath (NewDevicePath, Handle, RemainingDevicePath);
        }
    }

    if (RemainingDevicePath) {
        *RemainingDevicePath = Remaining;
    }

    return Status;
}