Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 9 Mar 2017 00:31:31 +0000 (UTC)
From:      Warner Losh <imp@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r314926 - head/lib/libefivar
Message-ID:  <201703090031.v290VVDQ041055@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: imp
Date: Thu Mar  9 00:31:31 2017
New Revision: 314926
URL: https://svnweb.freebsd.org/changeset/base/314926

Log:
  Bring in EDK2 routines for printing and parsing device paths.
  
  This commit implements the (mostly?) Linux compatible
  efidp_format_device_path and efidp_parse_device_path APIs. These are
  the only APIs exposed through this library. However, they are built on
  code from Tianocore's EDK2 MdePkg. They are brought in as new files
  here for reasons described in FreeBSD-update.
  
  Symbol versioning will be introduced to control what's exported from
  the EDK2 code.
  
  Some structural changes may be necessary when we move to sharing with
  sys/boot/efi.
  
  Sponsored by: Netflix

Added:
  head/lib/libefivar/FreeBSD-update   (contents, props changed)
  head/lib/libefivar/ProcessorBind.h   (contents, props changed)
  head/lib/libefivar/efi-osdep.h   (contents, props changed)
  head/lib/libefivar/efivar-dp-format.c   (contents, props changed)
  head/lib/libefivar/efivar-dp-parse.c   (contents, props changed)
  head/lib/libefivar/efivar-dp.h   (contents, props changed)
  head/lib/libefivar/uefi-dplib.h   (contents, props changed)
  head/lib/libefivar/uefi-dputil.c   (contents, props changed)
  head/lib/libefivar/uefi-guid.c   (contents, props changed)
  head/lib/libefivar/uefi-guid.dat   (contents, props changed)
Modified:
  head/lib/libefivar/Makefile
  head/lib/libefivar/efivar.h

Added: head/lib/libefivar/FreeBSD-update
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/lib/libefivar/FreeBSD-update	Thu Mar  9 00:31:31 2017	(r314926)
@@ -0,0 +1,39 @@
+$FreeBSD$
+
+For the printing and parsing functionalit, we use the Tianocore routines directly.
+
+efivar-dp-format.c is a copy of MdePkg/Library/UefiDevicePathLib/DevicePathToText.c
+efivar-dp-parse.c is a copy of MdePkg/Library/UefiDevicePathLib/DevicePathFromText.c
+
+These files are first mechnaically processed with
+
+sed -e "s/L'/'/;"'s/L"/"/g;s/%g/%36s/g;s/%a/%s/g;s/^VOID/static VOID/g;s/ *$//g'
+
+for several reasons. We're moving from wide rotuines to narrow
+routines. The UTC-2 this code is written for is a bad match for
+wchar_t which is an int. It's a much better match for plain narrow
+characters on FreeBSD. So we pretend that CHAR16 for these files is
+really char * (ASCII).
+
+Next, we have have to convert the Unicode printf that this code
+expects to FreeBSD's printf. %g means "Print the GUID" and %a means
+"print the ASCII string." so we mechanically convert them. Once we've
+done that we can compare efivar-dp-*.c to its source to see what's
+changed. Because we go through this indirection, I've done that
+outside of svn. To upgrade you have to do these files by hand. You
+have to go through and make routines static.
+
+uefi-*.[ch] are internal routines to support this. They've been copied
+from EDK2 as well, but in a more hap-hazard manner. This was a trade
+off between ease of implementation / upgrade vs pulling in too much
+since less than half of any file was needed.
+
+efi-osdep.h shims the EDK2 types to FreeBSD's types. It's included by
+ProcessorBind.h which EDK2 uses to define the CPU. We keep it separate
+from uefi-dplib.h to allow better sharing.
+
+uefi-dplib.h shims the EDK2 routines that are needed to FreeBSD's
+routines. This is relatively easy since we map all the UCS-2 routines
+to simple char * routines.
+
+RESIST THE URGE TO CLEAN UP THESE FILES.

Modified: head/lib/libefivar/Makefile
==============================================================================
--- head/lib/libefivar/Makefile	Thu Mar  9 00:24:01 2017	(r314925)
+++ head/lib/libefivar/Makefile	Thu Mar  9 00:31:31 2017	(r314926)
@@ -27,17 +27,23 @@
 .include <src.opts.mk>
 
 EFIBOOT=${SRCTOP}/sys/boot/efi
