Home | History | Annotate | Line # | Download | only in efi
      1 /* $NetBSD: devpath5.c,v 1.2 2025/03/02 00:23:59 riastradh Exp $ */
      2 
      3 /*
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
     14  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     16  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     19  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     23  * SUCH DAMAGE.
     24  */
     25 
     26 #include <sys/cdefs.h>
     27 #ifndef lint
     28 __RCSID("$NetBSD: devpath5.c,v 1.2 2025/03/02 00:23:59 riastradh Exp $");
     29 #endif /* not lint */
     30 
     31 #include <assert.h>
     32 #include <stdio.h>
     33 
     34 #include "defs.h"
     35 #include "devpath.h"
     36 #include "devpath5.h"
     37 
     38 #define easprintf	(size_t)easprintf
     39 
     40 /************************************************************************
     41  * Type 5 - BIOS Boot Specification Device Path
     42  ************************************************************************/
     43 
     44 /*
     45  * See Appendix A of BIOSBootSpecsV1.01.pdf for typename and statusflag.
     46  * Available from <http:/www.uefi.org/uefi>
     47  */
     48 static inline const char *
     49 devpath_bios_typename(uint devtype)
     50 {
     51 
     52 	switch (devtype) {
     53 	case 0x01:	return "Floppy";
     54 	case 0x02:	return "HardDisk";
     55 	case 0x03:	return "CDRom";
     56 	case 0x04:	return "PCMCIA";
     57 	case 0x05:	return "USB";
     58 	case 0x06:	return "Network";
     59 	case 0x80:	return "BEV device";
     60 	case 0xff:	return "Unknown";
     61 	default:	return "Reserved";
     62 	}
     63 }
     64 
     65 #define BIOS_STATUS_OLD_POSITION	__BITS(3,0)
     66 #define BIOS_STATUS_ENABLED		__BIT(8)
     67 #define BIOS_STATUS_FAILED		__BIT(9)
     68 #define BIOS_STATUS_MEDIA		__BITS(11,10)
     69 #define BIOS_STATUS_MEDIA_NONE		__SHIFTIN(0, BIOS_STATUS_MEDIA)
     70 #define BIOS_STATUS_MEDIA_UNKNOWN	__SHIFTIN(1, BIOS_STATUS_MEDIA)
     71 #define BIOS_STATUS_MEDIA_PRESENT	__SHIFTIN(2, BIOS_STATUS_MEDIA)
     72 #define BIOS_STATUS_MEDIA_RESVD		__SHIFTIN(3, BIOS_STATUS_MEDIA)
     73 #define BIOS_STATUS_RESERVED		(__BITS(15,12) | __BITS(7,4))
     74 #define BIOS_STATUS_BITS \
     75 	"\177\020"		\
     76 	"f\x00\x04""POS\0"	\
     77 	"b\x08""ENBL\0"		\
     78 	"b\x09""FAIL\0"		\
     79 	"f\x0a\x02""MEDIA\0"	\
     80 	"=\0""NONE\0"		\
     81 	"=\1""UNKNOWN\0"	\
     82 	"=\2""PRESENT\0"	\
     83 	"=\3""RSVD\0"
     84 
     85 /* Bios Boot Specification Device */
     86 static inline void
     87 devpath_bios_BBS(devpath_t *dp, devpath_elm_t *path, devpath_elm_t *dbg)
     88 {	/* See 10.3.6 */
     89 	struct { /* Sub-Type 1 */
     90 		devpath_t	hdr;	/* Length = 8 */
     91 		uint16_t	DeviceType; /* see devpath_bios_typename() */
     92 		uint16_t	StatusFlag;
     93 		char		Description[]; /* asciiz */
     94 	} __packed *p = (void *)dp;
     95 	__CTASSERT(sizeof(*p) == 8);
     96 	const char *typename;
     97 
     98 	typename = devpath_bios_typename(p->DeviceType);
     99 
    100 	path->sz = easprintf(&path->cp, "BBS(%s(%#x),0x%04x,%s)",
    101 	    typename, p->DeviceType, p->StatusFlag, p->Description);
    102 
    103 	if (dbg != NULL) {
    104 		char statusflag[128];
    105 
    106 		snprintb(statusflag, sizeof(statusflag), BIOS_STATUS_BITS,
    107 		    p->StatusFlag);
    108 		dbg->sz = easprintf(&dbg->cp,
    109 		    DEVPATH_FMT_HDR
    110 		    DEVPATH_FMT(DeviceType: %x (%s)\n)
    111 		    DEVPATH_FMT(StatusFlag: %s\n)
    112 		    DEVPATH_FMT(Description: '%s'\n),
    113 		    DEVPATH_DAT_HDR(dp),
    114 		    p->DeviceType,
    115 		    typename,
    116 		    statusflag,
    117 		    p->Description);
    118 	}
    119 }
    120 
    121 PUBLIC void
    122 devpath_bios(devpath_t *dp, devpath_elm_t *path, devpath_elm_t *dbg)
    123 {
    124 
    125 	assert(dp->Type = 5);
    126 
    127 	switch (dp->SubType) {
    128 	case 1:   devpath_bios_BBS(dp, path, dbg);	return;
    129 	default:  devpath_unsupported(dp, path, dbg);	return;
    130 	}
    131 }
    132