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