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 }