/*++

Copyright (c) 1998  Intel Corporation

Module Name:

    dpath.c

Abstract:
    MBR & Device Path functions



Revision History

2014/04 B.Burette - updated device path text representation, conforming to
	UEFI specification 2.4 (dec. 2013). More specifically:
	- § 9.3.5: added some media types ie. Sata()
	- § 9.6.1.2: Acpi(PNP0A03,0) makes more sense when displayed as PciRoot(0)
	- § 9.6.1.5: use commas (instead of '|') between option specific parameters
	- § 9.6.1.6: hex values in device paths must be preceded by "0x" or "0X"

--*/

#include "lib.h"

#define ALIGN_SIZE(a)   ((a % MIN_ALIGNMENT_SIZE) ? MIN_ALIGNMENT_SIZE - (a % MIN_ALIGNMENT_SIZE) : 0)



EFI_DEVICE_PATH *
DevicePathFromHandle (
    IN EFI_HANDLE       Handle
    )
{
    EFI_STATUS          Status;
    EFI_DEVICE_PATH     *DevicePath;

    Status = uefi_call_wrapper(BS->HandleProtocol, 3, Handle, &DevicePathProtocol, (VOID*)&DevicePath);
    if (EFI_ERROR(Status)) {
        DevicePath = NULL;
    }

    return DevicePath;
}


