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