summaryrefslogtreecommitdiffstats
path: root/util/intelp2m/parser/parser.go
blob: c6a9388a4291d287d34c53249162d44259e78202 (plain)
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
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
package parser

import (
	"bufio"
	"fmt"
	"strings"
	"strconv"

	"review.coreboot.org/coreboot.git/util/intelp2m/platforms/common"
	"review.coreboot.org/coreboot.git/util/intelp2m/platforms/snr"
	"review.coreboot.org/coreboot.git/util/intelp2m/platforms/lbg"
	"review.coreboot.org/coreboot.git/util/intelp2m/platforms/apl"
	"review.coreboot.org/coreboot.git/util/intelp2m/platforms/cnl"
	"review.coreboot.org/coreboot.git/util/intelp2m/platforms/adl"
	"review.coreboot.org/coreboot.git/util/intelp2m/config"
)

// PlatformSpecific - platform-specific interface
type PlatformSpecific interface {
	GenMacro(id string, dw0 uint32, dw1 uint32, ownership uint8) string
	GroupNameExtract(line string) (bool, string)
	KeywordCheck(line string) bool
}

// padInfo - information about pad
// id        : pad id string
// offset    : the offset of the register address relative to the base
// function  : the string that means the pad function
// dw0       : DW0 register value
// dw1       : DW1 register value
// ownership : host software ownership
type padInfo struct {
	id        string
	offset    uint16
	function  string
	dw0       uint32
	dw1       uint32
	ownership uint8
}

// generate - wrapper for Fprintf(). Writes text to the file specified
// in config.OutputGenFile
func (info *padInfo) generate(lvl int, line string, a ...interface{}) {
	if config.InfoLevelGet() >= lvl {
		fmt.Fprintf(config.OutputGenFile, line, a...)
	}
}

// titleFprint - print GPIO group title to file
// /* ------- GPIO Group GPP_L ------- */
func (info *padInfo) titleFprint() {
	info.generate(0, "\n\t/* %s */\n", info.function)
}

// reservedFprint - print reserved GPIO to file as comment
// /* GPP_H17 - RESERVED */
func (info *padInfo) reservedFprint() {
	info.generate(2, "\n")
	// small comment about reserved port
	info.generate(0, "\t/* %s - %s */\n", info.id, info.function)
}

// padInfoMacroFprint - print information about current pad to file using
// special macros:
// PAD_CFG_NF(GPP_F1, 20K_PU, PLTRST, NF1), /* SATAXPCIE4 */
// gpio  : gpio.c file descriptor
// macro : string of the generated macro
func (info *padInfo) padInfoMacroFprint(macro string) {
	info.generate(2,
		"\n\t/* %s - %s */\n\t/* DW0: 0x%0.8x, DW1: 0x%0.8x */\n",
		info.id,
		info.function,
		info.dw0,
		info.dw1)
	info.generate(0, "\t%s", macro)
	if config.InfoLevelGet() == 1 {
		info.generate(1, "\t/* %s */", info.function)
	}
	info.generate(0, "\n")
}

// ParserData - global data
// line       : string from the configuration file
// padmap     : pad info map
// RawFmt     : flag for generating pads config file with DW0/1 reg raw values
// Template   : structure template type of ConfigFile
type ParserData struct {
	platform   PlatformSpecific
	line       string
	padmap     []padInfo
	ownership  map[string]uint32
}

// hostOwnershipGet - get the host software ownership value for the corresponding
// pad ID
// id : pad ID string
// return the host software ownership form the parser struct
func (parser *ParserData) hostOwnershipGet(id string) uint8 {
	var ownership uint8 = 0
	status, group := parser.platform.GroupNameExtract(id)
	if config.TemplateGet() == config.TempInteltool && status {
		numder, _ := strconv.Atoi(strings.TrimLeft(id, group))
		if (parser.ownership[group] & (1 << uint8(numder))) != 0 {
			ownership = 1
		}
	}
	return ownership
}

// padInfoExtract - adds a new entry to pad info map
// return error status
func (parser *ParserData) padInfoExtract() int {
	var function, id string
	var dw0, dw1 uint32
	var template = map[int]template{
		config.TempInteltool: useInteltoolLogTemplate,
		config.TempGpioh    : useGpioHTemplate,
		config.TempSpec     : useYourTemplate,
	}
	if template[config.TemplateGet()](parser.line, &function, &id, &dw0, &dw1) == 0 {
		pad := padInfo{id: id,
			function: function,
			dw0: dw0,
			dw1: dw1,
			ownership: parser.hostOwnershipGet(id)}
		parser.padmap = append(parser.padmap, pad)
		return 0
	}
	fmt.Printf("This template (%d) does not match!\n", config.TemplateGet())
	return -1
}