EFI_DEVICE_PATH *
DevicePathInstance (
    IN OUT EFI_DEVICE_PATH  **DevicePath,
    OUT UINTN               *Size
    )
{
    EFI_DEVICE_PATH         *Start, *Next, *DevPath;
    UINTN                   Count;

    DevPath = *DevicePath;
    Start = DevPath;

    if (!DevPath) {
        return NULL;
    }

    //
    // Check for end of device path type
    //

    for (Count = 0; ; Count++) {
        Next = NextDevicePathNode(DevPath);

        if (IsDevicePathEndType(DevPath)) {
            break;
        }

        if (Count > 01000) {
            //
            // BugBug: Debug code to catch bogus device paths
            //
            DEBUG((D_ERROR, "DevicePathInstance: DevicePath %x Size %d", *DevicePath, ((UINT8 *) DevPath) - ((UINT8 *) Start) ));
            DumpHex (0, 0, ((UINT8 *) DevPath) - ((UINT8 *) Start), Start);
            break;
        }

        DevPath = Next;
    }

    ASSERT (DevicePathSubType(DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE ||
            DevicePathSubType(DevPath) == END_INSTANCE_DEVICE_PATH_SUBTYPE);

    //
    // Set next position
    //

    if (DevicePathSubType(DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE) {
        Next = NULL;
    }

    *DevicePath = Next;

    //
    // Return size and start of device path instance
    //

    *Size = ((UINT8 *) DevPath) - ((UINT8 *) Start);
    return Start;
}

UINTN
DevicePathInstanceCount (
    IN EFI_DEVICE_PATH      *DevicePath
    )
{
    UINTN       Count, Size;

    Count = 0;
    while (DevicePathInstance(&DevicePath, &Size)) {
        Count += 1;
    }

    return Count;
}


EFI_DEVICE_PATH *
AppendDevicePath (
    IN EFI_DEVICE_PATH  *Src1,
    IN EFI_DEVICE_PATH  *Src2
    )
// Src1 may have multiple "instances" and each instance is appended
// Src2 is appended to each instance is Src1.  (E.g., it's possible
// to append a new instance to the complete device path by passing
// it in Src2)
{
    UINTN               Src1Size, Src1Inst, Src2Size, Size;
    EFI_DEVICE_PATH     *Dst, *Inst;
    UINT8               *DstPos;

    //
    // If there's only 1 path, just duplicate it
    //

    if (!Src1) {
        ASSERT (!IsDevicePathUnpacked (Src2));
        return DuplicateDevicePath (Src2);
    }

    if (!Src2) {
        ASSERT (!IsDevicePathUnpacked (Src1));
        return DuplicateDevicePath (Src1);
    }

    //
    // Verify we're not working with unpacked paths
    //

//    ASSERT (!IsDevicePathUnpacked (Src1));
//    ASSERT (!IsDevicePathUnpacked (Src2));

    //
    // Append Src2 to every instance in Src1
    //

    Src1Size = DevicePathSize(Src1);
    Src1Inst = DevicePathInstanceCount(Src1);
    Src2Size = DevicePathSize(Src2);
    Size = Src1Size * Src1Inst + Src2Size;

    Dst = AllocatePool (Size);
    if (Dst) {
        DstPos = (UINT8 *) Dst;

        //
        // Copy all device path instances
        //

        while ((Inst = DevicePathInstance (&Src1, &Size))) {

            CopyMem(DstPos, Inst, Size);
            DstPos += Size;

            CopyMem(DstPos, Src2, Src2Size);
            DstPos += Src2Size;

            CopyMem(DstPos, EndInstanceDevicePath, sizeof(EFI_DEVICE_PATH));
            DstPos += sizeof(EFI_DEVICE_PATH);
        }

        // Change last end marker
        DstPos -= sizeof(EFI_DEVICE_PATH);
        CopyMem(DstPos, EndDevicePath, sizeof(EFI_DEVICE_PATH));
    }

    return Dst;
}


EFI_DEVICE_PATH *
AppendDevicePathNode (
    IN EFI_DEVICE_PATH  *Src1,
    IN EFI_DEVICE_PATH  *Src2
    )
// Src1 may have multiple "instances" and each instance is appended
// Src2 is a signal device path node (without a terminator) that is
// appended to each instance is Src1.
{
    EFI_DEVICE_PATH     *Temp, *Eop;
    UINTN               Length;

    //
    // Build a Src2 that has a terminator on it
    //

    Length = DevicePathNodeLength(Src2);
    Temp = AllocatePool (Length + sizeof(EFI_DEVICE_PATH));
    if (!Temp) {
        return NULL;
    }

    CopyMem (Temp, Src2, Length);
    Eop = NextDevicePathNode(Temp);
    SetDevicePathEndNode(Eop);

    //
    // Append device paths
    //

    Src1 = AppendDevicePath (Src1, Temp);
    FreePool (Temp);
    return Src1;
}


EFI_DEVICE_PATH *
FileDevicePath (
    IN EFI_HANDLE       Device  OPTIONAL,
    IN CHAR16           *FileName
    )
/*++

    N.B. Results are allocated from pool.  The caller must FreePool
    the resulting device path structure

--*/
{
    UINTN                   Size;
    FILEPATH_DEVICE_PATH    *FilePath;
    EFI_DEVICE_PATH         *Eop, *DevicePath;

    Size = StrSize(FileName);
    FilePath = AllocateZeroPool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + sizeof(EFI_DEVICE_PATH));
    DevicePath = NULL;

    if (FilePath) {

        //
        // Build a file path
        //

        FilePath->Header.Type = MEDIA_DEVICE_PATH;
        FilePath->Header.SubType = MEDIA_FILEPATH_DP;
        SetDevicePathNodeLength (&FilePath->Header, Size + SIZE_OF_FILEPATH_DEVICE_PATH);
        CopyMem (FilePath->PathName, FileName, Size);
        Eop = NextDevicePathNode(&FilePath->Header);
        SetDevicePathEndNode(Eop);

        //
        // Append file path to device's device path
        //

        DevicePath = (EFI_DEVICE_PATH *) FilePath;
        if (Device) {
            DevicePath = AppendDevicePath (
                            DevicePathFromHandle(Device),
                            DevicePath
                            );

            FreePool(FilePath);
        }
    }

    return DevicePath;
}



UINTN
DevicePathSize (
    IN EFI_DEVICE_PATH  *DevPath
    )
{
    EFI_DEVICE_PATH     *Start;

    //
    // Search for the end of the device path structure
    //

    Start = DevPath;
    while (!IsDevicePathEnd(DevPath)) {
        DevPath = NextDevicePathNode(DevPath);
    }

    //
    // Compute the size
    //

    return ((UINTN) DevPath - (UINTN) Start) + sizeof(EFI_DEVICE_PATH);
}

EFI_DEVICE_PATH *
DuplicateDevicePath (
    IN EFI_DEVICE_PATH  *DevPath
    )
{
    EFI_DEVICE_PATH     *NewDevPath;
    UINTN               Size;


    //
    // Compute the size
    //

    Size = DevicePathSize (DevPath);

    //
    // Make a copy
    //

    NewDevPath = AllocatePool (Size);
    if (NewDevPath) {
        CopyMem (NewDevPath, DevPath, Size);
    }

    return NewDevPath;
}

EFI_DEVICE_PATH *
UnpackDevicePath (
    IN EFI_DEVICE_PATH  *DevPath
    )
{
    EFI_DEVICE_PATH     *Src, *Dest, *NewPath;
    UINTN               Size;

    //
    // Walk device path and round sizes to valid boundries
    //

    Src = DevPath;
    Size = 0;
    for (; ;) {
        Size += DevicePathNodeLength(Src);
        Size += ALIGN_SIZE(Size);

        if (IsDevicePathEnd(Src)) {
            break;
        }

        Src = NextDevicePathNode(Src);
    }


    //
    // Allocate space for the unpacked path
    //

    NewPath = AllocateZeroPool (Size);
    if (NewPath) {

        ASSERT (((UINTN)NewPath) % MIN_ALIGNMENT_SIZE == 0);

        //
        // Copy each node
        //

        Src = DevPath;
        Dest = NewPath;
        for (; ;) {
            Size = DevicePathNodeLength(Src);
            CopyMem (Dest, Src, Size);
            Size += ALIGN_SIZE(Size);
            SetDevicePathNodeLength (Dest, Size);
            Dest->Type |= EFI_DP_TYPE_UNPACKED;
            Dest = (EFI_DEVICE_PATH *) (((UINT8 *) Dest) + Size);

            if (IsDevicePathEnd(Src)) {
                break;
            }

            Src = NextDevicePathNode(Src);
        }
    }

    return NewPath;
}


EFI_DEVICE_PATH*
AppendDevicePathInstance (
    IN EFI_DEVICE_PATH  *Src,
    IN EFI_DEVICE_PATH  *Instance
    )
{
    UINT8           *Ptr;
    EFI_DEVICE_PATH *DevPath;
    UINTN           SrcSize;
    UINTN           InstanceSize;

    if (Src == NULL) {
        return DuplicateDevicePath (Instance);
    }
    SrcSize = DevicePathSize(Src);
    InstanceSize = DevicePathSize(Instance);
    Ptr = AllocatePool (SrcSize + InstanceSize);
    DevPath = (EFI_DEVICE_PATH *)Ptr;
    ASSERT(DevPath);

    CopyMem (Ptr, Src, SrcSize);
//    FreePool (Src);

    while (!IsDevicePathEnd(DevPath)) {
        DevPath = NextDevicePathNode(DevPath);
    }
    //
    // Convert the End to an End Instance, since we are
    //  appending another instacne after this one its a good
    //  idea.
    //
    DevPath->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE;

    DevPath = NextDevicePathNode(DevPath);
    CopyMem (DevPath, Instance, InstanceSize);
    return (EFI_DEVICE_PATH *)Ptr;
}

EFI_STATUS
LibDevicePathToInterface (
    IN EFI_GUID             *Protocol,
    IN EFI_DEVICE_PATH      *FilePath,
    OUT VOID                **Interface
    )
{
    EFI_STATUS              Status;
    EFI_HANDLE              Device;

    Status = uefi_call_wrapper(BS->LocateDevicePath, 3, Protocol, &FilePath, &Device);

    if (!EFI_ERROR(Status)) {

        // If we didn't get a direct match return not found
        Status = EFI_NOT_FOUND;

        if (IsDevicePathEnd(FilePath)) {

            //
            // It was a direct match, lookup the protocol interface
            //

            Status =uefi_call_wrapper(BS->HandleProtocol, 3, Device, Protocol, Interface);
        }
    }

    //
    // If there was an error, do not return an interface
    //

    if (EFI_ERROR(Status)) {
        *Interface = NULL;
    }

    return Status;
}

static VOID
_DevPathPci (
    IN OUT POOL_PRINT       *Str,
    IN VOID                 *DevPath
    )
{
    PCI_DEVICE_PATH         *Pci;

    Pci = DevPath;
    CatPrint(Str, L"Pci(0x%x,0x%x)", Pci->Device, Pci->Function);
}

static VOID
_DevPathPccard (
    IN OUT POOL_PRINT       *Str,
    IN VOID                 *DevPath
    )
{
    PCCARD_DEVICE_PATH      *Pccard;

    Pccard = DevPath;
    CatPrint(Str, L"Pccard(0x%x)", Pccard-> FunctionNumber );
}

static VOID
_DevPathMemMap (
    IN OUT POOL_PRINT       *Str,
    IN VOID                 *DevPath
    )
{
    MEMMAP_DEVICE_PATH      *MemMap;

    MemMap = DevPath;
    CatPrint(Str, L"MemMap(%d,0x%x,0x%x)",
        MemMap->MemoryType,
        MemMap->StartingAddress,
        MemMap->EndingAddress
        );
}

static VOID
_DevPathController (
    IN OUT POOL_PRINT       *Str,
    IN VOID                 *DevPath
    )
{
    CONTROLLER_DEVICE_PATH  *Controller;

    Controller = DevPath;
    CatPrint(Str, L"Ctrl(%d)",
        Controller->Controller
        );
}

static VOID
_DevPathVendor (
    IN OUT POOL_PRINT       *Str,
    IN VOID                 *DevPath
    )
{
    VENDOR_DEVICE_PATH                  *Vendor;
    CHAR16                              *Type;
    UNKNOWN_DEVICE_VENDOR_DEVICE_PATH   *UnknownDevPath;

    Vendor = DevPath;
    switch (DevicePathType(&Vendor->Header)) {
    case HARDWARE_DEVICE_PATH:  Type = L"Hw";        break;
    case MESSAGING_DEVICE_PATH: Type = L"Msg";       break;
    case MEDIA_DEVICE_PATH:     Type = L"Media";     break;
    default:                    Type = L"?";         break;
    }

    CatPrint(Str, L"Ven%s(%g", Type, &Vendor->Guid);
    if (CompareGuid (&Vendor->Guid, &UnknownDevice) == 0) {
        //
        // GUID used by EFI to enumerate an EDD 1.1 device
        //
        UnknownDevPath = (UNKNOWN_DEVICE_VENDOR_DEVICE_PATH *)Vendor;
        CatPrint(Str, L":%02x)", UnknownDevPath->LegacyDriveLetter);
    } else {
        CatPrint(Str, L")");
    }
}


/*
  Type: 2 (ACPI Device Path) SubType: 1 (ACPI Device Path)
 */
static VOID
_DevPathAcpi (
    IN OUT POOL_PRINT       *Str,
    IN VOID                 *DevPath
    )
{
    ACPI_HID_DEVICE_PATH        *Acpi;

    Acpi = DevPath;
    if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
        switch ( EISA_ID_TO_NUM( Acpi-> HID ) ) {
            case 0x301 : {
                CatPrint( Str , L"Keyboard(%d)" , Acpi-> UID ) ;
                break ;
            }
            case 0x401 : {
                CatPrint( Str , L"ParallelPort(%d)" , Acpi-> UID ) ;
                break ;
            }
            case 0x501 : {
                CatPrint( Str , L"Serial(%d)" , Acpi-> UID ) ;
                break ;
            }
            case 0x604 : {
                CatPrint( Str , L"Floppy(%d)" , Acpi-> UID ) ;
                break ;
            }
            case 0xa03 : {
                CatPrint( Str , L"PciRoot(%d)" , Acpi-> UID ) ;
                break ;
            }
            case 0xa08 : {
                CatPrint( Str , L"PcieRoot(%d)" , Acpi-> UID ) ;
                break ;
            }
            default : {
                CatPrint( Str , L"Acpi(PNP%04x" , EISA_ID_TO_NUM( Acpi-> HID ) ) ;
                if ( Acpi-> UID ) CatPrint( Str , L",%d" , Acpi-> UID ) ;
                CatPrint( Str , L")" ) ;
                break ;
            }
	}
    } else {
        CatPrint( Str , L"Acpi(0x%X" , Acpi-> HID ) ;
        if ( Acpi-> UID ) CatPrint( Str , L",%d" , Acpi-> UID ) ;
        CatPrint( Str , L")" , Acpi-> HID , Acpi-> UID ) ;
    }
}