+EDK2INC=${SRCTOP}/sys/contrib/edk2/Include
 
 .PATH:	${EFIBOOT}/libefi
 
 PACKAGE=lib${LIB}
 LIB=		efivar
-SRCS=		efivar.c efichar.c
-INCS=		efivar.h
+SRCS=		efivar.c efichar.c efivar-dp-format.c \
+		efivar-dp-parse.c \
+		uefi-guid.c uefi-dputil.c
+INCS=		efivar.h efivar-dp.h
 SHLIB_MAJOR=	1
 MAN=		efivar.3
 
 CFLAGS+=	-I${EFIBOOT}/include
+CFLAGS+=	-I${.CURDIR} -I${EDK2INC}
+
+CFLAGS.efivar-dp-format.c=-Wno-unused-parameter
 
 MLINKS+=efivar.3 efi_set_variables_supported.3 \
 	efivar.3 efi_del_variable.3 \
@@ -57,3 +63,5 @@ MLINKS+=efivar.3 efi_set_variables_suppo
 WARNS?=		9
 
 .include <bsd.lib.mk>
+
+CFLAGS+= -Wno-cast-align -Wno-unused-parameter

Added: head/lib/libefivar/ProcessorBind.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/lib/libefivar/ProcessorBind.h	Thu Mar  9 00:31:31 2017	(r314926)
@@ -0,0 +1,4 @@
+/* File in public domain */
+/* Brings in the glue for UEFI/EDK2 Tianocore code to run on this OS */
+/* $FreeBSD$ */
+#include "efi-osdep.h"

Added: head/lib/libefivar/efi-osdep.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/lib/libefivar/efi-osdep.h	Thu Mar  9 00:31:31 2017	(r314926)
@@ -0,0 +1,111 @@
+/*-
+ * Copyright (c) 2017 Netflix, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer
+ *    in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef	_EFI_OSDEP_H_
+#define	_EFI_OSDEP_H_
+
+/*
+ * Defines to adjust the types that EDK2 uses for FreeBSD so we can
+ * use the code and headers mostly unchanged. The headers are imported
+ * all into one directory to avoid case issues with filenames and
+ * included. The actual code is heavily modified since it has too many
+ * annoying dependencies that are difficult to satisfy.
+ */
+
+#include <sys/cdefs.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <uuid.h>
+
+typedef int8_t INT8;
+typedef int16_t INT16;
+typedef int32_t INT32;
+typedef int64_t INT64;
+typedef intptr_t INTN;
+typedef uint8_t UINT8;
+typedef uint16_t UINT16;
+typedef uint32_t UINT32;
+typedef uint64_t UINT64;
+typedef uintptr_t UINTN;
+//typedef uintptr_t EFI_PHYSICAL_ADDRESS;
+//typedef uint32_t EFI_IPv4_ADDRESS;
+//typedef uint8_t EFI_MAC_ADDRESS[6];
+//typedef uint8_t EFI_IPv6_ADDRESS[16];
+typedef uint8_t CHAR8;
+typedef uint16_t CHAR16;
+typedef UINT8 BOOLEAN;
+typedef void VOID;
+//typedef uuid_t GUID;
+//typedef uuid_t EFI_GUID;
+
+/* We can't actually call this stuff, so snip out API syntactic sugar */
+#define INTERFACE_DECL(x)
+#define EFIAPI
+#define IN
+#define OUT
+#define CONST const
+#define OPTIONAL
+//#define TRUE 1
+//#define FALSE 0
+
+/*
+ * EDK2 has fine definitions for these, so let it define them.
+ */
+#undef NULL
+#undef EFI_PAGE_SIZE
+#undef EFI_PAGE_MASK
+
+/*
+ * Note: the EDK2 code assumed #pragma packed works and PACKED is a
+ * workaround for some old toolchain issues for EDK2 that aren't
+ * relevent to FreeBSD.
+ */
+#define PACKED
+
+/*
+ * Since we're not compiling for the UEFI boot time (which use ms abi
+ * conventions), tell EDK2 to define VA_START correctly. For the boot
+ * loader, this likely needs to be different.
+ */
+#define NO_MSABI_VA_FUNCS 1
+
+/*
+ * Finally, we need to define the processor we are in EDK2 terms.
+ */
+#if defined(__i386__)
+#define MDE_CPU_IA32
+#elif defined(__amd64__)
+#define MDE_CPU_X64
+#elif defined(__arm__)
+#define MDE_CPU_ARM
+#elif defined(__aarch64__)
+#define MDE_CPU_AARCH64
+#endif
+/* FreeBSD doesn't have/use MDE_CPU_EBC or MDE_CPU_IPF (ia64) */
+
+#endif /* _EFI_OSDEP_H_ */

