/ util / intelp2m / parser / parser.go
parser.go
  1  package parser
  2  
  3  import (
  4  	"bufio"
  5  	"errors"
  6  	"fmt"
  7  	"strconv"
  8  	"strings"
  9  
 10  	"review.coreboot.org/coreboot.git/util/intelp2m/config"
 11  	"review.coreboot.org/coreboot.git/util/intelp2m/platforms/adl"
 12  	"review.coreboot.org/coreboot.git/util/intelp2m/platforms/apl"
 13  	"review.coreboot.org/coreboot.git/util/intelp2m/platforms/cnl"
 14  	"review.coreboot.org/coreboot.git/util/intelp2m/platforms/common"
 15  	"review.coreboot.org/coreboot.git/util/intelp2m/platforms/ebg"
 16  	"review.coreboot.org/coreboot.git/util/intelp2m/platforms/jsl"
 17  	"review.coreboot.org/coreboot.git/util/intelp2m/platforms/lbg"
 18  	"review.coreboot.org/coreboot.git/util/intelp2m/platforms/mtl"
 19  	"review.coreboot.org/coreboot.git/util/intelp2m/platforms/snr"
 20  	"review.coreboot.org/coreboot.git/util/intelp2m/platforms/tgl"
 21  )
 22  
 23  // PlatformSpecific - platform-specific interface
 24  type PlatformSpecific interface {
 25  	GenMacro(id string, dw0 uint32, dw1 uint32, ownership uint8) string
 26  	GroupNameExtract(line string) (bool, string)
 27  	KeywordCheck(line string) bool
 28  }
 29  
 30  // padInfo - information about pad
 31  // id        : pad id string
 32  // offset    : the offset of the register address relative to the base
 33  // function  : the string that means the pad function
 34  // dw0       : DW0 register value
 35  // dw1       : DW1 register value
 36  // ownership : host software ownership
 37  type padInfo struct {
 38  	id        string
 39  	offset    uint16
 40  	function  string
 41  	dw0       uint32
 42  	dw1       uint32
 43  	ownership uint8
 44  }
 45  
 46  // ParserData - global data
 47  // line       : string from the configuration file
 48  // padmap     : pad info map
 49  // RawFmt     : flag for generating pads config file with DW0/1 reg raw values
 50  // Template   : structure template type of ConfigFile
 51  type ParserData struct {
 52  	platform  PlatformSpecific
 53  	line      string
 54  	padmap    []padInfo
 55  	ownership map[string]uint32
 56  }
 57  
 58  // hostOwnershipGet - get the host software ownership value for the corresponding
 59  // pad ID
 60  // id : pad ID string
 61  // return the host software ownership form the parser struct
 62  func (parser *ParserData) hostOwnershipGet(id string) uint8 {
 63  	var ownership uint8 = 0
 64  	status, group := parser.platform.GroupNameExtract(id)
 65  	if config.TemplateGet() == config.TempInteltool && status {
 66  		numder, _ := strconv.Atoi(strings.TrimLeft(id, group))
 67  		if (parser.ownership[group] & (1 << uint8(numder))) != 0 {
 68  			ownership = 1
 69  		}
 70  	}
 71  	return ownership
 72  }
 73  
 74  // padInfoExtract - adds a new entry to pad info map
 75  // return error status
 76  func (parser *ParserData) padInfoExtract() int {
 77  	var function, id string
 78  	var dw0, dw1 uint32
 79  	var template = map[int]template{
 80  		config.TempInteltool: UseInteltoolLogTemplate,
 81  		config.TempGpioh:     useGpioHTemplate,
 82  		config.TempSpec:      useYourTemplate,
 83  	}
 84  	if template[config.TemplateGet()](parser.line, &function, &id, &dw0, &dw1) == 0 {
 85  		pad := padInfo{id: id,
 86  			function:  function,
 87  			dw0:       dw0,
 88  			dw1:       dw1,
 89  			ownership: parser.hostOwnershipGet(id)}
 90  		parser.padmap = append(parser.padmap, pad)
 91  		return 0
 92  	}
 93  	fmt.Printf("This template (%d) does not match!\n", config.TemplateGet())
 94  	return -1
 95  }
 96  
 97  // communityGroupExtract
 98  func (parser *ParserData) communityGroupExtract() {
 99  	pad := padInfo{function: parser.line}
100  	parser.padmap = append(parser.padmap, pad)
101  }
102  
103  // PlatformSpecificInterfaceSet - specific interface for the platform selected
104  // in the configuration
105  func (parser *ParserData) PlatformSpecificInterfaceSet() {
106  	var platform = map[uint8]PlatformSpecific{
107  		config.SunriseType: snr.PlatformSpecific{},
108  		// See platforms/lbg/macro.go
109  		config.LewisburgType: lbg.PlatformSpecific{
110  			InheritanceTemplate: snr.PlatformSpecific{},
111  		},
112  		config.ApolloType: apl.PlatformSpecific{},
113  		config.CannonType: cnl.PlatformSpecific{
114  			InheritanceTemplate: snr.PlatformSpecific{},
115  		},
116  		config.TigerType:  tgl.PlatformSpecific{},
117  		config.AlderType:  adl.PlatformSpecific{},
118  		config.JasperType: jsl.PlatformSpecific{},
119  		config.MeteorType: mtl.PlatformSpecific{},
120  		// See platforms/ebg/macro.go
121  		config.EmmitsburgType: ebg.PlatformSpecific{
122  			InheritanceTemplate: cnl.PlatformSpecific{
123  				InheritanceTemplate: snr.PlatformSpecific{},
124  			},
125  		},
126  	}
127  	parser.platform = platform[config.PlatformGet()]
128  }
129  
130  // Register - read specific platform registers (32 bits)
131  // line         : string from file with pad config map
132  // nameTemplate : register name femplate to filter parsed lines
133  // return
134  //
135  //	valid  : true if the dump of the register in intertool.log is set in accordance
136  //	         with the template
137  //	name   : full register name
138  //	offset : register offset relative to the base address
139  //	value  : register value
140  func (parser *ParserData) Register(nameTemplate string) (
141  	valid bool,
142  	name string,
143  	offset uint32,
144  	value uint32,
145  ) {
146  	if strings.Contains(parser.line, nameTemplate) &&
147  		config.TemplateGet() == config.TempInteltool {
148  		if registerInfoTemplate(parser.line, &name, &offset, &value) == 0 {
149  			fmt.Printf("\n\t/* %s : 0x%x : 0x%x */\n", name, offset, value)
150  			return true, name, offset, value
151  		}
152  	}
153  	return false, "ERROR", 0, 0
154  }
155  
156  // padOwnershipExtract - extract Host Software Pad Ownership from inteltool dump
157  //
158  //	return true if success
159  func (parser *ParserData) padOwnershipExtract() bool {
160  	var group string
161  	status, name, offset, value := parser.Register("HOSTSW_OWN_GPP_")
162  	if status {
163  		_, group = parser.platform.GroupNameExtract(parser.line)
164  		parser.ownership[group] = value
165  		fmt.Printf("\n\t/* padOwnershipExtract: [offset 0x%x] %s = 0x%x */\n",
166  			offset, name, parser.ownership[group])
167  	}
168  	return status
169  }
170  
171  // padConfigurationExtract - reads GPIO configuration registers and returns true if the
172  //
173  //	information from the inteltool log was successfully parsed.
174  func (parser *ParserData) padConfigurationExtract() bool {
175  	// Only for Sunrise or CannonLake, and only for inteltool.log file template
176  	if config.TemplateGet() != config.TempInteltool || config.IsPlatformApollo() {
177  		return false
178  	}
179  	return parser.padOwnershipExtract()
180  }
181  
182  // Parse pads groupe information in the inteltool log file
183  // ConfigFile : name of inteltool log file
184  func (parser *ParserData) Parse() {
185  	// Read all lines from inteltool log file
186  	fmt.Println("Parse IntelTool Log File...")
187  
188  	// determine the platform type and set the interface for it
189  	parser.PlatformSpecificInterfaceSet()
190  
191  	// map of thepad ownership registers for the GPIO controller
192  	parser.ownership = make(map[string]uint32)
193  
194  	scanner := bufio.NewScanner(config.InputRegDumpFile)
195  	for scanner.Scan() {
196  		parser.line = scanner.Text()
197  		isIncluded, _ := common.KeywordsCheck(parser.line, "GPIO Community", "GPIO Group")
198  		if isIncluded {
199  			parser.communityGroupExtract()
200  		} else if !parser.padConfigurationExtract() && parser.platform.KeywordCheck(parser.line) {
201  			if parser.padInfoExtract() != 0 {
202  				fmt.Println("...error!")
203  			}
204  		}
205  	}
206  	fmt.Println("...done!")
207  }
208  
209  type PrinterIf interface {
210  	Linef(lvl int, format string, args ...interface{})
211  	Line(lvl int, str string)
212  }
213  
214  type Generator struct {
215  	Data      *ParserData // information from the parser
216  	PrinterIf             // interface for printing
217  }
218  
219  // Run - generate a new gpio file based on the information from the parser
220  func (g Generator) Run() error {
221  	if g.PrinterIf == nil && g.Data == nil {
222  		return errors.New("Generator: Incorrect initialization")
223  	}
224  	for _, pad := range g.Data.padmap {
225  		switch pad.dw0 {
226  		case 0x00000000:
227  			// titleFprint - print GPIO group title to file
228  			// /* ------- GPIO Group GPP_L ------- */
229  			g.Linef(0, "\n\t/* %s */\n", pad.function)
230  		case 0xffffffff:
231  			// reservedFprint - print reserved GPIO to file as comment
232  			// /* GPP_H17 - RESERVED */
233  			g.Line(2, "\n")
234  			// small comment about reserved port
235  			g.Linef(0, "\t/* %s - %s */\n", pad.id, pad.function)
236  		default:
237  			// padInfoMacroFprint - print information about current pad to file using
238  			// special macros:
239  			// PAD_CFG_NF(GPP_F1, 20K_PU, PLTRST, NF1), /* SATAXPCIE4 */
240  			platform := g.Data.platform
241  			macro := platform.GenMacro(pad.id, pad.dw0, pad.dw1, pad.ownership)
242  			g.Linef(2, "\n\t/* %s - %s */\n\t/* DW0: 0x%0.8x, DW1: 0x%0.8x */\n",
243  				pad.id, pad.function, pad.dw0, pad.dw1)
244  			g.Linef(0, "\t%s", macro)
245  			if config.InfoLevelGet() == 1 {
246  				g.Linef(1, "\t/* %s */", pad.function)
247  			}
248  			g.Line(0, "\n")
249  		}
250  	}
251  	return nil
252  }