// communityGroupExtract
func (parser *ParserData) communityGroupExtract() {
	pad := padInfo{function: parser.line}
	parser.padmap = append(parser.padmap, pad)
}

// PlatformSpecificInterfaceSet - specific interface for the platform selected
// in the configuration
func (parser *ParserData) PlatformSpecificInterfaceSet() {
	var platform = map[uint8]PlatformSpecific {
		config.SunriseType   : snr.PlatformSpecific{},
		// See platforms/lbg/macro.go
		config.LewisburgType : lbg.PlatformSpecific{
			InheritanceTemplate : snr.PlatformSpecific{},
		},
		config.ApolloType    : apl.PlatformSpecific{},
		config.CannonType    : cnl.PlatformSpecific{
			InheritanceTemplate : snr.PlatformSpecific{},
		},
		config.AlderType    : adl.PlatformSpecific{},
	}
	parser.platform = platform[config.PlatformGet()]
}

// PadMapFprint - print pad info map to file
func (parser *ParserData) PadMapFprint() {
	for _, pad := range parser.padmap {
		switch pad.dw0 {
		case 0:
			pad.titleFprint()
		case 0xffffffff:
			pad.reservedFprint()
		default:
			str := parser.platform.GenMacro(pad.id, pad.dw0, pad.dw1, pad.ownership)
			pad.padInfoMacroFprint(str)
		}
	}
}

// Register - read specific platform registers (32 bits)
// line         : string from file with pad config map
// nameTemplate : register name femplate to filter parsed lines
// return
//     valid  : true if the dump of the register in intertool.log is set in accordance
//              with the template
//     name   : full register name
//     offset : register offset relative to the base address
//     value  : register value
func (parser *ParserData) Register(nameTemplate string) (
		valid bool, name string, offset uint32, value uint32) {
	if strings.Contains(parser.line, nameTemplate) &&
		config.TemplateGet() == config.TempInteltool {
		if registerInfoTemplate(parser.line, &name, &offset, &value) == 0 {
			fmt.Printf("\n\t/* %s : 0x%x : 0x%x */\n", name, offset, value)
			return true, name, offset, value
		}
	}
	return false, "ERROR", 0, 0
}

// padOwnershipExtract - extract Host Software Pad Ownership from inteltool dump
//                       return true if success
func (parser *ParserData) padOwnershipExtract() bool {
	var group string
	status, name, offset, value := parser.Register("HOSTSW_OWN_GPP_")
	if status {
		_, group = parser.platform.GroupNameExtract(parser.line)
		parser.ownership[group] = value
		fmt.Printf("\n\t/* padOwnershipExtract: [offset 0x%x] %s = 0x%x */\n",
				offset, name, parser.ownership[group])
	}
	return status
}

// padConfigurationExtract - reads GPIO configuration registers and returns true if the
//                           information from the inteltool log was successfully parsed.
func (parser *ParserData) padConfigurationExtract() bool {
	// Only for Sunrise or CannonLake, and only for inteltool.log file template
	if config.TemplateGet() != config.TempInteltool || config.IsPlatformApollo() {
		return false
	}
	return parser.padOwnershipExtract()
}

// Parse pads groupe information in the inteltool log file
// ConfigFile : name of inteltool log file
func (parser *ParserData) Parse() {
	// Read all lines from inteltool log file
	fmt.Println("Parse IntelTool Log File...")

	// determine the platform type and set the interface for it
	parser.PlatformSpecificInterfaceSet()

	// map of thepad ownership registers for the GPIO controller
	parser.ownership = make(map[string]uint32)

	scanner := bufio.NewScanner(config.InputRegDumpFile)
	for scanner.Scan() {
		parser.line = scanner.Text()
		isIncluded, _ := common.KeywordsCheck(parser.line, "GPIO Community", "GPIO Group");
		if isIncluded {
			parser.communityGroupExtract()
		} else if !parser.padConfigurationExtract() && parser.platform.KeywordCheck(parser.line) {
			if parser.padInfoExtract() != 0 {
				fmt.Println("...error!")
			}
		}
	}
	fmt.Println("...done!")
}