forked from u-root/u-root
-
Notifications
You must be signed in to change notification settings - Fork 0
/
sdt.go
76 lines (66 loc) · 1.61 KB
/
sdt.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
// Copyright 2019 the u-root Authors. All rights reserved
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package acpi
import (
"bytes"
"encoding/binary"
"fmt"
)
var (
sdtLen = 36
)
// SDT contains information about tables. It does not differentiate 32- vs 64-bit
// tables.
type SDT struct {
// Table is the SDT itself.
Table
// Addrs is the array of physical addresses in the SDT.
Addrs []int64
// Base is the SDT base, used to generate a new SDT for, e.g, coreboot.
Base int64
}
var _ = Table(&SDT{})
// NewSDTAddr returns an SDT, given an address.
func NewSDTAddr(addr int64) (*SDT, error) {
t, err := ReadRawTable(addr)
if err != nil {
return nil, fmt.Errorf("can not read SDT at %#x", addr)
}
Debug("NewSDTAddr: %s %#x", String(t), t.TableData())
return NewSDT(t, addr)
}
// NewSDT returns an SDT, given a Table
func NewSDT(t Table, addr int64) (*SDT, error) {
s := &SDT{
Table: t,
Base: addr,
}
r := bytes.NewReader(t.TableData())
x := true
if t.Sig() == "RSDT" {
x = false
}
for r.Len() > 0 {
var a int64
if x {
if err := binary.Read(r, binary.LittleEndian, &a); err != nil {
return nil, err
}
} else {
var a32 uint32
if err := binary.Read(r, binary.LittleEndian, &a32); err != nil {
return nil, err
}
a = int64(a32)
}
Debug("Add addr %#x", a)
s.Addrs = append(s.Addrs, a)
}
Debug("NewSDT: %v", s.String())
return s, nil
}
// String implements string for an SDT.
func (sdt *SDT) String() string {
return fmt.Sprintf("%s at %#x with %d tables: %#x", String(sdt), sdt.Base, len(sdt.Addrs), sdt.Addrs)
}