static VOID
_DevPathAtapi (
    IN OUT POOL_PRINT       *Str,
    IN VOID                 *DevPath
    )
{
    ATAPI_DEVICE_PATH       *Atapi;

    Atapi = DevPath;
    CatPrint(Str, L"Ata(%s,%s)",
        Atapi->PrimarySecondary ? L"Secondary" : L"Primary",
        Atapi->SlaveMaster ? L"Slave" : L"Master"
        );
}

static VOID
_DevPathScsi (
    IN OUT POOL_PRINT       *Str,
    IN VOID                 *DevPath
    )
{
    SCSI_DEVICE_PATH        *Scsi;

    Scsi = DevPath;
    CatPrint(Str, L"Scsi(%d,%d)", Scsi->Pun, Scsi->Lun);
}


static VOID
_DevPathFibre (
    IN OUT POOL_PRINT       *Str,
    IN VOID                 *DevPath
    )
{
    FIBRECHANNEL_DEVICE_PATH    *Fibre;

    Fibre = DevPath;
    CatPrint( Str , L"Fibre%s(0x%016lx,0x%016lx)" ,
        DevicePathType( & Fibre-> Header ) == MSG_FIBRECHANNEL_DP ? L"" : L"Ex" ,
        Fibre-> WWN , Fibre-> Lun ) ;
}

