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  }