github.com/u-root/u-root@v7.0.1-0.20200915234505-ad7babab0a8e+incompatible/pkg/acpi/sdt.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  	"bytes"
     9  	"encoding/binary"
    10  	"fmt"
    11  )
    12  
    13  var (
    14  	sdtLen = 36
    15  )
    16  
    17  // SDT contains information about tables. It does not differentiate 32- vs 64-bit
    18  // tables.
    19  type SDT struct {
    20  	// Table is the SDT itself.
    21  	Table
    22  
    23  	// Addrs is the array of physical addresses in the SDT.
    24  	Addrs []int64
    25  
    26  	// Base is the SDT base, used to generate a new SDT for, e.g, coreboot.
    27  	Base int64
    28  }
    29  
    30  var _ = Table(&SDT{})
    31  
    32  // NewSDTAddr returns an SDT, given an address.
    33  func NewSDTAddr(addr int64) (*SDT, error) {
    34  	t, err := ReadRawTable(addr)
    35  	if err != nil {
    36  		return nil, fmt.Errorf("can not read SDT at %#x", addr)
    37  	}
    38  	Debug("NewSDTAddr: %s %#x", String(t), t.TableData())
    39  	return NewSDT(t, addr)
    40  }
    41  
    42  // NewSDT returns an SDT, given a Table
    43  func NewSDT(t Table, addr int64) (*SDT, error) {
    44  	s := &SDT{
    45  		Table: t,
    46  		Base:  addr,
    47  	}
    48  	r := bytes.NewReader(t.TableData())
    49  	x := true
    50  	if t.Sig() == "RSDT" {
    51  		x = false
    52  	}
    53  	for r.Len() > 0 {
    54  		var a int64
    55  		if x {
    56  			if err := binary.Read(r, binary.LittleEndian, &a); err != nil {
    57  				return nil, err
    58  			}
    59  		} else {
    60  			var a32 uint32
    61  			if err := binary.Read(r, binary.LittleEndian, &a32); err != nil {
    62  				return nil, err
    63  			}
    64  			a = int64(a32)
    65  		}
    66  		Debug("Add addr %#x", a)
    67  		s.Addrs = append(s.Addrs, a)
    68  	}
    69  	Debug("NewSDT: %v", s.String())
    70  	return s, nil
    71  }
    72  
    73  // String implements string for an SDT.
    74  func (sdt *SDT) String() string {
    75  	return fmt.Sprintf("%s at %#x with %d tables: %#x", String(sdt), sdt.Base, len(sdt.Addrs), sdt.Addrs)
    76  }