static VOID
_DevPath1394 (
    IN OUT POOL_PRINT       *Str,
    IN VOID                 *DevPath
    )
{
    F1394_DEVICE_PATH       *F1394;

    F1394 = DevPath;
    CatPrint(Str, L"1394(%g)", &F1394->Guid);
}



static VOID
_DevPathUsb (
    IN OUT POOL_PRINT       *Str,
    IN VOID                 *DevPath
    )
{
    USB_DEVICE_PATH         *Usb;

    Usb = DevPath;
    CatPrint( Str , L"Usb(0x%x,0x%x)" , Usb-> Port , Usb-> Endpoint ) ;
}


static VOID
_DevPathI2O (
    IN OUT POOL_PRINT       *Str,
    IN VOID                 *DevPath
    )
{
    I2O_DEVICE_PATH         *I2O;

    I2O = DevPath;
    CatPrint(Str, L"I2O(0x%X)", I2O->Tid);
}

static VOID
_DevPathMacAddr (
    IN OUT POOL_PRINT       *Str,
    IN VOID                 *DevPath
    )
{
    MAC_ADDR_DEVICE_PATH    *MAC;
    UINTN                   HwAddressSize;
    UINTN                   Index;

    MAC = DevPath;

    /* HwAddressSize = sizeof(EFI_MAC_ADDRESS); */
    HwAddressSize = DevicePathNodeLength( & MAC-> Header ) ;
    HwAddressSize -= sizeof( MAC-> Header ) ;
    HwAddressSize -= sizeof( MAC-> IfType ) ;
    if (MAC->IfType == 0x01 || MAC->IfType == 0x00) {
        HwAddressSize = 6;
    }

    CatPrint(Str, L"Mac(");

    for(Index = 0; Index < HwAddressSize; Index++) {
        CatPrint(Str, L"%02x",MAC->MacAddress.Addr[Index]);
    }
    if ( MAC-> IfType != 0 ) {
        CatPrint(Str, L",%d" , MAC-> IfType ) ;
    }
    CatPrint(Str, L")");
}

