coreboot-kgpe-d16/util/intelp2m/parser/parser.go

241 lines
7.4 KiB
Go

package parser
import (
"bufio"
"fmt"
"strings"
"strconv"
)
import "../platforms/common"
import "../platforms/snr"
import "../platforms/lbg"
import "../platforms/apl"
import "../platforms/cnl"
import "../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{},
},
}
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!")
}