summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2017-05-20 16:12:44 +0000
committerkib <kib@FreeBSD.org>2017-05-20 16:12:44 +0000
commitf954c5056d909af5d65546fe9bce8951fdae0b70 (patch)
tree6e26ea5d1ee32f63a09c90b6e14accc3eac6e847 /lib
parent78abf039aa297d9b0021f82c669f194c4bfc611e (diff)
downloadFreeBSD-src-f954c5056d909af5d65546fe9bce8951fdae0b70.zip
FreeBSD-src-f954c5056d909af5d65546fe9bce8951fdae0b70.tar.gz
MFC efivar(8) (by imp):
List of revisions merged: r307070 r307071 r307072 r307074 r307189 r307224 r307339 r307390 r307391 r309776 r314231 r314232 r314615 r314616 r314617 r314618 r314619 r314620 r314621 r314623 r314890 r314925 r314926 r314927 r314928 r315770 r315771 Discussed with: gjb (re), imp Sponsored by: The FreeBSD Foundation
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile5
-rw-r--r--lib/libefi/Makefile23
-rw-r--r--lib/libefi/efi_getvar.c68
-rw-r--r--lib/libefi/efi_nextvarname.c66
-rw-r--r--lib/libefi/efi_setvar.c66
-rw-r--r--lib/libefi/libefi.3143
-rw-r--r--lib/libefi/libefi.c176
-rw-r--r--lib/libefi/libefi.h57
-rw-r--r--lib/libefi/libefi_int.h40
-rw-r--r--lib/libefivar/FreeBSD-update39
-rw-r--r--lib/libefivar/Makefile67
-rw-r--r--lib/libefivar/ProcessorBind.h4
-rw-r--r--lib/libefivar/efi-osdep.h111
-rw-r--r--lib/libefivar/efivar-dp-format.c2427
-rw-r--r--lib/libefivar/efivar-dp-parse.c3715
-rw-r--r--lib/libefivar/efivar-dp.h65
-rw-r--r--lib/libefivar/efivar.398
-rw-r--r--lib/libefivar/efivar.c391
-rw-r--r--lib/libefivar/efivar.h135
-rw-r--r--lib/libefivar/uefi-dplib.h635
-rw-r--r--lib/libefivar/uefi-dputil.c636
-rw-r--r--lib/libefivar/uefi-guid.c36
-rw-r--r--lib/libefivar/uefi-guid.dat11
23 files changed, 8375 insertions, 639 deletions
diff --git a/lib/Makefile b/lib/Makefile
index 229d064..c9692c1 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -49,6 +49,7 @@ SUBDIR= ${SUBDIR_BOOTSTRAP} \
libdpv \
libdwarf \
libedit \
+ ${_libefivar} \
${_libelftc} \
libevent \
libexecinfo \
@@ -232,6 +233,10 @@ _libcxxrt= libcxxrt
_libcplusplus= libc++
.endif
+.if ${MK_EFI} != "no"
+_libefivar= libefivar
+.endif
+
.if ${MK_LIBTHR} != "no"
_libthr= libthr
.endif
diff --git a/lib/libefi/Makefile b/lib/libefi/Makefile
deleted file mode 100644
index d9862f0..0000000
--- a/lib/libefi/Makefile
+++ /dev/null
@@ -1,23 +0,0 @@
-# $FreeBSD$
-
-.include <bsd.own.mk>
-
-PACKAGE=lib${LIB}
-LIB= efi
-SHLIB_MAJOR= 1
-
-SRCS= libefi.c \
- efi_getvar.c \
- efi_nextvarname.c \
- efi_setvar.c
-
-CFLAGS+= -I${.CURDIR}
-
-INCS= libefi.h
-
-MAN+= libefi.3
-MLINKS+=libefi.3 efi_getvar.3 \
- libefi.3 efi_nextvarname.3 \
- libefi.3 efi_setvar.3
-
-.include <bsd.lib.mk>
diff --git a/lib/libefi/efi_getvar.c b/lib/libefi/efi_getvar.c
deleted file mode 100644
index 97e842e..0000000
--- a/lib/libefi/efi_getvar.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*-
- * Copyright (c) 2010 Marcel Moolenaar
- * 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.
- * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <libefi.h>
-#include <stdlib.h>
-
-#include "libefi_int.h"
-
-/*
- * EFI_STATUS
- * GetVariable(
- * IN CHAR16 *VariableName,
- * IN EFI_GUID *VendorGuid,
- * OUT UINT32 *Attributes OPTIONAL,
- * IN OUT UINTN *DataSize,
- * OUT VOID *Data
- * );
- */
-
-int
-efi_getvar(char *name, uuid_t *vendor, uint32_t *attrib, size_t *datasize,
- void *data)
-{
- struct iodev_efivar_req req;
- int error;
-
- req.namesize = 0;
- error = libefi_utf8_to_ucs2(name, &req.namesize, &req.name);
- if (error)
- return (error);
-
- req.vendor = *vendor;
- req.datasize = *datasize;
- req.data = data;
- req.access = IODEV_EFIVAR_GETVAR;
- error = libefi_efivar(&req);
- *datasize = req.datasize;
- if (!error && attrib != NULL)
- *attrib = req.attrib;
- free(req.name);
- return (error);
-}
diff --git a/lib/libefi/efi_nextvarname.c b/lib/libefi/efi_nextvarname.c
deleted file mode 100644
index e07659f..0000000
--- a/lib/libefi/efi_nextvarname.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/*-
- * Copyright (c) 2010 Marcel Moolenaar
- * 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.
- * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <libefi.h>
-#include <stdlib.h>
-
-#include "libefi_int.h"
-
-/*
- * EFI_STATUS
- * GetNextVariableName(
- * IN OUT UINTN *VariableNameSize,
- * IN OUT CHAR16 *VariableName,
- * IN OUT EFI_GUID *VendorGuid
- * );
- */
-
-int
-efi_nextvarname(size_t *namesize, char *name, uuid_t *vendor)
-{
- struct iodev_efivar_req req;
- int error;
-
- req.namesize = *namesize;
- error = libefi_utf8_to_ucs2(name, &req.namesize, &req.name);
- if (error)
- return (error);
-
- req.vendor = *vendor;
- req.access = IODEV_EFIVAR_NEXTNAME;
- error = libefi_efivar(&req);
- *namesize = req.namesize;
- if (!error) {
- error = libefi_ucs2_to_utf8(req.name, namesize, name);
- if (!error)
- *vendor = req.vendor;
- }
- free(req.name);
- return (error);
-}
diff --git a/lib/libefi/efi_setvar.c b/lib/libefi/efi_setvar.c
deleted file mode 100644
index be43694..0000000
--- a/lib/libefi/efi_setvar.c
+++ /dev/null
@@ -1,66 +0,0 @@
-/*-
- * Copyright (c) 2010 Marcel Moolenaar
- * 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.
- * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <libefi.h>
-#include <stdlib.h>
-
-#include "libefi_int.h"
-
-/*
- * EFI_STATUS
- * SetVariable(
- * IN CHAR16 *VariableName,
- * IN EFI_GUID *VendorGuid,
- * IN UINT32 Attributes,
- * IN UINTN DataSize,
- * IN VOID *Data
- * );
- */
-
-int
-efi_setvar(char *name, uuid_t *vendor, uint32_t attrib, size_t datasize,
- void *data)
-{
- struct iodev_efivar_req req;
- int error;
-
- req.namesize = 0;
- error = libefi_utf8_to_ucs2(name, &req.namesize, &req.name);
- if (error)
- return (error);
-
- req.vendor = *vendor;
- req.attrib = attrib;
- req.datasize = datasize;
- req.data = data;
- req.access = IODEV_EFIVAR_SETVAR;
- error = libefi_efivar(&req);
- free(req.name);
- return (error);
-}
diff --git a/lib/libefi/libefi.3 b/lib/libefi/libefi.3
deleted file mode 100644
index e090fd6..0000000
--- a/lib/libefi/libefi.3
+++ /dev/null
@@ -1,143 +0,0 @@
-.\"-
-.\" Copyright (c) 2010 Marcel Moolenaar
-.\" 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.
-.\" 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$
-.\"
-.Dd January 29, 2010
-.Dt LIBEFI 3
-.Os
-.Sh NAME
-.Nm efi_getvar , efi_nextvarname , efi_setvar
-.Nd "interface for accessing the EFI variable services"
-.Sh LIBRARY
-.Lb libefi
-.Sh SYNOPSIS
-.In libefi.h
-.Ft int
-.Fo efi_getvar
-.Fa "char *name" "uuid_t *vendor" "uint32_t *attrib"
-.Fa "size_t *datasize" "void *data"
-.Fc
-.Ft int
-.Fn efi_nextvarname "size_t *namesize" "char *name" "uuid_t *vendor"
-.Ft int
-.Fo efi_setvar
-.Fa "char *name" "uuid_t *vendor" "uint32_t attrib"
-.Fa "size_t datasize" "void *data"
-.Fc
-.Sh DESCRIPTION
-The
-.Nm libefi
-library provides access to a select set of the runtime services of the
-Extensible Firmware Interface (EFI).
-.Pp
-The
-.Fn efi_nextvarname
-function is used to enumerate the variables.
-The
-.Fa namesize
-parameter needs to be set to the size of the buffer pointed to by
-.Fa name .
-On return,
-.Fa namesize
-is set to the length of the variable name (including the terminating
-.Ql \e0 )
-irrespective of whether the buffer was big enough.
-The buffer pointed to by
-.Fa name
-contains the full or partial variable name on return.
-Only on successful completion of the request is the
-.Fa vendor
-updated.
-The values returned should be passed to successive calls to
-.Fn efi_nextvarname
-until all variables have been enumerated.
-.Pp
-The variable name and vendor as returned by
-.Fn efi_nextvarname
-can be passed to
-.Fn efi_getvar
-to obtain the value and attribute of the variable.
-The buffer that is to contain the value is specified by
-.Fa data
-and the size of the buffer is given by
-.Fa datasize .
-The attribute pointed to by
-.Fa attrib
-consists of the bit values defined by the EFI specification.
-.Pp
-Variables can be created, modified and deleted using the
-.Fn efi_setvar
-function.
-All new variables must be non-volatile and runtime accessible in
-order for the request to succeed.
-Note that for runtime accessable variables the boottime accessable bit must
-be set as well.
-To delete a variable, set
-.Fa datasize
-to 0.
-.Pp
-The vendor UUID is used to avoid collisions between variable names of
-different vendors.
-Variables created for use by
-.Fx
-should use the
-.Dv EFI_FREEBSD_VARIABLE
-UUID as defined in the
-.In libefi.h
-header file.
-.Sh RETURN VALUES
-Upon successful completion, these functions return 0.
-Otherwise, the error number is returned.
-These functions will fail if:
-.Bl -tag -width Er
-.It Bq Er EACCES
-Insufficient permissions to access the EFI services.
-.It Bq Er EILSEQ
-The variable name is not in UTF-8.
-.It Bq Er EINVAL
-The request has invalid parameters.
-.It Bq Er ENOENT
-The variable does not exist or no more variables exist.
-.It Bq Er ENOMEM
-Temporary storage could not be allocated.
-.It Bq Er EOVERFLOW
-The variable name is too long or the data is too big to fit in
-the buffer provided.
-.El
-.Sh SEE ALSO
-.Xr errno 2 ,
-.Xr uuid 3
-.Sh HISTORY
-The
-.Nm libefi
-library first appeared in
-.Fx 9.0
-for the ia64 architecture.
-.Sh AUTHORS
-The
-.Nm libefi
-library and this manual page were written by
-.An Marcel Moolenaar Aq Mt marcel@FreeBSD.org .
diff --git a/lib/libefi/libefi.c b/lib/libefi/libefi.c
deleted file mode 100644
index c65784f..0000000
--- a/lib/libefi/libefi.c
+++ /dev/null
@@ -1,176 +0,0 @@
-/*-
- * Copyright (c) 2010 Marcel Moolenaar
- * 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.
- * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "libefi_int.h"
-
-static int __iofd = -1;
-
-static void
-iodev_fd_close(void)
-{
-
- close(__iofd);
-}
-
-static int
-iodev_fd(int *fd)
-{
-
- *fd = __iofd;
- if (__iofd != -1)
- return (0);
-
- __iofd = open("/dev/io", O_RDWR);
- if (__iofd == -1)
- return (errno);
-
- atexit(iodev_fd_close);
- *fd = __iofd;
- return (0);
-}
-
-int
-libefi_ucs2_to_utf8(u_short *nm, size_t *szp, char *name)
-{
- size_t len, sz;
- u_short c;
-
- len = 0;
- sz = *szp;
- while (*nm) {
- c = *nm++;
- if (c > 0x7ff) {
- if (len++ < sz)
- *name++ = 0xE0 | (c >> 12);
- if (len++ < sz)
- *name++ = 0x80 | ((c >> 6) & 0x3f);
- if (len++ < sz)
- *name++ = 0x80 | (c & 0x3f);
- } else if (c > 0x7f) {
- if (len++ < sz)
- *name++ = 0xC0 | ((c >> 6) & 0x1f);
- if (len++ < sz)
- *name++ = 0x80 | (c & 0x3f);
- } else {
- if (len++ < sz)
- *name++ = (c & 0x7f);
- }
- }
- if (len++ < sz)
- *name++ = 0;
-
- *szp = len;
- return ((len <= sz) ? 0 : EOVERFLOW);
-}
-
-int
-libefi_utf8_to_ucs2(char *name, size_t *szp, u_short **nmp)
-{
- u_short *nm;
- size_t sz;
- uint32_t ucs4;
- int c, bytes;
-
- *szp = sz = (*szp == 0) ? strlen(name) * 2 + 2 : *szp;
- *nmp = nm = malloc(sz);
-
- ucs4 = 0;
- bytes = 0;
- while (sz > 1 && *name != '\0') {
- c = *name++;
- /*
- * Conditionalize on the two major character types:
- * initial and followup characters.
- */
- if ((c & 0xc0) != 0x80) {
- /* Initial characters. */
- if (bytes != 0) {
- free(nm);
- return (EILSEQ);
- }
- if ((c & 0xf8) == 0xf0) {
- ucs4 = c & 0x07;
- bytes = 3;
- } else if ((c & 0xf0) == 0xe0) {
- ucs4 = c & 0x0f;
- bytes = 2;
- } else if ((c & 0xe0) == 0xc0) {
- ucs4 = c & 0x1f;
- bytes = 1;
- } else {
- ucs4 = c & 0x7f;
- bytes = 0;
- }
- } else {
- /* Followup characters. */
- if (bytes > 0) {
- ucs4 = (ucs4 << 6) + (c & 0x3f);
- bytes--;
- } else if (bytes == 0) {
- free(nm);
- return (EILSEQ);
- }
- }
- if (bytes == 0) {
- if (ucs4 > 0xffff) {
- free(nm);
- return (EILSEQ);
- }
- *nm++ = (u_short)ucs4;
- sz -= 2;
- }
- }
- if (sz < 2) {
- free(nm);
- return (EDOOFUS);
- }
- *nm = 0;
- return (0);
-}
-
-int
-libefi_efivar(struct iodev_efivar_req *req)
-{
- int error, fd;
-
- error = iodev_fd(&fd);
- if (!error)
- error = (ioctl(fd, IODEV_EFIVAR, req) == -1) ? errno : 0;
- if (!error)
- error = req->result;
- return (error);
-}
diff --git a/lib/libefi/libefi.h b/lib/libefi/libefi.h
deleted file mode 100644
index 56d18ac..0000000
--- a/lib/libefi/libefi.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*-
- * Copyright (c) 2010 Marcel Moolenaar
- * 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.
- * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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 _LIBEFI_H_
-#define _LIBEFI_H_
-
-#include <sys/types.h>
-#include <sys/uuid.h>
-#include <stddef.h>
-
-/* Attributes. */
-#define EFI_ATTR_NV 0x0001 /* Variable stored in NVRAM. */
-#define EFI_ATTR_BS 0x0002 /* Boot services accessable. */
-#define EFI_ATTR_RT 0x0004 /* Runtime accessable. */
-#define EFI_ATTR_HR 0x0008 /* Hardware error record. */
-#define EFI_ATTR_WR 0x0010 /* Authenticated write access. */
-
-/* Vendor for architecturally defined variables. */
-#define EFI_GLOBAL_VARIABLE \
- {0x8be4df61,0x93ca,0x11d2,0xaa,0x0d,{0x00,0xe0,0x98,0x03,0x2b,0x8c}}
-
-/* Vendor for FreeBSD-specific variables. */
-#define EFI_FREEBSD_VARIABLE \
- {0x13c32014,0x0c9c,0x11df,0xa2,0x38,{0x00,0x17,0xa4,0xab,0x91,0x2d}}
-
-__BEGIN_DECLS
-int efi_getvar (char *, uuid_t *, uint32_t *, size_t *, void *);
-int efi_nextvarname (size_t *, char *, uuid_t *);
-int efi_setvar (char *, uuid_t *, uint32_t, size_t, void *);
-__END_DECLS
-
-#endif /* _LIBEFI_H_ */
diff --git a/lib/libefi/libefi_int.h b/lib/libefi/libefi_int.h
deleted file mode 100644
index 28ee822..0000000
--- a/lib/libefi/libefi_int.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*-
- * Copyright (c) 2010 Marcel Moolenaar
- * 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.
- * 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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 _LIBEFI_INT_H_
-#define _LIBEFI_INT_H_
-
-#include <sys/errno.h>
-#include <machine/iodev.h>
-
-int libefi_ucs2_to_utf8(u_short *, size_t *, char *);
-int libefi_utf8_to_ucs2(char *, size_t *, u_short **);
-
-int libefi_efivar(struct iodev_efivar_req *);
-
-#endif /* _LIBEFI_INT_H_ */
diff --git a/lib/libefivar/FreeBSD-update b/lib/libefivar/FreeBSD-update
new file mode 100644
index 0000000..8b45dce
--- /dev/null
+++ b/lib/libefivar/FreeBSD-update
@@ -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.
diff --git a/lib/libefivar/Makefile b/lib/libefivar/Makefile
new file mode 100644
index 0000000..d7f7898
--- /dev/null
+++ b/lib/libefivar/Makefile
@@ -0,0 +1,67 @@
+# Copyright 1998 Juniper Networks, 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.
+# 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$
+
+.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 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 \
+ efivar.3 efi_get_variable.3 \
+ efivar.3 efi_get_variable_attributes.3 \
+ efivar.3 efi_get_variable_size.3 \
+ efivar.3 efi_append_variable.3 \
+ efivar.3 efi_set_variable.3 \
+ efivar.3 efi_get_next_variable_name.3 \
+ efivar.3 efi_str_to_guid.3 \
+ efivar.3 efi_guid_to_str.3 \
+ efivar.3 efi_name_to_guid.3 \
+ efivar.3 efi_guid_to_name.3 \
+ efivar.3 efi_guid_to_symbol.3 \
+ efivar.3 libefivar.3
+
+WARNS?= 9
+
+.include <bsd.lib.mk>
+
+CFLAGS+= -Wno-cast-align -Wno-unused-parameter
diff --git a/lib/libefivar/ProcessorBind.h b/lib/libefivar/ProcessorBind.h
new file mode 100644
index 0000000..ecba687
--- /dev/null
+++ b/lib/libefivar/ProcessorBind.h
@@ -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"
diff --git a/lib/libefivar/efi-osdep.h b/lib/libefivar/efi-osdep.h
new file mode 100644
index 0000000..834e299
--- /dev/null
+++ b/lib/libefivar/efi-osdep.h
@@ -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_ */
diff --git a/lib/libefivar/efivar-dp-format.c b/lib/libefivar/efivar-dp-format.c
new file mode 100644
index 0000000..4914763
--- /dev/null
+++ b/lib/libefivar/efivar-dp-format.c
@@ -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
+ 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
+DevPathToTextNVMe (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ NVME_NAMESPACE_DEVICE_PATH *Nvme;
+ UINT8 *Uuid;
+
+ Nvme = DevPath;
+ Uuid = (UINT8 *) &Nvme->NamespaceUuid;
+ UefiDevicePathLibCatPrint (
+ Str,
+ "NVMe(0x%x,%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x)",
+ Nvme->NamespaceId,
+ Uuid[7], Uuid[6], Uuid[5], Uuid[4],
+ Uuid[3], Uuid[2], Uuid[1], Uuid[0]
+ );
+}
+
+/**
+ Converts a UFS 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
+DevPathToTextUfs (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ UFS_DEVICE_PATH *Ufs;
+
+ Ufs = DevPath;
+ UefiDevicePathLibCatPrint (Str, "UFS(0x%x,0x%x)", Ufs->Pun, Ufs->Lun);
+}
+
+/**
+ Converts a SD (Secure Digital) 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
+DevPathToTextSd (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ SD_DEVICE_PATH *Sd;
+
+ Sd = DevPath;
+ UefiDevicePathLibCatPrint (
+ Str,
+ "SD(0x%x)",
+ Sd->SlotNumber
+ );
+}
+
+/**
+ Converts a EMMC (Embedded MMC) 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
+DevPathToTextEmmc (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ EMMC_DEVICE_PATH *Emmc;
+
+ Emmc = DevPath;
+ UefiDevicePathLibCatPrint (
+ Str,
+ "eMMC(0x%x)",
+ Emmc->SlotNumber
+ );
+}
+
+/**
+ Converts a 1394 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
+DevPathToText1394 (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ F1394_DEVICE_PATH *F1394DevPath;
+
+ F1394DevPath = DevPath;
+ //
+ // Guid has format of IEEE-EUI64
+ //
+ UefiDevicePathLibCatPrint (Str, "I1394(%016lx)", F1394DevPath->Guid);
+}
+
+/**
+ Converts a USB 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
+DevPathToTextUsb (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ USB_DEVICE_PATH *Usb;
+
+ Usb = DevPath;
+ UefiDevicePathLibCatPrint (Str, "USB(0x%x,0x%x)", Usb->ParentPortNumber, Usb->InterfaceNumber);
+}
+
+/**
+ Converts a USB WWID 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
+DevPathToTextUsbWWID (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ USB_WWID_DEVICE_PATH *UsbWWId;
+ CHAR16 *SerialNumberStr;
+ CHAR16 *NewStr;
+ UINT16 Length;
+
+ UsbWWId = DevPath;
+
+ SerialNumberStr = (CHAR16 *) (&UsbWWId + 1);
+ Length = (UINT16) ((DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) UsbWWId) - sizeof (USB_WWID_DEVICE_PATH)) / sizeof (CHAR16));
+ if (SerialNumberStr [Length - 1] != 0) {
+ //
+ // In case no NULL terminator in SerialNumber, create a new one with NULL terminator
+ //
+ NewStr = AllocateCopyPool ((Length + 1) * sizeof (CHAR16), SerialNumberStr);
+ ASSERT (NewStr != NULL);
+ NewStr [Length] = 0;
+ SerialNumberStr = NewStr;
+ }
+
+ UefiDevicePathLibCatPrint (
+ Str,
+ "UsbWwid(0x%x,0x%x,0x%x,\"%S\")",
+ UsbWWId->VendorId,
+ UsbWWId->ProductId,
+ UsbWWId->InterfaceNumber,
+ SerialNumberStr
+ );
+}
+
+/**
+ Converts a Logic Unit 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
+DevPathToTextLogicalUnit (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ DEVICE_LOGICAL_UNIT_DEVICE_PATH *LogicalUnit;
+
+ LogicalUnit = DevPath;
+ UefiDevicePathLibCatPrint (Str, "Unit(0x%x)", LogicalUnit->Lun);
+}
+
+/**
+ Converts a USB class 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
+DevPathToTextUsbClass (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ USB_CLASS_DEVICE_PATH *UsbClass;
+ BOOLEAN IsKnownSubClass;
+
+
+ UsbClass = DevPath;
+
+ IsKnownSubClass = TRUE;
+ switch (UsbClass->DeviceClass) {
+ case USB_CLASS_AUDIO:
+ UefiDevicePathLibCatPrint (Str, "UsbAudio");
+ break;
+
+ case USB_CLASS_CDCCONTROL:
+ UefiDevicePathLibCatPrint (Str, "UsbCDCControl");
+ break;
+
+ case USB_CLASS_HID:
+ UefiDevicePathLibCatPrint (Str, "UsbHID");
+ break;
+
+ case USB_CLASS_IMAGE:
+ UefiDevicePathLibCatPrint (Str, "UsbImage");
+ break;
+
+ case USB_CLASS_PRINTER:
+ UefiDevicePathLibCatPrint (Str, "UsbPrinter");
+ break;
+
+ case USB_CLASS_MASS_STORAGE:
+ UefiDevicePathLibCatPrint (Str, "UsbMassStorage");
+ break;
+
+ case USB_CLASS_HUB:
+ UefiDevicePathLibCatPrint (Str, "UsbHub");
+ break;
+
+ case USB_CLASS_CDCDATA:
+ UefiDevicePathLibCatPrint (Str, "UsbCDCData");
+ break;
+
+ case USB_CLASS_SMART_CARD:
+ UefiDevicePathLibCatPrint (Str, "UsbSmartCard");
+ break;
+
+ case USB_CLASS_VIDEO:
+ UefiDevicePathLibCatPrint (Str, "UsbVideo");
+ break;
+
+ case USB_CLASS_DIAGNOSTIC:
+ UefiDevicePathLibCatPrint (Str, "UsbDiagnostic");
+ break;
+
+ case USB_CLASS_WIRELESS:
+ UefiDevicePathLibCatPrint (Str, "UsbWireless");
+ break;
+
+ default:
+ IsKnownSubClass = FALSE;
+ break;
+ }
+
+ if (IsKnownSubClass) {
+ UefiDevicePathLibCatPrint (
+ Str,
+ "(0x%x,0x%x,0x%x,0x%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceSubClass,
+ UsbClass->DeviceProtocol
+ );
+ return;
+ }
+
+ if (UsbClass->DeviceClass == USB_CLASS_RESERVE) {
+ if (UsbClass->DeviceSubClass == USB_SUBCLASS_FW_UPDATE) {
+ UefiDevicePathLibCatPrint (
+ Str,
+ "UsbDeviceFirmwareUpdate(0x%x,0x%x,0x%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceProtocol
+ );
+ return;
+ } else if (UsbClass->DeviceSubClass == USB_SUBCLASS_IRDA_BRIDGE) {
+ UefiDevicePathLibCatPrint (
+ Str,
+ "UsbIrdaBridge(0x%x,0x%x,0x%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceProtocol
+ );
+ return;
+ } else if (UsbClass->DeviceSubClass == USB_SUBCLASS_TEST) {
+ UefiDevicePathLibCatPrint (
+ Str,
+ "UsbTestAndMeasurement(0x%x,0x%x,0x%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceProtocol
+ );
+ return;
+ }
+ }
+
+ UefiDevicePathLibCatPrint (
+ Str,
+ "UsbClass(0x%x,0x%x,0x%x,0x%x,0x%x)",
+ UsbClass->VendorId,
+ UsbClass->ProductId,
+ UsbClass->DeviceClass,
+ UsbClass->DeviceSubClass,
+ UsbClass->DeviceProtocol
+ );
+}
+
+/**
+ Converts a SATA 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
+DevPathToTextSata (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ SATA_DEVICE_PATH *Sata;
+
+ Sata = DevPath;
+ UefiDevicePathLibCatPrint (
+ Str,
+ "Sata(0x%x,0x%x,0x%x)",
+ Sata->HBAPortNumber,
+ Sata->PortMultiplierPortNumber,
+ Sata->Lun
+ );
+}
+
+/**
+ Converts a I20 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
+DevPathToTextI2O (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ I2O_DEVICE_PATH *I2ODevPath;
+
+ I2ODevPath = DevPath;
+ UefiDevicePathLibCatPrint (Str, "I2O(0x%x)", I2ODevPath->Tid);
+}
+
+/**
+ Converts a MAC 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
+DevPathToTextMacAddr (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ MAC_ADDR_DEVICE_PATH *MacDevPath;
+ UINTN HwAddressSize;
+ UINTN Index;
+
+ MacDevPath = DevPath;
+
+ HwAddressSize = sizeof (EFI_MAC_ADDRESS);
+ if (MacDevPath->IfType == 0x01 || MacDevPath->IfType == 0x00) {
+ HwAddressSize = 6;
+ }
+
+ UefiDevicePathLibCatPrint (Str, "MAC(");
+
+ for (Index = 0; Index < HwAddressSize; Index++) {
+ UefiDevicePathLibCatPrint (Str, "%02x", MacDevPath->MacAddress.Addr[Index]);
+ }
+
+ UefiDevicePathLibCatPrint (Str, ",0x%x)", MacDevPath->IfType);
+}
+
+/**
+ Converts network protocol string to its text representation.
+
+ @param Str The string representative of input device.
+ @param Protocol The network protocol ID.
+
+**/
+static VOID
+CatNetworkProtocol (
+ IN OUT POOL_PRINT *Str,
+ IN UINT16 Protocol
+ )
+{
+ if (Protocol == RFC_1700_TCP_PROTOCOL) {
+ UefiDevicePathLibCatPrint (Str, "TCP");
+ } else if (Protocol == RFC_1700_UDP_PROTOCOL) {
+ UefiDevicePathLibCatPrint (Str, "UDP");
+ } else {
+ UefiDevicePathLibCatPrint (Str, "0x%x", Protocol);
+ }
+}
+
+/**
+ Converts IP v4 address to its text representation.
+
+ @param Str The string representative of input device.
+ @param Address The IP v4 address.
+**/
+static VOID
+CatIPv4Address (
+ IN OUT POOL_PRINT *Str,
+ IN EFI_IPv4_ADDRESS *Address
+ )
+{
+ UefiDevicePathLibCatPrint (Str, "%d.%d.%d.%d", Address->Addr[0], Address->Addr[1], Address->Addr[2], Address->Addr[3]);
+}
+
+/**
+ Converts IP v6 address to its text representation.
+
+ @param Str The string representative of input device.
+ @param Address The IP v6 address.
+**/
+static VOID
+CatIPv6Address (
+ IN OUT POOL_PRINT *Str,
+ IN EFI_IPv6_ADDRESS *Address
+ )
+{
+ UefiDevicePathLibCatPrint (
+ Str, "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
+ Address->Addr[0], Address->Addr[1],
+ Address->Addr[2], Address->Addr[3],
+ Address->Addr[4], Address->Addr[5],
+ Address->Addr[6], Address->Addr[7],
+ Address->Addr[8], Address->Addr[9],
+ Address->Addr[10], Address->Addr[11],
+ Address->Addr[12], Address->Addr[13],
+ Address->Addr[14], Address->Addr[15]
+ );
+}
+
+/**
+ Converts a IPv4 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
+DevPathToTextIPv4 (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ IPv4_DEVICE_PATH *IPDevPath;
+
+ IPDevPath = DevPath;
+ UefiDevicePathLibCatPrint (Str, "IPv4(");
+ CatIPv4Address (Str, &IPDevPath->RemoteIpAddress);
+
+ if (DisplayOnly) {
+ UefiDevicePathLibCatPrint (Str, ")");
+ return ;
+ }
+
+ UefiDevicePathLibCatPrint (Str, ",");
+ CatNetworkProtocol (Str, IPDevPath->Protocol);
+
+ UefiDevicePathLibCatPrint (Str, ",%s,", IPDevPath->StaticIpAddress ? "Static" : "DHCP");
+ CatIPv4Address (Str, &IPDevPath->LocalIpAddress);
+ if (DevicePathNodeLength (IPDevPath) == sizeof (IPv4_DEVICE_PATH)) {
+ UefiDevicePathLibCatPrint (Str, ",");
+ CatIPv4Address (Str, &IPDevPath->GatewayIpAddress);
+ UefiDevicePathLibCatPrint (Str, ",");
+ CatIPv4Address (Str, &IPDevPath->SubnetMask);
+ }
+ UefiDevicePathLibCatPrint (Str, ")");
+}
+
+/**
+ Converts a IPv6 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
+DevPathToTextIPv6 (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ IPv6_DEVICE_PATH *IPDevPath;
+
+ IPDevPath = DevPath;
+ UefiDevicePathLibCatPrint (Str, "IPv6(");
+ CatIPv6Address (Str, &IPDevPath->RemoteIpAddress);
+ if (DisplayOnly) {
+ UefiDevicePathLibCatPrint (Str, ")");
+ return ;
+ }
+
+ UefiDevicePathLibCatPrint (Str, ",");
+ CatNetworkProtocol (Str, IPDevPath->Protocol);
+
+ switch (IPDevPath->IpAddressOrigin) {
+ case 0:
+ UefiDevicePathLibCatPrint (Str, ",Static,");
+ break;
+ case 1:
+ UefiDevicePathLibCatPrint (Str, ",StatelessAutoConfigure,");
+ break;
+ default:
+ UefiDevicePathLibCatPrint (Str, ",StatefulAutoConfigure,");
+ break;
+ }
+
+ CatIPv6Address (Str, &IPDevPath->LocalIpAddress);
+
+ if (DevicePathNodeLength (IPDevPath) == sizeof (IPv6_DEVICE_PATH)) {
+ UefiDevicePathLibCatPrint (Str, ",0x%x,", IPDevPath->PrefixLength);
+ CatIPv6Address (Str, &IPDevPath->GatewayIpAddress);
+ }
+ UefiDevicePathLibCatPrint (Str, ")");
+}
+
+/**
+ Converts an Infini Band 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
+DevPathToTextInfiniBand (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ INFINIBAND_DEVICE_PATH *InfiniBand;
+
+ InfiniBand = DevPath;
+ UefiDevicePathLibCatPrint (
+ Str,
+ "Infiniband(0x%x,%36s,0x%lx,0x%lx,0x%lx)",
+ InfiniBand->ResourceFlags,
+ G(InfiniBand->PortGid),
+ InfiniBand->ServiceId,
+ InfiniBand->TargetPortId,
+ InfiniBand->DeviceId
+ );
+}
+
+/**
+ Converts a UART 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
+DevPathToTextUart (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ 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) {
+ UefiDevicePathLibCatPrint (Str, "Uart(DEFAULT,");
+ } else {
+ UefiDevicePathLibCatPrint (Str, "Uart(%ld,", Uart->BaudRate);
+ }
+
+ if (Uart->DataBits == 0) {
+ UefiDevicePathLibCatPrint (Str, "DEFAULT,");
+ } else {
+ UefiDevicePathLibCatPrint (Str, "%d,", Uart->DataBits);
+ }
+
+ UefiDevicePathLibCatPrint (Str, "%c,", Parity);
+
+ switch (Uart->StopBits) {
+ case 0:
+ UefiDevicePathLibCatPrint (Str, "D)");
+ break;
+
+ case 1:
+ UefiDevicePathLibCatPrint (Str, "1)");
+ break;
+
+ case 2:
+ UefiDevicePathLibCatPrint (Str, "1.5)");
+ break;
+
+ case 3:
+ UefiDevicePathLibCatPrint (Str, "2)");
+ break;
+
+ default:
+ UefiDevicePathLibCatPrint (Str, "x)");
+ break;
+ }
+}
+
+/**
+ Converts an iSCSI 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
+DevPathToTextiSCSI (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ ISCSI_DEVICE_PATH_WITH_NAME *ISCSIDevPath;
+ UINT16 Options;
+
+ ISCSIDevPath = DevPath;
+ UefiDevicePathLibCatPrint (
+ Str,
+ "iSCSI(%s,0x%x,0x%lx,",
+ ISCSIDevPath->TargetName,
+ ISCSIDevPath->TargetPortalGroupTag,
+ ISCSIDevPath->Lun
+ );
+
+ Options = ISCSIDevPath->LoginOption;
+ UefiDevicePathLibCatPrint (Str, "%s,", (((Options >> 1) & 0x0001) != 0) ? "CRC32C" : "None");
+ UefiDevicePathLibCatPrint (Str, "%s,", (((Options >> 3) & 0x0001) != 0) ? "CRC32C" : "None");
+ if (((Options >> 11) & 0x0001) != 0) {
+ UefiDevicePathLibCatPrint (Str, "%s,", "None");
+ } else if (((Options >> 12) & 0x0001) != 0) {
+ UefiDevicePathLibCatPrint (Str, "%s,", "CHAP_UNI");
+ } else {
+ UefiDevicePathLibCatPrint (Str, "%s,", "CHAP_BI");
+
+ }
+
+ UefiDevicePathLibCatPrint (Str, "%s)", (ISCSIDevPath->NetworkProtocol == 0) ? "TCP" : "reserved");
+}
+
+/**
+ Converts a VLAN 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
+DevPathToTextVlan (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ VLAN_DEVICE_PATH *Vlan;
+
+ Vlan = DevPath;
+ UefiDevicePathLibCatPrint (Str, "Vlan(%d)", Vlan->VlanId);
+}
+
+/**
+ Converts a Bluetooth 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
+DevPathToTextBluetooth (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ BLUETOOTH_DEVICE_PATH *Bluetooth;
+
+ Bluetooth = DevPath;
+ UefiDevicePathLibCatPrint (
+ Str,
+ "Bluetooth(%02x%02x%02x%02x%02x%02x)",
+ Bluetooth->BD_ADDR.Address[5],
+ Bluetooth->BD_ADDR.Address[4],
+ Bluetooth->BD_ADDR.Address[3],
+ Bluetooth->BD_ADDR.Address[2],
+ Bluetooth->BD_ADDR.Address[1],
+ Bluetooth->BD_ADDR.Address[0]
+ );
+}
+
+/**
+ Converts a Wi-Fi 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
+DevPathToTextWiFi (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ WIFI_DEVICE_PATH *WiFi;
+ UINT8 SSId[33];
+
+ WiFi = DevPath;
+
+ SSId[32] = '\0';
+ CopyMem (SSId, WiFi->SSId, 32);
+
+ UefiDevicePathLibCatPrint (Str, "Wi-Fi(%s)", SSId);
+}
+
+/**
+ Converts a URI 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
+DevPathToTextUri (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ URI_DEVICE_PATH *Uri;
+ UINTN UriLength;
+ CHAR8 *UriStr;
+
+ //
+ // Uri in the device path may not be null terminated.
+ //
+ Uri = DevPath;
+ UriLength = DevicePathNodeLength (Uri) - sizeof (URI_DEVICE_PATH);
+ UriStr = AllocatePool (UriLength + 1);
+ ASSERT (UriStr != NULL);
+
+ CopyMem (UriStr, Uri->Uri, UriLength);
+ UriStr[UriLength] = '\0';
+ UefiDevicePathLibCatPrint (Str, "Uri(%s)", UriStr);
+ FreePool (UriStr);
+}
+
+/**
+ Converts a Hard drive 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
+DevPathToTextHardDrive (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ HARDDRIVE_DEVICE_PATH *Hd;
+
+ Hd = DevPath;
+ switch (Hd->SignatureType) {
+ case SIGNATURE_TYPE_MBR:
+ UefiDevicePathLibCatPrint (
+ Str,
+ "HD(%d,%s,0x%08x,",
+ Hd->PartitionNumber,
+ "MBR",
+// *((UINT32 *) (&(Hd->Signature[0])))
+ le32dec(&(Hd->Signature[0]))
+ );
+ break;
+
+ case SIGNATURE_TYPE_GUID:
+ UefiDevicePathLibCatPrint (
+ Str,
+ "HD(%d,%s,%36s,",
+ Hd->PartitionNumber,
+ "GPT",
+ G(&(Hd->Signature[0]))
+ );
+ break;
+
+ default:
+ UefiDevicePathLibCatPrint (
+ Str,
+ "HD(%d,%d,0,",
+ Hd->PartitionNumber,
+ Hd->SignatureType
+ );
+ break;
+ }
+
+ UefiDevicePathLibCatPrint (Str, "0x%lx,0x%lx)", Hd->PartitionStart, Hd->PartitionSize);
+}
+
+/**
+ Converts a CDROM 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
+DevPathToTextCDROM (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ CDROM_DEVICE_PATH *Cd;
+
+ Cd = DevPath;
+ if (DisplayOnly) {
+ UefiDevicePathLibCatPrint (Str, "CDROM(0x%x)", Cd->BootEntry);
+ return ;
+ }
+
+ UefiDevicePathLibCatPrint (Str, "CDROM(0x%x,0x%lx,0x%lx)", Cd->BootEntry, Cd->PartitionStart, Cd->PartitionSize);
+}
+
+/**
+ Converts a File 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
+DevPathToTextFilePath (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ FILEPATH_DEVICE_PATH *Fp;
+
+ Fp = DevPath;
+ UefiDevicePathLibCatPrint (Str, "%s", Fp->PathName);
+}
+
+/**
+ Converts a Media protocol 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
+DevPathToTextMediaProtocol (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ MEDIA_PROTOCOL_DEVICE_PATH *MediaProt;
+
+ MediaProt = DevPath;
+ UefiDevicePathLibCatPrint (Str, "Media(%36s)", G(&MediaProt->Protocol));
+}
+
+/**
+ Converts a Firmware Volume 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
+DevPathToTextFv (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ MEDIA_FW_VOL_DEVICE_PATH *Fv;
+
+ Fv = DevPath;
+ UefiDevicePathLibCatPrint (Str, "Fv(%36s)", G(&Fv->FvName));
+}
+
+/**
+ Converts a Firmware Volume File 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
+DevPathToTextFvFile (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFile;
+
+ FvFile = DevPath;
+ UefiDevicePathLibCatPrint (Str, "FvFile(%36s)", G(&FvFile->FvFileName));
+}
+
+/**
+ Converts a Relative Offset 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
+DevPathRelativeOffsetRange (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *Offset;
+
+ Offset = DevPath;
+ UefiDevicePathLibCatPrint (
+ Str,
+ "Offset(0x%lx,0x%lx)",
+ Offset->StartingOffset,
+ Offset->EndingOffset
+ );
+}
+
+/**
+ Converts a Ram Disk 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
+DevPathToTextRamDisk (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ MEDIA_RAM_DISK_DEVICE_PATH *RamDisk;
+
+ RamDisk = DevPath;
+
+ if (CompareGuid (&RamDisk->TypeGuid, &gEfiVirtualDiskGuid)) {
+ UefiDevicePathLibCatPrint (
+ Str,
+ "VirtualDisk(0x%lx,0x%lx,%d)",
+ LShiftU64 ((UINT64)RamDisk->StartingAddr[1], 32) | RamDisk->StartingAddr[0],
+ LShiftU64 ((UINT64)RamDisk->EndingAddr[1], 32) | RamDisk->EndingAddr[0],
+ RamDisk->Instance
+ );
+ } else if (CompareGuid (&RamDisk->TypeGuid, &gEfiVirtualCdGuid)) {
+ UefiDevicePathLibCatPrint (
+ Str,
+ "VirtualCD(0x%lx,0x%lx,%d)",
+ LShiftU64 ((UINT64)RamDisk->StartingAddr[1], 32) | RamDisk->StartingAddr[0],
+ LShiftU64 ((UINT64)RamDisk->EndingAddr[1], 32) | RamDisk->EndingAddr[0],
+ RamDisk->Instance
+ );
+ } else if (CompareGuid (&RamDisk->TypeGuid, &gEfiPersistentVirtualDiskGuid)) {
+ UefiDevicePathLibCatPrint (
+ Str,
+ "PersistentVirtualDisk(0x%lx,0x%lx,%d)",
+ LShiftU64 ((UINT64)RamDisk->StartingAddr[1], 32) | RamDisk->StartingAddr[0],
+ LShiftU64 ((UINT64)RamDisk->EndingAddr[1], 32) | RamDisk->EndingAddr[0],
+ RamDisk->Instance
+ );
+ } else if (CompareGuid (&RamDisk->TypeGuid, &gEfiPersistentVirtualCdGuid)) {
+ UefiDevicePathLibCatPrint (
+ Str,
+ "PersistentVirtualCD(0x%lx,0x%lx,%d)",
+ LShiftU64 ((UINT64)RamDisk->StartingAddr[1], 32) | RamDisk->StartingAddr[0],
+ LShiftU64 ((UINT64)RamDisk->EndingAddr[1], 32) | RamDisk->EndingAddr[0],
+ RamDisk->Instance
+ );
+ } else {
+ UefiDevicePathLibCatPrint (
+ Str,
+ "RamDisk(0x%lx,0x%lx,%d,%36s)",
+ LShiftU64 ((UINT64)RamDisk->StartingAddr[1], 32) | RamDisk->StartingAddr[0],
+ LShiftU64 ((UINT64)RamDisk->EndingAddr[1], 32) | RamDisk->EndingAddr[0],
+ RamDisk->Instance,
+ G(&RamDisk->TypeGuid)
+ );
+ }
+}
+
+/**
+ Converts a BIOS Boot Specification 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
+DevPathToTextBBS (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ BBS_BBS_DEVICE_PATH *Bbs;
+ const char *Type;
+
+ Bbs = DevPath;
+ switch (Bbs->DeviceType) {
+ case BBS_TYPE_FLOPPY:
+ Type = "Floppy";
+ break;
+
+ case BBS_TYPE_HARDDRIVE:
+ Type = "HD";
+ break;
+
+ case BBS_TYPE_CDROM:
+ Type = "CDROM";
+ break;
+
+ case BBS_TYPE_PCMCIA:
+ Type = "PCMCIA";
+ break;
+
+ case BBS_TYPE_USB:
+ Type = "USB";
+ break;
+
+ case BBS_TYPE_EMBEDDED_NETWORK:
+ Type = "Network";
+ break;
+
+ default:
+ Type = NULL;
+ break;
+ }
+
+ if (Type != NULL) {
+ UefiDevicePathLibCatPrint (Str, "BBS(%s,%s", Type, Bbs->String);
+ } else {
+ UefiDevicePathLibCatPrint (Str, "BBS(0x%x,%s", Bbs->DeviceType, Bbs->String);
+ }
+
+ if (DisplayOnly) {
+ UefiDevicePathLibCatPrint (Str, ")");
+ return ;
+ }
+
+ UefiDevicePathLibCatPrint (Str, ",0x%x)", Bbs->StatusFlag);
+}
+
+/**
+ Converts an End-of-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
+DevPathToTextEndInstance (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ UefiDevicePathLibCatPrint (Str, ",");
+}
+
+GLOBAL_REMOVE_IF_UNREFERENCED const DEVICE_PATH_TO_TEXT_GENERIC_TABLE mUefiDevicePathLibToTextTableGeneric[] = {
+ {HARDWARE_DEVICE_PATH, "HardwarePath" },
+ {ACPI_DEVICE_PATH, "AcpiPath" },
+ {MESSAGING_DEVICE_PATH, "Msg" },
+ {MEDIA_DEVICE_PATH, "MediaPath" },
+ {BBS_DEVICE_PATH, "BbsPath" },
+ {0, NULL}
+};
+
+/**
+ Converts an unknown 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
+DevPathToTextNodeGeneric (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL *Node;
+ UINTN Index;
+
+ Node = DevPath;
+
+ for (Index = 0; mUefiDevicePathLibToTextTableGeneric[Index].Text != NULL; Index++) {
+ if (DevicePathType (Node) == mUefiDevicePathLibToTextTableGeneric[Index].Type) {
+ break;
+ }
+ }
+
+ if (mUefiDevicePathLibToTextTableGeneric[Index].Text == NULL) {
+ //
+ // It's a node whose type cannot be recognized
+ //
+ UefiDevicePathLibCatPrint (Str, "Path(%d,%d", DevicePathType (Node), DevicePathSubType (Node));
+ } else {
+ //
+ // It's a node whose type can be recognized
+ //
+ UefiDevicePathLibCatPrint (Str, "%s(%d", mUefiDevicePathLibToTextTableGeneric[Index].Text, DevicePathSubType (Node));
+ }
+
+ Index = sizeof (EFI_DEVICE_PATH_PROTOCOL);
+ if (Index < DevicePathNodeLength (Node)) {
+ UefiDevicePathLibCatPrint (Str, ",");
+ for (; Index < DevicePathNodeLength (Node); Index++) {
+ UefiDevicePathLibCatPrint (Str, "%02x", ((UINT8 *) Node)[Index]);
+ }
+ }
+
+ UefiDevicePathLibCatPrint (Str, ")");
+}
+
+static const DEVICE_PATH_TO_TEXT_TABLE mUefiDevicePathLibToTextTable[] = {
+ {HARDWARE_DEVICE_PATH, HW_PCI_DP, DevPathToTextPci },
+ {HARDWARE_DEVICE_PATH, HW_PCCARD_DP, DevPathToTextPccard },
+ {HARDWARE_DEVICE_PATH, HW_MEMMAP_DP, DevPathToTextMemMap },
+ {HARDWARE_DEVICE_PATH, HW_VENDOR_DP, DevPathToTextVendor },
+ {HARDWARE_DEVICE_PATH, HW_CONTROLLER_DP, DevPathToTextController },
+ {HARDWARE_DEVICE_PATH, HW_BMC_DP, DevPathToTextBmc },
+ {ACPI_DEVICE_PATH, ACPI_DP, DevPathToTextAcpi },
+ {ACPI_DEVICE_PATH, ACPI_EXTENDED_DP, DevPathToTextAcpiEx },
+ {ACPI_DEVICE_PATH, ACPI_ADR_DP, DevPathToTextAcpiAdr },
+ {MESSAGING_DEVICE_PATH, MSG_ATAPI_DP, DevPathToTextAtapi },
+ {MESSAGING_DEVICE_PATH, MSG_SCSI_DP, DevPathToTextScsi },
+ {MESSAGING_DEVICE_PATH, MSG_FIBRECHANNEL_DP, DevPathToTextFibre },
+ {MESSAGING_DEVICE_PATH, MSG_FIBRECHANNELEX_DP, DevPathToTextFibreEx },
+ {MESSAGING_DEVICE_PATH, MSG_SASEX_DP, DevPathToTextSasEx },
+ {MESSAGING_DEVICE_PATH, MSG_NVME_NAMESPACE_DP, DevPathToTextNVMe },
+ {MESSAGING_DEVICE_PATH, MSG_UFS_DP, DevPathToTextUfs },
+ {MESSAGING_DEVICE_PATH, MSG_SD_DP, DevPathToTextSd },
+ {MESSAGING_DEVICE_PATH, MSG_EMMC_DP, DevPathToTextEmmc },
+ {MESSAGING_DEVICE_PATH, MSG_1394_DP, DevPathToText1394 },
+ {MESSAGING_DEVICE_PATH, MSG_USB_DP, DevPathToTextUsb },
+ {MESSAGING_DEVICE_PATH, MSG_USB_WWID_DP, DevPathToTextUsbWWID },
+ {MESSAGING_DEVICE_PATH, MSG_DEVICE_LOGICAL_UNIT_DP, DevPathToTextLogicalUnit },
+ {MESSAGING_DEVICE_PATH, MSG_USB_CLASS_DP, DevPathToTextUsbClass },
+ {MESSAGING_DEVICE_PATH, MSG_SATA_DP, DevPathToTextSata },
+ {MESSAGING_DEVICE_PATH, MSG_I2O_DP, DevPathToTextI2O },
+ {MESSAGING_DEVICE_PATH, MSG_MAC_ADDR_DP, DevPathToTextMacAddr },
+ {MESSAGING_DEVICE_PATH, MSG_IPv4_DP, DevPathToTextIPv4 },
+ {MESSAGING_DEVICE_PATH, MSG_IPv6_DP, DevPathToTextIPv6 },
+ {MESSAGING_DEVICE_PATH, MSG_INFINIBAND_DP, DevPathToTextInfiniBand },
+ {MESSAGING_DEVICE_PATH, MSG_UART_DP, DevPathToTextUart },
+ {MESSAGING_DEVICE_PATH, MSG_VENDOR_DP, DevPathToTextVendor },
+ {MESSAGING_DEVICE_PATH, MSG_ISCSI_DP, DevPathToTextiSCSI },
+ {MESSAGING_DEVICE_PATH, MSG_VLAN_DP, DevPathToTextVlan },
+ {MESSAGING_DEVICE_PATH, MSG_URI_DP, DevPathToTextUri },
+ {MESSAGING_DEVICE_PATH, MSG_BLUETOOTH_DP, DevPathToTextBluetooth },
+ {MESSAGING_DEVICE_PATH, MSG_WIFI_DP, DevPathToTextWiFi },
+ {MEDIA_DEVICE_PATH, MEDIA_HARDDRIVE_DP, DevPathToTextHardDrive },
+ {MEDIA_DEVICE_PATH, MEDIA_CDROM_DP, DevPathToTextCDROM },
+ {MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP, DevPathToTextVendor },
+ {MEDIA_DEVICE_PATH, MEDIA_PROTOCOL_DP, DevPathToTextMediaProtocol },
+ {MEDIA_DEVICE_PATH, MEDIA_FILEPATH_DP, DevPathToTextFilePath },
+ {MEDIA_DEVICE_PATH, MEDIA_PIWG_FW_VOL_DP, DevPathToTextFv },
+ {MEDIA_DEVICE_PATH, MEDIA_PIWG_FW_FILE_DP, DevPathToTextFvFile },
+ {MEDIA_DEVICE_PATH, MEDIA_RELATIVE_OFFSET_RANGE_DP, DevPathRelativeOffsetRange },
+ {MEDIA_DEVICE_PATH, MEDIA_RAM_DISK_DP, DevPathToTextRamDisk },
+ {BBS_DEVICE_PATH, BBS_BBS_DP, DevPathToTextBBS },
+ {END_DEVICE_PATH_TYPE, END_INSTANCE_DEVICE_PATH_SUBTYPE, DevPathToTextEndInstance },
+ {0, 0, NULL}
+};
+
+#ifndef __FreeBSD__
+/**
+ Converts a device node to its string representation.
+
+ @param DeviceNode A Pointer to the device node to be converted.
+ @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.
+
+ @return A pointer to the allocated text representation of the device node or NULL if DeviceNode
+ is NULL or there was insufficient memory.
+
+**/
+CHAR16 *
+EFIAPI
+UefiDevicePathLibConvertDeviceNodeToText (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ POOL_PRINT Str;
+ UINTN Index;
+ DEVICE_PATH_TO_TEXT ToText;
+
+ if (DeviceNode == NULL) {
+ return NULL;
+ }
+
+ ZeroMem (&Str, sizeof (Str));
+
+ //
+ // Process the device path node
+ // If not found, use a generic function
+ //
+ ToText = DevPathToTextNodeGeneric;
+ for (Index = 0; mUefiDevicePathLibToTextTable[Index].Function != NULL; Index++) {
+ if (DevicePathType (DeviceNode) == mUefiDevicePathLibToTextTable[Index].Type &&
+ DevicePathSubType (DeviceNode) == mUefiDevicePathLibToTextTable[Index].SubType
+ ) {
+ ToText = mUefiDevicePathLibToTextTable[Index].Function;
+ break;
+ }
+ }
+
+ //
+ // Print this node
+ //
+ ToText (&Str, (VOID *) DeviceNode, DisplayOnly, AllowShortcuts);
+
+ ASSERT (Str.Str != NULL);
+ return Str.Str;
+}
+#endif
+
+/**
+ Converts a device path to its text representation.
+
+ @param DevicePath A Pointer to the device to be converted.
+ @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.
+
+ @return A pointer to the allocated text representation of the device path or
+ NULL if DeviceNode is NULL or there was insufficient memory.
+
+**/
+static char *
+EFIAPI
+UefiDevicePathLibConvertDevicePathToText (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ POOL_PRINT Str;
+ EFI_DEVICE_PATH_PROTOCOL *Node;
+ EFI_DEVICE_PATH_PROTOCOL *AlignedNode;
+ UINTN Index;
+ DEVICE_PATH_TO_TEXT ToText;
+
+ if (DevicePath == NULL) {
+ return NULL;
+ }
+
+ ZeroMem (&Str, sizeof (Str));
+
+ //
+ // Process each device path node
+ //
+ Node = __DECONST(EFI_DEVICE_PATH_PROTOCOL *, DevicePath);
+ while (!IsDevicePathEnd (Node)) {
+ //
+ // Find the handler to dump this device path node
+ // If not found, use a generic function
+ //
+ ToText = DevPathToTextNodeGeneric;
+ for (Index = 0; mUefiDevicePathLibToTextTable[Index].Function != NULL; Index += 1) {
+
+ if (DevicePathType (Node) == mUefiDevicePathLibToTextTable[Index].Type &&
+ DevicePathSubType (Node) == mUefiDevicePathLibToTextTable[Index].SubType
+ ) {
+ ToText = mUefiDevicePathLibToTextTable[Index].Function;
+ break;
+ }
+ }
+ //
+ // Put a path separator in if needed
+ //
+ if ((Str.Count != 0) && (ToText != DevPathToTextEndInstance)) {
+ if (Str.Str[Str.Count] != ',') {
+ UefiDevicePathLibCatPrint (&Str, "/");
+ }
+ }
+
+ AlignedNode = AllocateCopyPool (DevicePathNodeLength (Node), Node);
+ //
+ // Print this node of the device path
+ //
+ ToText (&Str, AlignedNode, DisplayOnly, AllowShortcuts);
+ FreePool (AlignedNode);
+
+ //
+ // Next device path node
+ //
+ Node = NextDevicePathNode (Node);
+ }
+
+ if (Str.Str == NULL) {
+ return AllocateZeroPool (sizeof (CHAR16));
+ } else {
+ return Str.Str;
+ }
+}
+
+
+ssize_t
+efidp_format_device_path(char *buf, size_t len, const_efidp dp, ssize_t max)
+{
+ char *str;
+ ssize_t retval;
+
+ str = UefiDevicePathLibConvertDevicePathToText (
+ __DECONST(EFI_DEVICE_PATH_PROTOCOL *, dp), FALSE, TRUE);
+ if (str == NULL)
+ return -1;
+ strlcpy(buf, str, len);
+ retval = strlen(str);
+ free(str);
+
+ return retval;
+}
diff --git a/lib/libefivar/efivar-dp-parse.c b/lib/libefivar/efivar-dp-parse.c
new file mode 100644
index 0000000..c1ca9b7
--- /dev/null
+++ b/lib/libefivar/efivar-dp-parse.c
@@ -0,0 +1,3715 @@
+/*-
+ * 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 <ctype.h>
+#include <efivar.h>
+#include <stdio.h>
+#include <string.h>
+#include <wchar.h>
+
+#include "efi-osdep.h"
+#include "efivar-dp.h"
+
+#include "uefi-dplib.h"
+
+/* XXX STUBS -- this stuff doesn't work yet */
+#define StrToIpv4Address(str, unk, ipv4ptr, unk2)
+#define StrToIpv6Address(str, unk, ipv6ptr, unk2)
+
+/*
+ * OK. Now this is evil. Can't typedef it again. Sure beats changing them all.
+ * Since we're doing it all as narrow characters since wchar_t can't be used on
+ * FreeBSD and CHAR16 strings generally aren't a good fit. Since this parsing
+ * doesn't need Unicode for anything, this works out well.
+ */
+#define CHAR16 char
+
+/*
+ * Taken from MdePkg/Library/UefiDevicePathLib/DevicePathFromText.c
+ * hash a11928f3310518ab1c6fd34e8d0fdbb72de9602c 2017-Mar-01
+ */
+
+/** @file
+ DevicePathFromText protocol as defined in the UEFI 2.0 specification.
+
+Copyright (c) 2013 - 2017, 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"
+
+/**
+
+ Duplicates a string.
+
+ @param Src Source string.
+
+ @return The duplicated string.
+
+**/
+static
+CHAR16 *
+UefiDevicePathLibStrDuplicate (
+ IN CONST CHAR16 *Src
+ )
+{
+ return AllocateCopyPool (StrSize (Src), Src);
+}
+
+/**
+
+ Get parameter in a pair of parentheses follow the given node name.
+ For example, given the "Pci(0,1)" and NodeName "Pci", it returns "0,1".
+
+ @param Str Device Path Text.
+ @param NodeName Name of the node.
+
+ @return Parameter text for the node.
+
+**/
+static
+CHAR16 *
+GetParamByNodeName (
+ IN CHAR16 *Str,
+ IN const CHAR16 *NodeName
+ )
+{
+ CHAR16 *ParamStr;
+ CHAR16 *StrPointer;
+ UINTN NodeNameLength;
+ UINTN ParameterLength;
+
+ //
+ // Check whether the node name matchs
+ //
+ NodeNameLength = StrLen (NodeName);
+ if (StrnCmp (Str, NodeName, NodeNameLength) != 0) {
+ return NULL;
+ }
+
+ ParamStr = Str + NodeNameLength;
+ if (!IS_LEFT_PARENTH (*ParamStr)) {
+ return NULL;
+ }
+
+ //
+ // Skip the found '(' and find first occurrence of ')'
+ //
+ ParamStr++;
+ ParameterLength = 0;
+ StrPointer = ParamStr;
+ while (!IS_NULL (*StrPointer)) {
+ if (IS_RIGHT_PARENTH (*StrPointer)) {
+ break;
+ }
+ StrPointer++;
+ ParameterLength++;
+ }
+ if (IS_NULL (*StrPointer)) {
+ //
+ // ')' not found
+ //
+ return NULL;
+ }
+
+ ParamStr = AllocateCopyPool ((ParameterLength + 1) * sizeof (CHAR16), ParamStr);
+ if (ParamStr == NULL) {
+ return NULL;
+ }
+ //
+ // Terminate the parameter string
+ //
+ ParamStr[ParameterLength] = '\0';
+
+ return ParamStr;
+}
+
+/**
+ Gets current sub-string from a string list, before return
+ the list header is moved to next sub-string. The sub-string is separated
+ by the specified character. For example, the separator is ',', the string
+ list is "2,0,3", it returns "2", the remain list move to "0,3"
+
+ @param List A string list separated by the specified separator
+ @param Separator The separator character
+
+ @return A pointer to the current sub-string
+
+**/
+static
+CHAR16 *
+SplitStr (
+ IN OUT CHAR16 **List,
+ IN CHAR16 Separator
+ )
+{
+ CHAR16 *Str;
+ CHAR16 *ReturnStr;
+
+ Str = *List;
+ ReturnStr = Str;
+
+ if (IS_NULL (*Str)) {
+ return ReturnStr;
+ }
+
+ //
+ // Find first occurrence of the separator
+ //
+ while (!IS_NULL (*Str)) {
+ if (*Str == Separator) {
+ break;
+ }
+ Str++;
+ }
+
+ if (*Str == Separator) {
+ //
+ // Find a sub-string, terminate it
+ //
+ *Str = '\0';
+ Str++;
+ }
+
+ //
+ // Move to next sub-string
+ //
+ *List = Str;
+
+ return ReturnStr;
+}
+
+/**
+ Gets the next parameter string from the list.
+
+ @param List A string list separated by the specified separator
+
+ @return A pointer to the current sub-string
+
+**/
+static
+CHAR16 *
+GetNextParamStr (
+ IN OUT CHAR16 **List
+ )
+{
+ //
+ // The separator is comma
+ //
+ return SplitStr (List, ',');
+}
+
+/**
+ Get one device node from entire device path text.
+
+ @param DevicePath On input, the current Device Path node; on output, the next device path node
+ @param IsInstanceEnd This node is the end of a device path instance
+
+ @return A device node text or NULL if no more device node available
+
+**/
+static
+CHAR16 *
+GetNextDeviceNodeStr (
+ IN OUT CHAR16 **DevicePath,
+ OUT BOOLEAN *IsInstanceEnd
+ )
+{
+ CHAR16 *Str;
+ CHAR16 *ReturnStr;
+ UINTN ParenthesesStack;
+
+ Str = *DevicePath;
+ if (IS_NULL (*Str)) {
+ return NULL;
+ }
+
+ //
+ // Skip the leading '/', '(', ')' and ','
+ //
+ while (!IS_NULL (*Str)) {
+ if (!IS_SLASH (*Str) &&
+ !IS_COMMA (*Str) &&
+ !IS_LEFT_PARENTH (*Str) &&
+ !IS_RIGHT_PARENTH (*Str)) {
+ break;
+ }
+ Str++;
+ }
+
+ ReturnStr = Str;
+
+ //
+ // Scan for the separator of this device node, '/' or ','
+ //
+ ParenthesesStack = 0;
+ while (!IS_NULL (*Str)) {
+ if ((IS_COMMA (*Str) || IS_SLASH (*Str)) && (ParenthesesStack == 0)) {
+ break;
+ }
+
+ if (IS_LEFT_PARENTH (*Str)) {
+ ParenthesesStack++;
+ } else if (IS_RIGHT_PARENTH (*Str)) {
+ ParenthesesStack--;
+ }
+
+ Str++;
+ }
+
+ if (ParenthesesStack != 0) {
+ //
+ // The '(' doesn't pair with ')', invalid device path text
+ //
+ return NULL;
+ }
+
+ if (IS_COMMA (*Str)) {
+ *IsInstanceEnd = TRUE;
+ *Str = '\0';
+ Str++;
+ } else {
+ *IsInstanceEnd = FALSE;
+ if (!IS_NULL (*Str)) {
+ *Str = '\0';
+ Str++;
+ }
+ }
+
+ *DevicePath = Str;
+
+ return ReturnStr;
+}
+
+
+#ifndef __FreeBSD__
+/**
+ Return whether the integer string is a hex string.
+
+ @param Str The integer string
+
+ @retval TRUE Hex string
+ @retval FALSE Decimal string
+
+**/
+static
+BOOLEAN
+IsHexStr (
+ IN CHAR16 *Str
+ )
+{
+ //
+ // skip preceeding white space
+ //
+ while ((*Str != 0) && *Str == ' ') {
+ Str ++;
+ }
+ //
+ // skip preceeding zeros
+ //
+ while ((*Str != 0) && *Str == '0') {
+ Str ++;
+ }
+
+ return (BOOLEAN) (*Str == 'x' || *Str == 'X');
+}
+
+/**
+
+ Convert integer string to uint.
+
+ @param Str The integer string. If leading with "0x" or "0X", it's hexadecimal.
+
+ @return A UINTN value represented by Str
+
+**/
+static
+UINTN
+Strtoi (
+ IN CHAR16 *Str
+ )
+{
+ if (IsHexStr (Str)) {
+ return StrHexToUintn (Str);
+ } else {
+ return StrDecimalToUintn (Str);
+ }
+}
+
+/**
+
+ Convert integer string to 64 bit data.
+
+ @param Str The integer string. If leading with "0x" or "0X", it's hexadecimal.
+ @param Data A pointer to the UINT64 value represented by Str
+
+**/
+static
+VOID
+Strtoi64 (
+ IN CHAR16 *Str,
+ OUT UINT64 *Data
+ )
+{
+ if (IsHexStr (Str)) {
+ *Data = StrHexToUint64 (Str);
+ } else {
+ *Data = StrDecimalToUint64 (Str);
+ }
+}
+#endif
+
+/**
+ Converts a Unicode string to ASCII string.
+
+ @param Str The equivalent Unicode string
+ @param AsciiStr On input, it points to destination ASCII string buffer; on output, it points
+ to the next ASCII string next to it
+
+**/
+static
+VOID
+StrToAscii (
+ IN CHAR16 *Str,
+ IN OUT CHAR8 **AsciiStr
+ )
+{
+ CHAR8 *Dest;
+
+ Dest = *AsciiStr;
+ while (!IS_NULL (*Str)) {
+ *(Dest++) = (CHAR8) *(Str++);
+ }
+ *Dest = 0;
+
+ //
+ // Return the string next to it
+ //
+ *AsciiStr = Dest + 1;
+}
+
+/**
+ Converts a generic text device path node to device path structure.
+
+ @param Type The type of the device path node.
+ @param TextDeviceNode The input text device path node.
+
+ @return A pointer to device path structure.
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextGenericPath (
+ IN UINT8 Type,
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL *Node;
+ CHAR16 *SubtypeStr;
+ CHAR16 *DataStr;
+ UINTN DataLength;
+
+ SubtypeStr = GetNextParamStr (&TextDeviceNode);
+ DataStr = GetNextParamStr (&TextDeviceNode);
+
+ if (DataStr == NULL) {
+ DataLength = 0;
+ } else {
+ DataLength = StrLen (DataStr) / 2;
+ }
+ Node = CreateDeviceNode (
+ Type,
+ (UINT8) Strtoi (SubtypeStr),
+ (UINT16) (sizeof (EFI_DEVICE_PATH_PROTOCOL) + DataLength)
+ );
+
+ StrHexToBytes (DataStr, DataLength * 2, (UINT8 *) (Node + 1), DataLength);
+ return Node;
+}
+
+/**
+ Converts a generic text device path node to device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextPath (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *TypeStr;
+
+ TypeStr = GetNextParamStr (&TextDeviceNode);
+
+ return DevPathFromTextGenericPath ((UINT8) Strtoi (TypeStr), TextDeviceNode);
+}
+
+/**
+ Converts a generic hardware text device path node to Hardware device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to Hardware device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextHardwarePath (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ return DevPathFromTextGenericPath (HARDWARE_DEVICE_PATH, TextDeviceNode);
+}
+
+/**
+ Converts a text device path node to Hardware PCI device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to Hardware PCI device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextPci (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *FunctionStr;
+ CHAR16 *DeviceStr;
+ PCI_DEVICE_PATH *Pci;
+
+ DeviceStr = GetNextParamStr (&TextDeviceNode);
+ FunctionStr = GetNextParamStr (&TextDeviceNode);
+ Pci = (PCI_DEVICE_PATH *) CreateDeviceNode (
+ HARDWARE_DEVICE_PATH,
+ HW_PCI_DP,
+ (UINT16) sizeof (PCI_DEVICE_PATH)
+ );
+
+ Pci->Function = (UINT8) Strtoi (FunctionStr);
+ Pci->Device = (UINT8) Strtoi (DeviceStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Pci;
+}
+
+/**
+ Converts a text device path node to Hardware PC card device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to Hardware PC card device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextPcCard (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *FunctionNumberStr;
+ PCCARD_DEVICE_PATH *Pccard;
+
+ FunctionNumberStr = GetNextParamStr (&TextDeviceNode);
+ Pccard = (PCCARD_DEVICE_PATH *) CreateDeviceNode (
+ HARDWARE_DEVICE_PATH,
+ HW_PCCARD_DP,
+ (UINT16) sizeof (PCCARD_DEVICE_PATH)
+ );
+
+ Pccard->FunctionNumber = (UINT8) Strtoi (FunctionNumberStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Pccard;
+}
+
+/**
+ Converts a text device path node to Hardware memory map device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to Hardware memory map device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextMemoryMapped (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *MemoryTypeStr;
+ CHAR16 *StartingAddressStr;
+ CHAR16 *EndingAddressStr;
+ MEMMAP_DEVICE_PATH *MemMap;
+
+ MemoryTypeStr = GetNextParamStr (&TextDeviceNode);
+ StartingAddressStr = GetNextParamStr (&TextDeviceNode);
+ EndingAddressStr = GetNextParamStr (&TextDeviceNode);
+ MemMap = (MEMMAP_DEVICE_PATH *) CreateDeviceNode (
+ HARDWARE_DEVICE_PATH,
+ HW_MEMMAP_DP,
+ (UINT16) sizeof (MEMMAP_DEVICE_PATH)
+ );
+
+ MemMap->MemoryType = (UINT32) Strtoi (MemoryTypeStr);
+ Strtoi64 (StartingAddressStr, &MemMap->StartingAddress);
+ Strtoi64 (EndingAddressStr, &MemMap->EndingAddress);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) MemMap;
+}
+
+/**
+ Converts a text device path node to Vendor device path structure based on the input Type
+ and SubType.
+
+ @param TextDeviceNode The input Text device path node.
+ @param Type The type of device path node.
+ @param SubType The subtype of device path node.
+
+ @return A pointer to the newly-created Vendor device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertFromTextVendor (
+ IN CHAR16 *TextDeviceNode,
+ IN UINT8 Type,
+ IN UINT8 SubType
+ )
+{
+ CHAR16 *GuidStr;
+ CHAR16 *DataStr;
+ UINTN Length;
+ VENDOR_DEVICE_PATH *Vendor;
+
+ GuidStr = GetNextParamStr (&TextDeviceNode);
+
+ DataStr = GetNextParamStr (&TextDeviceNode);
+ Length = StrLen (DataStr);
+ //
+ // Two hex characters make up 1 buffer byte
+ //
+ Length = (Length + 1) / 2;
+
+ Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
+ Type,
+ SubType,
+ (UINT16) (sizeof (VENDOR_DEVICE_PATH) + Length)
+ );
+
+ StrToGuid (GuidStr, &Vendor->Guid);
+ StrHexToBytes (DataStr, Length * 2, (UINT8 *) (Vendor + 1), Length);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+/**
+ Converts a text device path node to Vendor Hardware device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Vendor Hardware device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenHw (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextVendor (
+ TextDeviceNode,
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP
+ );
+}
+
+/**
+ Converts a text device path node to Hardware Controller device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Hardware Controller device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextCtrl (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *ControllerStr;
+ CONTROLLER_DEVICE_PATH *Controller;
+
+ ControllerStr = GetNextParamStr (&TextDeviceNode);
+ Controller = (CONTROLLER_DEVICE_PATH *) CreateDeviceNode (
+ HARDWARE_DEVICE_PATH,
+ HW_CONTROLLER_DP,
+ (UINT16) sizeof (CONTROLLER_DEVICE_PATH)
+ );
+ Controller->ControllerNumber = (UINT32) Strtoi (ControllerStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Controller;
+}
+
+/**
+ Converts a text device path node to BMC device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created BMC device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextBmc (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *InterfaceTypeStr;
+ CHAR16 *BaseAddressStr;
+ BMC_DEVICE_PATH *BmcDp;
+
+ InterfaceTypeStr = GetNextParamStr (&TextDeviceNode);
+ BaseAddressStr = GetNextParamStr (&TextDeviceNode);
+ BmcDp = (BMC_DEVICE_PATH *) CreateDeviceNode (
+ HARDWARE_DEVICE_PATH,
+ HW_BMC_DP,
+ (UINT16) sizeof (BMC_DEVICE_PATH)
+ );
+
+ BmcDp->InterfaceType = (UINT8) Strtoi (InterfaceTypeStr);
+ WriteUnaligned64 (
+ (UINT64 *) (&BmcDp->BaseAddress),
+ StrHexToUint64 (BaseAddressStr)
+ );
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) BmcDp;
+}
+
+/**
+ Converts a generic ACPI text device path node to ACPI device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to ACPI device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextAcpiPath (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ return DevPathFromTextGenericPath (ACPI_DEVICE_PATH, TextDeviceNode);
+}
+
+/**
+ Converts a string to EisaId.
+
+ @param Text The input string.
+
+ @return UINT32 EISA ID.
+**/
+static
+UINT32
+EisaIdFromText (
+ IN CHAR16 *Text
+ )
+{
+ return (((Text[0] - 'A' + 1) & 0x1f) << 10)
+ + (((Text[1] - 'A' + 1) & 0x1f) << 5)
+ + (((Text[2] - 'A' + 1) & 0x1f) << 0)
+ + (UINT32) (StrHexToUintn (&Text[3]) << 16)
+ ;
+}
+
+/**
+ Converts a text device path node to ACPI HID device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created ACPI HID device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextAcpi (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *HIDStr;
+ CHAR16 *UIDStr;
+ ACPI_HID_DEVICE_PATH *Acpi;
+
+ HIDStr = GetNextParamStr (&TextDeviceNode);
+ UIDStr = GetNextParamStr (&TextDeviceNode);
+ Acpi = (ACPI_HID_DEVICE_PATH *) CreateDeviceNode (
+ ACPI_DEVICE_PATH,
+ ACPI_DP,
+ (UINT16) sizeof (ACPI_HID_DEVICE_PATH)
+ );
+
+ Acpi->HID = EisaIdFromText (HIDStr);
+ Acpi->UID = (UINT32) Strtoi (UIDStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Acpi;
+}
+
+/**
+ Converts a text device path node to ACPI HID device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+ @param PnPId The input plug and play identification.
+
+ @return A pointer to the newly-created ACPI HID device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertFromTextAcpi (
+ IN CHAR16 *TextDeviceNode,
+ IN UINT32 PnPId
+ )
+{
+ CHAR16 *UIDStr;
+ ACPI_HID_DEVICE_PATH *Acpi;
+
+ UIDStr = GetNextParamStr (&TextDeviceNode);
+ Acpi = (ACPI_HID_DEVICE_PATH *) CreateDeviceNode (
+ ACPI_DEVICE_PATH,
+ ACPI_DP,
+ (UINT16) sizeof (ACPI_HID_DEVICE_PATH)
+ );
+
+ Acpi->HID = EFI_PNP_ID (PnPId);
+ Acpi->UID = (UINT32) Strtoi (UIDStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Acpi;
+}
+
+/**
+ Converts a text device path node to PCI root device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created PCI root device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextPciRoot (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextAcpi (TextDeviceNode, 0x0a03);
+}
+
+/**
+ Converts a text device path node to PCIE root device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created PCIE root device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextPcieRoot (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextAcpi (TextDeviceNode, 0x0a08);
+}
+
+/**
+ Converts a text device path node to Floppy device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Floppy device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextFloppy (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextAcpi (TextDeviceNode, 0x0604);
+}
+
+/**
+ Converts a text device path node to Keyboard device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Keyboard device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextKeyboard (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextAcpi (TextDeviceNode, 0x0301);
+}
+
+/**
+ Converts a text device path node to Serial device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Serial device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextSerial (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextAcpi (TextDeviceNode, 0x0501);
+}
+
+/**
+ Converts a text device path node to Parallel Port device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Parallel Port device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextParallelPort (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextAcpi (TextDeviceNode, 0x0401);
+}
+
+/**
+ Converts a text device path node to ACPI extension device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created ACPI extension device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextAcpiEx (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *HIDStr;
+ CHAR16 *CIDStr;
+ CHAR16 *UIDStr;
+ CHAR16 *HIDSTRStr;
+ CHAR16 *CIDSTRStr;
+ CHAR16 *UIDSTRStr;
+ CHAR8 *AsciiStr;
+ UINT16 Length;
+ ACPI_EXTENDED_HID_DEVICE_PATH *AcpiEx;
+
+ HIDStr = GetNextParamStr (&TextDeviceNode);
+ CIDStr = GetNextParamStr (&TextDeviceNode);
+ UIDStr = GetNextParamStr (&TextDeviceNode);
+ HIDSTRStr = GetNextParamStr (&TextDeviceNode);
+ CIDSTRStr = GetNextParamStr (&TextDeviceNode);
+ UIDSTRStr = GetNextParamStr (&TextDeviceNode);
+
+ Length = (UINT16) (sizeof (ACPI_EXTENDED_HID_DEVICE_PATH) + StrLen (HIDSTRStr) + 1);
+ Length = (UINT16) (Length + StrLen (UIDSTRStr) + 1);
+ Length = (UINT16) (Length + StrLen (CIDSTRStr) + 1);
+ AcpiEx = (ACPI_EXTENDED_HID_DEVICE_PATH *) CreateDeviceNode (
+ ACPI_DEVICE_PATH,
+ ACPI_EXTENDED_DP,
+ Length
+ );
+
+ AcpiEx->HID = EisaIdFromText (HIDStr);
+ AcpiEx->CID = EisaIdFromText (CIDStr);
+ AcpiEx->UID = (UINT32) Strtoi (UIDStr);
+
+ AsciiStr = (CHAR8 *) ((UINT8 *)AcpiEx + sizeof (ACPI_EXTENDED_HID_DEVICE_PATH));
+ StrToAscii (HIDSTRStr, &AsciiStr);
+ StrToAscii (UIDSTRStr, &AsciiStr);
+ StrToAscii (CIDSTRStr, &AsciiStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) AcpiEx;
+}
+
+/**
+ Converts a text device path node to ACPI extension device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created ACPI extension device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextAcpiExp (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *HIDStr;
+ CHAR16 *CIDStr;
+ CHAR16 *UIDSTRStr;
+ CHAR8 *AsciiStr;
+ UINT16 Length;
+ ACPI_EXTENDED_HID_DEVICE_PATH *AcpiEx;
+
+ HIDStr = GetNextParamStr (&TextDeviceNode);
+ CIDStr = GetNextParamStr (&TextDeviceNode);
+ UIDSTRStr = GetNextParamStr (&TextDeviceNode);
+ Length = (UINT16) (sizeof (ACPI_EXTENDED_HID_DEVICE_PATH) + StrLen (UIDSTRStr) + 3);
+ AcpiEx = (ACPI_EXTENDED_HID_DEVICE_PATH *) CreateDeviceNode (
+ ACPI_DEVICE_PATH,
+ ACPI_EXTENDED_DP,
+ Length
+ );
+
+ AcpiEx->HID = EisaIdFromText (HIDStr);
+ AcpiEx->CID = EisaIdFromText (CIDStr);
+ AcpiEx->UID = 0;
+
+ AsciiStr = (CHAR8 *) ((UINT8 *)AcpiEx + sizeof (ACPI_EXTENDED_HID_DEVICE_PATH));
+ //
+ // HID string is NULL
+ //
+ *AsciiStr = '\0';
+ //
+ // Convert UID string
+ //
+ AsciiStr++;
+ StrToAscii (UIDSTRStr, &AsciiStr);
+ //
+ // CID string is NULL
+ //
+ *AsciiStr = '\0';
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) AcpiEx;
+}
+
+/**
+ Converts a text device path node to ACPI _ADR device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created ACPI _ADR device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextAcpiAdr (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *DisplayDeviceStr;
+ ACPI_ADR_DEVICE_PATH *AcpiAdr;
+ UINTN Index;
+ UINTN Length;
+
+ AcpiAdr = (ACPI_ADR_DEVICE_PATH *) CreateDeviceNode (
+ ACPI_DEVICE_PATH,
+ ACPI_ADR_DP,
+ (UINT16) sizeof (ACPI_ADR_DEVICE_PATH)
+ );
+ ASSERT (AcpiAdr != NULL);
+
+ for (Index = 0; ; Index++) {
+ DisplayDeviceStr = GetNextParamStr (&TextDeviceNode);
+ if (IS_NULL (*DisplayDeviceStr)) {
+ break;
+ }
+ if (Index > 0) {
+ Length = DevicePathNodeLength (AcpiAdr);
+ AcpiAdr = ReallocatePool (
+ Length,
+ Length + sizeof (UINT32),
+ AcpiAdr
+ );
+ ASSERT (AcpiAdr != NULL);
+ SetDevicePathNodeLength (AcpiAdr, Length + sizeof (UINT32));
+ }
+
+ (&AcpiAdr->ADR)[Index] = (UINT32) Strtoi (DisplayDeviceStr);
+ }
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) AcpiAdr;
+}
+
+/**
+ Converts a generic messaging text device path node to messaging device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to messaging device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextMsg (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ return DevPathFromTextGenericPath (MESSAGING_DEVICE_PATH, TextDeviceNode);
+}
+
+/**
+ Converts a text device path node to Parallel Port device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Parallel Port device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextAta (
+IN CHAR16 *TextDeviceNode
+)
+{
+ CHAR16 *PrimarySecondaryStr;
+ CHAR16 *SlaveMasterStr;
+ CHAR16 *LunStr;
+ ATAPI_DEVICE_PATH *Atapi;
+
+ Atapi = (ATAPI_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_ATAPI_DP,
+ (UINT16) sizeof (ATAPI_DEVICE_PATH)
+ );
+
+ PrimarySecondaryStr = GetNextParamStr (&TextDeviceNode);
+ SlaveMasterStr = GetNextParamStr (&TextDeviceNode);
+ LunStr = GetNextParamStr (&TextDeviceNode);
+
+ if (StrCmp (PrimarySecondaryStr, "Primary") == 0) {
+ Atapi->PrimarySecondary = 0;
+ } else if (StrCmp (PrimarySecondaryStr, "Secondary") == 0) {
+ Atapi->PrimarySecondary = 1;
+ } else {
+ Atapi->PrimarySecondary = (UINT8) Strtoi (PrimarySecondaryStr);
+ }
+ if (StrCmp (SlaveMasterStr, "Master") == 0) {
+ Atapi->SlaveMaster = 0;
+ } else if (StrCmp (SlaveMasterStr, "Slave") == 0) {
+ Atapi->SlaveMaster = 1;
+ } else {
+ Atapi->SlaveMaster = (UINT8) Strtoi (SlaveMasterStr);
+ }
+
+ Atapi->Lun = (UINT16) Strtoi (LunStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Atapi;
+}
+
+/**
+ Converts a text device path node to SCSI device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created SCSI device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextScsi (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *PunStr;
+ CHAR16 *LunStr;
+ SCSI_DEVICE_PATH *Scsi;
+
+ PunStr = GetNextParamStr (&TextDeviceNode);
+ LunStr = GetNextParamStr (&TextDeviceNode);
+ Scsi = (SCSI_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_SCSI_DP,
+ (UINT16) sizeof (SCSI_DEVICE_PATH)
+ );
+
+ Scsi->Pun = (UINT16) Strtoi (PunStr);
+ Scsi->Lun = (UINT16) Strtoi (LunStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Scsi;
+}
+
+/**
+ Converts a text device path node to Fibre device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Fibre device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextFibre (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *WWNStr;
+ CHAR16 *LunStr;
+ FIBRECHANNEL_DEVICE_PATH *Fibre;
+
+ WWNStr = GetNextParamStr (&TextDeviceNode);
+ LunStr = GetNextParamStr (&TextDeviceNode);
+ Fibre = (FIBRECHANNEL_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_FIBRECHANNEL_DP,
+ (UINT16) sizeof (FIBRECHANNEL_DEVICE_PATH)
+ );
+
+ Fibre->Reserved = 0;
+ Strtoi64 (WWNStr, &Fibre->WWN);
+ Strtoi64 (LunStr, &Fibre->Lun);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Fibre;
+}
+
+/**
+ Converts a text device path node to FibreEx device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created FibreEx device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextFibreEx (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *WWNStr;
+ CHAR16 *LunStr;
+ FIBRECHANNELEX_DEVICE_PATH *FibreEx;
+
+ WWNStr = GetNextParamStr (&TextDeviceNode);
+ LunStr = GetNextParamStr (&TextDeviceNode);
+ FibreEx = (FIBRECHANNELEX_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_FIBRECHANNELEX_DP,
+ (UINT16) sizeof (FIBRECHANNELEX_DEVICE_PATH)
+ );
+
+ FibreEx->Reserved = 0;
+ Strtoi64 (WWNStr, (UINT64 *) (&FibreEx->WWN));
+ Strtoi64 (LunStr, (UINT64 *) (&FibreEx->Lun));
+
+ *(UINT64 *) (&FibreEx->WWN) = SwapBytes64 (*(UINT64 *) (&FibreEx->WWN));
+ *(UINT64 *) (&FibreEx->Lun) = SwapBytes64 (*(UINT64 *) (&FibreEx->Lun));
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) FibreEx;
+}
+
+/**
+ Converts a text device path node to 1394 device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created 1394 device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromText1394 (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *GuidStr;
+ F1394_DEVICE_PATH *F1394DevPath;
+
+ GuidStr = GetNextParamStr (&TextDeviceNode);
+ F1394DevPath = (F1394_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_1394_DP,
+ (UINT16) sizeof (F1394_DEVICE_PATH)
+ );
+
+ F1394DevPath->Reserved = 0;
+ F1394DevPath->Guid = StrHexToUint64 (GuidStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) F1394DevPath;
+}
+
+/**
+ Converts a text device path node to USB device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsb (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *PortStr;
+ CHAR16 *InterfaceStr;
+ USB_DEVICE_PATH *Usb;
+
+ PortStr = GetNextParamStr (&TextDeviceNode);
+ InterfaceStr = GetNextParamStr (&TextDeviceNode);
+ Usb = (USB_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_USB_DP,
+ (UINT16) sizeof (USB_DEVICE_PATH)
+ );
+
+ Usb->ParentPortNumber = (UINT8) Strtoi (PortStr);
+ Usb->InterfaceNumber = (UINT8) Strtoi (InterfaceStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Usb;
+}
+
+/**
+ Converts a text device path node to I20 device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created I20 device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextI2O (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *TIDStr;
+ I2O_DEVICE_PATH *I2ODevPath;
+
+ TIDStr = GetNextParamStr (&TextDeviceNode);
+ I2ODevPath = (I2O_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_I2O_DP,
+ (UINT16) sizeof (I2O_DEVICE_PATH)
+ );
+
+ I2ODevPath->Tid = (UINT32) Strtoi (TIDStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) I2ODevPath;
+}
+
+/**
+ Converts a text device path node to Infini Band device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Infini Band device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextInfiniband (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *FlagsStr;
+ CHAR16 *GuidStr;
+ CHAR16 *SidStr;
+ CHAR16 *TidStr;
+ CHAR16 *DidStr;
+ INFINIBAND_DEVICE_PATH *InfiniBand;
+
+ FlagsStr = GetNextParamStr (&TextDeviceNode);
+ GuidStr = GetNextParamStr (&TextDeviceNode);
+ SidStr = GetNextParamStr (&TextDeviceNode);
+ TidStr = GetNextParamStr (&TextDeviceNode);
+ DidStr = GetNextParamStr (&TextDeviceNode);
+ InfiniBand = (INFINIBAND_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_INFINIBAND_DP,
+ (UINT16) sizeof (INFINIBAND_DEVICE_PATH)
+ );
+
+ InfiniBand->ResourceFlags = (UINT32) Strtoi (FlagsStr);
+ StrToGuid (GuidStr, (EFI_GUID *) InfiniBand->PortGid);
+ Strtoi64 (SidStr, &InfiniBand->ServiceId);
+ Strtoi64 (TidStr, &InfiniBand->TargetPortId);
+ Strtoi64 (DidStr, &InfiniBand->DeviceId);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) InfiniBand;
+}
+
+/**
+ Converts a text device path node to Vendor-Defined Messaging device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Vendor-Defined Messaging device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenMsg (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextVendor (
+ TextDeviceNode,
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP
+ );
+}
+
+/**
+ Converts a text device path node to Vendor defined PC-ANSI device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Vendor defined PC-ANSI device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenPcAnsi (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ VENDOR_DEVICE_PATH *Vendor;
+
+ Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ (UINT16) sizeof (VENDOR_DEVICE_PATH));
+ CopyGuid (&Vendor->Guid, &gEfiPcAnsiGuid);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+/**
+ Converts a text device path node to Vendor defined VT100 device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Vendor defined VT100 device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenVt100 (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ VENDOR_DEVICE_PATH *Vendor;
+
+ Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ (UINT16) sizeof (VENDOR_DEVICE_PATH));
+ CopyGuid (&Vendor->Guid, &gEfiVT100Guid);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+/**
+ Converts a text device path node to Vendor defined VT100 Plus device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Vendor defined VT100 Plus device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenVt100Plus (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ VENDOR_DEVICE_PATH *Vendor;
+
+ Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ (UINT16) sizeof (VENDOR_DEVICE_PATH));
+ CopyGuid (&Vendor->Guid, &gEfiVT100PlusGuid);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+/**
+ Converts a text device path node to Vendor defined UTF8 device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Vendor defined UTF8 device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenUtf8 (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ VENDOR_DEVICE_PATH *Vendor;
+
+ Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ (UINT16) sizeof (VENDOR_DEVICE_PATH));
+ CopyGuid (&Vendor->Guid, &gEfiVTUTF8Guid);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+/**
+ Converts a text device path node to UART Flow Control device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created UART Flow Control device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUartFlowCtrl (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *ValueStr;
+ UART_FLOW_CONTROL_DEVICE_PATH *UartFlowControl;
+
+ ValueStr = GetNextParamStr (&TextDeviceNode);
+ UartFlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ (UINT16) sizeof (UART_FLOW_CONTROL_DEVICE_PATH)
+ );
+
+ CopyGuid (&UartFlowControl->Guid, &gEfiUartDevicePathGuid);
+ if (StrCmp (ValueStr, "XonXoff") == 0) {
+ UartFlowControl->FlowControlMap = 2;
+ } else if (StrCmp (ValueStr, "Hardware") == 0) {
+ UartFlowControl->FlowControlMap = 1;
+ } else {
+ UartFlowControl->FlowControlMap = 0;
+ }
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) UartFlowControl;
+}
+
+/**
+ Converts a text device path node to Serial Attached SCSI device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Serial Attached SCSI device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextSAS (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *AddressStr;
+ CHAR16 *LunStr;
+ CHAR16 *RTPStr;
+ CHAR16 *SASSATAStr;
+ CHAR16 *LocationStr;
+ CHAR16 *ConnectStr;
+ CHAR16 *DriveBayStr;
+ CHAR16 *ReservedStr;
+ UINT16 Info;
+ UINT16 Uint16;
+ SAS_DEVICE_PATH *Sas;
+
+ AddressStr = GetNextParamStr (&TextDeviceNode);
+ LunStr = GetNextParamStr (&TextDeviceNode);
+ RTPStr = GetNextParamStr (&TextDeviceNode);
+ SASSATAStr = GetNextParamStr (&TextDeviceNode);
+ LocationStr = GetNextParamStr (&TextDeviceNode);
+ ConnectStr = GetNextParamStr (&TextDeviceNode);
+ DriveBayStr = GetNextParamStr (&TextDeviceNode);
+ ReservedStr = GetNextParamStr (&TextDeviceNode);
+ Sas = (SAS_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ (UINT16) sizeof (SAS_DEVICE_PATH)
+ );
+
+ CopyGuid (&Sas->Guid, &gEfiSasDevicePathGuid);
+ Strtoi64 (AddressStr, &Sas->SasAddress);
+ Strtoi64 (LunStr, &Sas->Lun);
+ Sas->RelativeTargetPort = (UINT16) Strtoi (RTPStr);
+
+ if (StrCmp (SASSATAStr, "NoTopology") == 0) {
+ Info = 0x0;
+
+ } else if ((StrCmp (SASSATAStr, "SATA") == 0) || (StrCmp (SASSATAStr, "SAS") == 0)) {
+
+ Uint16 = (UINT16) Strtoi (DriveBayStr);
+ if (Uint16 == 0) {
+ Info = 0x1;
+ } else {
+ Info = (UINT16) (0x2 | ((Uint16 - 1) << 8));
+ }
+
+ if (StrCmp (SASSATAStr, "SATA") == 0) {
+ Info |= BIT4;
+ }
+
+ //
+ // Location is an integer between 0 and 1 or else
+ // the keyword Internal (0) or External (1).
+ //
+ if (StrCmp (LocationStr, "External") == 0) {
+ Uint16 = 1;
+ } else if (StrCmp (LocationStr, "Internal") == 0) {
+ Uint16 = 0;
+ } else {
+ Uint16 = ((UINT16) Strtoi (LocationStr) & BIT0);
+ }
+ Info |= (Uint16 << 5);
+
+ //
+ // Connect is an integer between 0 and 3 or else
+ // the keyword Direct (0) or Expanded (1).
+ //
+ if (StrCmp (ConnectStr, "Expanded") == 0) {
+ Uint16 = 1;
+ } else if (StrCmp (ConnectStr, "Direct") == 0) {
+ Uint16 = 0;
+ } else {
+ Uint16 = ((UINT16) Strtoi (ConnectStr) & (BIT0 | BIT1));
+ }
+ Info |= (Uint16 << 6);
+
+ } else {
+ Info = (UINT16) Strtoi (SASSATAStr);
+ }
+
+ Sas->DeviceTopology = Info;
+ Sas->Reserved = (UINT32) Strtoi (ReservedStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Sas;
+}
+
+/**
+ Converts a text device path node to Serial Attached SCSI Ex device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Serial Attached SCSI Ex device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextSasEx (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *AddressStr;
+ CHAR16 *LunStr;
+ CHAR16 *RTPStr;
+ CHAR16 *SASSATAStr;
+ CHAR16 *LocationStr;
+ CHAR16 *ConnectStr;
+ CHAR16 *DriveBayStr;
+ UINT16 Info;
+ UINT16 Uint16;
+ UINT64 SasAddress;
+ UINT64 Lun;
+ SASEX_DEVICE_PATH *SasEx;
+
+ AddressStr = GetNextParamStr (&TextDeviceNode);
+ LunStr = GetNextParamStr (&TextDeviceNode);
+ RTPStr = GetNextParamStr (&TextDeviceNode);
+ SASSATAStr = GetNextParamStr (&TextDeviceNode);
+ LocationStr = GetNextParamStr (&TextDeviceNode);
+ ConnectStr = GetNextParamStr (&TextDeviceNode);
+ DriveBayStr = GetNextParamStr (&TextDeviceNode);
+ SasEx = (SASEX_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_SASEX_DP,
+ (UINT16) sizeof (SASEX_DEVICE_PATH)
+ );
+
+ Strtoi64 (AddressStr, &SasAddress);
+ Strtoi64 (LunStr, &Lun);
+ WriteUnaligned64 ((UINT64 *) &SasEx->SasAddress, SwapBytes64 (SasAddress));
+ WriteUnaligned64 ((UINT64 *) &SasEx->Lun, SwapBytes64 (Lun));
+ SasEx->RelativeTargetPort = (UINT16) Strtoi (RTPStr);
+
+ if (StrCmp (SASSATAStr, "NoTopology") == 0) {
+ Info = 0x0;
+
+ } else if ((StrCmp (SASSATAStr, "SATA") == 0) || (StrCmp (SASSATAStr, "SAS") == 0)) {
+
+ Uint16 = (UINT16) Strtoi (DriveBayStr);
+ if (Uint16 == 0) {
+ Info = 0x1;
+ } else {
+ Info = (UINT16) (0x2 | ((Uint16 - 1) << 8));
+ }
+
+ if (StrCmp (SASSATAStr, "SATA") == 0) {
+ Info |= BIT4;
+ }
+
+ //
+ // Location is an integer between 0 and 1 or else
+ // the keyword Internal (0) or External (1).
+ //
+ if (StrCmp (LocationStr, "External") == 0) {
+ Uint16 = 1;
+ } else if (StrCmp (LocationStr, "Internal") == 0) {
+ Uint16 = 0;
+ } else {
+ Uint16 = ((UINT16) Strtoi (LocationStr) & BIT0);
+ }
+ Info |= (Uint16 << 5);
+
+ //
+ // Connect is an integer between 0 and 3 or else
+ // the keyword Direct (0) or Expanded (1).
+ //
+ if (StrCmp (ConnectStr, "Expanded") == 0) {
+ Uint16 = 1;
+ } else if (StrCmp (ConnectStr, "Direct") == 0) {
+ Uint16 = 0;
+ } else {
+ Uint16 = ((UINT16) Strtoi (ConnectStr) & (BIT0 | BIT1));
+ }
+ Info |= (Uint16 << 6);
+
+ } else {
+ Info = (UINT16) Strtoi (SASSATAStr);
+ }
+
+ SasEx->DeviceTopology = Info;
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) SasEx;
+}
+
+/**
+ Converts a text device path node to NVM Express Namespace device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created NVM Express Namespace device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextNVMe (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *NamespaceIdStr;
+ CHAR16 *NamespaceUuidStr;
+ NVME_NAMESPACE_DEVICE_PATH *Nvme;
+ UINT8 *Uuid;
+ UINTN Index;
+
+ NamespaceIdStr = GetNextParamStr (&TextDeviceNode);
+ NamespaceUuidStr = GetNextParamStr (&TextDeviceNode);
+ Nvme = (NVME_NAMESPACE_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_NVME_NAMESPACE_DP,
+ (UINT16) sizeof (NVME_NAMESPACE_DEVICE_PATH)
+ );
+
+ Nvme->NamespaceId = (UINT32) Strtoi (NamespaceIdStr);
+ Uuid = (UINT8 *) &Nvme->NamespaceUuid;
+
+ Index = sizeof (Nvme->NamespaceUuid) / sizeof (UINT8);
+ while (Index-- != 0) {
+ Uuid[Index] = (UINT8) StrHexToUintn (SplitStr (&NamespaceUuidStr, '-'));
+ }
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Nvme;
+}
+
+/**
+ Converts a text device path node to UFS device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created UFS device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUfs (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *PunStr;
+ CHAR16 *LunStr;
+ UFS_DEVICE_PATH *Ufs;
+
+ PunStr = GetNextParamStr (&TextDeviceNode);
+ LunStr = GetNextParamStr (&TextDeviceNode);
+ Ufs = (UFS_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_UFS_DP,
+ (UINT16) sizeof (UFS_DEVICE_PATH)
+ );
+
+ Ufs->Pun = (UINT8) Strtoi (PunStr);
+ Ufs->Lun = (UINT8) Strtoi (LunStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Ufs;
+}
+
+/**
+ Converts a text device path node to SD (Secure Digital) device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created SD device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextSd (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *SlotNumberStr;
+ SD_DEVICE_PATH *Sd;
+
+ SlotNumberStr = GetNextParamStr (&TextDeviceNode);
+ Sd = (SD_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_SD_DP,
+ (UINT16) sizeof (SD_DEVICE_PATH)
+ );
+
+ Sd->SlotNumber = (UINT8) Strtoi (SlotNumberStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Sd;
+}
+
+/**
+ Converts a text device path node to EMMC (Embedded MMC) device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created EMMC device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextEmmc (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *SlotNumberStr;
+ EMMC_DEVICE_PATH *Emmc;
+
+ SlotNumberStr = GetNextParamStr (&TextDeviceNode);
+ Emmc = (EMMC_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_EMMC_DP,
+ (UINT16) sizeof (EMMC_DEVICE_PATH)
+ );
+
+ Emmc->SlotNumber = (UINT8) Strtoi (SlotNumberStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Emmc;
+}
+
+/**
+ Converts a text device path node to Debug Port device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Debug Port device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextDebugPort (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ VENDOR_DEFINED_MESSAGING_DEVICE_PATH *Vend;
+
+ Vend = (VENDOR_DEFINED_MESSAGING_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ (UINT16) sizeof (VENDOR_DEFINED_MESSAGING_DEVICE_PATH)
+ );
+
+ CopyGuid (&Vend->Guid, &gEfiDebugPortProtocolGuid);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vend;
+}
+
+/**
+ Converts a text device path node to MAC device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created MAC device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextMAC (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *AddressStr;
+ CHAR16 *IfTypeStr;
+ UINTN Length;
+ MAC_ADDR_DEVICE_PATH *MACDevPath;
+
+ AddressStr = GetNextParamStr (&TextDeviceNode);
+ IfTypeStr = GetNextParamStr (&TextDeviceNode);
+ MACDevPath = (MAC_ADDR_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_MAC_ADDR_DP,
+ (UINT16) sizeof (MAC_ADDR_DEVICE_PATH)
+ );
+
+ MACDevPath->IfType = (UINT8) Strtoi (IfTypeStr);
+
+ Length = sizeof (EFI_MAC_ADDRESS);
+ StrHexToBytes (AddressStr, Length * 2, MACDevPath->MacAddress.Addr, Length);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) MACDevPath;
+}
+
+
+/**
+ Converts a text format to the network protocol ID.
+
+ @param Text String of protocol field.
+
+ @return Network protocol ID .
+
+**/
+static
+UINTN
+NetworkProtocolFromText (
+ IN CHAR16 *Text
+ )
+{
+ if (StrCmp (Text, "UDP") == 0) {
+ return RFC_1700_UDP_PROTOCOL;
+ }
+
+ if (StrCmp (Text, "TCP") == 0) {
+ return RFC_1700_TCP_PROTOCOL;
+ }
+
+ return Strtoi (Text);
+}
+
+
+/**
+ Converts a text device path node to IPV4 device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created IPV4 device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextIPv4 (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *RemoteIPStr;
+ CHAR16 *ProtocolStr;
+ CHAR16 *TypeStr;
+ CHAR16 *LocalIPStr;
+ CHAR16 *GatewayIPStr;
+ CHAR16 *SubnetMaskStr;
+ IPv4_DEVICE_PATH *IPv4;
+
+ RemoteIPStr = GetNextParamStr (&TextDeviceNode);
+ ProtocolStr = GetNextParamStr (&TextDeviceNode);
+ TypeStr = GetNextParamStr (&TextDeviceNode);
+ LocalIPStr = GetNextParamStr (&TextDeviceNode);
+ GatewayIPStr = GetNextParamStr (&TextDeviceNode);
+ SubnetMaskStr = GetNextParamStr (&TextDeviceNode);
+ IPv4 = (IPv4_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_IPv4_DP,
+ (UINT16) sizeof (IPv4_DEVICE_PATH)
+ );
+
+ StrToIpv4Address (RemoteIPStr, NULL, &IPv4->RemoteIpAddress, NULL);
+ IPv4->Protocol = (UINT16) NetworkProtocolFromText (ProtocolStr);
+ if (StrCmp (TypeStr, "Static") == 0) {
+ IPv4->StaticIpAddress = TRUE;
+ } else {
+ IPv4->StaticIpAddress = FALSE;
+ }
+
+ StrToIpv4Address (LocalIPStr, NULL, &IPv4->LocalIpAddress, NULL);
+ if (!IS_NULL (*GatewayIPStr) && !IS_NULL (*SubnetMaskStr)) {
+ StrToIpv4Address (GatewayIPStr, NULL, &IPv4->GatewayIpAddress, NULL);
+ StrToIpv4Address (SubnetMaskStr, NULL, &IPv4->SubnetMask, NULL);
+ } else {
+ ZeroMem (&IPv4->GatewayIpAddress, sizeof (IPv4->GatewayIpAddress));
+ ZeroMem (&IPv4->SubnetMask, sizeof (IPv4->SubnetMask));
+ }
+
+ IPv4->LocalPort = 0;
+ IPv4->RemotePort = 0;
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) IPv4;
+}
+
+/**
+ Converts a text device path node to IPV6 device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created IPV6 device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextIPv6 (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *RemoteIPStr;
+ CHAR16 *ProtocolStr;
+ CHAR16 *TypeStr;
+ CHAR16 *LocalIPStr;
+ CHAR16 *GatewayIPStr;
+ CHAR16 *PrefixLengthStr;
+ IPv6_DEVICE_PATH *IPv6;
+
+ RemoteIPStr = GetNextParamStr (&TextDeviceNode);
+ ProtocolStr = GetNextParamStr (&TextDeviceNode);
+ TypeStr = GetNextParamStr (&TextDeviceNode);
+ LocalIPStr = GetNextParamStr (&TextDeviceNode);
+ PrefixLengthStr = GetNextParamStr (&TextDeviceNode);
+ GatewayIPStr = GetNextParamStr (&TextDeviceNode);
+ IPv6 = (IPv6_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_IPv6_DP,
+ (UINT16) sizeof (IPv6_DEVICE_PATH)
+ );
+
+ StrToIpv6Address (RemoteIPStr, NULL, &IPv6->RemoteIpAddress, NULL);
+ IPv6->Protocol = (UINT16) NetworkProtocolFromText (ProtocolStr);
+ if (StrCmp (TypeStr, "Static") == 0) {
+ IPv6->IpAddressOrigin = 0;
+ } else if (StrCmp (TypeStr, "StatelessAutoConfigure") == 0) {
+ IPv6->IpAddressOrigin = 1;
+ } else {
+ IPv6->IpAddressOrigin = 2;
+ }
+
+ StrToIpv6Address (LocalIPStr, NULL, &IPv6->LocalIpAddress, NULL);
+ if (!IS_NULL (*GatewayIPStr) && !IS_NULL (*PrefixLengthStr)) {
+ StrToIpv6Address (GatewayIPStr, NULL, &IPv6->GatewayIpAddress, NULL);
+ IPv6->PrefixLength = (UINT8) Strtoi (PrefixLengthStr);
+ } else {
+ ZeroMem (&IPv6->GatewayIpAddress, sizeof (IPv6->GatewayIpAddress));
+ IPv6->PrefixLength = 0;
+ }
+
+ IPv6->LocalPort = 0;
+ IPv6->RemotePort = 0;
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) IPv6;
+}
+
+/**
+ Converts a text device path node to UART device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created UART device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUart (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *BaudStr;
+ CHAR16 *DataBitsStr;
+ CHAR16 *ParityStr;
+ CHAR16 *StopBitsStr;
+ UART_DEVICE_PATH *Uart;
+
+ BaudStr = GetNextParamStr (&TextDeviceNode);
+ DataBitsStr = GetNextParamStr (&TextDeviceNode);
+ ParityStr = GetNextParamStr (&TextDeviceNode);
+ StopBitsStr = GetNextParamStr (&TextDeviceNode);
+ Uart = (UART_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_UART_DP,
+ (UINT16) sizeof (UART_DEVICE_PATH)
+ );
+
+ if (StrCmp (BaudStr, "DEFAULT") == 0) {
+ Uart->BaudRate = 115200;
+ } else {
+ Strtoi64 (BaudStr, &Uart->BaudRate);
+ }
+ Uart->DataBits = (UINT8) ((StrCmp (DataBitsStr, "DEFAULT") == 0) ? 8 : Strtoi (DataBitsStr));
+ switch (*ParityStr) {
+ case 'D':
+ Uart->Parity = 0;
+ break;
+
+ case 'N':
+ Uart->Parity = 1;
+ break;
+
+ case 'E':
+ Uart->Parity = 2;
+ break;
+
+ case 'O':
+ Uart->Parity = 3;
+ break;
+
+ case 'M':
+ Uart->Parity = 4;
+ break;
+
+ case 'S':
+ Uart->Parity = 5;
+ break;
+
+ default:
+ Uart->Parity = (UINT8) Strtoi (ParityStr);
+ break;
+ }
+
+ if (StrCmp (StopBitsStr, "D") == 0) {
+ Uart->StopBits = (UINT8) 0;
+ } else if (StrCmp (StopBitsStr, "1") == 0) {
+ Uart->StopBits = (UINT8) 1;
+ } else if (StrCmp (StopBitsStr, "1.5") == 0) {
+ Uart->StopBits = (UINT8) 2;
+ } else if (StrCmp (StopBitsStr, "2") == 0) {
+ Uart->StopBits = (UINT8) 3;
+ } else {
+ Uart->StopBits = (UINT8) Strtoi (StopBitsStr);
+ }
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Uart;
+}
+
+/**
+ Converts a text device path node to USB class device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+ @param UsbClassText A pointer to USB_CLASS_TEXT structure to be integrated to USB Class Text.
+
+ @return A pointer to the newly-created USB class device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertFromTextUsbClass (
+ IN CHAR16 *TextDeviceNode,
+ IN USB_CLASS_TEXT *UsbClassText
+ )
+{
+ CHAR16 *VIDStr;
+ CHAR16 *PIDStr;
+ CHAR16 *ClassStr;
+ CHAR16 *SubClassStr;
+ CHAR16 *ProtocolStr;
+ USB_CLASS_DEVICE_PATH *UsbClass;
+
+ UsbClass = (USB_CLASS_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_USB_CLASS_DP,
+ (UINT16) sizeof (USB_CLASS_DEVICE_PATH)
+ );
+
+ VIDStr = GetNextParamStr (&TextDeviceNode);
+ PIDStr = GetNextParamStr (&TextDeviceNode);
+ if (UsbClassText->ClassExist) {
+ ClassStr = GetNextParamStr (&TextDeviceNode);
+ UsbClass->DeviceClass = (UINT8) Strtoi (ClassStr);
+ } else {
+ UsbClass->DeviceClass = UsbClassText->Class;
+ }
+ if (UsbClassText->SubClassExist) {
+ SubClassStr = GetNextParamStr (&TextDeviceNode);
+ UsbClass->DeviceSubClass = (UINT8) Strtoi (SubClassStr);
+ } else {
+ UsbClass->DeviceSubClass = UsbClassText->SubClass;
+ }
+
+ ProtocolStr = GetNextParamStr (&TextDeviceNode);
+
+ UsbClass->VendorId = (UINT16) Strtoi (VIDStr);
+ UsbClass->ProductId = (UINT16) Strtoi (PIDStr);
+ UsbClass->DeviceProtocol = (UINT8) Strtoi (ProtocolStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) UsbClass;
+}
+
+
+/**
+ Converts a text device path node to USB class device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB class device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbClass (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = TRUE;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB audio device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB audio device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbAudio (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_AUDIO;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB CDC Control device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB CDC Control device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbCDCControl (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_CDCCONTROL;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB HID device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB HID device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbHID (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_HID;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB Image device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB Image device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbImage (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_IMAGE;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB Print device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB Print device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbPrinter (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_PRINTER;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB mass storage device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB mass storage device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbMassStorage (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_MASS_STORAGE;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB HUB device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB HUB device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbHub (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_HUB;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB CDC data device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB CDC data device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbCDCData (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_CDCDATA;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB smart card device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB smart card device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbSmartCard (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_SMART_CARD;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB video device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB video device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbVideo (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_VIDEO;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB diagnostic device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB diagnostic device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbDiagnostic (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_DIAGNOSTIC;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB wireless device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB wireless device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbWireless (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_WIRELESS;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB device firmware update device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB device firmware update device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbDeviceFirmwareUpdate (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_RESERVE;
+ UsbClassText.SubClassExist = FALSE;
+ UsbClassText.SubClass = USB_SUBCLASS_FW_UPDATE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB IRDA bridge device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB IRDA bridge device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbIrdaBridge (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_RESERVE;
+ UsbClassText.SubClassExist = FALSE;
+ UsbClassText.SubClass = USB_SUBCLASS_IRDA_BRIDGE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB text and measurement device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB text and measurement device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbTestAndMeasurement (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_RESERVE;
+ UsbClassText.SubClassExist = FALSE;
+ UsbClassText.SubClass = USB_SUBCLASS_TEST;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB WWID device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB WWID device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbWwid (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *VIDStr;
+ CHAR16 *PIDStr;
+ CHAR16 *InterfaceNumStr;
+ CHAR16 *SerialNumberStr;
+ USB_WWID_DEVICE_PATH *UsbWwid;
+ UINTN SerialNumberStrLen;
+
+ VIDStr = GetNextParamStr (&TextDeviceNode);
+ PIDStr = GetNextParamStr (&TextDeviceNode);
+ InterfaceNumStr = GetNextParamStr (&TextDeviceNode);
+ SerialNumberStr = GetNextParamStr (&TextDeviceNode);
+ SerialNumberStrLen = StrLen (SerialNumberStr);
+ if (SerialNumberStrLen >= 2 &&
+ SerialNumberStr[0] == '\"' &&
+ SerialNumberStr[SerialNumberStrLen - 1] == '\"'
+ ) {
+ SerialNumberStr[SerialNumberStrLen - 1] = '\0';
+ SerialNumberStr++;
+ SerialNumberStrLen -= 2;
+ }
+ UsbWwid = (USB_WWID_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_USB_WWID_DP,
+ (UINT16) (sizeof (USB_WWID_DEVICE_PATH) + SerialNumberStrLen * sizeof (CHAR16))
+ );
+ UsbWwid->VendorId = (UINT16) Strtoi (VIDStr);
+ UsbWwid->ProductId = (UINT16) Strtoi (PIDStr);
+ UsbWwid->InterfaceNumber = (UINT16) Strtoi (InterfaceNumStr);
+
+ //
+ // There is no memory allocated in UsbWwid for the '\0' in SerialNumberStr.
+ // Therefore, the '\0' will not be copied.
+ //
+ CopyMem (
+ (UINT8 *) UsbWwid + sizeof (USB_WWID_DEVICE_PATH),
+ SerialNumberStr,
+ SerialNumberStrLen * sizeof (CHAR16)
+ );
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) UsbWwid;
+}
+
+/**
+ Converts a text device path node to Logic Unit device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Logic Unit device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUnit (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *LunStr;
+ DEVICE_LOGICAL_UNIT_DEVICE_PATH *LogicalUnit;
+
+ LunStr = GetNextParamStr (&TextDeviceNode);
+ LogicalUnit = (DEVICE_LOGICAL_UNIT_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_DEVICE_LOGICAL_UNIT_DP,
+ (UINT16) sizeof (DEVICE_LOGICAL_UNIT_DEVICE_PATH)
+ );
+
+ LogicalUnit->Lun = (UINT8) Strtoi (LunStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) LogicalUnit;
+}
+
+/**
+ Converts a text device path node to iSCSI device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created iSCSI device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextiSCSI (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ UINT16 Options;
+ CHAR16 *NameStr;
+ CHAR16 *PortalGroupStr;
+ CHAR16 *LunStr;
+ CHAR16 *HeaderDigestStr;
+ CHAR16 *DataDigestStr;
+ CHAR16 *AuthenticationStr;
+ CHAR16 *ProtocolStr;
+ CHAR8 *AsciiStr;
+ ISCSI_DEVICE_PATH_WITH_NAME *ISCSIDevPath;
+
+ NameStr = GetNextParamStr (&TextDeviceNode);
+ PortalGroupStr = GetNextParamStr (&TextDeviceNode);
+ LunStr = GetNextParamStr (&TextDeviceNode);
+ HeaderDigestStr = GetNextParamStr (&TextDeviceNode);
+ DataDigestStr = GetNextParamStr (&TextDeviceNode);
+ AuthenticationStr = GetNextParamStr (&TextDeviceNode);
+ ProtocolStr = GetNextParamStr (&TextDeviceNode);
+ ISCSIDevPath = (ISCSI_DEVICE_PATH_WITH_NAME *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_ISCSI_DP,
+ (UINT16) (sizeof (ISCSI_DEVICE_PATH_WITH_NAME) + StrLen (NameStr))
+ );
+
+ AsciiStr = ISCSIDevPath->TargetName;
+ StrToAscii (NameStr, &AsciiStr);
+
+ ISCSIDevPath->TargetPortalGroupTag = (UINT16) Strtoi (PortalGroupStr);
+ Strtoi64 (LunStr, &ISCSIDevPath->Lun);
+
+ Options = 0x0000;
+ if (StrCmp (HeaderDigestStr, "CRC32C") == 0) {
+ Options |= 0x0002;
+ }
+
+ if (StrCmp (DataDigestStr, "CRC32C") == 0) {
+ Options |= 0x0008;
+ }
+
+ if (StrCmp (AuthenticationStr, "None") == 0) {
+ Options |= 0x0800;
+ }
+
+ if (StrCmp (AuthenticationStr, "CHAP_UNI") == 0) {
+ Options |= 0x1000;
+ }
+
+ ISCSIDevPath->LoginOption = (UINT16) Options;
+
+ ISCSIDevPath->NetworkProtocol = (UINT16) StrCmp (ProtocolStr, "TCP");
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) ISCSIDevPath;
+}
+
+/**
+ Converts a text device path node to VLAN device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created VLAN device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVlan (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *VlanStr;
+ VLAN_DEVICE_PATH *Vlan;
+
+ VlanStr = GetNextParamStr (&TextDeviceNode);
+ Vlan = (VLAN_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VLAN_DP,
+ (UINT16) sizeof (VLAN_DEVICE_PATH)
+ );
+
+ Vlan->VlanId = (UINT16) Strtoi (VlanStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vlan;
+}
+
+/**
+ Converts a text device path node to Bluetooth device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Bluetooth device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextBluetooth (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *BluetoothStr;
+ CHAR16 *Walker;
+ CHAR16 *TempNumBuffer;
+ UINTN TempBufferSize;
+ INT32 Index;
+ BLUETOOTH_DEVICE_PATH *BluetoothDp;
+
+ BluetoothStr = GetNextParamStr (&TextDeviceNode);
+ BluetoothDp = (BLUETOOTH_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_BLUETOOTH_DP,
+ (UINT16) sizeof (BLUETOOTH_DEVICE_PATH)
+ );
+
+ Index = sizeof (BLUETOOTH_ADDRESS) - 1;
+ Walker = BluetoothStr;
+ while (!IS_NULL(*Walker) && Index >= 0) {
+ TempBufferSize = 2 * sizeof(CHAR16) + StrSize("0x");
+ TempNumBuffer = AllocateZeroPool (TempBufferSize);
+ if (TempNumBuffer == NULL) {
+ break;
+ }
+ StrCpyS (TempNumBuffer, TempBufferSize / sizeof (CHAR16), "0x");
+ StrnCatS (TempNumBuffer, TempBufferSize / sizeof (CHAR16), Walker, 2);
+ BluetoothDp->BD_ADDR.Address[Index] = (UINT8)Strtoi (TempNumBuffer);
+ FreePool (TempNumBuffer);
+ Walker += 2;
+ Index--;
+ }
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) BluetoothDp;
+}
+
+/**
+ Converts a text device path node to Wi-Fi device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Wi-Fi device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextWiFi (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *SSIdStr;
+ CHAR8 AsciiStr[33];
+ UINTN DataLen;
+ WIFI_DEVICE_PATH *WiFiDp;
+
+ SSIdStr = GetNextParamStr (&TextDeviceNode);
+ WiFiDp = (WIFI_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_WIFI_DP,
+ (UINT16) sizeof (WIFI_DEVICE_PATH)
+ );
+
+ if (NULL != SSIdStr) {
+ DataLen = StrLen (SSIdStr);
+ if (StrLen (SSIdStr) > 32) {
+ SSIdStr[32] = '\0';
+ DataLen = 32;
+ }
+
+ UnicodeStrToAsciiStrS (SSIdStr, AsciiStr, sizeof (AsciiStr));
+ CopyMem (WiFiDp->SSId, AsciiStr, DataLen);
+ }
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) WiFiDp;
+}
+
+/**
+ Converts a text device path node to URI device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created URI device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUri (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *UriStr;
+ UINTN UriLength;
+ URI_DEVICE_PATH *Uri;
+
+ UriStr = GetNextParamStr (&TextDeviceNode);
+ UriLength = StrnLenS (UriStr, MAX_UINT16 - sizeof (URI_DEVICE_PATH));
+ Uri = (URI_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_URI_DP,
+ (UINT16) (sizeof (URI_DEVICE_PATH) + UriLength)
+ );
+
+ while (UriLength-- != 0) {
+ Uri->Uri[UriLength] = (CHAR8) UriStr[UriLength];
+ }
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Uri;
+}
+
+/**
+ Converts a media text device path node to media device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to media device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextMediaPath (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ return DevPathFromTextGenericPath (MEDIA_DEVICE_PATH, TextDeviceNode);
+}
+
+/**
+ Converts a text device path node to HD device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created HD device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextHD (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *PartitionStr;
+ CHAR16 *TypeStr;
+ CHAR16 *SignatureStr;
+ CHAR16 *StartStr;
+ CHAR16 *SizeStr;
+ UINT32 Signature32;
+ HARDDRIVE_DEVICE_PATH *Hd;
+
+ PartitionStr = GetNextParamStr (&TextDeviceNode);
+ TypeStr = GetNextParamStr (&TextDeviceNode);
+ SignatureStr = GetNextParamStr (&TextDeviceNode);
+ StartStr = GetNextParamStr (&TextDeviceNode);
+ SizeStr = GetNextParamStr (&TextDeviceNode);
+ Hd = (HARDDRIVE_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_HARDDRIVE_DP,
+ (UINT16) sizeof (HARDDRIVE_DEVICE_PATH)
+ );
+
+ Hd->PartitionNumber = (UINT32) Strtoi (PartitionStr);
+
+ ZeroMem (Hd->Signature, 16);
+ Hd->MBRType = (UINT8) 0;
+
+ if (StrCmp (TypeStr, "MBR") == 0) {
+ Hd->SignatureType = SIGNATURE_TYPE_MBR;
+ Hd->MBRType = 0x01;
+
+ Signature32 = (UINT32) Strtoi (SignatureStr);
+ CopyMem (Hd->Signature, &Signature32, sizeof (UINT32));
+ } else if (StrCmp (TypeStr, "GPT") == 0) {
+ Hd->SignatureType = SIGNATURE_TYPE_GUID;
+ Hd->MBRType = 0x02;
+
+ StrToGuid (SignatureStr, (EFI_GUID *) Hd->Signature);
+ } else {
+ Hd->SignatureType = (UINT8) Strtoi (TypeStr);
+ }
+
+ Strtoi64 (StartStr, &Hd->PartitionStart);
+ Strtoi64 (SizeStr, &Hd->PartitionSize);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Hd;
+}
+
+/**
+ Converts a text device path node to CDROM device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created CDROM device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextCDROM (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *EntryStr;
+ CHAR16 *StartStr;
+ CHAR16 *SizeStr;
+ CDROM_DEVICE_PATH *CDROMDevPath;
+
+ EntryStr = GetNextParamStr (&TextDeviceNode);
+ StartStr = GetNextParamStr (&TextDeviceNode);
+ SizeStr = GetNextParamStr (&TextDeviceNode);
+ CDROMDevPath = (CDROM_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_CDROM_DP,
+ (UINT16) sizeof (CDROM_DEVICE_PATH)
+ );
+
+ CDROMDevPath->BootEntry = (UINT32) Strtoi (EntryStr);
+ Strtoi64 (StartStr, &CDROMDevPath->PartitionStart);
+ Strtoi64 (SizeStr, &CDROMDevPath->PartitionSize);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) CDROMDevPath;
+}
+
+/**
+ Converts a text device path node to Vendor-defined media device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Vendor-defined media device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenMedia (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextVendor (
+ TextDeviceNode,
+ MEDIA_DEVICE_PATH,
+ MEDIA_VENDOR_DP
+ );
+}
+
+/**
+ Converts a text device path node to File device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created File device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextFilePath (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ FILEPATH_DEVICE_PATH *File;
+
+#ifndef __FreeBSD__
+ File = (FILEPATH_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_FILEPATH_DP,
+ (UINT16) (sizeof (FILEPATH_DEVICE_PATH) + StrLen (TextDeviceNode) * 2)
+ );
+
+ StrCpyS (File->PathName, StrLen (TextDeviceNode) + 1, TextDeviceNode);
+#else
+ File = (FILEPATH_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_FILEPATH_DP,
+ (UINT16) (sizeof (FILEPATH_DEVICE_PATH) + StrLen (TextDeviceNode) + 1)
+ );
+
+ /*
+ * Note: We'd have to change the Tianocore header files to fix this
+ * to not need a cast. Instead we just cast it here. The Interface
+ * to the user may have issues since this won't be a UCS-2
+ * string. Also note that in the original code, a NUL wasn't
+ * allocated for the end of the string, but we copy that below. This
+ * has been corrected.
+ */
+ StrCpyS ((char *)File->PathName, StrLen (TextDeviceNode) + 1, TextDeviceNode);
+#endif
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) File;
+}
+
+/**
+ Converts a text device path node to Media protocol device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Media protocol device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextMedia (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *GuidStr;
+ MEDIA_PROTOCOL_DEVICE_PATH *Media;
+
+ GuidStr = GetNextParamStr (&TextDeviceNode);
+ Media = (MEDIA_PROTOCOL_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_PROTOCOL_DP,
+ (UINT16) sizeof (MEDIA_PROTOCOL_DEVICE_PATH)
+ );
+
+ StrToGuid (GuidStr, &Media->Protocol);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Media;
+}
+
+/**
+ Converts a text device path node to firmware volume device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created firmware volume device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextFv (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *GuidStr;
+ MEDIA_FW_VOL_DEVICE_PATH *Fv;
+
+ GuidStr = GetNextParamStr (&TextDeviceNode);
+ Fv = (MEDIA_FW_VOL_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_PIWG_FW_VOL_DP,
+ (UINT16) sizeof (MEDIA_FW_VOL_DEVICE_PATH)
+ );
+
+ StrToGuid (GuidStr, &Fv->FvName);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Fv;
+}
+
+/**
+ Converts a text device path node to firmware file device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created firmware file device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextFvFile (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *GuidStr;
+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFile;
+
+ GuidStr = GetNextParamStr (&TextDeviceNode);
+ FvFile = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_PIWG_FW_FILE_DP,
+ (UINT16) sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH)
+ );
+
+ StrToGuid (GuidStr, &FvFile->FvFileName);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) FvFile;
+}
+
+/**
+ Converts a text device path node to text relative offset device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Text device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextRelativeOffsetRange (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *StartingOffsetStr;
+ CHAR16 *EndingOffsetStr;
+ MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *Offset;
+
+ StartingOffsetStr = GetNextParamStr (&TextDeviceNode);
+ EndingOffsetStr = GetNextParamStr (&TextDeviceNode);
+ Offset = (MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_RELATIVE_OFFSET_RANGE_DP,
+ (UINT16) sizeof (MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH)
+ );
+
+ Strtoi64 (StartingOffsetStr, &Offset->StartingOffset);
+ Strtoi64 (EndingOffsetStr, &Offset->EndingOffset);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Offset;
+}
+
+/**
+ Converts a text device path node to text ram disk device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Text device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextRamDisk (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *StartingAddrStr;
+ CHAR16 *EndingAddrStr;
+ CHAR16 *TypeGuidStr;
+ CHAR16 *InstanceStr;
+ MEDIA_RAM_DISK_DEVICE_PATH *RamDisk;
+ UINT64 StartingAddr;
+ UINT64 EndingAddr;
+
+ StartingAddrStr = GetNextParamStr (&TextDeviceNode);
+ EndingAddrStr = GetNextParamStr (&TextDeviceNode);
+ InstanceStr = GetNextParamStr (&TextDeviceNode);
+ TypeGuidStr = GetNextParamStr (&TextDeviceNode);
+ RamDisk = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_RAM_DISK_DP,
+ (UINT16) sizeof (MEDIA_RAM_DISK_DEVICE_PATH)
+ );
+
+ Strtoi64 (StartingAddrStr, &StartingAddr);
+ WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr);
+ Strtoi64 (EndingAddrStr, &EndingAddr);
+ WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr);
+ RamDisk->Instance = (UINT16) Strtoi (InstanceStr);
+ StrToGuid (TypeGuidStr, &RamDisk->TypeGuid);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk;
+}
+
+/**
+ Converts a text device path node to text virtual disk device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Text device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVirtualDisk (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *StartingAddrStr;
+ CHAR16 *EndingAddrStr;
+ CHAR16 *InstanceStr;
+ MEDIA_RAM_DISK_DEVICE_PATH *RamDisk;
+ UINT64 StartingAddr;
+ UINT64 EndingAddr;
+
+ StartingAddrStr = GetNextParamStr (&TextDeviceNode);
+ EndingAddrStr = GetNextParamStr (&TextDeviceNode);
+ InstanceStr = GetNextParamStr (&TextDeviceNode);
+
+ RamDisk = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_RAM_DISK_DP,
+ (UINT16) sizeof (MEDIA_RAM_DISK_DEVICE_PATH)
+ );
+
+ Strtoi64 (StartingAddrStr, &StartingAddr);
+ WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr);
+ Strtoi64 (EndingAddrStr, &EndingAddr);
+ WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr);
+ RamDisk->Instance = (UINT16) Strtoi (InstanceStr);
+ CopyGuid (&RamDisk->TypeGuid, &gEfiVirtualDiskGuid);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk;
+}
+
+/**
+ Converts a text device path node to text virtual cd device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Text device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVirtualCd (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *StartingAddrStr;
+ CHAR16 *EndingAddrStr;
+ CHAR16 *InstanceStr;
+ MEDIA_RAM_DISK_DEVICE_PATH *RamDisk;
+ UINT64 StartingAddr;
+ UINT64 EndingAddr;
+
+ StartingAddrStr = GetNextParamStr (&TextDeviceNode);
+ EndingAddrStr = GetNextParamStr (&TextDeviceNode);
+ InstanceStr = GetNextParamStr (&TextDeviceNode);
+
+ RamDisk = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_RAM_DISK_DP,
+ (UINT16) sizeof (MEDIA_RAM_DISK_DEVICE_PATH)
+ );
+
+ Strtoi64 (StartingAddrStr, &StartingAddr);
+ WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr);
+ Strtoi64 (EndingAddrStr, &EndingAddr);
+ WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr);
+ RamDisk->Instance = (UINT16) Strtoi (InstanceStr);
+ CopyGuid (&RamDisk->TypeGuid, &gEfiVirtualCdGuid);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk;
+}
+
+/**
+ Converts a text device path node to text persistent virtual disk device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Text device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextPersistentVirtualDisk (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *StartingAddrStr;
+ CHAR16 *EndingAddrStr;
+ CHAR16 *InstanceStr;
+ MEDIA_RAM_DISK_DEVICE_PATH *RamDisk;
+ UINT64 StartingAddr;
+ UINT64 EndingAddr;
+
+ StartingAddrStr = GetNextParamStr (&TextDeviceNode);
+ EndingAddrStr = GetNextParamStr (&TextDeviceNode);
+ InstanceStr = GetNextParamStr (&TextDeviceNode);
+
+ RamDisk = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_RAM_DISK_DP,
+ (UINT16) sizeof (MEDIA_RAM_DISK_DEVICE_PATH)
+ );
+
+ Strtoi64 (StartingAddrStr, &StartingAddr);
+ WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr);
+ Strtoi64 (EndingAddrStr, &EndingAddr);
+ WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr);
+ RamDisk->Instance = (UINT16) Strtoi (InstanceStr);
+ CopyGuid (&RamDisk->TypeGuid, &gEfiPersistentVirtualDiskGuid);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk;
+}
+
+/**
+ Converts a text device path node to text persistent virtual cd device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Text device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextPersistentVirtualCd (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *StartingAddrStr;
+ CHAR16 *EndingAddrStr;
+ CHAR16 *InstanceStr;
+ MEDIA_RAM_DISK_DEVICE_PATH *RamDisk;
+ UINT64 StartingAddr;
+ UINT64 EndingAddr;
+
+ StartingAddrStr = GetNextParamStr (&TextDeviceNode);
+ EndingAddrStr = GetNextParamStr (&TextDeviceNode);
+ InstanceStr = GetNextParamStr (&TextDeviceNode);
+
+ RamDisk = (MEDIA_RAM_DISK_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_RAM_DISK_DP,
+ (UINT16) sizeof (MEDIA_RAM_DISK_DEVICE_PATH)
+ );
+
+ Strtoi64 (StartingAddrStr, &StartingAddr);
+ WriteUnaligned64 ((UINT64 *) &(RamDisk->StartingAddr[0]), StartingAddr);
+ Strtoi64 (EndingAddrStr, &EndingAddr);
+ WriteUnaligned64 ((UINT64 *) &(RamDisk->EndingAddr[0]), EndingAddr);
+ RamDisk->Instance = (UINT16) Strtoi (InstanceStr);
+ CopyGuid (&RamDisk->TypeGuid, &gEfiPersistentVirtualCdGuid);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) RamDisk;
+}
+
+/**
+ Converts a BBS text device path node to BBS device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to BBS device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextBbsPath (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ return DevPathFromTextGenericPath (BBS_DEVICE_PATH, TextDeviceNode);
+}
+
+/**
+ Converts a text device path node to BIOS Boot Specification device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created BIOS Boot Specification device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextBBS (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *TypeStr;
+ CHAR16 *IdStr;
+ CHAR16 *FlagsStr;
+ CHAR8 *AsciiStr;
+ BBS_BBS_DEVICE_PATH *Bbs;
+
+ TypeStr = GetNextParamStr (&TextDeviceNode);
+ IdStr = GetNextParamStr (&TextDeviceNode);
+ FlagsStr = GetNextParamStr (&TextDeviceNode);
+ Bbs = (BBS_BBS_DEVICE_PATH *) CreateDeviceNode (
+ BBS_DEVICE_PATH,
+ BBS_BBS_DP,
+ (UINT16) (sizeof (BBS_BBS_DEVICE_PATH) + StrLen (IdStr))
+ );
+
+ if (StrCmp (TypeStr, "Floppy") == 0) {
+ Bbs->DeviceType = BBS_TYPE_FLOPPY;
+ } else if (StrCmp (TypeStr, "HD") == 0) {
+ Bbs->DeviceType = BBS_TYPE_HARDDRIVE;
+ } else if (StrCmp (TypeStr, "CDROM") == 0) {
+ Bbs->DeviceType = BBS_TYPE_CDROM;
+ } else if (StrCmp (TypeStr, "PCMCIA") == 0) {
+ Bbs->DeviceType = BBS_TYPE_PCMCIA;
+ } else if (StrCmp (TypeStr, "USB") == 0) {
+ Bbs->DeviceType = BBS_TYPE_USB;
+ } else if (StrCmp (TypeStr, "Network") == 0) {
+ Bbs->DeviceType = BBS_TYPE_EMBEDDED_NETWORK;
+ } else {
+ Bbs->DeviceType = (UINT16) Strtoi (TypeStr);
+ }
+
+ AsciiStr = Bbs->String;
+ StrToAscii (IdStr, &AsciiStr);
+
+ Bbs->StatusFlag = (UINT16) Strtoi (FlagsStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Bbs;
+}
+
+/**
+ Converts a text device path node to SATA device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created SATA device path structure.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextSata (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ SATA_DEVICE_PATH *Sata;
+ CHAR16 *Param1;
+ CHAR16 *Param2;
+ CHAR16 *Param3;
+
+ Param1 = GetNextParamStr (&TextDeviceNode);
+ Param2 = GetNextParamStr (&TextDeviceNode);
+ Param3 = GetNextParamStr (&TextDeviceNode);
+
+ Sata = (SATA_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_SATA_DP,
+ (UINT16) sizeof (SATA_DEVICE_PATH)
+ );
+ Sata->HBAPortNumber = (UINT16) Strtoi (Param1);
+ Sata->PortMultiplierPortNumber = (UINT16) Strtoi (Param2);
+ Sata->Lun = (UINT16) Strtoi (Param3);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Sata;
+}
+
+GLOBAL_REMOVE_IF_UNREFERENCED DEVICE_PATH_FROM_TEXT_TABLE mUefiDevicePathLibDevPathFromTextTable[] = {
+ {"Path", DevPathFromTextPath },
+
+ {"HardwarePath", DevPathFromTextHardwarePath },
+ {"Pci", DevPathFromTextPci },
+ {"PcCard", DevPathFromTextPcCard },
+ {"MemoryMapped", DevPathFromTextMemoryMapped },
+ {"VenHw", DevPathFromTextVenHw },
+ {"Ctrl", DevPathFromTextCtrl },
+ {"BMC", DevPathFromTextBmc },
+
+ {"AcpiPath", DevPathFromTextAcpiPath },
+ {"Acpi", DevPathFromTextAcpi },
+ {"PciRoot", DevPathFromTextPciRoot },
+ {"PcieRoot", DevPathFromTextPcieRoot },
+ {"Floppy", DevPathFromTextFloppy },
+ {"Keyboard", DevPathFromTextKeyboard },
+ {"Serial", DevPathFromTextSerial },
+ {"ParallelPort", DevPathFromTextParallelPort },
+ {"AcpiEx", DevPathFromTextAcpiEx },
+ {"AcpiExp", DevPathFromTextAcpiExp },
+ {"AcpiAdr", DevPathFromTextAcpiAdr },
+
+ {"Msg", DevPathFromTextMsg },
+ {"Ata", DevPathFromTextAta },
+ {"Scsi", DevPathFromTextScsi },
+ {"Fibre", DevPathFromTextFibre },
+ {"FibreEx", DevPathFromTextFibreEx },
+ {"I1394", DevPathFromText1394 },
+ {"USB", DevPathFromTextUsb },
+ {"I2O", DevPathFromTextI2O },
+ {"Infiniband", DevPathFromTextInfiniband },
+ {"VenMsg", DevPathFromTextVenMsg },
+ {"VenPcAnsi", DevPathFromTextVenPcAnsi },
+ {"VenVt100", DevPathFromTextVenVt100 },
+ {"VenVt100Plus", DevPathFromTextVenVt100Plus },
+ {"VenUtf8", DevPathFromTextVenUtf8 },
+ {"UartFlowCtrl", DevPathFromTextUartFlowCtrl },
+ {"SAS", DevPathFromTextSAS },
+ {"SasEx", DevPathFromTextSasEx },
+ {"NVMe", DevPathFromTextNVMe },
+ {"UFS", DevPathFromTextUfs },
+ {"SD", DevPathFromTextSd },
+ {"eMMC", DevPathFromTextEmmc },
+ {"DebugPort", DevPathFromTextDebugPort },
+ {"MAC", DevPathFromTextMAC },
+ {"IPv4", DevPathFromTextIPv4 },
+ {"IPv6", DevPathFromTextIPv6 },
+ {"Uart", DevPathFromTextUart },
+ {"UsbClass", DevPathFromTextUsbClass },
+ {"UsbAudio", DevPathFromTextUsbAudio },
+ {"UsbCDCControl", DevPathFromTextUsbCDCControl },
+ {"UsbHID", DevPathFromTextUsbHID },
+ {"UsbImage", DevPathFromTextUsbImage },
+ {"UsbPrinter", DevPathFromTextUsbPrinter },
+ {"UsbMassStorage", DevPathFromTextUsbMassStorage },
+ {"UsbHub", DevPathFromTextUsbHub },
+ {"UsbCDCData", DevPathFromTextUsbCDCData },
+ {"UsbSmartCard", DevPathFromTextUsbSmartCard },
+ {"UsbVideo", DevPathFromTextUsbVideo },
+ {"UsbDiagnostic", DevPathFromTextUsbDiagnostic },
+ {"UsbWireless", DevPathFromTextUsbWireless },
+ {"UsbDeviceFirmwareUpdate", DevPathFromTextUsbDeviceFirmwareUpdate },
+ {"UsbIrdaBridge", DevPathFromTextUsbIrdaBridge },
+ {"UsbTestAndMeasurement", DevPathFromTextUsbTestAndMeasurement },
+ {"UsbWwid", DevPathFromTextUsbWwid },
+ {"Unit", DevPathFromTextUnit },
+ {"iSCSI", DevPathFromTextiSCSI },
+ {"Vlan", DevPathFromTextVlan },
+ {"Uri", DevPathFromTextUri },
+ {"Bluetooth", DevPathFromTextBluetooth },
+ {"Wi-Fi", DevPathFromTextWiFi },
+ {"MediaPath", DevPathFromTextMediaPath },
+ {"HD", DevPathFromTextHD },
+ {"CDROM", DevPathFromTextCDROM },
+ {"VenMedia", DevPathFromTextVenMedia },
+ {"Media", DevPathFromTextMedia },
+ {"Fv", DevPathFromTextFv },
+ {"FvFile", DevPathFromTextFvFile },
+ {"Offset", DevPathFromTextRelativeOffsetRange },
+ {"RamDisk", DevPathFromTextRamDisk },
+ {"VirtualDisk", DevPathFromTextVirtualDisk },
+ {"VirtualCD", DevPathFromTextVirtualCd },
+ {"PersistentVirtualDisk", DevPathFromTextPersistentVirtualDisk },
+ {"PersistentVirtualCD", DevPathFromTextPersistentVirtualCd },
+
+ {"BbsPath", DevPathFromTextBbsPath },
+ {"BBS", DevPathFromTextBBS },
+ {"Sata", DevPathFromTextSata },
+ {NULL, NULL}
+};
+
+/**
+ Convert text to the binary representation of a device node.
+
+ @param TextDeviceNode TextDeviceNode points to the text representation of a device
+ node. Conversion starts with the first character and continues
+ until the first non-device node character.
+
+ @return A pointer to the EFI device node or NULL if TextDeviceNode is NULL or there was
+ insufficient memory or text unsupported.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+UefiDevicePathLibConvertTextToDeviceNode (
+ IN CONST CHAR16 *TextDeviceNode
+ )
+{
+ DEVICE_PATH_FROM_TEXT FromText;
+ CHAR16 *ParamStr;
+ EFI_DEVICE_PATH_PROTOCOL *DeviceNode;
+ CHAR16 *DeviceNodeStr;
+ UINTN Index;
+
+ if ((TextDeviceNode == NULL) || (IS_NULL (*TextDeviceNode))) {
+ return NULL;
+ }
+
+ ParamStr = NULL;
+ FromText = NULL;
+ DeviceNodeStr = UefiDevicePathLibStrDuplicate (TextDeviceNode);
+ ASSERT (DeviceNodeStr != NULL);
+
+ for (Index = 0; mUefiDevicePathLibDevPathFromTextTable[Index].Function != NULL; Index++) {
+ ParamStr = GetParamByNodeName (DeviceNodeStr, mUefiDevicePathLibDevPathFromTextTable[Index].DevicePathNodeText);
+ if (ParamStr != NULL) {
+ FromText = mUefiDevicePathLibDevPathFromTextTable[Index].Function;
+ break;
+ }
+ }
+
+ if (FromText == NULL) {
+ //
+ // A file path
+ //
+ FromText = DevPathFromTextFilePath;
+ DeviceNode = FromText (DeviceNodeStr);
+ } else {
+ DeviceNode = FromText (ParamStr);
+ FreePool (ParamStr);
+ }
+
+ FreePool (DeviceNodeStr);
+
+ return DeviceNode;
+}
+
+/**
+ Convert text to the binary representation of a device path.
+
+
+ @param TextDevicePath TextDevicePath points to the text representation of a device
+ path. Conversion starts with the first character and continues
+ until the first non-device node character.
+
+ @return A pointer to the allocated device path or NULL if TextDeviceNode is NULL or
+ there was insufficient memory.
+
+**/
+static
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+UefiDevicePathLibConvertTextToDevicePath (
+ IN CONST CHAR16 *TextDevicePath
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL *DeviceNode;
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
+ CHAR16 *DevicePathStr;
+ CHAR16 *Str;
+ CHAR16 *DeviceNodeStr;
+ BOOLEAN IsInstanceEnd;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ if ((TextDevicePath == NULL) || (IS_NULL (*TextDevicePath))) {
+ return NULL;
+ }
+
+ DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocatePool (END_DEVICE_PATH_LENGTH);
+ ASSERT (DevicePath != NULL);
+ SetDevicePathEndNode (DevicePath);
+
+ DevicePathStr = UefiDevicePathLibStrDuplicate (TextDevicePath);
+
+ Str = DevicePathStr;
+ while ((DeviceNodeStr = GetNextDeviceNodeStr (&Str, &IsInstanceEnd)) != NULL) {
+ DeviceNode = UefiDevicePathLibConvertTextToDeviceNode (DeviceNodeStr);
+
+ NewDevicePath = AppendDevicePathNode (DevicePath, DeviceNode);
+ FreePool (DevicePath);
+ FreePool (DeviceNode);
+ DevicePath = NewDevicePath;
+
+ if (IsInstanceEnd) {
+ DeviceNode = (EFI_DEVICE_PATH_PROTOCOL *) AllocatePool (END_DEVICE_PATH_LENGTH);
+ ASSERT (DeviceNode != NULL);
+ SetDevicePathEndNode (DeviceNode);
+ // Fix from https://bugzilla.tianocore.org/show_bug.cgi?id=419
+ DeviceNode->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE;
+
+ NewDevicePath = AppendDevicePathNode (DevicePath, DeviceNode);
+ FreePool (DevicePath);
+ FreePool (DeviceNode);
+ DevicePath = NewDevicePath;
+ }
+ }
+
+ FreePool (DevicePathStr);
+ return DevicePath;
+}
+
+ssize_t
+efidp_parse_device_path(char *path, efidp out, size_t max)
+{
+ EFI_DEVICE_PATH_PROTOCOL *dp;
+ UINTN len;
+
+ dp = UefiDevicePathLibConvertTextToDevicePath (path);
+ if (dp == NULL)
+ return -1;
+ len = GetDevicePathSize(dp);
+ if (len > max) {
+ free(dp);
+ return -1;
+ }
+ memcpy(out, dp, len);
+ free(dp);
+
+ return len;
+}
diff --git a/lib/libefivar/efivar-dp.h b/lib/libefivar/efivar-dp.h
new file mode 100644
index 0000000..94dd118
--- /dev/null
+++ b/lib/libefivar/efivar-dp.h
@@ -0,0 +1,65 @@
+/*-
+ * 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 _EFIVAR_DP_H_
+#define _EFIVAR_DP_H_
+
+/*
+ * "Linux compatible" efivar-dp.h header. At the moment, it's really a
+ * very thin, minimal interface.
+ */
+
+/*
+ * Generic EFI_DEVICE_PATH, spelled the Linux way. We use this
+ * interface to the outside world and type-pun to the EFI EDK2 code
+ * we use to implement it.
+ */
+typedef struct {
+ uint8_t type;
+ uint8_t subtype;
+ uint16_t length;
+} __packed efidp_header;
+
+/* NB: Linux has shadow types for all dp type */
+
+typedef union {
+ efidp_header header;
+} efidp_data;
+typedef efidp_data *efidp;
+typedef const efidp_data *const_efidp;
+
+/** format a device path into UEFI standard conforming output.
+ *
+ * NB: FreeBSD's implementation is taken from EDK2, while Linux's
+ * was hand-rolled. There may be differences as a result.
+ */
+ssize_t efidp_format_device_path(char *buf, size_t len, const_efidp dp,
+ ssize_t max);
+ssize_t efidp_parse_device_path(char *path, efidp out, size_t max);
+
+#endif /* _EFIVAR_DP_H_ */
diff --git a/lib/libefivar/efivar.3 b/lib/libefivar/efivar.3
new file mode 100644
index 0000000..4d1d504
--- /dev/null
+++ b/lib/libefivar/efivar.3
@@ -0,0 +1,98 @@
+.\" Copyright 2016 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.
+.\" 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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$
+.\"
+.Dd September 14, 2016
+.Dt LIBEFIVAR 3
+.Os
+.Sh NAME
+.Nm libefivar
+.Nd EFI Non Volatile Variable Suppoert
+.Sh SYNOPSIS
+.In efivar.h
+.Ft int
+.Fn efi_append_variable "efi_guid_t guid" "const char *name" "void *data" "size_t data_size" "uint32_t attributes"
+.Ft int
+.Fn efi_del_variable "efi_guid_t guid" "const char *name"
+.Ft int
+.Fn efi_get_variable "efi_guid_t guid" "const char *name" "void **data" "ssize_t *data_size" "uint32_t *attributes"
+.Ft int
+.Fn efi_get_variable_attributes "efi_guid_t guid" "const char *name" "uint32_t *attributes"
+.Ft int
+.Fn efi_get_variable_size "efi_guid_t guid" "const char *name" "size_t *size"
+.Ft int
+.Fn efi_get_next_variable_name "efi_guid_t **guid" "char **name"
+.Ft int
+.Fn efi_guid_to_name "efi_guid_t *guid" "char **name"
+.Ft int
+.Fn efi_guid_to_symbol "efi_guid_t *guid" "char **symbol"
+.Ft int
+.Fn efi_guid_to_str "const efi_guid_t *guid" "char **sp"
+.Ft int
+.Fn efi_name_to_guid "const char *name" "efi_guid_t *guid"
+.Ft int
+.Fn efi_set_variable "efi_guid_t guid" "const char *name" "void *data" "size_t data_size" "uint32_t attributes"
+.Ft int
+.Fn efi_str_to_guid "const char *s" "efi_guid_t *guid";
+.Ft int
+.Fn efi_variables_supported "void";
+.Sh DESCRIPTION
+The
+.Nm
+library implements access to EFI Variables via the EFI Runtime
+Serivces.
+All char * strings are converted to 16-bit UTF strings before passing
+them to EFI.
+.Pp
+.Fn efi_variables_supported
+returns non-zero if the current machine supports setting of EFI firmware
+variables and the kernel support for doing so is present.
+Otherwise zero is returned.
+.Pp
+.Fn efi_del_variable
+deletes the EFI variable selected by
+.Dv guid
+and
+.Dv name .
+.Pp
+.Fn efi_get_variable
+.Fn efi_get_variable_attributes
+.Fn efi_get_variable_size
+.Fn efi_append_variable
+.Fn efi_set_variable
+.Fn efi_get_next_variable_name
+.Fn efi_str_to_guid
+.Fn efi_guid_to_str
+.Fn efi_name_to_guid
+.Fn efi_guid_to_name
+.Fn efi_guid_to_symbol
+This function is not actually implemented.
+.Sh BUGS
+No facilities exist to process the strings as native UTF.
+This is a limitation in the Linux libefivar library interface.
+.Sh AUTHORS
+.An -nosplit
+This software was originally written by
+.An Warner Losh .
diff --git a/lib/libefivar/efivar.c b/lib/libefivar/efivar.c
new file mode 100644
index 0000000..bce4a14
--- /dev/null
+++ b/lib/libefivar/efivar.c
@@ -0,0 +1,391 @@
+/*-
+ * Copyright (c) 2016 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.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <efivar.h>
+#include <sys/efiio.h>
+#include <sys/param.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "efichar.h"
+
+static int efi_fd = -2;
+
+#define Z { 0, 0, 0, 0, 0, { 0 } }
+
+const efi_guid_t efi_guid_empty = Z;
+
+static struct uuid_table guid_tbl [] =
+{
+ { "00000000-0000-0000-0000-000000000000", "zero", Z },
+ { "093e0fae-a6c4-4f50-9f1b-d41e2b89c19a", "sha512", Z },
+ { "0abba7dc-e516-4167-bbf5-4d9d1c739416", "redhat", Z },
+ { "0b6e5233-a65c-44c9-9407-d9ab83bfc8bd", "sha224", Z },
+ { "126a762d-5758-4fca-8531-201a7f57f850", "lenovo_boot_menu", Z },
+ { "3bd2a492-96c0-4079-b420-fcf98ef103ed", "x509_sha256", Z },
+ { "3c5766e8-269c-4e34-aa14-ed776e85b3b6", "rsa2048", Z },
+ { "3CC24E96-22C7-41D8-8863-8E39DCDCC2CF", "lenovo", Z },
+ { "3f7e615b-0d45-4f80-88dc-26b234958560", "lenovo_diag", Z },
+ { "446dbf63-2502-4cda-bcfa-2465d2b0fe9d", "x509_sha512", Z },
+ { "4aafd29d-68df-49ee-8aa9-347d375665a7", "pkcs7_cert", Z },
+ { "605dab50-e046-4300-abb6-3dd810dd8b23", "shim", Z },
+ { "665d3f60-ad3e-4cad-8e26-db46eee9f1b5", "lenovo_rescue", Z },
+ { "67f8444f-8743-48f1-a328-1eaab8736080", "rsa2048_sha1", Z },
+ { "7076876e-80c2-4ee6-aad2-28b349a6865b", "x509_sha384", Z },
+ { "721c8b66-426c-4e86-8e99-3457c46ab0b9", "lenovo_setup", Z },
+ { "77fa9abd-0359-4d32-bd60-28f4e78f784b", "microsoft", Z },
+ { "7FACC7B6-127F-4E9C-9C5D-080F98994345", "lenovo_2", Z },
+ { "826ca512-cf10-4ac9-b187-be01496631bd", "sha1", Z },
+ { "82988420-7467-4490-9059-feb448dd1963", "lenovo_me_config", Z },
+ { "8be4df61-93ca-11d2-aa0d-00e098032b8c", "global", Z },
+ { "a5c059a1-94e4-4aa7-87b5-ab155c2bf072", "x509_cert", Z },
+ { "a7717414-c616-4977-9420-844712a735bf", "rsa2048_sha256_cert", Z },
+ { "a7d8d9a6-6ab0-4aeb-ad9d-163e59a7a380", "lenovo_diag_splash", Z },
+ { "ade9e48f-9cb8-98e6-31af-b4e6009e2fe3", "redhat_2", Z },
+ { "bc7838d2-0f82-4d60-8316-c068ee79d25b", "lenovo_msg", Z },
+ { "c1c41626-504c-4092-aca9-41f936934328", "sha256", Z },
+ { "c57ad6b7-0515-40a8-9d21-551652854e37", "shell", Z },
+ { "d719b2cb-3d3a-4596-a3bc-dad00e67656f", "security", Z },
+ { "e2b36190-879b-4a3d-ad8d-f2e7bba32784", "rsa2048_sha256", Z },
+ { "ff3e5307-9fd0-48c9-85f1-8ad56c701e01", "sha384", Z },
+ { "f46ee6f4-4785-43a3-923d-7f786c3c8479", "lenovo_startup_interrupt", Z },
+ { "ffffffff-ffff-ffff-ffff-ffffffffffff", "zzignore-this-guid", Z },
+};
+#undef Z
+
+static void
+efi_guid_tbl_compile(void)
+{
+ size_t i;
+ uint32_t status;
+ static int done = 0;
+
+ if (done)
+ return;
+ for (i = 0; i < nitems(guid_tbl); i++) {
+ uuid_from_string(guid_tbl[i].uuid_str, &guid_tbl[i].guid,
+ &status);
+ /* all f's is a bad version, so ignore that error */
+ if (status != uuid_s_ok && status != uuid_s_bad_version)
+ fprintf(stderr, "Can't convert %s to a uuid for %s: %d\n",
+ guid_tbl[i].uuid_str, guid_tbl[i].name, (int)status);
+ }
+ done = 1;
+}
+
+int
+efi_known_guid(struct uuid_table **tbl)
+{
+
+ *tbl = guid_tbl;
+ return (nitems(guid_tbl));
+}
+
+static int
+efi_open_dev(void)
+{
+
+ if (efi_fd == -2)
+ efi_fd = open("/dev/efi", O_RDWR);
+ if (efi_fd < 0)
+ efi_fd = -1;
+ else
+ efi_guid_tbl_compile();
+ return (efi_fd);
+}
+
+static void
+efi_var_reset(struct efi_var_ioc *var)
+{
+ var->name = NULL;
+ var->namesize = 0;
+ memset(&var->vendor, 0, sizeof(var->vendor));
+ var->attrib = 0;
+ var->data = NULL;
+ var->datasize = 0;
+}
+
+static int
+rv_to_linux_rv(int rv)
+{
+ if (rv == 0)
+ rv = 1;
+ else
+ rv = -errno;
+ return (rv);
+}
+
+int
+efi_append_variable(efi_guid_t guid, const char *name,
+ uint8_t *data, size_t data_size, uint32_t attributes)
+{
+
+ return efi_set_variable(guid, name, data, data_size,
+ attributes | EFI_VARIABLE_APPEND_WRITE, 0);
+}
+
+int
+efi_del_variable(efi_guid_t guid, const char *name)
+{
+
+ /* data_size of 0 deletes the variable */
+ return efi_set_variable(guid, name, NULL, 0, 0, 0);
+}
+
+int
+efi_get_variable(efi_guid_t guid, const char *name,
+ uint8_t **data, size_t *data_size, uint32_t *attributes)
+{
+ struct efi_var_ioc var;
+ int rv;
+ static uint8_t buf[1024*32];
+
+ if (efi_open_dev() == -1)
+ return -1;
+
+ efi_var_reset(&var);
+ rv = utf8_to_ucs2(name, &var.name, &var.namesize);
+ if (rv != 0)
+ goto errout;
+ var.vendor = guid;
+ var.data = buf;
+ var.datasize = sizeof(buf);
+ rv = ioctl(efi_fd, EFIIOC_VAR_GET, &var);
+ if (data_size != NULL)
+ *data_size = var.datasize;
+ if (data != NULL)
+ *data = buf;
+ if (attributes != NULL)
+ *attributes = var.attrib;
+errout:
+ free(var.name);
+
+ return rv_to_linux_rv(rv);
+}
+
+int
+efi_get_variable_attributes(efi_guid_t guid, const char *name,
+ uint32_t *attributes)
+{
+ /* Make sure this construct works -- I think it will fail */
+
+ return efi_get_variable(guid, name, NULL, NULL, attributes);
+}
+
+int
+efi_get_variable_size(efi_guid_t guid, const char *name,
+ size_t *size)
+{
+
+ /* XXX check to make sure this matches the linux value */
+
+ *size = 0;
+ return efi_get_variable(guid, name, NULL, size, NULL);
+}
+
+int
+efi_get_next_variable_name(efi_guid_t **guid, char **name)
+{
+ struct efi_var_ioc var;
+ int rv;
+ static efi_char *buf;
+ static size_t buflen = 256 * sizeof(efi_char);
+ static efi_guid_t retguid;
+ size_t size;
+
+ if (efi_open_dev() == -1)
+ return -1;
+
+ if (buf == NULL)
+ buf = malloc(buflen);
+
+again:
+ efi_var_reset(&var);
+ var.name = buf;
+ var.namesize = buflen;
+ if (*name == NULL) {
+ *buf = 0;
+ /* GUID zeroed in var_reset */
+ } else {
+ rv = utf8_to_ucs2(*name, &var.name, &size);
+ if (rv != 0)
+ goto errout;
+ var.vendor = **guid;
+ }
+ rv = ioctl(efi_fd, EFIIOC_VAR_NEXT, &var);
+ if (rv == 0 && var.name == NULL) {
+ /*
+ * oops, too little space. Try again.
+ */
+ void *new = realloc(buf, buflen);
+ buflen = var.namesize;
+ if (new == NULL) {
+ rv = -1;
+ errno = ENOMEM;
+ goto done;
+ }
+ buf = new;
+ goto again;
+ }
+
+ if (rv == 0) {
+ *name = NULL; /* XXX */
+ var.name[var.namesize / sizeof(efi_char)] = 0; /* EFI doesn't NUL terminate */
+ rv = ucs2_to_utf8(var.name, name);
+ if (rv != 0)
+ goto errout;
+ retguid = var.vendor;
+ *guid = &retguid;
+ }
+errout:
+
+ /* XXX The linux interface expects name to be a static buffer -- fix or leak memory? */
+done:
+ if (errno == ENOENT) {
+ errno = 0;
+ return 0;
+ }
+
+ return (rv_to_linux_rv(rv));
+}
+
+int
+efi_guid_cmp(const efi_guid_t *guid1, const efi_guid_t *guid2)
+{
+ uint32_t status;
+
+ return uuid_compare(guid1, guid2, &status);
+}
+
+int
+efi_guid_is_zero(const efi_guid_t *guid)
+{
+ uint32_t status;
+
+ return uuid_is_nil(guid, &status);
+}
+
+int
+efi_guid_to_name(efi_guid_t *guid, char **name)
+{
+ size_t i;
+ uint32_t status;
+
+ efi_guid_tbl_compile();
+ for (i = 0; i < nitems(guid_tbl); i++) {
+ if (uuid_equal(guid, &guid_tbl[i].guid, &status)) {
+ *name = strdup(guid_tbl[i].name);
+ return (0);
+ }
+ }
+ return (efi_guid_to_str(guid, name));
+}
+
+int
+efi_guid_to_symbol(efi_guid_t *guid __unused, char **symbol __unused)
+{
+
+ /*
+ * Unsure what this is used for, efibootmgr doesn't use it.
+ * Leave unimplemented for now.
+ */
+ return -1;
+}
+
+int
+efi_guid_to_str(const efi_guid_t *guid, char **sp)
+{
+ uint32_t status;
+
+ /* knows efi_guid_t is a typedef of uuid_t */
+ uuid_to_string(guid, sp, &status);
+
+ return (status == uuid_s_ok ? 0 : -1);
+}
+
+int
+efi_name_to_guid(const char *name, efi_guid_t *guid)
+{
+ size_t i;
+
+ efi_guid_tbl_compile();
+ for (i = 0; i < nitems(guid_tbl); i++) {
+ if (strcmp(name, guid_tbl[i].name) == 0) {
+ *guid = guid_tbl[i].guid;
+ return (0);
+ }
+ }
+ return (efi_str_to_guid(name, guid));
+}
+
+int
+efi_set_variable(efi_guid_t guid, const char *name,
+ uint8_t *data, size_t data_size, uint32_t attributes, mode_t mode __unused)
+{
+ struct efi_var_ioc var;
+ int rv;
+
+ if (efi_open_dev() == -1)
+ return -1;
+
+ efi_var_reset(&var);
+ rv = utf8_to_ucs2(name, &var.name, &var.namesize);
+ if (rv != 0)
+ goto errout;
+ var.vendor = guid;
+ var.data = data;
+ var.datasize = data_size;
+ var.attrib = attributes;
+ rv = ioctl(efi_fd, EFIIOC_VAR_SET, &var);
+errout:
+ free(var.name);
+
+ return rv;
+}
+
+int
+efi_str_to_guid(const char *s, efi_guid_t *guid)
+{
+ uint32_t status;
+
+ /* knows efi_guid_t is a typedef of uuid_t */
+ uuid_from_string(s, guid, &status);
+
+ return (status == uuid_s_ok ? 0 : -1);
+}
+
+int
+efi_variables_supported(void)
+{
+
+ return efi_open_dev() != -1;
+}
diff --git a/lib/libefivar/efivar.h b/lib/libefivar/efivar.h
new file mode 100644
index 0000000..cba8a8e
--- /dev/null
+++ b/lib/libefivar/efivar.h
@@ -0,0 +1,135 @@
+/*-
+ * Copyright (c) 2016 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 _EFIVAR_H_
+#define _EFIVAR_H_
+
+#include <uuid.h>
+#include <sys/efi.h>
+#include <sys/endian.h>
+#include <stdint.h>
+
+/* Shoud these be elsewhere ? */
+#define EFI_VARIABLE_NON_VOLATILE 0x00000001
+#define EFI_VARIABLE_BOOTSERVICE_ACCESS 0x00000002
+#define EFI_VARIABLE_RUNTIME_ACCESS 0x00000004
+#define EFI_VARIABLE_HARDWARE_ERROR_RECORD 0x00000008
+#define EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS 0x00000010
+#define EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS \
+ 0x00000020
+#define EFI_VARIABLE_APPEND_WRITE 0x00000040
+#if 0 /* todo */
+#define EFI_VARIABLE_HAS_AUTH_HEADER
+#define EFI_VARIABLE_HAS_SIGNATURE
+#endif
+
+
+#ifndef _EFIVAR_EFI_GUID_T_DEF
+#define _EFIVAR_EFI_GUID_T_DEF
+typedef uuid_t efi_guid_t;
+#endif
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define EFI_GUID(a, b, c, d, e0, e1, e2, e3, e4, e5) \
+ ((efi_guid_t) {(a), (b), (c), (d) >> 8, (d) & 0xff, \
+ { (e0), (e1), (e2), (e3), (e4), (e5) }})
+#else
+#define EFI_GUID(a, b, c, d, e0, e1, e2, e3, e4, e5) \
+ ((efi_guid_t) {(a), (b), (c), (d) & 0xff, (d) >> 8, \
+ { (e0), (e1), (e2), (e3), (e4), (e5) }})
+#endif
+
+#define EFI_GLOBAL_GUID EFI_GUID(0x8be4df61, 0x93ca, 0x11d2, 0xaa0d, \
+ 0x00, 0xe0, 0x98, 0x03, 0x2b, 0x8c)
+
+int efi_append_variable(efi_guid_t guid, const char *name,
+ uint8_t *data, size_t data_size, uint32_t attributes);
+int efi_del_variable(efi_guid_t guid, const char *name);
+int efi_get_variable(efi_guid_t guid, const char *name,
+ uint8_t **data, size_t *data_size, uint32_t *attributes);
+int efi_get_variable_attributes(efi_guid_t guid, const char *name,
+ uint32_t *attributes);
+int efi_get_variable_size(efi_guid_t guid, const char *name, size_t *size);
+int efi_get_next_variable_name(efi_guid_t **guid, char **name);
+int efi_guid_cmp(const efi_guid_t *guid1, const efi_guid_t *guid2);
+int efi_guid_is_zero(const efi_guid_t *guid1);
+int efi_guid_to_name(efi_guid_t *guid, char **name);
+int efi_guid_to_symbol(efi_guid_t *guid, char **symbol);
+int efi_guid_to_str(const efi_guid_t *guid, char **sp);
+int efi_name_to_guid(const char *name, efi_guid_t *guid);
+int efi_set_variable(efi_guid_t guid, const char *name,
+ uint8_t *data, size_t data_size, uint32_t attributes, mode_t mode);
+int efi_str_to_guid(const char *s, efi_guid_t *guid);
+int efi_variables_supported(void);
+
+/* FreeBSD extensions */
+struct uuid_table
+{
+ const char *uuid_str;
+ const char *name;
+ efi_guid_t guid;
+};
+
+int efi_known_guid(struct uuid_table **);
+
+extern const efi_guid_t efi_guid_empty;
+
+/* Stubs that are expected, but aren't really used */
+static inline int
+efi_error_get(unsigned int n __unused, char ** const fn __unused,
+ char ** const func __unused, int *line __unused,
+ char ** const msg __unused, int *err __unused)
+{
+ return 0;
+}
+
+static inline int
+efi_error_set(const char *fn __unused, const char *func __unused,
+ int line __unused, int err __unused, const char *fmt __unused, ...)
+{
+ return 0;
+}
+
+static inline void
+efi_error_clear(void)
+{
+}
+
+static inline int
+efi_error(const char *fmt __unused, ...)
+{
+ return 0;
+}
+
+static inline int
+efi_error_val(int val __unused, const char *fmt __unused, ...)
+{
+ return 0;
+}
+
+#endif /* _EFIVAR_H_ */
diff --git a/lib/libefivar/uefi-dplib.h b/lib/libefivar/uefi-dplib.h
new file mode 100644
index 0000000..a7d3b72
--- /dev/null
+++ b/lib/libefivar/uefi-dplib.h
@@ -0,0 +1,635 @@
+/*-
+ * 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$
+ */
+
+/*
+ * Taken from MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.h
+ * hash a11928f3310518ab1c6fd34e8d0fdbb72de9602c 2017-Mar-01
+ */
+
+/** @file
+ Definition for Device Path library.
+
+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.
+
+**/
+
+#ifndef _UEFI_DEVICE_PATH_LIB_H_
+#define _UEFI_DEVICE_PATH_LIB_H_
+#include <Uefi.h>
+#include <Protocol/DevicePathUtilities.h>
+#include <Protocol/DebugPort.h>
+#include <Protocol/DevicePathToText.h>
+#include <Protocol/DevicePathFromText.h>
+#include <Guid/PcAnsi.h>
+#include <Library/DebugLib.h>
+#include <Library/PrintLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/PcdLib.h>
+#include <IndustryStandard/Bluetooth.h>
+
+#define IS_COMMA(a) ((a) == ',')
+#define IS_HYPHEN(a) ((a) == '-')
+#define IS_DOT(a) ((a) == '.')
+#define IS_LEFT_PARENTH(a) ((a) == '(')
+#define IS_RIGHT_PARENTH(a) ((a) == ')')
+#define IS_SLASH(a) ((a) == '/')
+#define IS_NULL(a) ((a) == '\0')
+
+
+//
+// Private Data structure
+//
+typedef struct {
+ char *Str;
+ UINTN Count;
+ UINTN Capacity;
+} POOL_PRINT;
+
+typedef
+EFI_DEVICE_PATH_PROTOCOL *
+(*DEVICE_PATH_FROM_TEXT) (
+ IN char *Str
+ );
+
+typedef
+VOID
+(*DEVICE_PATH_TO_TEXT) (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevicePath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ );
+
+typedef struct {
+ UINT8 Type;
+ UINT8 SubType;
+ DEVICE_PATH_TO_TEXT Function;
+} DEVICE_PATH_TO_TEXT_TABLE;
+
+typedef struct {
+ UINT8 Type;
+ const char *Text;
+} DEVICE_PATH_TO_TEXT_GENERIC_TABLE;
+
+typedef struct {
+ const char *DevicePathNodeText;
+ DEVICE_PATH_FROM_TEXT Function;
+} DEVICE_PATH_FROM_TEXT_TABLE;
+
+typedef struct {
+ BOOLEAN ClassExist;
+ UINT8 Class;
+ BOOLEAN SubClassExist;
+ UINT8 SubClass;
+} USB_CLASS_TEXT;
+
+#define USB_CLASS_AUDIO 1
+#define USB_CLASS_CDCCONTROL 2
+#define USB_CLASS_HID 3
+#define USB_CLASS_IMAGE 6
+#define USB_CLASS_PRINTER 7
+#define USB_CLASS_MASS_STORAGE 8
+#define USB_CLASS_HUB 9
+#define USB_CLASS_CDCDATA 10
+#define USB_CLASS_SMART_CARD 11
+#define USB_CLASS_VIDEO 14
+#define USB_CLASS_DIAGNOSTIC 220
+#define USB_CLASS_WIRELESS 224
+
+#define USB_CLASS_RESERVE 254
+#define USB_SUBCLASS_FW_UPDATE 1
+#define USB_SUBCLASS_IRDA_BRIDGE 2
+#define USB_SUBCLASS_TEST 3
+
+#define RFC_1700_UDP_PROTOCOL 17
+#define RFC_1700_TCP_PROTOCOL 6
+
+#pragma pack(1)
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ EFI_GUID Guid;
+ UINT8 VendorDefinedData[1];
+} VENDOR_DEFINED_HARDWARE_DEVICE_PATH;
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ EFI_GUID Guid;
+ UINT8 VendorDefinedData[1];
+} VENDOR_DEFINED_MESSAGING_DEVICE_PATH;
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ EFI_GUID Guid;
+ UINT8 VendorDefinedData[1];
+} VENDOR_DEFINED_MEDIA_DEVICE_PATH;
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT32 Hid;
+ UINT32 Uid;
+ UINT32 Cid;
+ CHAR8 HidUidCidStr[3];
+} ACPI_EXTENDED_HID_DEVICE_PATH_WITH_STR;
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT16 NetworkProtocol;
+ UINT16 LoginOption;
+ UINT64 Lun;
+ UINT16 TargetPortalGroupTag;
+ CHAR8 TargetName[1];
+} ISCSI_DEVICE_PATH_WITH_NAME;
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ EFI_GUID Guid;
+ UINT8 VendorDefinedData[1];
+} VENDOR_DEVICE_PATH_WITH_DATA;
+
+#pragma pack()
+
+#ifdef FreeBSD /* Remove these on FreeBSD */
+
+/**
+ Returns the size of a device path in bytes.
+
+ This function returns the size, in bytes, of the device path data structure
+ specified by DevicePath including the end of device path node.
+ If DevicePath is NULL or invalid, then 0 is returned.
+
+ @param DevicePath A pointer to a device path data structure.
+
+ @retval 0 If DevicePath is NULL or invalid.
+ @retval Others The size of a device path in bytes.
+
+**/
+UINTN
+EFIAPI
+UefiDevicePathLibGetDevicePathSize (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+/**
+ Creates a new copy of an existing device path.
+
+ This function allocates space for a new copy of the device path specified by DevicePath.
+ If DevicePath is NULL, then NULL is returned. If the memory is successfully
+ allocated, then the contents of DevicePath are copied to the newly allocated
+ buffer, and a pointer to that buffer is returned. Otherwise, NULL is returned.
+ The memory for the new device path is allocated from EFI boot services memory.
+ It is the responsibility of the caller to free the memory allocated.
+
+ @param DevicePath A pointer to a device path data structure.
+
+ @retval NULL DevicePath is NULL or invalid.
+ @retval Others A pointer to the duplicated device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+UefiDevicePathLibDuplicateDevicePath (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+/**
+ Creates a new device path by appending a second device path to a first device path.
+
+ This function creates a new device path by appending a copy of SecondDevicePath
+ to a copy of FirstDevicePath in a newly allocated buffer. Only the end-of-device-path
+ device node from SecondDevicePath is retained. The newly created device path is
+ returned. If FirstDevicePath is NULL, then it is ignored, and a duplicate of
+ SecondDevicePath is returned. If SecondDevicePath is NULL, then it is ignored,
+ and a duplicate of FirstDevicePath is returned. If both FirstDevicePath and
+ SecondDevicePath are NULL, then a copy of an end-of-device-path is returned.
+
+ If there is not enough memory for the newly allocated buffer, then NULL is returned.
+ The memory for the new device path is allocated from EFI boot services memory.
+ It is the responsibility of the caller to free the memory allocated.
+
+ @param FirstDevicePath A pointer to a device path data structure.
+ @param SecondDevicePath A pointer to a device path data structure.
+
+ @retval NULL If there is not enough memory for the newly allocated buffer.
+ @retval NULL If FirstDevicePath or SecondDevicePath is invalid.
+ @retval Others A pointer to the new device path if success.
+ Or a copy an end-of-device-path if both FirstDevicePath and SecondDevicePath are NULL.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+UefiDevicePathLibAppendDevicePath (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath, OPTIONAL
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath OPTIONAL
+ );
+
+/**
+ Creates a new path by appending the device node to the device path.
+
+ This function creates a new device path by appending a copy of the device node
+ specified by DevicePathNode to a copy of the device path specified by DevicePath
+ in an allocated buffer. The end-of-device-path device node is moved after the
+ end of the appended device node.
+ If DevicePathNode is NULL then a copy of DevicePath is returned.
+ If DevicePath is NULL then a copy of DevicePathNode, followed by an end-of-device
+ path device node is returned.
+ If both DevicePathNode and DevicePath are NULL then a copy of an end-of-device-path
+ device node is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+
+ @param DevicePath A pointer to a device path data structure.
+ @param DevicePathNode A pointer to a single device path node.
+
+ @retval NULL If there is not enough memory for the new device path.
+ @retval Others A pointer to the new device path if success.
+ A copy of DevicePathNode followed by an end-of-device-path node
+ if both FirstDevicePath and SecondDevicePath are NULL.
+ A copy of an end-of-device-path node if both FirstDevicePath
+ and SecondDevicePath are NULL.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+UefiDevicePathLibAppendDevicePathNode (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL
+ );
+
+/**
+ Creates a new device path by appending the specified device path instance to the specified device
+ path.
+
+ This function creates a new device path by appending a copy of the device path
+ instance specified by DevicePathInstance to a copy of the device path specified
+ by DevicePath in a allocated buffer.
+ The end-of-device-path device node is moved after the end of the appended device
+ path instance and a new end-of-device-path-instance node is inserted between.
+ If DevicePath is NULL, then a copy if DevicePathInstance is returned.
+ If DevicePathInstance is NULL, then NULL is returned.
+ If DevicePath or DevicePathInstance is invalid, then NULL is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+
+ @param DevicePath A pointer to a device path data structure.
+ @param DevicePathInstance A pointer to a device path instance.
+
+ @return A pointer to the new device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+UefiDevicePathLibAppendDevicePathInstance (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance OPTIONAL
+ );
+
+/**
+ Creates a copy of the current device path instance and returns a pointer to the next device path
+ instance.
+
+ This function creates a copy of the current device path instance. It also updates
+ DevicePath to point to the next device path instance in the device path (or NULL
+ if no more) and updates Size to hold the size of the device path instance copy.
+ If DevicePath is NULL, then NULL is returned.
+ If DevicePath points to a invalid device path, then NULL is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+ If Size is NULL, then ASSERT().
+
+ @param DevicePath On input, this holds the pointer to the current
+ device path instance. On output, this holds
+ the pointer to the next device path instance
+ or NULL if there are no more device path
+ instances in the device path pointer to a
+ device path data structure.
+ @param Size On output, this holds the size of the device
+ path instance, in bytes or zero, if DevicePath
+ is NULL.
+
+ @return A pointer to the current device path instance.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+UefiDevicePathLibGetNextDevicePathInstance (
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,
+ OUT UINTN *Size
+ );
+
+/**
+ Creates a device node.
+
+ This function creates a new device node in a newly allocated buffer of size
+ NodeLength and initializes the device path node header with NodeType and NodeSubType.
+ The new device path node is returned.
+ If NodeLength is smaller than a device path header, then NULL is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+
+ @param NodeType The device node type for the new device node.
+ @param NodeSubType The device node sub-type for the new device node.
+ @param NodeLength The length of the new device node.
+
+ @return The new device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+UefiDevicePathLibCreateDeviceNode (
+ IN UINT8 NodeType,
+ IN UINT8 NodeSubType,
+ IN UINT16 NodeLength
+ );
+
+/**
+ Determines if a device path is single or multi-instance.
+
+ This function returns TRUE if the device path specified by DevicePath is
+ multi-instance.
+ Otherwise, FALSE is returned.
+ If DevicePath is NULL or invalid, then FALSE is returned.
+
+ @param DevicePath A pointer to a device path data structure.
+
+ @retval TRUE DevicePath is multi-instance.
+ @retval FALSE DevicePath is not multi-instance, or DevicePath
+ is NULL or invalid.
+
+**/
+BOOLEAN
+EFIAPI
+UefiDevicePathLibIsDevicePathMultiInstance (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+
+/**
+ Converts a device path to its text representation.
+
+ @param DevicePath A Pointer to the device to be converted.
+ @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.
+
+ @return A pointer to the allocated text representation of the device path or
+ NULL if DeviceNode is NULL or there was insufficient memory.
+
+**/
+CHAR16 *
+EFIAPI
+UefiDevicePathLibConvertDevicePathToText (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ );
+
+/**
+ Converts a device node to its string representation.
+
+ @param DeviceNode A Pointer to the device node to be converted.
+ @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.
+
+ @return A pointer to the allocated text representation of the device node or NULL if DeviceNode
+ is NULL or there was insufficient memory.
+
+**/
+CHAR16 *
+EFIAPI
+UefiDevicePathLibConvertDeviceNodeToText (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ );
+
+/**
+ Convert text to the binary representation of a device node.
+
+ @param TextDeviceNode TextDeviceNode points to the text representation of a device
+ node. Conversion starts with the first character and continues
+ until the first non-device node character.
+
+ @return A pointer to the EFI device node or NULL if TextDeviceNode is NULL or there was
+ insufficient memory or text unsupported.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+UefiDevicePathLibConvertTextToDeviceNode (
+ IN CONST CHAR16 *TextDeviceNode
+ );
+
+/**
+ Convert text to the binary representation of a device path.
+
+
+ @param TextDevicePath TextDevicePath points to the text representation of a device
+ path. Conversion starts with the first character and continues
+ until the first non-device node character.
+
+ @return A pointer to the allocated device path or NULL if TextDeviceNode is NULL or
+ there was insufficient memory.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+UefiDevicePathLibConvertTextToDevicePath (
+ IN CONST CHAR16 *TextDevicePath
+ );
+#else
+
+/*
+ * Small FreeBSD shim layer. Fast and lose hacks to make this code work with FreeBSD.
+ */
+
+#include <ctype.h>
+
+#define _PCD_GET_MODE_32_PcdMaximumDevicePathNodeCount 1000
+#define MAX_UINTN UINTPTR_MAX
+
+#define AllocatePool(x) malloc(x)
+#define AllocateZeroPool(x) calloc(1,x)
+#define AsciiStrLen(s) strlen(s)
+#define CopyGuid(dst, src) memcpy(dst, src, sizeof(uuid_t))
+#define CopyMem(d, s, l) memcpy(d, s, l)
+#define FreePool(x) free(x)
+#define LShiftU64(x, s) ((x) << s)
+#define ReadUnaligned64(x) le64dec(x)
+#define ReallocatePool(old, new, ptr) realloc(ptr, new)
+/*
+ * Quirky StrCmp returns 0 if equal, 1 if not. This is what the code
+ * expects, though that expectation is likely a bug (it casts the
+ * return value. EDK2's StrCmp returns values just like C's strcmp,
+ * but the parse code casts this to an UINTN, which is bogus. This
+ * definition papers over that bogusness to do the right thing. If
+ * iSCSI protocol string processing is ever fixed, we can remove this
+ * bletcherous kludge.
+ */
+#define StrCmp(a, b) (strcmp(a, b) != 0)
+#define StrCpyS(d, l, s) strcpy(d, s)
+#define StrHexToUint64(x) strtoll(x, NULL, 16)
+#define StrHexToUintn(x) strtoll(x, NULL, 16)
+#define StrLen(x) strlen(x)
+#define StrSize(x) (strlen(x) + 1)
+#define StrnCatS(d, l, s, len) strncat(d, s, len)
+#define StrnCmp(a, b, n) strncmp(a, b, n)
+#define StrnLenS(str, max) strlen(str)
+#define Strtoi(x) strtol(x, NULL, 0)
+#define Strtoi64(x, y) *(long long *)y = strtoll(x, NULL, 0)
+#define SwapBytes64(u64) bswap64(u64)
+#define UnicodeStrToAsciiStrS(src, dest, len) strlcpy(dest, src, len)
+#define ZeroMem(p,l) memset(p, 0, l)
+
+#undef ASSERT
+#define ASSERT(x)
+
+/*
+ * Define AllocateCopyPool and others so that we "forget" about the
+ * previous non-static deifnition since we want these to be static
+ * inlines.
+ */
+#define AllocateCopyPool AllocateCopyPoolFreeBSD
+#define CompareGuid CompareGuidFreeBSD
+#define StrHexToBytes StrHexToBytesFreeBSD
+#define StrToGuid StrToGuidFreeBSD
+#define WriteUnaligned64 WriteUnaligned64FreeBSD
+
+static inline void *
+AllocateCopyPool(size_t l, const void *p)
+{
+ void *rv;
+
+ rv = malloc(l);
+ if (rv == NULL)
+ return NULL;
+ memcpy(rv, p, l);
+ return (rv);
+}
+
+static inline BOOLEAN
+CompareGuid (const GUID *g1, const GUID *g2)
+{
+ uint32_t ignored_status;
+
+ return (uuid_compare((const uuid_t *)g1, (const uuid_t *)g2,
+ &ignored_status) == 0);
+}
+
+static inline int
+StrHexToBytes(const char *str, size_t len, uint8_t *buf, size_t buflen)
+{
+ size_t i;
+ char hex[3];
+
+ /*
+ * Sanity check preconditions.
+ */
+ if (buflen != len / 2 || (len % 1) == 1)
+ return 1;
+ for (i = 0; i < len; i += 2) {
+ if (!isxdigit(str[i]) || !isxdigit(str[i + 1]))
+ return 1;
+ hex[0] = str[i];
+ hex[1] = str[i + 1];
+ hex[2] = '\0';
+ buf[i / 2] = strtol(hex, NULL, 16);
+ }
+ return 0;
+}
+
+static inline void
+StrToGuid(const char *str, GUID *guid)
+{
+ uint32_t status;
+
+ uuid_from_string(str, (uuid_t *)guid, &status);
+}
+
+static inline void
+WriteUnaligned64(void *ptr, uint64_t val)
+{
+ memcpy(ptr, &val, sizeof(val));
+}
+
+/*
+ * Hack to allow converting %g to %s in printfs. Hack because
+ * it's single entry, uses a static buffer, etc. Sufficient for
+ * the day for this file though. IF you ever have to convert
+ * two %g's in one format, punt. Did I mention this was super lame.
+ * Not to mention it's name.... Also, the error GUID is horrific.
+ */
+static inline const char *
+guid_str(const GUID *g)
+{
+ static char buf[36 + 1];
+ char *str = NULL;
+ int32_t ignored_status;
+
+ uuid_to_string((const uuid_t *)g, &str, &ignored_status);
+ if (str != NULL)
+ strlcpy(buf, str, sizeof(buf));
+ else
+ strlcpy(buf, "groot-cannot-decode-guid-groot-smash",
+ sizeof(buf)); /* ^^^^^^^ 36 characters ^^^^^^^ */
+ free(str);
+ return buf;
+}
+#define G(x) guid_str((const GUID *)(const void *)x)
+#endif
+
+#undef GLOBAL_REMOVE_IF_UNREFERENCED
+#define GLOBAL_REMOVE_IF_UNREFERENCED static
+
+#endif
diff --git a/lib/libefivar/uefi-dputil.c b/lib/libefivar/uefi-dputil.c
new file mode 100644
index 0000000..670ba9d
--- /dev/null
+++ b/lib/libefivar/uefi-dputil.c
@@ -0,0 +1,636 @@
+/*-
+ * 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 <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/endian.h>
+
+#include "efi-osdep.h"
+
+#include "uefi-dplib.h"
+
+/* XXX maybe I sould include the entire DevicePathUtiltiies.c and ifdef out what we don't use */
+
+/*
+ * Taken from MdePkg/Library/UefiDevicePathLib/DevicePathUtilities.c
+ * hash a11928f3310518ab1c6fd34e8d0fdbb72de9602c 2017-Mar-01
+ */
+
+/** @file
+ Device Path services. The thing to remember is device paths are built out of
+ nodes. The device path is terminated by an end node that is length
+ sizeof(EFI_DEVICE_PATH_PROTOCOL). That would be why there is sizeof(EFI_DEVICE_PATH_PROTOCOL)
+ all over this file.
+
+ The only place where multi-instance device paths are supported is in
+ environment varibles. Multi-instance device paths should never be placed
+ on a Handle.
+
+ Copyright (c) 2006 - 2016, 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.
+
+**/
+
+//
+// Template for an end-of-device path node.
+//
+static CONST EFI_DEVICE_PATH_PROTOCOL mUefiDevicePathLibEndDevicePath = {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ END_DEVICE_PATH_LENGTH,
+ 0
+ }
+};
+
+
+/**
+ Returns the size of a device path in bytes.
+
+ This function returns the size, in bytes, of the device path data structure
+ specified by DevicePath including the end of device path node.
+ If DevicePath is NULL or invalid, then 0 is returned.
+
+ @param DevicePath A pointer to a device path data structure.
+
+ @retval 0 If DevicePath is NULL or invalid.
+ @retval Others The size of a device path in bytes.
+
+**/
+UINTN
+EFIAPI
+GetDevicePathSize (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+{
+ CONST EFI_DEVICE_PATH_PROTOCOL *Start;
+
+ if (DevicePath == NULL) {
+ return 0;
+ }
+
+ if (!IsDevicePathValid (DevicePath, 0)) {
+ return 0;
+ }
+
+ //
+ // Search for the end of the device path structure
+ //
+ Start = DevicePath;
+ while (!IsDevicePathEnd (DevicePath)) {
+ DevicePath = NextDevicePathNode (DevicePath);
+ }
+
+ //
+ // Compute the size and add back in the size of the end device path structure
+ //
+ return ((UINTN) DevicePath - (UINTN) Start) + DevicePathNodeLength (DevicePath);
+}
+
+/**
+ Determine whether a given device path is valid.
+ If DevicePath is NULL, then ASSERT().
+
+ @param DevicePath A pointer to a device path data structure.
+ @param MaxSize The maximum size of the device path data structure.
+
+ @retval TRUE DevicePath is valid.
+ @retval FALSE The length of any node node in the DevicePath is less
+ than sizeof (EFI_DEVICE_PATH_PROTOCOL).
+ @retval FALSE If MaxSize is not zero, the size of the DevicePath
+ exceeds MaxSize.
+ @retval FALSE If PcdMaximumDevicePathNodeCount is not zero, the node
+ count of the DevicePath exceeds PcdMaximumDevicePathNodeCount.
+**/
+BOOLEAN
+EFIAPI
+IsDevicePathValid (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN UINTN MaxSize
+ )
+{
+ UINTN Count;
+ UINTN Size;
+ UINTN NodeLength;
+
+ ASSERT (DevicePath != NULL);
+
+ if (MaxSize == 0) {
+ MaxSize = MAX_UINTN;
+ }
+
+ //
+ // Validate the input size big enough to touch the first node.
+ //
+ if (MaxSize < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
+ return FALSE;
+ }
+
+ for (Count = 0, Size = 0; !IsDevicePathEnd (DevicePath); DevicePath = NextDevicePathNode (DevicePath)) {
+ NodeLength = DevicePathNodeLength (DevicePath);
+ if (NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
+ return FALSE;
+ }
+
+ if (NodeLength > MAX_UINTN - Size) {
+ return FALSE;
+ }
+ Size += NodeLength;
+
+ //
+ // Validate next node before touch it.
+ //
+ if (Size > MaxSize - END_DEVICE_PATH_LENGTH ) {
+ return FALSE;
+ }
+
+ if (PcdGet32 (PcdMaximumDevicePathNodeCount) > 0) {
+ Count++;
+ if (Count >= PcdGet32 (PcdMaximumDevicePathNodeCount)) {
+ return FALSE;
+ }
+ }
+ }
+
+ //
+ // Only return TRUE when the End Device Path node is valid.
+ //
+ return (BOOLEAN) (DevicePathNodeLength (DevicePath) == END_DEVICE_PATH_LENGTH);
+}
+
+/**
+ Returns the Type field of a device path node.
+
+ Returns the Type field of the device path node specified by Node.
+
+ If Node is NULL, then ASSERT().
+
+ @param Node A pointer to a device path node data structure.
+
+ @return The Type field of the device path node specified by Node.
+
+**/
+UINT8
+EFIAPI
+DevicePathType (
+ IN CONST VOID *Node
+ )
+{
+ ASSERT (Node != NULL);
+ return ((const EFI_DEVICE_PATH_PROTOCOL *)(Node))->Type;
+}
+
+
+/**
+ Returns the SubType field of a device path node.
+
+ Returns the SubType field of the device path node specified by Node.
+
+ If Node is NULL, then ASSERT().
+
+ @param Node A pointer to a device path node data structure.
+
+ @return The SubType field of the device path node specified by Node.
+
+**/
+UINT8
+EFIAPI
+DevicePathSubType (
+ IN CONST VOID *Node
+ )
+{
+ ASSERT (Node != NULL);
+ return ((const EFI_DEVICE_PATH_PROTOCOL *)(Node))->SubType;
+}
+
+/**
+ Returns the 16-bit Length field of a device path node.
+
+ Returns the 16-bit Length field of the device path node specified by Node.
+ Node is not required to be aligned on a 16-bit boundary, so it is recommended
+ that a function such as ReadUnaligned16() be used to extract the contents of
+ the Length field.
+
+ If Node is NULL, then ASSERT().
+
+ @param Node A pointer to a device path node data structure.
+
+ @return The 16-bit Length field of the device path node specified by Node.
+
+**/
+UINTN
+EFIAPI
+DevicePathNodeLength (
+ IN CONST VOID *Node
+ )
+{
+ ASSERT (Node != NULL);
+ return ((const EFI_DEVICE_PATH_PROTOCOL *)Node)->Length[0] |
+ (((const EFI_DEVICE_PATH_PROTOCOL *)Node)->Length[1] << 8);
+}
+
+/**
+ Returns a pointer to the next node in a device path.
+
+ Returns a pointer to the device path node that follows the device path node
+ specified by Node.
+
+ If Node is NULL, then ASSERT().
+
+ @param Node A pointer to a device path node data structure.
+
+ @return a pointer to the device path node that follows the device path node
+ specified by Node.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+NextDevicePathNode (
+ IN CONST VOID *Node
+ )
+{
+ ASSERT (Node != NULL);
+ return ((EFI_DEVICE_PATH_PROTOCOL *)(__DECONST(UINT8 *, Node) + DevicePathNodeLength(Node)));
+}
+
+/**
+ Determines if a device path node is an end node of a device path.
+ This includes nodes that are the end of a device path instance and nodes that
+ are the end of an entire device path.
+
+ Determines if the device path node specified by Node is an end node of a device path.
+ This includes nodes that are the end of a device path instance and nodes that are the
+ end of an entire device path. If Node represents an end node of a device path,
+ then TRUE is returned. Otherwise, FALSE is returned.
+
+ If Node is NULL, then ASSERT().
+
+ @param Node A pointer to a device path node data structure.
+
+ @retval TRUE The device path node specified by Node is an end node of a
+ device path.
+ @retval FALSE The device path node specified by Node is not an end node of
+ a device path.
+
+**/
+BOOLEAN
+EFIAPI
+IsDevicePathEndType (
+ IN CONST VOID *Node
+ )
+{
+ ASSERT (Node != NULL);
+ return (BOOLEAN) (DevicePathType (Node) == END_DEVICE_PATH_TYPE);
+}
+
+/**
+ Determines if a device path node is an end node of an entire device path.
+
+ Determines if a device path node specified by Node is an end node of an entire
+ device path. If Node represents the end of an entire device path, then TRUE is
+ returned. Otherwise, FALSE is returned.
+
+ If Node is NULL, then ASSERT().
+
+ @param Node A pointer to a device path node data structure.
+
+ @retval TRUE The device path node specified by Node is the end of an entire
+ device path.
+ @retval FALSE The device path node specified by Node is not the end of an
+ entire device path.
+
+**/
+BOOLEAN
+EFIAPI
+IsDevicePathEnd (
+ IN CONST VOID *Node
+ )
+{
+ ASSERT (Node != NULL);
+ return (BOOLEAN) (IsDevicePathEndType (Node) && DevicePathSubType(Node) == END_ENTIRE_DEVICE_PATH_SUBTYPE);
+}
+
+/**
+ Fills in all the fields of a device path node that is the end of an entire device path.
+
+ Fills in all the fields of a device path node specified by Node so Node represents
+ the end of an entire device path. The Type field of Node is set to
+ END_DEVICE_PATH_TYPE, the SubType field of Node is set to
+ END_ENTIRE_DEVICE_PATH_SUBTYPE, and the Length field of Node is set to
+ END_DEVICE_PATH_LENGTH. Node is not required to be aligned on a 16-bit boundary,
+ so it is recommended that a function such as WriteUnaligned16() be used to set
+ the contents of the Length field.
+
+ If Node is NULL, then ASSERT().
+
+ @param Node A pointer to a device path node data structure.
+
+**/
+VOID
+EFIAPI
+SetDevicePathEndNode (
+ OUT VOID *Node
+ )
+{
+ ASSERT (Node != NULL);
+ memcpy (Node, &mUefiDevicePathLibEndDevicePath, sizeof (mUefiDevicePathLibEndDevicePath));
+}
+
+/**
+ Sets the length, in bytes, of a device path node.
+
+ Sets the length of the device path node specified by Node to the value specified
+ by NodeLength. NodeLength is returned. Node is not required to be aligned on
+ a 16-bit boundary, so it is recommended that a function such as WriteUnaligned16()
+ be used to set the contents of the Length field.
+
+ If Node is NULL, then ASSERT().
+ If NodeLength >= SIZE_64KB, then ASSERT().
+ If NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL), then ASSERT().
+
+ @param Node A pointer to a device path node data structure.
+ @param Length The length, in bytes, of the device path node.
+
+ @return Length
+
+**/
+UINT16
+EFIAPI
+SetDevicePathNodeLength (
+ IN OUT VOID *Node,
+ IN UINTN Length
+ )
+{
+ ASSERT (Node != NULL);
+ ASSERT ((Length >= sizeof (EFI_DEVICE_PATH_PROTOCOL)) && (Length < SIZE_64KB));
+// return WriteUnaligned16 ((UINT16 *)&((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Length[0], (UINT16)(Length));
+ le16enc(&((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Length[0], (UINT16)(Length));
+ return Length;
+}
+
+/**
+ Creates a device node.
+
+ This function creates a new device node in a newly allocated buffer of size
+ NodeLength and initializes the device path node header with NodeType and NodeSubType.
+ The new device path node is returned.
+ If NodeLength is smaller than a device path header, then NULL is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+
+ @param NodeType The device node type for the new device node.
+ @param NodeSubType The device node sub-type for the new device node.
+ @param NodeLength The length of the new device node.
+
+ @return The new device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+CreateDeviceNode (
+ IN UINT8 NodeType,
+ IN UINT8 NodeSubType,
+ IN UINT16 NodeLength
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ if (NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
+ //
+ // NodeLength is less than the size of the header.
+ //
+ return NULL;
+ }
+
+ DevicePath = AllocateZeroPool (NodeLength);
+ if (DevicePath != NULL) {
+ DevicePath->Type = NodeType;
+ DevicePath->SubType = NodeSubType;
+ SetDevicePathNodeLength (DevicePath, NodeLength);
+ }
+
+ return DevicePath;
+}
+
+/**
+ Creates a new copy of an existing device path.
+
+ This function allocates space for a new copy of the device path specified by DevicePath.
+ If DevicePath is NULL, then NULL is returned. If the memory is successfully
+ allocated, then the contents of DevicePath are copied to the newly allocated
+ buffer, and a pointer to that buffer is returned. Otherwise, NULL is returned.
+ The memory for the new device path is allocated from EFI boot services memory.
+ It is the responsibility of the caller to free the memory allocated.
+
+ @param DevicePath A pointer to a device path data structure.
+
+ @retval NULL DevicePath is NULL or invalid.
+ @retval Others A pointer to the duplicated device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+DuplicateDevicePath (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+{
+ UINTN Size;
+
+ //
+ // Compute the size
+ //
+ Size = GetDevicePathSize (DevicePath);
+ if (Size == 0) {
+ return NULL;
+ }
+
+ //
+ // Allocate space for duplicate device path
+ //
+
+ return AllocateCopyPool (Size, DevicePath);
+}
+
+/**
+ Creates a new device path by appending a second device path to a first device path.
+
+ This function creates a new device path by appending a copy of SecondDevicePath
+ to a copy of FirstDevicePath in a newly allocated buffer. Only the end-of-device-path
+ device node from SecondDevicePath is retained. The newly created device path is
+ returned. If FirstDevicePath is NULL, then it is ignored, and a duplicate of
+ SecondDevicePath is returned. If SecondDevicePath is NULL, then it is ignored,
+ and a duplicate of FirstDevicePath is returned. If both FirstDevicePath and
+ SecondDevicePath are NULL, then a copy of an end-of-device-path is returned.
+
+ If there is not enough memory for the newly allocated buffer, then NULL is returned.
+ The memory for the new device path is allocated from EFI boot services memory.
+ It is the responsibility of the caller to free the memory allocated.
+
+ @param FirstDevicePath A pointer to a device path data structure.
+ @param SecondDevicePath A pointer to a device path data structure.
+
+ @retval NULL If there is not enough memory for the newly allocated buffer.
+ @retval NULL If FirstDevicePath or SecondDevicePath is invalid.
+ @retval Others A pointer to the new device path if success.
+ Or a copy an end-of-device-path if both FirstDevicePath and SecondDevicePath are NULL.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+AppendDevicePath (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath, OPTIONAL
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath OPTIONAL
+ )
+{
+ UINTN Size;
+ UINTN Size1;
+ UINTN Size2;
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath2;
+
+ //
+ // If there's only 1 path, just duplicate it.
+ //
+ if (FirstDevicePath == NULL) {
+ return DuplicateDevicePath ((SecondDevicePath != NULL) ? SecondDevicePath : &mUefiDevicePathLibEndDevicePath);
+ }
+
+ if (SecondDevicePath == NULL) {
+ return DuplicateDevicePath (FirstDevicePath);
+ }
+
+ if (!IsDevicePathValid (FirstDevicePath, 0) || !IsDevicePathValid (SecondDevicePath, 0)) {
+ return NULL;
+ }
+
+ //
+ // Allocate space for the combined device path. It only has one end node of
+ // length EFI_DEVICE_PATH_PROTOCOL.
+ //
+ Size1 = GetDevicePathSize (FirstDevicePath);
+ Size2 = GetDevicePathSize (SecondDevicePath);
+ Size = Size1 + Size2 - END_DEVICE_PATH_LENGTH;
+
+ NewDevicePath = AllocatePool (Size);
+
+ if (NewDevicePath != NULL) {
+ NewDevicePath = CopyMem (NewDevicePath, FirstDevicePath, Size1);
+ //
+ // Over write FirstDevicePath EndNode and do the copy
+ //
+ DevicePath2 = (EFI_DEVICE_PATH_PROTOCOL *) ((CHAR8 *) NewDevicePath +
+ (Size1 - END_DEVICE_PATH_LENGTH));
+ CopyMem (DevicePath2, SecondDevicePath, Size2);
+ }
+
+ return NewDevicePath;
+}
+
+/**
+ Creates a new path by appending the device node to the device path.
+
+ This function creates a new device path by appending a copy of the device node
+ specified by DevicePathNode to a copy of the device path specified by DevicePath
+ in an allocated buffer. The end-of-device-path device node is moved after the
+ end of the appended device node.
+ If DevicePathNode is NULL then a copy of DevicePath is returned.
+ If DevicePath is NULL then a copy of DevicePathNode, followed by an end-of-device
+ path device node is returned.
+ If both DevicePathNode and DevicePath are NULL then a copy of an end-of-device-path
+ device node is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+
+ @param DevicePath A pointer to a device path data structure.
+ @param DevicePathNode A pointer to a single device path node.
+
+ @retval NULL If there is not enough memory for the new device path.
+ @retval Others A pointer to the new device path if success.
+ A copy of DevicePathNode followed by an end-of-device-path node
+ if both FirstDevicePath and SecondDevicePath are NULL.
+ A copy of an end-of-device-path node if both FirstDevicePath
+ and SecondDevicePath are NULL.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+AppendDevicePathNode (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *NextNode;
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
+ UINTN NodeLength;
+
+ if (DevicePathNode == NULL) {
+ return DuplicateDevicePath ((DevicePath != NULL) ? DevicePath : &mUefiDevicePathLibEndDevicePath);
+ }
+ //
+ // Build a Node that has a terminator on it
+ //
+ NodeLength = DevicePathNodeLength (DevicePathNode);
+
+ TempDevicePath = AllocatePool (NodeLength + END_DEVICE_PATH_LENGTH);
+ if (TempDevicePath == NULL) {
+ return NULL;
+ }
+ TempDevicePath = CopyMem (TempDevicePath, DevicePathNode, NodeLength);
+ //
+ // Add and end device path node to convert Node to device path
+ //
+ NextNode = NextDevicePathNode (TempDevicePath);
+ SetDevicePathEndNode (NextNode);
+ //
+ // Append device paths
+ //
+ NewDevicePath = AppendDevicePath (DevicePath, TempDevicePath);
+
+ FreePool (TempDevicePath);
+
+ return NewDevicePath;
+}
diff --git a/lib/libefivar/uefi-guid.c b/lib/libefivar/uefi-guid.c
new file mode 100644
index 0000000..c173a44
--- /dev/null
+++ b/lib/libefivar/uefi-guid.c
@@ -0,0 +1,36 @@
+/* This generated file is in the public domain */
+/* $FreeBSD$ */
+
+#include <uuid.h>
+#include <stdint.h>
+
+typedef struct {
+ uint32_t Data1;
+ uint16_t Data2;
+ uint16_t Data3;
+ uint8_t Data4[8];
+} EFI_GUID;
+
+extern EFI_GUID gEfiDebugPortProtocolGuid;
+extern EFI_GUID gEfiPcAnsiGuid;
+extern EFI_GUID gEfiPersistentVirtualCdGuid;
+extern EFI_GUID gEfiPersistentVirtualDiskGuid;
+extern EFI_GUID gEfiSasDevicePathGuid;
+extern EFI_GUID gEfiUartDevicePathGuid;
+extern EFI_GUID gEfiVT100Guid;
+extern EFI_GUID gEfiVT100PlusGuid;
+extern EFI_GUID gEfiVTUTF8Guid;
+extern EFI_GUID gEfiVirtualCdGuid;
+extern EFI_GUID gEfiVirtualDiskGuid;
+
+EFI_GUID gEfiDebugPortProtocolGuid = { 0xEBA4E8D2, 0x3858, 0x41EC, { 0xA2, 0x81, 0x26, 0x47, 0xBA, 0x96, 0x60, 0xD0 }} ;
+EFI_GUID gEfiPcAnsiGuid = { 0xE0C14753, 0xF9BE, 0x11D2, { 0x9A, 0x0C, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }} ;
+EFI_GUID gEfiPersistentVirtualCdGuid = { 0x08018188, 0x42CD, 0xBB48, {0x10, 0x0F, 0x53, 0x87, 0xD5, 0x3D, 0xED, 0x3D }} ;
+EFI_GUID gEfiPersistentVirtualDiskGuid = { 0x5CEA02C9, 0x4D07, 0x69D3, {0x26, 0x9F ,0x44, 0x96, 0xFB, 0xE0, 0x96, 0xF9 }} ;
+EFI_GUID gEfiSasDevicePathGuid = { 0xd487ddb4, 0x008b, 0x11d9, { 0xaf, 0xdc, 0x00, 0x10, 0x83, 0xff, 0xca, 0x4d }} ;
+EFI_GUID gEfiUartDevicePathGuid = { 0x37499a9d, 0x542f, 0x4c89, { 0xa0, 0x26, 0x35, 0xda, 0x14, 0x20, 0x94, 0xe4 }} ;
+EFI_GUID gEfiVT100Guid = { 0xDFA66065, 0xB419, 0x11D3, { 0x9A, 0x2D, 0x00, 0x90, 0x27, 0x3F, 0xC1, 0x4D }} ;
+EFI_GUID gEfiVT100PlusGuid = { 0x7BAEC70B, 0x57E0, 0x4C76, { 0x8E, 0x87, 0x2F, 0x9E, 0x28, 0x08, 0x83, 0x43 }} ;
+EFI_GUID gEfiVTUTF8Guid = { 0xAD15A0D6, 0x8BEC, 0x4ACF, { 0xA0, 0x73, 0xD0, 0x1D, 0xE7, 0x7E, 0x2D, 0x88 }} ;
+EFI_GUID gEfiVirtualCdGuid = { 0x3D5ABD30, 0x4175, 0x87CE, {0x6D, 0x64, 0xD2, 0xAD, 0xE5, 0x23, 0xC4, 0xBB }} ;
+EFI_GUID gEfiVirtualDiskGuid = { 0x77AB535A, 0x45FC, 0x624B, {0x55, 0x60, 0xF7, 0xB2, 0x81, 0xD1, 0xF9, 0x6E }} ;
diff --git a/lib/libefivar/uefi-guid.dat b/lib/libefivar/uefi-guid.dat
new file mode 100644
index 0000000..921b179
--- /dev/null
+++ b/lib/libefivar/uefi-guid.dat
@@ -0,0 +1,11 @@
+gEfiDebugPortProtocolGuid
+gEfiPcAnsiGuid
+gEfiPersistentVirtualCdGuid
+gEfiPersistentVirtualDiskGuid
+gEfiSasDevicePathGuid
+gEfiUartDevicePathGuid
+gEfiVT100Guid
+gEfiVT100PlusGuid
+gEfiVTUTF8Guid
+gEfiVirtualCdGuid
+gEfiVirtualDiskGuid
OpenPOWER on IntegriCloud