/** @file
  The device path help function.

  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "NvmExpressPei.h"

//
// Template for an Nvm Express Device Path node
//
NVME_NAMESPACE_DEVICE_PATH  mNvmeDevicePathNodeTemplate = {
  {        // Header
    MESSAGING_DEVICE_PATH,
    MSG_NVME_NAMESPACE_DP,
    {
      (UINT8)(sizeof (NVME_NAMESPACE_DEVICE_PATH)),
      (UINT8)((sizeof (NVME_NAMESPACE_DEVICE_PATH)) >> 8)
    }
  },
  0x0,     // NamespaceId
  0x0      // NamespaceUuid
};

//
// Template for an End of entire Device Path node
//
EFI_DEVICE_PATH_PROTOCOL  mNvmeEndDevicePathNodeTemplate = {
  END_DEVICE_PATH_TYPE,
  END_ENTIRE_DEVICE_PATH_SUBTYPE,
  {
    (UINT8)(sizeof (EFI_DEVICE_PATH_PROTOCOL)),
    (UINT8)((sizeof (EFI_DEVICE_PATH_PROTOCOL)) >> 8)
  }
};

/**
  Get the size of the current device path instance.

  @param[in]  DevicePath             A pointer to the EFI_DEVICE_PATH_PROTOCOL
                                     structure.
  @param[out] InstanceSize           The size of the current device path instance.
  @param[out] EntireDevicePathEnd    Indicate whether the instance is the last
                                     one in the device path strucure.

  @retval EFI_SUCCESS    The size of the current device path instance is fetched.
  @retval Others         Fails to get the size of the current device path instance.

**/
EFI_STATUS
GetDevicePathInstanceSize (
  IN  EFI_DEVICE_PATH_PROTOCOL  *DevicePath,
  OUT UINTN                     *InstanceSize,
  OUT BOOLEAN                   *EntireDevicePathEnd
  )
{
  EFI_DEVICE_PATH_PROTOCOL  *Walker;

  if ((DevicePath == NULL) || (InstanceSize == NULL) || (EntireDevicePathEnd == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Find the end of the device path instance
  //
  Walker = DevicePath;
  while (Walker->Type != END_DEVICE_PATH_TYPE) {
    Walker = NextDevicePathNode (Walker);
  }

  //
  // Check if 'Walker' points to the end of an entire device path
  //
  if (Walker->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE) {
    *EntireDevicePathEnd = TRUE;
  } else if (Walker->SubType == END_INSTANCE_DEVICE_PATH_SUBTYPE) {
    *EntireDevicePathEnd = FALSE;
  } else {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Compute the size of the device path instance
  //
  *InstanceSize = ((UINTN)Walker - (UINTN)(DevicePath)) + sizeof (EFI_DEVICE_PATH_PROTOCOL);

  return EFI_SUCCESS;
}

/**
  Check the validity of the device path of a NVM Express host controller.

  @param[in] DevicePath          A pointer to the EFI_DEVICE_PATH_PROTOCOL
                                 structure.
  @param[in] DevicePathLength    The length of the device path.

  @retval EFI_SUCCESS              The device path is valid.
  @retval EFI_INVALID_PARAMETER    The device path is invalid.

**/
EFI_STATUS
NvmeIsHcDevicePathValid (
  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath,
  IN UINTN                     DevicePathLength
  )
{
  EFI_DEVICE_PATH_PROTOCOL  *Start;
  UINTN                     Size;

  if (DevicePath == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Validate the DevicePathLength is big enough to touch the first node.
  //
  if (DevicePathLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
    return EFI_INVALID_PARAMETER;
  }

  Start = DevicePath;
  while (!(DevicePath->Type == END_DEVICE_PATH_TYPE &&
           DevicePath->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE))
  {
    DevicePath = NextDevicePathNode (DevicePath);

    //
    // Prevent overflow and invalid zero in the 'Length' field of a device path
    // node.
    //
    if ((UINTN)DevicePath <= (UINTN)Start) {
      return EFI_INVALID_PARAMETER;
    }

    //
    // Prevent touching memory beyond given DevicePathLength.
    //
    if ((UINTN)DevicePath - (UINTN)Start >
        DevicePathLength - sizeof (EFI_DEVICE_PATH_PROTOCOL))
    {
      return EFI_INVALID_PARAMETER;
    }
  }

  //
  // Check if the device path and its size match exactly with each other.
  //
  Size = ((UINTN)DevicePath - (UINTN)Start) + sizeof (EFI_DEVICE_PATH_PROTOCOL);
  if (Size != DevicePathLength) {
    return EFI_INVALID_PARAMETER;
  }

  return EFI_SUCCESS;
}

/**
  Build the device path for an Nvm Express device with given namespace identifier
  and namespace extended unique identifier.

  @param[in]  Private              A pointer to the PEI_NVME_CONTROLLER_PRIVATE_DATA
                                   data structure.
  @param[in]  NamespaceId          The given namespace identifier.
  @param[in]  NamespaceUuid        The given namespace extended unique identifier.
  @param[out] DevicePathLength     The length of the device path in bytes specified
                                   by DevicePath.
  @param[out] DevicePath           The device path of Nvm Express device.

  @retval EFI_SUCCESS              The operation succeeds.
  @retval EFI_INVALID_PARAMETER    The parameters are invalid.
  @retval EFI_OUT_OF_RESOURCES     The operation fails due to lack of resources.

**/
EFI_STATUS
NvmeBuildDevicePath (
  IN  PEI_NVME_CONTROLLER_PRIVATE_DATA  *Private,
  IN  UINT32                            NamespaceId,
  IN  UINT64                            NamespaceUuid,
  OUT UINTN                             *DevicePathLength,
  OUT EFI_DEVICE_PATH_PROTOCOL          **DevicePath
  )
{
  EFI_DEVICE_PATH_PROTOCOL    *DevicePathWalker;
  NVME_NAMESPACE_DEVICE_PATH  *NvmeDeviceNode;

  if ((DevicePathLength == NULL) || (DevicePath == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  *DevicePathLength = Private->DevicePathLength + sizeof (NVME_NAMESPACE_DEVICE_PATH);
  *DevicePath       = AllocatePool (*DevicePathLength);
  if (*DevicePath == NULL) {
    *DevicePathLength = 0;
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Construct the host controller part device nodes
  //
  DevicePathWalker = *DevicePath;
  CopyMem (
    DevicePathWalker,
    Private->DevicePath,
    Private->DevicePathLength - sizeof (EFI_DEVICE_PATH_PROTOCOL)
    );

  //
  // Construct the Nvm Express device node
  //
  DevicePathWalker = (EFI_DEVICE_PATH_PROTOCOL *)((UINT8 *)DevicePathWalker +
                                                  (Private->DevicePathLength - sizeof (EFI_DEVICE_PATH_PROTOCOL)));
  CopyMem (
    DevicePathWalker,
    &mNvmeDevicePathNodeTemplate,
    sizeof (mNvmeDevicePathNodeTemplate)
    );
  NvmeDeviceNode                = (NVME_NAMESPACE_DEVICE_PATH *)DevicePathWalker;
  NvmeDeviceNode->NamespaceId   = NamespaceId;
  NvmeDeviceNode->NamespaceUuid = NamespaceUuid;

  //
  // Construct the end device node
  //
  DevicePathWalker = (EFI_DEVICE_PATH_PROTOCOL *)((UINT8 *)DevicePathWalker +
                                                  sizeof (NVME_NAMESPACE_DEVICE_PATH));
  CopyMem (
    DevicePathWalker,
    &mNvmeEndDevicePathNodeTemplate,
    sizeof (mNvmeEndDevicePathNodeTemplate)
    );

  return EFI_SUCCESS;
}