static VOID
CatPrintIPv4(
    IN OUT POOL_PRINT * Str ,
    IN EFI_IPv4_ADDRESS * Address
    )
{
    CatPrint( Str , L"%d.%d.%d.%d" , Address-> Addr[ 0 ] , Address-> Addr[ 1 ] ,
        Address-> Addr[ 2 ] , Address-> Addr[ 3 ] ) ;
}

static BOOLEAN
IsNotNullIPv4(
    IN EFI_IPv4_ADDRESS * Address
    )
{
    UINT8 val ;
    val = Address-> Addr[ 0 ] | Address-> Addr[ 1 ] ;
    val |= Address-> Addr[ 2 ] | Address-> Addr[ 3 ] ;
    return val != 0 ;
}

static VOID
CatPrintNetworkProtocol(
    IN OUT POOL_PRINT * Str ,
    IN UINT16 Proto
    )
{
    if ( Proto == 6 ) {
        CatPrint( Str , L"TCP" ) ;
    } else if ( Proto == 17 ) {
        CatPrint( Str , L"UDP" ) ;
    } else {
        CatPrint( Str , L"%d" , Proto ) ;
    }
}

static VOID
_DevPathIPv4 (
    IN OUT POOL_PRINT       *Str,
    IN VOID                 *DevPath
    )
{
    IPv4_DEVICE_PATH     *IP;
    BOOLEAN show ;

    IP = DevPath;
    CatPrint( Str , L"IPv4(") ;
    CatPrintIPv4( Str , & IP-> RemoteIpAddress ) ;
    CatPrint( Str , L",") ;
    CatPrintNetworkProtocol( Str , IP-> Protocol ) ;
    CatPrint( Str , L",%s" , IP-> StaticIpAddress ? L"Static" : L"DHCP" ) ;
    show = IsNotNullIPv4( & IP-> LocalIpAddress ) ;
    if ( ! show && DevicePathNodeLength( & IP-> Header ) == sizeof( IPv4_DEVICE_PATH ) ) {
        /* only version 2 includes gateway and netmask */
        show |= IsNotNullIPv4( & IP-> GatewayIpAddress ) ;
        show |= IsNotNullIPv4( & IP-> SubnetMask  ) ;
    }
    if ( show ) {
        CatPrint( Str , L"," ) ;
        CatPrintIPv4( Str , & IP-> LocalIpAddress ) ;
        if ( DevicePathNodeLength( & IP-> Header ) == sizeof( IPv4_DEVICE_PATH ) ) {
            /* only version 2 includes gateway and netmask */
            show = IsNotNullIPv4( & IP-> GatewayIpAddress ) ;
            show |= IsNotNullIPv4( & IP-> SubnetMask ) ;
            if ( show ) {
                CatPrint( Str , L",") ;
                CatPrintIPv4( Str , & IP-> GatewayIpAddress ) ;
                if ( IsNotNullIPv4( & IP-> SubnetMask ) ) {
                    CatPrint( Str , L",") ;
                    CatPrintIPv4( Str , & IP-> SubnetMask ) ;
                }
            }
        }
    }
    CatPrint( Str , L")") ;
}

#define CatPrintIPv6_ADD( x , y ) ( ( (UINT16) ( x ) ) << 8 | ( y ) )
static VOID
CatPrintIPv6(
    IN OUT POOL_PRINT * Str ,
    IN EFI_IPv6_ADDRESS * Address
    )
{
    CatPrint( Str , L"%x:%x:%x:%x:%x:%x:%x:%x" ,
        CatPrintIPv6_ADD( Address-> Addr[ 0 ] , Address-> Addr[ 1 ] ) ,
        CatPrintIPv6_ADD( Address-> Addr[ 2 ] , Address-> Addr[ 3 ] ) ,
        CatPrintIPv6_ADD( Address-> Addr[ 4 ] , Address-> Addr[ 5 ] ) ,
        CatPrintIPv6_ADD( Address-> Addr[ 6 ] , Address-> Addr[ 7 ] ) ,
        CatPrintIPv6_ADD( Address-> Addr[ 8 ] , Address-> Addr[ 9 ] ) ,
        CatPrintIPv6_ADD( Address-> Addr[ 10 ] , Address-> Addr[ 11 ] ) ,
        CatPrintIPv6_ADD( Address-> Addr[ 12 ] , Address-> Addr[ 13 ] ) ,
        CatPrintIPv6_ADD( Address-> Addr[ 14 ] , Address-> Addr[ 15 ] ) ) ;
}

static VOID
_DevPathIPv6 (
    IN OUT POOL_PRINT       *Str,
    IN VOID                 *DevPath
    )
{
    IPv6_DEVICE_PATH     *IP;

    IP = DevPath;
    CatPrint( Str , L"IPv6(") ;
    CatPrintIPv6( Str , & IP-> RemoteIpAddress ) ;
    CatPrint( Str , L",") ;
    CatPrintNetworkProtocol( Str, IP-> Protocol ) ;
    CatPrint( Str , L",%s," , IP-> IPAddressOrigin ?
        ( IP-> IPAddressOrigin == 1 ? L"StatelessAutoConfigure" :
        L"StatefulAutoConfigure" ) : L"Static" ) ;
    CatPrintIPv6( Str , & IP-> LocalIpAddress ) ;
    if ( DevicePathNodeLength( & IP-> Header ) == sizeof( IPv6_DEVICE_PATH ) ) {
        CatPrint( Str , L",") ;
        CatPrintIPv6( Str , & IP-> GatewayIpAddress ) ;
        CatPrint( Str , L",") ;
        CatPrint( Str , L"%d" , & IP-> PrefixLength ) ;
    }
    CatPrint( Str , L")") ;
}

