/
header.go
164 lines (135 loc) · 3.81 KB
/
header.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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
// Copyright 2018 the LinuxBoot Authors. All rights reserved
// Copyright 2020 Johanna Amélie Schander <git@mimoja.de>
package intelfsp
import (
"bytes"
"encoding/binary"
"fmt"
"strings"
)
const (
FSPHeaderSignature = "FSPH"
FSPExtHeaderSignature = "FSPE"
FixedInfoHeaderLength = 12
HeaderFSP1Length = 64
HeaderFSP2Length = 72
HeaderFSP3Length = 72
HeaderFSP4Length = 72
FixedExtendedInfoHeaderLength = 20
)
type ImageAttributes struct {
GraphicsSupport *bool
DispatchModeSupport *bool
}
func (ia ImageAttributes) String() string {
var attrs []string
if ia.GraphicsSupport != nil && *ia.GraphicsSupport{
attrs = append(attrs,"Graphics Display Supported")
} else if ia.GraphicsSupport != nil && !*ia.GraphicsSupport{
attrs = append(attrs,"Graphics Display Not Supported")
}
if ia.DispatchModeSupport != nil && *ia.DispatchModeSupport{
attrs = append(attrs,"Dispatch Mode Supported")
} else if ia.GraphicsSupport != nil && !*ia.GraphicsSupport{
attrs = append(attrs,"Dispatch Mode Not Supported")
}
return strings.Join(attrs, "|")
}
type ComponentAttributes struct {
ReleaseBuild bool
OfficialRelease bool
Type Type
TypeName string
}
func (ca ComponentAttributes) String() string {
var attrs []string
if ca.ReleaseBuild {
attrs = append(attrs, "Release Build")
} else {
attrs = append(attrs, "Debug Build")
}
if ca.OfficialRelease {
attrs = append(attrs, "Official Release")
} else {
attrs = append(attrs, "Test Release")
}
attrs = append(attrs, ca.TypeName)
return strings.Join(attrs, "|")
}
type BinaryFSPHeader interface {
Summary() string
GetImageSize() uint32
GetImageAttributes() *ImageAttributes
GetComponentAttributes() *ComponentAttributes
}
type CommonInfoHeader struct {
Signature [4]byte
HeaderLength uint32
Reserved1 uint16
SpecVersion SpecVersion
HeaderRevision HeaderRevision
}
// ImageRevision is the image revision field of the FSP info header.
type HeaderRevision uint8
func (hr HeaderRevision) GetHeader() (BinaryFSPHeader, error) {
switch hr {
case 0x01:
return &InfoHeaderV1{}, nil
case 0x02:
return &InfoHeaderV2{}, nil
case 0x03:
return &InfoHeaderV3{}, nil
case 0x04:
return &InfoHeaderV4{}, nil
default:
return nil, fmt.Errorf("Unknown Header Revision: 0x%03X", hr)
}
}
// SpecVersion represents the spec version as a packed BCD two-digit,
// dot-separated unsigned integer.
type SpecVersion uint8
func (sv SpecVersion) String() string {
return fmt.Sprintf("%d.%d", (sv>>4)&0x0f, sv&0x0f)
}
type Type uint8
var (
TypeT Type = 1
TypeM Type = 2
TypeS Type = 3
TypeO Type = 8
// TypeReserved is a fake type that represents a reserved FSP type.
TypeReserved Type
)
var fspTypeNames = map[Type]string{
TypeT: "FSP-T",
TypeM: "FSP-M",
TypeS: "FSP-S",
TypeO: "FSP-O",
TypeReserved: "FSP-ReservedType",
}
func ParseHeader(b []byte) (*BinaryFSPHeader, error) {
if len(b) < FixedInfoHeaderLength {
return nil, fmt.Errorf("short FSP Info Header length %d; want at least %d", len(b), FixedInfoHeaderLength)
}
var f CommonInfoHeader
reader := bytes.NewReader(b)
if err := binary.Read(reader, binary.LittleEndian, &f); err != nil {
return nil, err
}
if !bytes.Equal(f.Signature[:], []byte(FSPHeaderSignature)) {
return nil, fmt.Errorf("invalid signature %v (%s); want %s", f.Signature, string(f.Signature[:]), FSPHeaderSignature)
}
if f.Reserved1 != 0x0 {
return nil, fmt.Errorf("reserved bytes must be zero")
}
var bh BinaryFSPHeader
bh, err := f.HeaderRevision.GetHeader()
if err != nil {
return nil, fmt.Errorf("Could not determin header version: %v", err)
}
reader = bytes.NewReader(b)
if err := binary.Read(reader, binary.LittleEndian, bh); err != nil {
return nil, err
}
return &bh, nil
}