Added: head/lib/libefivar/efivar-dp-format.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ head/lib/libefivar/efivar-dp-format.c	Thu Mar  9 00:31:31 2017	(r314926)
@@ -0,0 +1,2427 @@
+/*-
+ * Copyright (c) 2017 Netflix, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer
+ *    in this position and unchanged.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Routines to format EFI_DEVICE_PATHs from the UEFI standard. Much of
+ * this file is taken from EDK2 and rototilled.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <efivar.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "efi-osdep.h"
+#include "efivar-dp.h"
+
+#include "uefi-dplib.h"
+
+/*
+ * This is a lie, but since we have converted everything
+ * from wide to narrow, it's the right lie now.
+ */
+#define UnicodeSPrint snprintf
+
+/*
+ * Taken from MdePkg/Library/UefiDevicePathLib/DevicePathToText.c
+ * hash a11928f3310518ab1c6fd34e8d0fdbb72de9602c 2017-Mar-01
+ * heavily modified:
+ *	wide strings converted to narrow
+ *	Low level printing code redone for narrow strings
+ *	Routines made static
+ *	%s -> %S in spots (where it is still UCS-2)
+ *	%a (ascii) -> %s
+ *	%g -> %36s hack to print guid (see above for caveat)
+ *	some tidying up of const and deconsting. It's evil, but const
+ *	  poisoning the whole file was too much.
+ */
+
+/** @file
+  DevicePathToText protocol as defined in the UEFI 2.0 specification.
+
+  (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>
+Copyright (c) 2013 - 2015, 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 "UefiDevicePathLib.h"
+
+/**
+  Concatenates a formatted unicode string to allocated pool. The caller must
+  free the resulting buffer.
+
+  @param Str             Tracks the allocated pool, size in use, and
+                         amount of pool allocated.
+  @param Fmt             The format string
+  @param ...             Variable arguments based on the format string.
+
+  @return Allocated buffer with the formatted string printed in it.
+          The caller must free the allocated buffer. The buffer
+          allocation is not packed.
+
+**/
+static char *
+EFIAPI
+UefiDevicePathLibCatPrint (
+  IN OUT POOL_PRINT   *Str,
+  IN const char       *Fmt,
+  ...
+  )
+{
+  UINTN   Count;
+  VA_LIST Args;
+
+  VA_START (Args, Fmt);
+  Count = vsnprintf(NULL, 0, Fmt, Args);
+  VA_END(Args);
+
+  if ((Str->Count + (Count + 1)) > Str->Capacity) {
+    Str->Capacity = (Str->Count + (Count + 1) * 2);
+    Str->Str = reallocf(Str->Str, Str->Capacity);
+    ASSERT (Str->Str != NULL);
+  }
+  VA_START (Args, Fmt);
+  vsnprintf(Str->Str + Str->Count, Str->Capacity - Str->Count, Fmt, Args);
+  Str->Count += Count;
+
+  VA_END (Args);
+  return Str->Str;
+}
+
+/**
+  Converts a PCI device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextPci (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  PCI_DEVICE_PATH *Pci;
+
+  Pci = DevPath;
+  UefiDevicePathLibCatPrint (Str, "Pci(0x%x,0x%x)", Pci->Device, Pci->Function);
+}
+
+/**
+  Converts a PC Card device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextPccard (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  PCCARD_DEVICE_PATH  *Pccard;
+
+  Pccard = DevPath;
+  UefiDevicePathLibCatPrint (Str, "PcCard(0x%x)", Pccard->FunctionNumber);
+}
+
+/**
+  Converts a Memory Map device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextMemMap (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  MEMMAP_DEVICE_PATH  *MemMap;
+
+  MemMap = DevPath;
+  UefiDevicePathLibCatPrint (
+    Str,
+    "MemoryMapped(0x%x,0x%lx,0x%lx)",
+    MemMap->MemoryType,
+    MemMap->StartingAddress,
+    MemMap->EndingAddress
+    );
+}
+
+/**
+  Converts a Vendor device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextVendor (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  VENDOR_DEVICE_PATH  *Vendor;
+  const char          *Type;
+  UINTN               Index;
+  UINTN               DataLength;
+  UINT32              FlowControlMap;
+  UINT16              Info;
+
+  Vendor = (VENDOR_DEVICE_PATH *) DevPath;
+  switch (DevicePathType (&Vendor->Header)) {
+  case HARDWARE_DEVICE_PATH:
+    Type = "Hw";
+    break;
+
+  case MESSAGING_DEVICE_PATH:
+    Type = "Msg";
+    if (AllowShortcuts) {
+      if (CompareGuid (&Vendor->Guid, &gEfiPcAnsiGuid)) {
+        UefiDevicePathLibCatPrint (Str, "VenPcAnsi()");
+        return ;
+      } else if (CompareGuid (&Vendor->Guid, &gEfiVT100Guid)) {
+        UefiDevicePathLibCatPrint (Str, "VenVt100()");
+        return ;
+      } else if (CompareGuid (&Vendor->Guid, &gEfiVT100PlusGuid)) {
+        UefiDevicePathLibCatPrint (Str, "VenVt100Plus()");
+        return ;
+      } else if (CompareGuid (&Vendor->Guid, &gEfiVTUTF8Guid)) {
+        UefiDevicePathLibCatPrint (Str, "VenUft8()");
+        return ;
+      } else if (CompareGuid (&Vendor->Guid, &gEfiUartDevicePathGuid)) {
+        FlowControlMap = (((UART_FLOW_CONTROL_DEVICE_PATH *) Vendor)->FlowControlMap);
+        switch (FlowControlMap & 0x00000003) {
+        case 0:
+          UefiDevicePathLibCatPrint (Str, "UartFlowCtrl(%s)", "None");
+          break;
+
+        case 1:
+          UefiDevicePathLibCatPrint (Str, "UartFlowCtrl(%s)", "Hardware");
+          break;
+
+        case 2:
+          UefiDevicePathLibCatPrint (Str, "UartFlowCtrl(%s)", "XonXoff");
+          break;
+
+        default:
+          break;
+        }
+
+        return ;
+      } else if (CompareGuid (&Vendor->Guid, &gEfiSasDevicePathGuid)) {
+        UefiDevicePathLibCatPrint (
+          Str,
+          "SAS(0x%lx,0x%lx,0x%x,",
+          ((SAS_DEVICE_PATH *) Vendor)->SasAddress,
+          ((SAS_DEVICE_PATH *) Vendor)->Lun,
+          ((SAS_DEVICE_PATH *) Vendor)->RelativeTargetPort
+          );
+        Info = (((SAS_DEVICE_PATH *) Vendor)->DeviceTopology);
+        if (((Info & 0x0f) == 0) && ((Info & BIT7) == 0)) {
+          UefiDevicePathLibCatPrint (Str, "NoTopology,0,0,0,");
+        } else if (((Info & 0x0f) <= 2) && ((Info & BIT7) == 0)) {
+          UefiDevicePathLibCatPrint (
+            Str,
+            "%s,%s,%s,",
+            ((Info & BIT4) != 0) ? "SATA" : "SAS",
+            ((Info & BIT5) != 0) ? "External" : "Internal",
+            ((Info & BIT6) != 0) ? "Expanded" : "Direct"
+            );
+          if ((Info & 0x0f) == 1) {
+            UefiDevicePathLibCatPrint (Str, "0,");
+          } else {
+            //
+            // Value 0x0 thru 0xFF -> Drive 1 thru Drive 256
+            //
+            UefiDevicePathLibCatPrint (Str, "0x%x,", ((Info >> 8) & 0xff) + 1);
+          }
+        } else {
+          UefiDevicePathLibCatPrint (Str, "0x%x,0,0,0,", Info);
+        }
+
+        UefiDevicePathLibCatPrint (Str, "0x%x)", ((SAS_DEVICE_PATH *) Vendor)->Reserved);
+        return ;
+      } else if (CompareGuid (&Vendor->Guid, &gEfiDebugPortProtocolGuid)) {
+        UefiDevicePathLibCatPrint (Str, "DebugPort()");
+        return ;
+      }
+    }
+    break;
+
+  case MEDIA_DEVICE_PATH:
+    Type = "Media";
+    break;
+
+  default:
+    Type = "?";
+    break;
+  }
+
+  DataLength = DevicePathNodeLength (&Vendor->Header) - sizeof (VENDOR_DEVICE_PATH);
+  UefiDevicePathLibCatPrint (Str, "Ven%s(%36s", Type, G(&Vendor->Guid));
+  if (DataLength != 0) {
+    UefiDevicePathLibCatPrint (Str, ",");
+    for (Index = 0; Index < DataLength; Index++) {
+      UefiDevicePathLibCatPrint (Str, "%02x", ((VENDOR_DEVICE_PATH_WITH_DATA *) Vendor)->VendorDefinedData[Index]);
+    }
+  }
+
+  UefiDevicePathLibCatPrint (Str, ")");
+}
+
+/**
+  Converts a Controller device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextController (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  CONTROLLER_DEVICE_PATH  *Controller;
+
+  Controller = DevPath;
+  UefiDevicePathLibCatPrint (
+    Str,
+    "Ctrl(0x%x)",
+    Controller->ControllerNumber
+    );
+}
+
+/**
+  Converts a BMC device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextBmc (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  BMC_DEVICE_PATH    *Bmc;
+
+  Bmc = DevPath;
+  UefiDevicePathLibCatPrint (
+    Str,
+    "BMC(0x%x,0x%lx)",
+    Bmc->InterfaceType,
+    ReadUnaligned64 ((&Bmc->BaseAddress))
+    );
+}
+
+/**
+  Converts a ACPI device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextAcpi (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  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 0x0a03:
+      UefiDevicePathLibCatPrint (Str, "PciRoot(0x%x)", Acpi->UID);
+      break;
+
+    case 0x0a08:
+      UefiDevicePathLibCatPrint (Str, "PcieRoot(0x%x)", Acpi->UID);
+      break;
+
+    case 0x0604:
+      UefiDevicePathLibCatPrint (Str, "Floppy(0x%x)", Acpi->UID);
+      break;
+
+    case 0x0301:
+      UefiDevicePathLibCatPrint (Str, "Keyboard(0x%x)", Acpi->UID);
+      break;
+
+    case 0x0501:
+      UefiDevicePathLibCatPrint (Str, "Serial(0x%x)", Acpi->UID);
+      break;
+
+    case 0x0401:
+      UefiDevicePathLibCatPrint (Str, "ParallelPort(0x%x)", Acpi->UID);
+      break;
+
+    default:
+      UefiDevicePathLibCatPrint (Str, "Acpi(PNP%04x,0x%x)", EISA_ID_TO_NUM (Acpi->HID), Acpi->UID);
+      break;
+    }
+  } else {
+    UefiDevicePathLibCatPrint (Str, "Acpi(0x%08x,0x%x)", Acpi->HID, Acpi->UID);
+  }
+}
+
+/**
+  Converts a ACPI extended HID device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextAcpiEx (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  ACPI_EXTENDED_HID_DEVICE_PATH  *AcpiEx;
+  CHAR8                          *HIDStr;
+  CHAR8                          *UIDStr;
+  CHAR8                          *CIDStr;
+  char                           HIDText[11];
+  char                           CIDText[11];
+
+  AcpiEx = DevPath;
+  HIDStr = (CHAR8 *) (((UINT8 *) AcpiEx) + sizeof (ACPI_EXTENDED_HID_DEVICE_PATH));
+  UIDStr = HIDStr + AsciiStrLen (HIDStr) + 1;
+  CIDStr = UIDStr + AsciiStrLen (UIDStr) + 1;
+
+  //
+  // Converts EISA identification to string.
+  //
+  UnicodeSPrint (
+    HIDText,
+    sizeof (HIDText),
+    "%c%c%c%04X",
+    ((AcpiEx->HID >> 10) & 0x1f) + 'A' - 1,
+    ((AcpiEx->HID >>  5) & 0x1f) + 'A' - 1,
+    ((AcpiEx->HID >>  0) & 0x1f) + 'A' - 1,
+    (AcpiEx->HID >> 16) & 0xFFFF
+    );
+  UnicodeSPrint (
+    CIDText,
+    sizeof (CIDText),
+    "%c%c%c%04X",
+    ((AcpiEx->CID >> 10) & 0x1f) + 'A' - 1,
+    ((AcpiEx->CID >>  5) & 0x1f) + 'A' - 1,
+    ((AcpiEx->CID >>  0) & 0x1f) + 'A' - 1,
+    (AcpiEx->CID >> 16) & 0xFFFF
+    );
+
+  if ((*HIDStr == '\0') && (*CIDStr == '\0') && (AcpiEx->UID == 0)) {
+    //
+    // use AcpiExp()
+    //
+    UefiDevicePathLibCatPrint (
+      Str,
+      "AcpiExp(%s,%s,%s)",
+      HIDText,
+      CIDText,
+      UIDStr
+      );
+  } else {
+    if (AllowShortcuts) {
+      //
+      // display only
+      //
+      if (AcpiEx->HID == 0) {
+        UefiDevicePathLibCatPrint (Str, "AcpiEx(%s,", HIDStr);
+      } else {
+        UefiDevicePathLibCatPrint (Str, "AcpiEx(%s,", HIDText);
+      }
+
+      if (AcpiEx->UID == 0) {
+        UefiDevicePathLibCatPrint (Str, "%s,", UIDStr);
+      } else {
+        UefiDevicePathLibCatPrint (Str, "0x%x,", AcpiEx->UID);
+      }
+
+      if (AcpiEx->CID == 0) {
+        UefiDevicePathLibCatPrint (Str, "%s)", CIDStr);
+      } else {
+        UefiDevicePathLibCatPrint (Str, "%s)", CIDText);
+      }
+    } else {
+      UefiDevicePathLibCatPrint (
+        Str,
+        "AcpiEx(%s,%s,0x%x,%s,%s,%s)",
+        HIDText,
+        CIDText,
+        AcpiEx->UID,
+        HIDStr,
+        CIDStr,
+        UIDStr
+        );
+    }
+  }
+}
+
+/**
+  Converts a ACPI address device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextAcpiAdr (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  ACPI_ADR_DEVICE_PATH    *AcpiAdr;
+  UINT32                  *Addr;
+  UINT16                  Index;
+  UINT16                  Length;
+  UINT16                  AdditionalAdrCount;
+
+  AcpiAdr            = DevPath;
+  Length             = (UINT16) DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) AcpiAdr);
+  AdditionalAdrCount = (UINT16) ((Length - 8) / 4);
+
+  UefiDevicePathLibCatPrint (Str, "AcpiAdr(0x%x", AcpiAdr->ADR);
+  Addr = &AcpiAdr->ADR + 1;
+  for (Index = 0; Index < AdditionalAdrCount; Index++) {
+    UefiDevicePathLibCatPrint (Str, ",0x%x", Addr[Index]);
+  }
+  UefiDevicePathLibCatPrint (Str, ")");
+}
+
+/**
+  Converts a ATAPI device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextAtapi (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  ATAPI_DEVICE_PATH *Atapi;
+
+  Atapi = DevPath;
+
+  if (DisplayOnly) {
+    UefiDevicePathLibCatPrint (Str, "Ata(0x%x)", Atapi->Lun);
+  } else {
+    UefiDevicePathLibCatPrint (
+      Str,
+      "Ata(%s,%s,0x%x)",
+      (Atapi->PrimarySecondary == 1) ? "Secondary" : "Primary",
+      (Atapi->SlaveMaster == 1) ? "Slave" : "Master",
+      Atapi->Lun
+      );
+  }
+}
+
+/**
+  Converts a SCSI device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextScsi (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  SCSI_DEVICE_PATH  *Scsi;
+
+  Scsi = DevPath;
+  UefiDevicePathLibCatPrint (Str, "Scsi(0x%x,0x%x)", Scsi->Pun, Scsi->Lun);
+}
+
+/**
+  Converts a Fibre device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextFibre (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  FIBRECHANNEL_DEVICE_PATH  *Fibre;
+
+  Fibre = DevPath;
+  UefiDevicePathLibCatPrint (Str, "Fibre(0x%lx,0x%lx)", Fibre->WWN, Fibre->Lun);
+}
+
+/**
+  Converts a FibreEx device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextFibreEx (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  FIBRECHANNELEX_DEVICE_PATH  *FibreEx;
+  UINTN                       Index;
+
+  FibreEx = DevPath;
+  UefiDevicePathLibCatPrint (Str, "FibreEx(0x");
+  for (Index = 0; Index < sizeof (FibreEx->WWN) / sizeof (FibreEx->WWN[0]); Index++) {
+    UefiDevicePathLibCatPrint (Str, "%02x", FibreEx->WWN[Index]);
+  }
+  UefiDevicePathLibCatPrint (Str, ",0x");
+  for (Index = 0; Index < sizeof (FibreEx->Lun) / sizeof (FibreEx->Lun[0]); Index++) {
+    UefiDevicePathLibCatPrint (Str, "%02x", FibreEx->Lun[Index]);
+  }
+  UefiDevicePathLibCatPrint (Str, ")");
+}
+
+/**
+  Converts a Sas Ex device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation
+                         of the display node is used, where applicable. If DisplayOnly
+                         is FALSE, then the longer text representation of the display node
+                         is used.
+  @param AllowShortcuts  If AllowShortcuts is TRUE, then the shortcut forms of text
+                         representation for a device node can be used, where applicable.
+
+**/
+static VOID
+DevPathToTextSasEx (
+  IN OUT POOL_PRINT  *Str,
+  IN VOID            *DevPath,
+  IN BOOLEAN         DisplayOnly,
+  IN BOOLEAN         AllowShortcuts
+  )
+{
+  SASEX_DEVICE_PATH  *SasEx;
+  UINTN              Index;
+
+  SasEx = DevPath;
+  UefiDevicePathLibCatPrint (Str, "SasEx(0x");
+
+  for (Index = 0; Index < sizeof (SasEx->SasAddress) / sizeof (SasEx->SasAddress[0]); Index++) {
+    UefiDevicePathLibCatPrint (Str, "%02x", SasEx->SasAddress[Index]);
+  }
+  UefiDevicePathLibCatPrint (Str, ",0x");
+  for (Index = 0; Index < sizeof (SasEx->Lun) / sizeof (SasEx->Lun[0]); Index++) {
+    UefiDevicePathLibCatPrint (Str, "%02x", SasEx->Lun[Index]);
+  }
+  UefiDevicePathLibCatPrint (Str, ",0x%x,", SasEx->RelativeTargetPort);
+
+  if (((SasEx->DeviceTopology & 0x0f) == 0) && ((SasEx->DeviceTopology & BIT7) == 0)) {
+    UefiDevicePathLibCatPrint (Str, "NoTopology,0,0,0");
+  } else if (((SasEx->DeviceTopology & 0x0f) <= 2) && ((SasEx->DeviceTopology & BIT7) == 0)) {
+    UefiDevicePathLibCatPrint (
+      Str,
+      "%s,%s,%s,",
+      ((SasEx->DeviceTopology & BIT4) != 0) ? "SATA" : "SAS",
+      ((SasEx->DeviceTopology & BIT5) != 0) ? "External" : "Internal",
+      ((SasEx->DeviceTopology & BIT6) != 0) ? "Expanded" : "Direct"
+      );
+    if ((SasEx->DeviceTopology & 0x0f) == 1) {
+      UefiDevicePathLibCatPrint (Str, "0");
+    } else {
+      //
+      // Value 0x0 thru 0xFF -> Drive 1 thru Drive 256
+      //
+      UefiDevicePathLibCatPrint (Str, "0x%x", ((SasEx->DeviceTopology >> 8) & 0xff) + 1);
+    }
+  } else {
+    UefiDevicePathLibCatPrint (Str, "0x%x,0,0,0", SasEx->DeviceTopology);
+  }
+
+  UefiDevicePathLibCatPrint (Str, ")");
+  return ;
+
+}
+
+/**
+  Converts a NVM Express Namespace device path structure to its string representative.
+
+  @param Str             The string representative of input device.
+  @param DevPath         The input device path structure.
+  @param DisplayOnly     If DisplayOnly is TRUE, then the shorter text representation

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201703090031.v290VVDQ041055>