static VOID
_DevPathUri (
    IN OUT POOL_PRINT       *Str,
    IN VOID                 *DevPath
    )
{
    URI_DEVICE_PATH  *Uri;

    Uri = DevPath;

    CatPrint( Str, L"Uri(%a)", Uri->Uri );
}

static VOID
_DevPathInfiniBand (
    IN OUT POOL_PRINT       *Str,
    IN VOID                 *DevPath
    )
{
    INFINIBAND_DEVICE_PATH  *InfiniBand;

    InfiniBand = DevPath;
    CatPrint( Str , L"Infiniband(0x%x,%g,0x%lx,0x%lx,0x%lx)" ,
        InfiniBand-> ResourceFlags , InfiniBand-> PortGid , InfiniBand-> ServiceId ,
        InfiniBand-> TargetPortId , InfiniBand-> DeviceId ) ;
}

static VOID
_DevPathUart (
    IN OUT POOL_PRINT       *Str,
    IN VOID                 *DevPath
    )
{
    UART_DEVICE_PATH  *Uart;
    CHAR8             Parity;

    Uart = DevPath;
    switch (Uart->Parity) {
        case 0  : Parity = 'D'; break;
        case 1  : Parity = 'N'; break;
        case 2  : Parity = 'E'; break;
        case 3  : Parity = 'O'; break;
        case 4  : Parity = 'M'; break;
        case 5  : Parity = 'S'; break;
        default : Parity = 'x'; break;
    }

    if (Uart->BaudRate == 0) {
        CatPrint(Str, L"Uart(DEFAULT %c",Uart->BaudRate,Parity);
    } else {
        CatPrint(Str, L"Uart(%d %c",Uart->BaudRate,Parity);
    }

    if (Uart->DataBits == 0) {
        CatPrint(Str, L"D");
    } else {
        CatPrint(Str, L"%d",Uart->DataBits);
    }

    switch (Uart->StopBits) {
        case 0  : CatPrint(Str, L"D)");   break;
        case 1  : CatPrint(Str, L"1)");   break;
        case 2  : CatPrint(Str, L"1.5)"); break;
        case 3  : CatPrint(Str, L"2)");   break;
        default : CatPrint(Str, L"x)");   break;
    }
}

static VOID
_DevPathSata (
    IN OUT POOL_PRINT       *Str,
    IN VOID                 *DevPath
    )
{
    SATA_DEVICE_PATH * Sata ;

    Sata = DevPath;
    CatPrint( Str , L"Sata(0x%x,0x%x,0x%x)" , Sata-> HBAPortNumber ,
        Sata-> PortMultiplierPortNumber , Sata-> Lun ) ;
}

static VOID
_DevPathHardDrive (
    IN OUT POOL_PRINT       *Str,
    IN VOID                 *DevPath
    )
{
    HARDDRIVE_DEVICE_PATH   *Hd;

    Hd = DevPath;
    switch (Hd->SignatureType) {
        case SIGNATURE_TYPE_MBR:
            CatPrint(Str, L"HD(Part%d,Sig%08X)",
                Hd->PartitionNumber,
                *((UINT32 *)(&(Hd->Signature[0])))
                );
            break;
        case SIGNATURE_TYPE_GUID:
            CatPrint(Str, L"HD(Part%d,Sig%g)",
                Hd->PartitionNumber,
                (EFI_GUID *) &(Hd->Signature[0])
                );
            break;
        default:
            CatPrint(Str, L"HD(Part%d,MBRType=%02x,SigType=%02x)",
                Hd->PartitionNumber,
                Hd->MBRType,
                Hd->SignatureType
                );
            break;
    }
}

static VOID
_DevPathCDROM (
    IN OUT POOL_PRINT       *Str,
    IN VOID                 *DevPath
    )
{
    CDROM_DEVICE_PATH       *Cd;

    Cd = DevPath;
    CatPrint( Str , L"CDROM(0x%x)" , Cd-> BootEntry ) ;
}

static VOID
_DevPathFilePath (
    IN OUT POOL_PRINT       *Str,
    IN VOID                 *DevPath
    )
{
    FILEPATH_DEVICE_PATH    *Fp;

    Fp = DevPath;
    CatPrint(Str, L"%s", Fp->PathName);
}

static VOID
_DevPathMediaProtocol (
    IN OUT POOL_PRINT       *Str,
    IN VOID                 *DevPath
    )
{
    MEDIA_PROTOCOL_DEVICE_PATH  *MediaProt;

    MediaProt = DevPath;
    CatPrint(Str, L"%g", &MediaProt->Protocol);
}

