github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+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"
    11  	"io/ioutil"
    12  	"os"
    13  
    14  	"github.com/u-root/u-root/pkg/memio"
    15  )
    16  
    17  // Raw ACPI table support. Raw tables are those tables
    18  // one needs to read in, write out, but not change in any way.
    19  // This is needed when, e.g., there is need to create files for
    20  // coreboot cbfs.
    21  
    22  // Raw is just a table embedded in a []byte.  Operations on Raw are
    23  // for figuring out how to skip a table you don't care about or, possibly,
    24  // truncating a table and regenerating a checksum.
    25  type Raw struct {
    26  	addr int64
    27  	data []byte
    28  }
    29  
    30  var _ = Table(&Raw{})
    31  
    32  // NewRaw returns a new Raw []Table fron a given byte slice.
    33  func NewRaw(b []byte) ([]Table, error) {
    34  	var tab []Table
    35  	for {
    36  		if len(b) == 0 {
    37  			break
    38  		}
    39  		if len(b) < headerLength {
    40  			return nil, fmt.Errorf("NewRaw: byte slice is only %d bytes and must be at least %d bytes", len(b), headerLength)
    41  		}
    42  		u := binary.LittleEndian.Uint32(b[lengthOffset : lengthOffset+4])
    43  		if int(u) > len(b) {
    44  			return nil, fmt.Errorf("Table length %d is too large for %d byte table (Signature %q", u, len(b), string(b[0:4]))
    45  		}
    46  		tab = append(tab, &Raw{data: b[:u]})
    47  		b = b[u:]
    48  	}
    49  	return tab, nil
    50  }
    51  
    52  // RawFromFile reads from an io.Reader and returns a []Table and error if any.
    53  func RawFromFile(r io.Reader) ([]Table, error) {
    54  	b, err := ioutil.ReadAll(r)
    55  	if err != nil {
    56  		return nil, err
    57  	}
    58  	return NewRaw(b)
    59  }
    60  
    61  // RawFromName reads a raw []Table in from a named file.
    62  func RawFromName(n string) ([]Table, error) {
    63  	f, err := os.Open(n)
    64  	defer f.Close()
    65  	if err != nil {
    66  		return nil, err
    67  	}
    68  	return RawFromFile(f)
    69  }
    70  
    71  // ReadRawTable reads a full table in, given an address.
    72  //
    73  // ReadRawTable uses the io package. This may not always work
    74  // if the kernel has restrictions on reading memory above
    75  // the 1M boundary, and the tables are above boundary.
    76  func ReadRawTable(physAddr int64) (Table, error) {
    77  	var u memio.Uint32
    78  	// Read the table size at a+4
    79  	if err := memio.Read(physAddr+4, &u); err != nil {
    80  		return nil, err
    81  	}
    82  	dat := memio.ByteSlice(make([]byte, u))
    83  	if err := memio.Read(physAddr, &dat); err != nil {
    84  		return nil, err
    85  	}
    86  	return &Raw{addr: physAddr, data: []byte(dat)}, nil
    87  }
    88  
    89  // Address returns the table's base address
    90  func (r *Raw) Address() int64 {
    91  	return r.addr
    92  }
    93  
    94  // Data returns all the data in a Raw table.
    95  func (r *Raw) Data() []byte {
    96  	return r.data
    97  }
    98  
    99  // TableData returns the Raw table, minus the standard ACPI header.
   100  func (r *Raw) TableData() []byte {
   101  	return r.data[headerLength:]
   102  }
   103  
   104  // Sig returns the table signature.
   105  func (r *Raw) Sig() string {
   106  	return fmt.Sprintf("%s", r.data[:4])
   107  }
   108  
   109  // Len returns the total table length.
   110  func (r *Raw) Len() uint32 {
   111  	return uint32(len(r.data))
   112  }
   113  
   114  // Revision returns the table Revision.
   115  func (r *Raw) Revision() uint8 {
   116  	return uint8(r.data[8])
   117  }
   118  
   119  // CheckSum returns the table CheckSum.
   120  func (r *Raw) CheckSum() uint8 {
   121  	return uint8(r.data[9])
   122  }
   123  
   124  // OEMID returns the table OEMID.
   125  func (r *Raw) OEMID() string {
   126  	return fmt.Sprintf("%q", r.data[10:16])
   127  }
   128  
   129  // OEMTableID returns the table OEMTableID.
   130  func (r *Raw) OEMTableID() string {
   131  	return fmt.Sprintf("%q", r.data[16:24])
   132  }
   133  
   134  // OEMRevision returns the table OEMRevision.
   135  func (r *Raw) OEMRevision() uint32 {
   136  	return binary.LittleEndian.Uint32(r.data[24 : 24+4])
   137  }
   138  
   139  // CreatorID returns the table CreatorID.
   140  func (r *Raw) CreatorID() uint32 {
   141  	return binary.LittleEndian.Uint32(r.data[28 : 28+4])
   142  }
   143  
   144  // CreatorRevision returns the table CreatorRevision.
   145  func (r *Raw) CreatorRevision() uint32 {
   146  	return binary.LittleEndian.Uint32(r.data[32 : 32+4])
   147  }