github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/pkg/uefivars/boot/efiDppACPI.go (about) 1 // Copyright 2020 the u-root Authors. All rights reserved 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 // 5 // SPDX-License-Identifier: BSD-3-Clause 6 // 7 8 package boot 9 10 import ( 11 "bytes" 12 "fmt" 13 ) 14 15 // EfiDppACPISubType is the dpp subtype for ACPI. 16 type EfiDppACPISubType EfiDevPathProtoSubType 17 18 const ( 19 DppAcpiTypeDevPath EfiDppACPISubType = iota + 1 20 DppAcpiTypeExpandedDevPath 21 DppAcpiTypeADR 22 DppAcpiTypeNVDIMM 23 ) 24 25 var efiDppACPISubTypeStrings = map[EfiDppACPISubType]string{ 26 DppAcpiTypeDevPath: "Device Path", 27 DppAcpiTypeExpandedDevPath: "Expanded Device Path", 28 DppAcpiTypeADR: "_ADR", 29 DppAcpiTypeNVDIMM: "NVDIMM", 30 } 31 32 func (e EfiDppACPISubType) String() string { 33 if s, ok := efiDppACPISubTypeStrings[e]; ok { 34 return s 35 } 36 return fmt.Sprintf("UNKNOWN-0x%x", uint8(e)) 37 } 38 39 // DppAcpiDevPath is an acpi device path. 40 type DppAcpiDevPath struct { 41 Hdr EfiDevicePathProtocolHdr 42 HID, UID []byte //both length 4; not sure of endianness 43 } 44 45 var _ EfiDevicePathProtocol = (*DppAcpiDevPath)(nil) 46 47 // ParseDppAcpiDevPath parses input into a DppAcpiDevPath. 48 func ParseDppAcpiDevPath(h EfiDevicePathProtocolHdr, b []byte) (*DppAcpiDevPath, error) { 49 if h.Length != 12 { 50 return nil, ErrParse 51 } 52 return &DppAcpiDevPath{ 53 Hdr: h, 54 HID: b[:4], 55 UID: b[4:8], 56 }, nil 57 } 58 59 func (e *DppAcpiDevPath) Header() EfiDevicePathProtocolHdr { return e.Hdr } 60 61 // ProtoSubTypeStr returns the subtype as human readable. 62 func (e *DppAcpiDevPath) ProtoSubTypeStr() string { 63 return EfiDppACPISubType(e.Hdr.ProtoSubType).String() 64 } 65 66 func (e *DppAcpiDevPath) String() string { return fmt.Sprintf("ACPI(0x%x,0x%x)", e.HID, e.UID) } 67 68 // Resolver returns a nil EfiPathSegmentResolver and ErrUnimpl. See the comment 69 // associated with ErrUnimpl. 70 func (e *DppAcpiDevPath) Resolver() (EfiPathSegmentResolver, error) { return nil, ErrUnimpl } 71 72 // DppAcpiExDevPath is an expanded dpp acpi device path. 73 type DppAcpiExDevPath struct { 74 Hdr EfiDevicePathProtocolHdr 75 HID, UID, CID []byte //all length 4; not sure of endianness 76 HIDSTR, UIDSTR, CIDSTR string 77 } 78 79 var _ EfiDevicePathProtocol = (*DppAcpiExDevPath)(nil) 80 81 // ParseDppAcpiExDevPath parses input into a DppAcpiExDevPath. 82 func ParseDppAcpiExDevPath(h EfiDevicePathProtocolHdr, b []byte) (*DppAcpiExDevPath, error) { 83 if h.Length < 19 { 84 return nil, ErrParse 85 } 86 ex := &DppAcpiExDevPath{ 87 Hdr: h, 88 HID: b[:4], 89 UID: b[4:8], 90 CID: b[8:12], 91 } 92 b = b[12:] 93 var err error 94 ex.HIDSTR, err = readToNull(b) 95 if err != nil { 96 return nil, err 97 } 98 b = b[len(ex.HIDSTR)+1:] 99 ex.UIDSTR, err = readToNull(b) 100 if err != nil { 101 return nil, err 102 } 103 b = b[len(ex.UIDSTR)+1:] 104 ex.CIDSTR, err = readToNull(b) 105 if err != nil { 106 return nil, err 107 } 108 return ex, nil 109 } 110 111 func (e *DppAcpiExDevPath) Header() EfiDevicePathProtocolHdr { return e.Hdr } 112 113 // ProtoSubTypeStr returns the subtype as human readable. 114 func (e *DppAcpiExDevPath) ProtoSubTypeStr() string { 115 return EfiDppACPISubType(e.Hdr.ProtoSubType).String() 116 } 117 118 func (e *DppAcpiExDevPath) String() string { 119 return fmt.Sprintf("ACPI_EX(0x%x,0x%x,0x%x,%s,%s,%s)", e.HID, e.UID, e.CID, e.HIDSTR, e.UIDSTR, e.CIDSTR) 120 } 121 122 // Resolver returns a nil EfiPathSegmentResolver and ErrUnimpl. See the comment 123 // associated with ErrUnimpl. 124 func (e *DppAcpiExDevPath) Resolver() (EfiPathSegmentResolver, error) { 125 return nil, ErrUnimpl 126 } 127 128 func readToNull(b []byte) (string, error) { 129 i := bytes.IndexRune(b, 0) 130 if i < 0 { 131 return "", ErrParse 132 } 133 return string(b[:i]), nil 134 }