github.com/system-transparency/u-root@v6.0.1-0.20190919065413-ed07a650de4c+incompatible/pkg/acpi/raw.go (about)

     1  // Copyright 2019 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  package acpi
     6  
     7  import (
     8  	"encoding/binary"
     9  	"fmt"
    10  	"io/ioutil"
    11  
    12  	"github.com/u-root/u-root/pkg/memio"
    13  )
    14  
    15  // Raw ACPI table support. Raw tables are those tables
    16  // one needs to read in, write out, but not change in any way.
    17  // This is needed when, e.g., a program has to reassemble all the
    18  // tables in /sys for kexec.
    19  
    20  // Raw is just a table embedded in a []byte.  Operations on Raw are
    21  // useful for unpacking into a more refined table or just figuring out
    22  // how to skip a table you don't care about.
    23  type Raw struct {
    24  	data []byte
    25  }
    26  
    27  var _ = Tabler(&Raw{})
    28  
    29  // NewRaw returns a new Raw table given a byte slice.
    30  func NewRaw(b []byte) (Tabler, error) {
    31  	if len(b) < HeaderLength {
    32  		return nil, fmt.Errorf("NewRaw: byte slice is only %d bytes and must be at least %d bytes", len(b), HeaderLength)
    33  	}
    34  	u := binary.LittleEndian.Uint32(b[LengthOffset : LengthOffset+4])
    35  	return &Raw{data: b[:u]}, nil
    36  }
    37  
    38  // RawFromFile reads a raw table in from a file.
    39  func RawFromFile(n string) (Tabler, error) {
    40  	b, err := ioutil.ReadFile(n)
    41  	if err != nil {
    42  		return nil, err
    43  	}
    44  	return NewRaw(b)
    45  }
    46  
    47  // ReadRaw reads a full table in, given an address.
    48  // ReadRaw uses the io package. This may not always work
    49  // if the kernel has restrictions on reading memory above
    50  // the 1M boundary, and the tables are above boundary.
    51  func ReadRaw(a int64) (Tabler, error) {
    52  	var u memio.Uint32
    53  	// Read the table size at a+4
    54  	if err := memio.Read(a+4, &u); err != nil {
    55  		return nil, err
    56  	}
    57  	Debug("ReadRaw: Size is %d", u)
    58  	dat := memio.ByteSlice(make([]byte, u))
    59  	if err := memio.Read(a, &dat); err != nil {
    60  		return nil, err
    61  	}
    62  	return &Raw{data: []byte(dat)}, nil
    63  }
    64  
    65  // Marshal marshals Raw tables to a byte slice.
    66  func (r *Raw) Marshal() ([]byte, error) {
    67  	return r.data, nil
    68  }
    69  
    70  // AllData returns all the data in a Raw table.
    71  func (r *Raw) AllData() []byte {
    72  	return r.data
    73  }
    74  
    75  // TableData returns the Raw table, minus the standard ACPI header.
    76  func (r *Raw) TableData() []byte {
    77  	return r.data[HeaderLength:]
    78  }
    79  
    80  // Sig returns the table signature.
    81  func (r *Raw) Sig() string {
    82  	return fmt.Sprintf("%s", r.data[:4])
    83  }
    84  
    85  // Len returns the total table length.
    86  func (r *Raw) Len() uint32 {
    87  	return uint32(len(r.data))
    88  }
    89  
    90  // Revision returns the table Revision.
    91  func (r *Raw) Revision() uint8 {
    92  	return uint8(r.data[8])
    93  }
    94  
    95  // CheckSum returns the table CheckSum.
    96  func (r *Raw) CheckSum() uint8 {
    97  	return uint8(r.data[9])
    98  }
    99  
   100  // OEMID returns the table OEMID.
   101  func (r *Raw) OEMID() string {
   102  	return fmt.Sprintf("%s", r.data[10:16])
   103  }
   104  
   105  // OEMTableID returns the table OEMTableID.
   106  func (r *Raw) OEMTableID() string {
   107  	return fmt.Sprintf("%s", r.data[16:24])
   108  }
   109  
   110  // OEMRevision returns the table OEMRevision.
   111  func (r *Raw) OEMRevision() uint32 {
   112  	return binary.LittleEndian.Uint32(r.data[24 : 24+4])
   113  }
   114  
   115  // CreatorID returns the table CreatorID.
   116  func (r *Raw) CreatorID() uint32 {
   117  	return binary.LittleEndian.Uint32(r.data[28 : 28+4])
   118  }
   119  
   120  // CreatorRevision returns the table CreatorRevision.
   121  func (r *Raw) CreatorRevision() uint32 {
   122  	return binary.LittleEndian.Uint32(r.data[32 : 32+4])
   123  }