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