static VOID
_DevPathBssBss (
    IN OUT POOL_PRINT       *Str,
    IN VOID                 *DevPath
    )
{
    BBS_BBS_DEVICE_PATH     *Bss;
    CHAR16                  *Type;

    Bss = DevPath;
    switch (Bss->DeviceType) {
    case BBS_TYPE_FLOPPY:               Type = L"Floppy";       break;
    case BBS_TYPE_HARDDRIVE:            Type = L"Harddrive";    break;
    case BBS_TYPE_CDROM:                Type = L"CDROM";        break;
    case BBS_TYPE_PCMCIA:               Type = L"PCMCIA";       break;
    case BBS_TYPE_USB:                  Type = L"Usb";          break;
    case BBS_TYPE_EMBEDDED_NETWORK:     Type = L"Net";          break;
    default:                            Type = L"?";            break;
    }

    CatPrint(Str, L"Bss-%s(%a)", Type, Bss->String);
}


static VOID
_DevPathEndInstance (
    IN OUT POOL_PRINT       *Str,
    IN VOID                 *DevPath EFI_UNUSED
    )
{
    CatPrint(Str, L",");
}

/**
 * Print unknown device node.
 * UEFI 2.4 § 9.6.1.6 table 89.
 */

static VOID
_DevPathNodeUnknown (
    IN OUT POOL_PRINT       *Str,
    IN VOID                 *DevPath
    )
{
    EFI_DEVICE_PATH * Path ;
    UINT8 * value ;
    int length , index ;
    Path = DevPath ;
    value = DevPath ;
    value += 4 ;
    switch ( Path-> Type ) {
        case HARDWARE_DEVICE_PATH : { /* Unknown Hardware Device Path */
            CatPrint( Str , L"HardwarePath(%d" , Path-> SubType ) ;
            break ;
        }
        case ACPI_DEVICE_PATH : { /* Unknown ACPI Device Path */
            CatPrint( Str , L"AcpiPath(%d" , Path-> SubType ) ;
            break ;
        }
        case MESSAGING_DEVICE_PATH : { /* Unknown Messaging Device Path */
            CatPrint( Str , L"Msg(%d" , Path-> SubType ) ;
            break ;
        }
        case MEDIA_DEVICE_PATH : { /* Unknown Media Device Path */
            CatPrint( Str , L"MediaPath(%d" , Path-> SubType ) ;
            break ;
        }
        case BBS_DEVICE_PATH : { /* Unknown BIOS Boot Specification Device Path */
            CatPrint( Str , L"BbsPath(%d" , Path-> SubType ) ;
            break ;
        }
        default : { /* Unknown Device Path */
            CatPrint( Str , L"Path(%d,%d" , Path-> Type , Path-> SubType ) ;
            break ;
        }
    }
    length = DevicePathNodeLength( Path ) ;
    for ( index = 0 ; index < length ; index ++ ) {
        if ( index == 0 ) CatPrint( Str , L",0x" ) ;
        CatPrint( Str , L"%02x" , * value ) ;
	value ++ ;
    }
    CatPrint( Str , L")" ) ;
}


/*
 * Table to convert "Type" and "SubType" to a "convert to text" function/
 * Entries hold "Type" and "SubType" for know values.
 * Special "SubType" 0 is used as default for known type with unknown subtype.
 */
struct {
    UINT8   Type;
    UINT8   SubType;
    VOID    (*Function)(POOL_PRINT *, VOID *);
} DevPathTable[] = {
	{ HARDWARE_DEVICE_PATH,   HW_PCI_DP,                        _DevPathPci},
	{ HARDWARE_DEVICE_PATH,   HW_PCCARD_DP,                     _DevPathPccard},
	{ HARDWARE_DEVICE_PATH,   HW_MEMMAP_DP,                     _DevPathMemMap},
	{ HARDWARE_DEVICE_PATH,   HW_VENDOR_DP,                     _DevPathVendor},
	{ HARDWARE_DEVICE_PATH,   HW_CONTROLLER_DP,                 _DevPathController},
	{ ACPI_DEVICE_PATH,       ACPI_DP,                          _DevPathAcpi},
	{ MESSAGING_DEVICE_PATH,  MSG_ATAPI_DP,                     _DevPathAtapi},
	{ MESSAGING_DEVICE_PATH,  MSG_SCSI_DP,                      _DevPathScsi},
	{ MESSAGING_DEVICE_PATH,  MSG_FIBRECHANNEL_DP,              _DevPathFibre},
	{ MESSAGING_DEVICE_PATH,  MSG_1394_DP,                      _DevPath1394},
	{ MESSAGING_DEVICE_PATH,  MSG_USB_DP,                       _DevPathUsb},
	{ MESSAGING_DEVICE_PATH,  MSG_I2O_DP,                       _DevPathI2O},
	{ MESSAGING_DEVICE_PATH,  MSG_MAC_ADDR_DP,                  _DevPathMacAddr},
	{ MESSAGING_DEVICE_PATH,  MSG_IPv4_DP,                      _DevPathIPv4},
	{ MESSAGING_DEVICE_PATH,  MSG_IPv6_DP,                      _DevPathIPv6},
	{ MESSAGING_DEVICE_PATH,  MSG_URI_DP,                       _DevPathUri},
	{ MESSAGING_DEVICE_PATH,  MSG_INFINIBAND_DP,                _DevPathInfiniBand},
	{ MESSAGING_DEVICE_PATH,  MSG_UART_DP,                      _DevPathUart},
	{ MESSAGING_DEVICE_PATH , MSG_SATA_DP ,                     _DevPathSata } ,
	{ MESSAGING_DEVICE_PATH,  MSG_VENDOR_DP,                    _DevPathVendor},
	{ MEDIA_DEVICE_PATH,      MEDIA_HARDDRIVE_DP,               _DevPathHardDrive},
	{ MEDIA_DEVICE_PATH,      MEDIA_CDROM_DP,                   _DevPathCDROM},
	{ MEDIA_DEVICE_PATH,      MEDIA_VENDOR_DP,                  _DevPathVendor},
	{ MEDIA_DEVICE_PATH,      MEDIA_FILEPATH_DP,                _DevPathFilePath},
	{ MEDIA_DEVICE_PATH,      MEDIA_PROTOCOL_DP,                _DevPathMediaProtocol},
	{ BBS_DEVICE_PATH,        BBS_BBS_DP,                       _DevPathBssBss},
	{ END_DEVICE_PATH_TYPE,   END_INSTANCE_DEVICE_PATH_SUBTYPE, _DevPathEndInstance},
	{ 0,                      0,                          NULL}
};


CHAR16 *
DevicePathToStr (
    EFI_DEVICE_PATH     *DevPath
    )
/*++

    Turns the Device Path into a printable string.  Allcoates
    the string from pool.  The caller must FreePool the returned
    string.

--*/
{
    POOL_PRINT          Str;
    EFI_DEVICE_PATH     *DevPathNode;
    VOID                (*DumpNode)(POOL_PRINT *, VOID *);
    UINTN               Index, NewSize;

    ZeroMem(&Str, sizeof(Str));

    //
    // Unpacked the device path
    //

    DevPath = UnpackDevicePath(DevPath);
    ASSERT (DevPath);


    //
    // Process each device path node
    //

    DevPathNode = DevPath;
    while (!IsDevicePathEnd(DevPathNode)) {
        //
        // Find the handler to dump this device path node
        //

        DumpNode = NULL;
        for (Index = 0; DevPathTable[Index].Function; Index += 1) {

            if (DevicePathType(DevPathNode) == DevPathTable[Index].Type &&
                DevicePathSubType(DevPathNode) == DevPathTable[Index].SubType) {
                DumpNode = DevPathTable[Index].Function;
                break;
            }
        }

        //
        // If not found, use a generic function
        //

        if (!DumpNode) {
            DumpNode = _DevPathNodeUnknown;
        }

        //
        //  Put a path seperator in if needed
        //

        if (Str.len  &&  DumpNode != _DevPathEndInstance) {
            CatPrint (&Str, L"/");
        }

        //
        // Print this node of the device path
        //

        DumpNode (&Str, DevPathNode);

        //
        // Next device path node
        //

        DevPathNode = NextDevicePathNode(DevPathNode);
    }

    //
    // Shrink pool used for string allocation
    //

    FreePool (DevPath);
    NewSize = (Str.len + 1) * sizeof(CHAR16);
    Str.str = ReallocatePool (Str.str, NewSize, NewSize);
    Str.str[Str.len] = 0;
    return Str.str;
}

BOOLEAN
LibMatchDevicePaths (
    IN  EFI_DEVICE_PATH *Multi,
    IN  EFI_DEVICE_PATH *Single
    )
{
    EFI_DEVICE_PATH     *DevicePath, *DevicePathInst;
    UINTN               Size;

    if (!Multi || !Single) {
        return FALSE;
    }

    DevicePath = Multi;
    while ((DevicePathInst = DevicePathInstance (&DevicePath, &Size))) {
        if (CompareMem (Single, DevicePathInst, Size) == 0) {
            return TRUE;
        }
    }
    return FALSE;
}

EFI_DEVICE_PATH *
LibDuplicateDevicePathInstance (
    IN EFI_DEVICE_PATH  *DevPath
    )
{
    EFI_DEVICE_PATH     *NewDevPath,*DevicePathInst,*Temp;
    UINTN               Size = 0;

    //
    // get the size of an instance from the input
    //

    Temp = DevPath;
    DevicePathInst = DevicePathInstance (&Temp, &Size);

    //
    // Make a copy and set proper end type
    //
    NewDevPath = NULL;
    if (Size) {
        NewDevPath = AllocatePool (Size + sizeof(EFI_DEVICE_PATH));
    }

    if (NewDevPath) {
        CopyMem (NewDevPath, DevicePathInst, Size);
        Temp = NextDevicePathNode(NewDevPath);
        SetDevicePathEndNode(Temp);
    }

    return NewDevPath;
}

