util/intelp2m: Rewrite parser

- Split the parser code into several packages to make its testing of its
  functions more convenient and detailed. This also makes embedding the
  parser in third-party applications more flexible - there is no need to
  use all the functionality of the parser.

- Clean up code and remove unnecessary objects to make intelp2m simpler
  and more readable.

- Change the common macro format to be consistent with the new parser.

- Rename the results directory containing gpio.h to output to avoid
  confusion with the generator package directory.

- At the moment there is no mechanism for setting the Ownership flag.
  This will be added in later versions.

Tests:
- make test = PASS
- gpio.h for Apollo Lake before and after the patch is the same

Change-Id: I9a29322dd31faf9ae100165f08f207360cbf9f80
Signed-off-by: Maxim Polyakov <max.senia.poliak@gmail.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/70543
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: David Hendricks <david.hendricks@gmail.com>
This commit is contained in:
Maxim Polyakov 2022-12-08 10:44:46 +03:00 committed by Felix Singer
commit e91324707e
22 changed files with 1006 additions and 357 deletions

View file

@ -5,7 +5,7 @@ THIS_FILE := $(lastword $(MAKEFILE_LIST))
THIS_DIR := $(abspath $(dir $(THIS_FILE)))
SCRIPTS_DIR := $(THIS_DIR)/scripts/linux
OUTPUT_DIR := $(THIS_DIR)/generate
OUTPUT_DIR := $(THIS_DIR)/output
VERSION ?= $(shell $(SCRIPTS_DIR)/version.sh)
LDFLAGS = "-X main.Version=$(VERSION)"

View file

@ -192,8 +192,9 @@ func cbOptionsInfo(_ string) error {
func ParseOptions() {
flag.Usage = Usage
flag.StringVar(&p2m.Config.InputPath, "file", "inteltool.log", "")
flag.StringVar(&p2m.Config.OutputPath, "out", "generate/gpio.h", "")
flag.StringVar(&p2m.Config.OutputPath, "out", "output/gpio.h", "")
flag.StringVar(&p2m.Config.LogsPath, "logs", "logs.txt", "")
help := flag.Bool("help", false, "")

View file

@ -2,7 +2,6 @@ package p2m
import (
"fmt"
"os"
)
type PlatformType int
@ -53,14 +52,12 @@ type Settings struct {
InputPath string
OutputPath string
LogsPath string
InputFile *os.File
OutputFile *os.File
IgnoredFields bool
AutoCheck bool
GenLevel int
}
var Config = Settings{
var defaultConfig = Settings{
Version: "unknown",
Platform: Sunrise,
Field: NoFlds,
@ -69,6 +66,12 @@ var Config = Settings{
GenLevel: 0,
}
var Config = defaultConfig
func SettingsReset() {
Config = defaultConfig
}
func SetPlatformType(format string) error {
if _, exist := platforms[format]; !exist {
return fmt.Errorf("unknown platform type %s", format)

View file

@ -0,0 +1,64 @@
package generator
import (
"fmt"
"review.coreboot.org/coreboot.git/util/intelp2m/config/p2m"
"review.coreboot.org/coreboot.git/util/intelp2m/logs"
"review.coreboot.org/coreboot.git/util/intelp2m/parser"
)
type collector []string
func (c *collector) Line(str string) {
*c = append(*c, str)
}
func (c *collector) Linef(format string, args ...interface{}) {
*c = append(*c, fmt.Sprintf(format, args...))
}
// Run() generates strings with macros
func Run(entries []parser.Entry) ([]string, error) {
if len(entries) == 0 {
err := fmt.Errorf("entries array is empty")
logs.Errorf("%v", err)
return nil, err
}
collection := make(collector, 0)
logs.Infof("run")
for _, entry := range entries {
switch entry.EType {
case parser.EntryGroup:
collection.Line("\n")
collection.Linef("\t/* %s */\n", entry.Function)
case parser.EntryReserved:
if p2m.Config.GenLevel >= 2 {
collection.Line("\n")
}
collection.Linef("\t/* %s - %s */\n", entry.ID, entry.Function)
case parser.EntryPad:
if p2m.Config.GenLevel >= 2 {
collection.Line("\n")
collection.Linef("\t/* %s - %s */\n", entry.ID, entry.Function)
collection.Linef("\t/* DW0: 0x%0.8x, DW1: 0x%0.8x */\n", entry.DW0, entry.DW1)
}
lines := entry.ToMacro()
if p2m.Config.GenLevel == 1 && len(lines) != 0 {
collection.Linef("\t%s\t/* %s */\n", lines[0], entry.Function)
break
}
for i := range lines {
collection.Linef("\t%s\n", lines[i])
}
default:
logs.Errorf("unknown entry type: %d", int(entry.EType))
}
}
logs.Infof("successfully completed: %d rows", len(collection))
return collection, nil
}

View file

@ -0,0 +1,63 @@
package generator_test
import (
"strings"
"testing"
"review.coreboot.org/coreboot.git/util/intelp2m/config/p2m"
"review.coreboot.org/coreboot.git/util/intelp2m/generator"
"review.coreboot.org/coreboot.git/util/intelp2m/generator/testsuites"
parsertest "review.coreboot.org/coreboot.git/util/intelp2m/parser/test"
)
func do(t *testing.T, reference string) {
actually, err := generator.Run(parsertest.Suite)
if err != nil {
t.Errorf("failed to run generator: %v", err)
}
expects := strings.SplitAfter(reference, "\n")
for i := range actually {
if expects[i] != actually[i] {
t.Errorf("row number %d:\n\tExpects: <%s>\n\tActually <%s>",
i, expects[i], actually[i])
}
}
}
func TestGenerator(t *testing.T) {
t.Run("GENERATOR/I0-NO-COMMENTS", func(t *testing.T) {
p2m.SettingsReset()
p2m.Config.AutoCheck = false
do(t, testsuites.ReferenceI0NoComments)
})
t.Run("GENERATOR/I1-WITH-COMMENTS", func(t *testing.T) {
p2m.SettingsReset()
p2m.Config.AutoCheck = false
p2m.Config.GenLevel = 1
do(t, testsuites.ReferenceI1Comments)
})
t.Run("GENERATOR/I2-AUTO-CHECK", func(t *testing.T) {
p2m.SettingsReset()
p2m.Config.GenLevel = 2
do(t, testsuites.ReferenceI2AutoCheck)
})
t.Run("GENERATOR/I3-UNCHECK", func(t *testing.T) {
p2m.SettingsReset()
p2m.Config.AutoCheck = false
p2m.Config.IgnoredFields = true
p2m.Config.GenLevel = 3
do(t, testsuites.ReferenceI3Uncheck)
})
t.Run("GENERATOR/I4-EXCLUDE-UNUSED-CB-FIELDS", func(t *testing.T) {
p2m.SettingsReset()
p2m.Config.IgnoredFields = true
p2m.Config.Field = p2m.CbFlds
p2m.Config.GenLevel = 4
do(t, testsuites.ReferenceI4ExcludeUnusedCbFlds)
})
}

View file

@ -0,0 +1,30 @@
package header
import (
"fmt"
"review.coreboot.org/coreboot.git/util/intelp2m/config/p2m"
)
const fileHeader string = `/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef CFG_GPIO_H
#define CFG_GPIO_H
#include <gpio.h>
/* Pad configuration was generated automatically using intelp2m %s */
static const struct pad_config gpio_table[] = {`
const completion string = `};
#endif /* CFG_GPIO_H */
`
func Add(lines []string) []string {
wrapper := make([]string, 0)
wrapper = append(wrapper, fmt.Sprintf(fileHeader, p2m.Config.Version))
wrapper = append(wrapper, lines...)
wrapper = append(wrapper, completion)
return wrapper
}

View file

@ -0,0 +1,35 @@
package printer
import (
"fmt"
"os"
"path/filepath"
"review.coreboot.org/coreboot.git/util/intelp2m/config/p2m"
"review.coreboot.org/coreboot.git/util/intelp2m/logs"
)
func Do(rows []string) error {
path := p2m.Config.OutputPath
if err := os.MkdirAll(filepath.Dir(path), os.ModePerm); err != nil {
logs.Errorf("failed to create output directory: %v", err)
return err
}
file, err := os.Create(path)
if err != nil {
logs.Errorf("failed to create output file: %v", err)
return err
}
defer file.Close()
logs.Infof("write lines to file %s", path)
for i := range rows {
if _, err := fmt.Fprint(file, rows[i]); err != nil {
logs.Errorf("failed to write: %v", err)
return err
}
}
logs.Infof("successfully completed: %d rows", len(rows))
return nil
}

View file

@ -0,0 +1,46 @@
package testsuites
const ReferenceI0NoComments = `
/* ------- GPIO Community 0 ------- */
/* ------- GPIO Group GPP_A ------- */
PAD_CFG_NF(GPP_A0, NONE, PLTRST, NF1),
PAD_CFG_NF(GPP_A1, UP_20K, PLTRST, NF1),
PAD_CFG_NF(GPP_A5, NONE, PLTRST, NF1),
PAD_CFG_NF(GPP_A13, NONE, DEEP, NF1),
PAD_CFG_GPI_TRIG_OWN(GPP_A23, NONE, PLTRST, OFF, ACPI),
/* ------- GPIO Group GPP_B ------- */
/* GPP_C1 - RESERVED */
PAD_CFG_GPI_TRIG_OWN(GPP_B0, NONE, PLTRST, OFF, ACPI),
PAD_CFG_NF(GPP_B23, DN_20K, PLTRST, NF2),
/* ------- GPIO Community 1 ------- */
/* ------- GPIO Group GPP_C ------- */
PAD_CFG_NF(GPP_C0, NONE, DEEP, NF1),
PAD_CFG_GPI_TRIG_OWN(GPP_C5, NONE, PLTRST, OFF, ACPI),
/* GPP_C6 - RESERVED */
/* GPP_C7 - RESERVED */
PAD_CFG_NF(GPP_C22, NONE, PLTRST, NF1),
/* ------- GPIO Group GPP_D ------- */
/* ------- GPIO Group GPP_E ------- */
PAD_CFG_NF(GPP_E0, UP_20K, PLTRST, NF1),
/* ------- GPIO Group GPP_G ------- */
PAD_CFG_NF(GPP_G19, NONE, PLTRST, NF1),
/* ------- GPIO Community 2 ------- */
/* -------- GPIO Group GPD -------- */
PAD_CFG_NF(GPD9, NONE, PWROK, NF1),
/* ------- GPIO Community 3 ------- */
/* ------- GPIO Group GPP_I ------- */
PAD_CFG_NF(GPP_I0, NONE, PLTRST, NF1),
PAD_CFG_NF(GPP_I1, NONE, PLTRST, NF1),
PAD_CFG_NF(GPP_I2, NONE, PLTRST, NF1),
`

View file

@ -0,0 +1,46 @@
package testsuites
const ReferenceI1Comments = `
/* ------- GPIO Community 0 ------- */
/* ------- GPIO Group GPP_A ------- */
PAD_CFG_NF(GPP_A0, NONE, PLTRST, NF1), /* RCIN# */
PAD_CFG_NF(GPP_A1, UP_20K, PLTRST, NF1), /* LAD0 */
PAD_CFG_NF(GPP_A5, NONE, PLTRST, NF1), /* LFRAME# */
PAD_CFG_NF(GPP_A13, NONE, DEEP, NF1), /* SUSWARN#/SUSPWRDNACK */
PAD_CFG_GPI_TRIG_OWN(GPP_A23, NONE, PLTRST, OFF, ACPI), /* GPIO */
/* ------- GPIO Group GPP_B ------- */
/* GPP_C1 - RESERVED */
PAD_CFG_GPI_TRIG_OWN(GPP_B0, NONE, PLTRST, OFF, ACPI), /* GPIO */
PAD_CFG_NF(GPP_B23, DN_20K, PLTRST, NF2), /* PCHHOT# */
/* ------- GPIO Community 1 ------- */
/* ------- GPIO Group GPP_C ------- */
PAD_CFG_NF(GPP_C0, NONE, DEEP, NF1), /* SMBCLK */
PAD_CFG_GPI_TRIG_OWN(GPP_C5, NONE, PLTRST, OFF, ACPI), /* GPIO */
/* GPP_C6 - RESERVED */
/* GPP_C7 - RESERVED */
PAD_CFG_NF(GPP_C22, NONE, PLTRST, NF1), /* UART2_RTS# */
/* ------- GPIO Group GPP_D ------- */
/* ------- GPIO Group GPP_E ------- */
PAD_CFG_NF(GPP_E0, UP_20K, PLTRST, NF1), /* SATAXPCIE0 */
/* ------- GPIO Group GPP_G ------- */
PAD_CFG_NF(GPP_G19, NONE, PLTRST, NF1), /* SMI# */
/* ------- GPIO Community 2 ------- */
/* -------- GPIO Group GPD -------- */
PAD_CFG_NF(GPD9, NONE, PWROK, NF1), /* SLP_WLAN# */
/* ------- GPIO Community 3 ------- */
/* ------- GPIO Group GPP_I ------- */
PAD_CFG_NF(GPP_I0, NONE, PLTRST, NF1), /* DDPB_HPD0 */
PAD_CFG_NF(GPP_I1, NONE, PLTRST, NF1), /* DDPC_HPD1 */
PAD_CFG_NF(GPP_I2, NONE, PLTRST, NF1), /* DDPD_HPD2 */
`

View file

@ -0,0 +1,97 @@
package testsuites
const ReferenceI2AutoCheck string = `
/* ------- GPIO Community 0 ------- */
/* ------- GPIO Group GPP_A ------- */
/* GPP_A0 - RCIN# */
/* DW0: 0x84000502, DW1: 0x00000000 */
_PAD_CFG_STRUCT(GPP_A0, PAD_FUNC(NF1) | PAD_RESET(PLTRST) | PAD_TRIG(OFF) | PAD_BUF(TX_DISABLE) | (1 << 1), 0),
/* GPP_A1 - LAD0 */
/* DW0: 0x84000402, DW1: 0x00003000 */
_PAD_CFG_STRUCT(GPP_A1, PAD_FUNC(NF1) | PAD_RESET(PLTRST) | PAD_TRIG(OFF) | (1 << 1), PAD_PULL(UP_20K)),
/* GPP_A5 - LFRAME# */
/* DW0: 0x84000600, DW1: 0x00000000 */
_PAD_CFG_STRUCT(GPP_A5, PAD_FUNC(NF1) | PAD_RESET(PLTRST) | PAD_TRIG(OFF) | PAD_BUF(RX_DISABLE), 0),
/* GPP_A13 - SUSWARN#/SUSPWRDNACK */
/* DW0: 0x44000600, DW1: 0x00000000 */
_PAD_CFG_STRUCT(GPP_A13, PAD_FUNC(NF1) | PAD_RESET(DEEP) | PAD_TRIG(OFF) | PAD_BUF(RX_DISABLE), 0),
/* GPP_A23 - GPIO */
/* DW0: 0x84000102, DW1: 0x00000000 */
_PAD_CFG_STRUCT(GPP_A23, PAD_FUNC(GPIO) | PAD_RESET(PLTRST) | PAD_TRIG(OFF) | PAD_BUF(TX_DISABLE) | (1 << 1), 0),
/* ------- GPIO Group GPP_B ------- */
/* GPP_C1 - RESERVED */
/* GPP_B0 - GPIO */
/* DW0: 0x84000100, DW1: 0x00000000 */
PAD_CFG_GPI_TRIG_OWN(GPP_B0, NONE, PLTRST, OFF, ACPI),
/* GPP_B23 - PCHHOT# */
/* DW0: 0x84000a01, DW1: 0x00001000 */
_PAD_CFG_STRUCT(GPP_B23, PAD_FUNC(NF2) | PAD_RESET(PLTRST) | PAD_TRIG(OFF) | PAD_BUF(RX_DISABLE) | 1, PAD_PULL(DN_20K)),
/* ------- GPIO Community 1 ------- */
/* ------- GPIO Group GPP_C ------- */
/* GPP_C0 - SMBCLK */
/* DW0: 0x44000502, DW1: 0x00000000 */
_PAD_CFG_STRUCT(GPP_C0, PAD_FUNC(NF1) | PAD_RESET(DEEP) | PAD_TRIG(OFF) | PAD_BUF(TX_DISABLE) | (1 << 1), 0),
/* GPP_C5 - GPIO */
/* DW0: 0x84000100, DW1: 0x00000000 */
PAD_CFG_GPI_TRIG_OWN(GPP_C5, NONE, PLTRST, OFF, ACPI),
/* GPP_C6 - RESERVED */
/* GPP_C7 - RESERVED */
/* GPP_C22 - UART2_RTS# */
/* DW0: 0x84000600, DW1: 0x00000000 */
_PAD_CFG_STRUCT(GPP_C22, PAD_FUNC(NF1) | PAD_RESET(PLTRST) | PAD_TRIG(OFF) | PAD_BUF(RX_DISABLE), 0),
/* ------- GPIO Group GPP_D ------- */
/* ------- GPIO Group GPP_E ------- */
/* GPP_E0 - SATAXPCIE0 */
/* DW0: 0x84000502, DW1: 0x00003000 */
_PAD_CFG_STRUCT(GPP_E0, PAD_FUNC(NF1) | PAD_RESET(PLTRST) | PAD_TRIG(OFF) | PAD_BUF(TX_DISABLE) | (1 << 1), PAD_PULL(UP_20K)),
/* ------- GPIO Group GPP_G ------- */
/* GPP_G19 - SMI# */
/* DW0: 0x84000500, DW1: 0x00000000 */
_PAD_CFG_STRUCT(GPP_G19, PAD_FUNC(NF1) | PAD_RESET(PLTRST) | PAD_TRIG(OFF) | PAD_BUF(TX_DISABLE), 0),
/* ------- GPIO Community 2 ------- */
/* -------- GPIO Group GPD -------- */
/* GPD9 - SLP_WLAN# */
/* DW0: 0x04000600, DW1: 0x00000000 */
_PAD_CFG_STRUCT(GPD9, PAD_FUNC(NF1) | PAD_TRIG(OFF) | PAD_BUF(RX_DISABLE), 0),
/* ------- GPIO Community 3 ------- */
/* ------- GPIO Group GPP_I ------- */
/* GPP_I0 - DDPB_HPD0 */
/* DW0: 0x84000500, DW1: 0x00000000 */
_PAD_CFG_STRUCT(GPP_I0, PAD_FUNC(NF1) | PAD_RESET(PLTRST) | PAD_TRIG(OFF) | PAD_BUF(TX_DISABLE), 0),
/* GPP_I1 - DDPC_HPD1 */
/* DW0: 0x84000502, DW1: 0x00000000 */
_PAD_CFG_STRUCT(GPP_I1, PAD_FUNC(NF1) | PAD_RESET(PLTRST) | PAD_TRIG(OFF) | PAD_BUF(TX_DISABLE) | (1 << 1), 0),
/* GPP_I2 - DDPD_HPD2 */
/* DW0: 0x84000502, DW1: 0x00000000 */
_PAD_CFG_STRUCT(GPP_I2, PAD_FUNC(NF1) | PAD_RESET(PLTRST) | PAD_TRIG(OFF) | PAD_BUF(TX_DISABLE) | (1 << 1), 0),
`

View file

@ -0,0 +1,111 @@
package testsuites
const ReferenceI3Uncheck string = `
/* ------- GPIO Community 0 ------- */
/* ------- GPIO Group GPP_A ------- */
/* GPP_A0 - RCIN# */
/* DW0: 0x84000502, DW1: 0x00000000 */
/* DW0: PAD_TRIG(OFF) | PAD_BUF(TX_DISABLE) | (1 << 1) - IGNORED */
PAD_CFG_NF(GPP_A0, NONE, PLTRST, NF1),
/* GPP_A1 - LAD0 */
/* DW0: 0x84000402, DW1: 0x00003000 */
/* DW0: PAD_TRIG(OFF) | (1 << 1) - IGNORED */
PAD_CFG_NF(GPP_A1, UP_20K, PLTRST, NF1),
/* GPP_A5 - LFRAME# */
/* DW0: 0x84000600, DW1: 0x00000000 */
/* DW0: PAD_TRIG(OFF) | PAD_BUF(RX_DISABLE) - IGNORED */
PAD_CFG_NF(GPP_A5, NONE, PLTRST, NF1),
/* GPP_A13 - SUSWARN#/SUSPWRDNACK */
/* DW0: 0x44000600, DW1: 0x00000000 */
/* DW0: PAD_TRIG(OFF) | PAD_BUF(RX_DISABLE) - IGNORED */
PAD_CFG_NF(GPP_A13, NONE, DEEP, NF1),
/* GPP_A23 - GPIO */
/* DW0: 0x84000102, DW1: 0x00000000 */
/* DW0: (1 << 1) - IGNORED */
PAD_CFG_GPI_TRIG_OWN(GPP_A23, NONE, PLTRST, OFF, ACPI),
/* ------- GPIO Group GPP_B ------- */
/* GPP_C1 - RESERVED */
/* GPP_B0 - GPIO */
/* DW0: 0x84000100, DW1: 0x00000000 */
PAD_CFG_GPI_TRIG_OWN(GPP_B0, NONE, PLTRST, OFF, ACPI),
/* GPP_B23 - PCHHOT# */
/* DW0: 0x84000a01, DW1: 0x00001000 */
/* DW0: PAD_TRIG(OFF) | PAD_BUF(RX_DISABLE) | 1 - IGNORED */
PAD_CFG_NF(GPP_B23, DN_20K, PLTRST, NF2),
/* ------- GPIO Community 1 ------- */
/* ------- GPIO Group GPP_C ------- */
/* GPP_C0 - SMBCLK */
/* DW0: 0x44000502, DW1: 0x00000000 */
/* DW0: PAD_TRIG(OFF) | PAD_BUF(TX_DISABLE) | (1 << 1) - IGNORED */
PAD_CFG_NF(GPP_C0, NONE, DEEP, NF1),
/* GPP_C5 - GPIO */
/* DW0: 0x84000100, DW1: 0x00000000 */
PAD_CFG_GPI_TRIG_OWN(GPP_C5, NONE, PLTRST, OFF, ACPI),
/* GPP_C6 - RESERVED */
/* GPP_C7 - RESERVED */
/* GPP_C22 - UART2_RTS# */
/* DW0: 0x84000600, DW1: 0x00000000 */
/* DW0: PAD_TRIG(OFF) | PAD_BUF(RX_DISABLE) - IGNORED */
PAD_CFG_NF(GPP_C22, NONE, PLTRST, NF1),
/* ------- GPIO Group GPP_D ------- */
/* ------- GPIO Group GPP_E ------- */
/* GPP_E0 - SATAXPCIE0 */
/* DW0: 0x84000502, DW1: 0x00003000 */
/* DW0: PAD_TRIG(OFF) | PAD_BUF(TX_DISABLE) | (1 << 1) - IGNORED */
PAD_CFG_NF(GPP_E0, UP_20K, PLTRST, NF1),
/* ------- GPIO Group GPP_G ------- */
/* GPP_G19 - SMI# */
/* DW0: 0x84000500, DW1: 0x00000000 */
/* DW0: PAD_TRIG(OFF) | PAD_BUF(TX_DISABLE) - IGNORED */
PAD_CFG_NF(GPP_G19, NONE, PLTRST, NF1),
/* ------- GPIO Community 2 ------- */
/* -------- GPIO Group GPD -------- */
/* GPD9 - SLP_WLAN# */
/* DW0: 0x04000600, DW1: 0x00000000 */
/* DW0: PAD_TRIG(OFF) | PAD_BUF(RX_DISABLE) - IGNORED */
PAD_CFG_NF(GPD9, NONE, PWROK, NF1),
/* ------- GPIO Community 3 ------- */
/* ------- GPIO Group GPP_I ------- */
/* GPP_I0 - DDPB_HPD0 */
/* DW0: 0x84000500, DW1: 0x00000000 */
/* DW0: PAD_TRIG(OFF) | PAD_BUF(TX_DISABLE) - IGNORED */
PAD_CFG_NF(GPP_I0, NONE, PLTRST, NF1),
/* GPP_I1 - DDPC_HPD1 */
/* DW0: 0x84000502, DW1: 0x00000000 */
/* DW0: PAD_TRIG(OFF) | PAD_BUF(TX_DISABLE) | (1 << 1) - IGNORED */
PAD_CFG_NF(GPP_I1, NONE, PLTRST, NF1),
/* GPP_I2 - DDPD_HPD2 */
/* DW0: 0x84000502, DW1: 0x00000000 */
/* DW0: PAD_TRIG(OFF) | PAD_BUF(TX_DISABLE) | (1 << 1) - IGNORED */
PAD_CFG_NF(GPP_I2, NONE, PLTRST, NF1),
`

View file

@ -0,0 +1,127 @@
package testsuites
const ReferenceI4ExcludeUnusedCbFlds string = `
/* ------- GPIO Community 0 ------- */
/* ------- GPIO Group GPP_A ------- */
/* GPP_A0 - RCIN# */
/* DW0: 0x84000502, DW1: 0x00000000 */
/* DW0: PAD_TRIG(OFF) | PAD_BUF(TX_DISABLE) | (1 << 1) - IGNORED */
/* PAD_CFG_NF(GPP_A0, NONE, PLTRST, NF1), */
_PAD_CFG_STRUCT(GPP_A0, PAD_FUNC(NF1) | PAD_RESET(PLTRST), 0),
/* GPP_A1 - LAD0 */
/* DW0: 0x84000402, DW1: 0x00003000 */
/* DW0: PAD_TRIG(OFF) | (1 << 1) - IGNORED */
/* PAD_CFG_NF(GPP_A1, UP_20K, PLTRST, NF1), */
_PAD_CFG_STRUCT(GPP_A1, PAD_FUNC(NF1) | PAD_RESET(PLTRST), PAD_PULL(UP_20K)),
/* GPP_A5 - LFRAME# */
/* DW0: 0x84000600, DW1: 0x00000000 */
/* DW0: PAD_TRIG(OFF) | PAD_BUF(RX_DISABLE) - IGNORED */
/* PAD_CFG_NF(GPP_A5, NONE, PLTRST, NF1), */
_PAD_CFG_STRUCT(GPP_A5, PAD_FUNC(NF1) | PAD_RESET(PLTRST), 0),
/* GPP_A13 - SUSWARN#/SUSPWRDNACK */
/* DW0: 0x44000600, DW1: 0x00000000 */
/* DW0: PAD_TRIG(OFF) | PAD_BUF(RX_DISABLE) - IGNORED */
/* PAD_CFG_NF(GPP_A13, NONE, DEEP, NF1), */
_PAD_CFG_STRUCT(GPP_A13, PAD_FUNC(NF1) | PAD_RESET(DEEP), 0),
/* GPP_A23 - GPIO */
/* DW0: 0x84000102, DW1: 0x00000000 */
/* DW0: (1 << 1) - IGNORED */
/* PAD_CFG_GPI_TRIG_OWN(GPP_A23, NONE, PLTRST, OFF, ACPI), */
_PAD_CFG_STRUCT(GPP_A23, PAD_RESET(PLTRST) | PAD_TRIG(OFF) | PAD_BUF(TX_DISABLE), 0),
/* ------- GPIO Group GPP_B ------- */
/* GPP_C1 - RESERVED */
/* GPP_B0 - GPIO */
/* DW0: 0x84000100, DW1: 0x00000000 */
/* PAD_CFG_GPI_TRIG_OWN(GPP_B0, NONE, PLTRST, OFF, ACPI), */
_PAD_CFG_STRUCT(GPP_B0, PAD_RESET(PLTRST) | PAD_TRIG(OFF) | PAD_BUF(TX_DISABLE), 0),
/* GPP_B23 - PCHHOT# */
/* DW0: 0x84000a01, DW1: 0x00001000 */
/* DW0: PAD_TRIG(OFF) | PAD_BUF(RX_DISABLE) | 1 - IGNORED */
/* PAD_CFG_NF(GPP_B23, DN_20K, PLTRST, NF2), */
_PAD_CFG_STRUCT(GPP_B23, PAD_FUNC(NF2) | PAD_RESET(PLTRST), PAD_PULL(DN_20K)),
/* ------- GPIO Community 1 ------- */
/* ------- GPIO Group GPP_C ------- */
/* GPP_C0 - SMBCLK */
/* DW0: 0x44000502, DW1: 0x00000000 */
/* DW0: PAD_TRIG(OFF) | PAD_BUF(TX_DISABLE) | (1 << 1) - IGNORED */
/* PAD_CFG_NF(GPP_C0, NONE, DEEP, NF1), */
_PAD_CFG_STRUCT(GPP_C0, PAD_FUNC(NF1) | PAD_RESET(DEEP), 0),
/* GPP_C5 - GPIO */
/* DW0: 0x84000100, DW1: 0x00000000 */
/* PAD_CFG_GPI_TRIG_OWN(GPP_C5, NONE, PLTRST, OFF, ACPI), */
_PAD_CFG_STRUCT(GPP_C5, PAD_RESET(PLTRST) | PAD_TRIG(OFF) | PAD_BUF(TX_DISABLE), 0),
/* GPP_C6 - RESERVED */
/* GPP_C7 - RESERVED */
/* GPP_C22 - UART2_RTS# */
/* DW0: 0x84000600, DW1: 0x00000000 */
/* DW0: PAD_TRIG(OFF) | PAD_BUF(RX_DISABLE) - IGNORED */
/* PAD_CFG_NF(GPP_C22, NONE, PLTRST, NF1), */
_PAD_CFG_STRUCT(GPP_C22, PAD_FUNC(NF1) | PAD_RESET(PLTRST), 0),
/* ------- GPIO Group GPP_D ------- */
/* ------- GPIO Group GPP_E ------- */
/* GPP_E0 - SATAXPCIE0 */
/* DW0: 0x84000502, DW1: 0x00003000 */
/* DW0: PAD_TRIG(OFF) | PAD_BUF(TX_DISABLE) | (1 << 1) - IGNORED */
/* PAD_CFG_NF(GPP_E0, UP_20K, PLTRST, NF1), */
_PAD_CFG_STRUCT(GPP_E0, PAD_FUNC(NF1) | PAD_RESET(PLTRST), PAD_PULL(UP_20K)),
/* ------- GPIO Group GPP_G ------- */
/* GPP_G19 - SMI# */
/* DW0: 0x84000500, DW1: 0x00000000 */
/* DW0: PAD_TRIG(OFF) | PAD_BUF(TX_DISABLE) - IGNORED */
/* PAD_CFG_NF(GPP_G19, NONE, PLTRST, NF1), */
_PAD_CFG_STRUCT(GPP_G19, PAD_FUNC(NF1) | PAD_RESET(PLTRST), 0),
/* ------- GPIO Community 2 ------- */
/* -------- GPIO Group GPD -------- */
/* GPD9 - SLP_WLAN# */
/* DW0: 0x04000600, DW1: 0x00000000 */
/* DW0: PAD_TRIG(OFF) | PAD_BUF(RX_DISABLE) - IGNORED */
/* PAD_CFG_NF(GPD9, NONE, PWROK, NF1), */
_PAD_CFG_STRUCT(GPD9, PAD_FUNC(NF1), 0),
/* ------- GPIO Community 3 ------- */
/* ------- GPIO Group GPP_I ------- */
/* GPP_I0 - DDPB_HPD0 */
/* DW0: 0x84000500, DW1: 0x00000000 */
/* DW0: PAD_TRIG(OFF) | PAD_BUF(TX_DISABLE) - IGNORED */
/* PAD_CFG_NF(GPP_I0, NONE, PLTRST, NF1), */
_PAD_CFG_STRUCT(GPP_I0, PAD_FUNC(NF1) | PAD_RESET(PLTRST), 0),
/* GPP_I1 - DDPC_HPD1 */
/* DW0: 0x84000502, DW1: 0x00000000 */
/* DW0: PAD_TRIG(OFF) | PAD_BUF(TX_DISABLE) | (1 << 1) - IGNORED */
/* PAD_CFG_NF(GPP_I1, NONE, PLTRST, NF1), */
_PAD_CFG_STRUCT(GPP_I1, PAD_FUNC(NF1) | PAD_RESET(PLTRST), 0),
/* GPP_I2 - DDPD_HPD2 */
/* DW0: 0x84000502, DW1: 0x00000000 */
/* DW0: PAD_TRIG(OFF) | PAD_BUF(TX_DISABLE) | (1 << 1) - IGNORED */
/* PAD_CFG_NF(GPP_I2, NONE, PLTRST, NF1), */
_PAD_CFG_STRUCT(GPP_I2, PAD_FUNC(NF1) | PAD_RESET(PLTRST), 0),
`

View file

@ -3,28 +3,17 @@ package main
import (
"fmt"
"os"
"path/filepath"
"time"
"review.coreboot.org/coreboot.git/util/intelp2m/cli"
"review.coreboot.org/coreboot.git/util/intelp2m/config/p2m"
"review.coreboot.org/coreboot.git/util/intelp2m/generator"
"review.coreboot.org/coreboot.git/util/intelp2m/generator/header"
"review.coreboot.org/coreboot.git/util/intelp2m/generator/printer"
"review.coreboot.org/coreboot.git/util/intelp2m/logs"
"review.coreboot.org/coreboot.git/util/intelp2m/parser"
)
type Printer struct{}
func (Printer) Linef(lvl int, format string, args ...interface{}) {
if p2m.Config.GenLevel >= lvl {
fmt.Fprintf(p2m.Config.OutputFile, format, args...)
}
}
func (Printer) Line(lvl int, str string) {
if p2m.Config.GenLevel >= lvl {
fmt.Fprint(p2m.Config.OutputFile, str)
}
}
// Version is injected into main during project build
var Version string = "Unknown"
@ -41,55 +30,29 @@ func main() {
defer file.Close()
}
if file, err := os.Open(p2m.Config.InputPath); err != nil {
fmt.Printf("input file error: %v\n", err)
os.Exit(1)
} else {
p2m.Config.InputFile = file
defer file.Close()
}
year, month, day := time.Now().Date()
hour, min, sec := time.Now().Clock()
logs.Infof("%d-%d-%d %d:%d:%d", year, month, day, hour, min, sec)
logs.Infof("============ start ============")
if err := os.MkdirAll(filepath.Dir(p2m.Config.OutputPath), os.ModePerm); err != nil {
fmt.Printf("failed to create output directory: %v\n", err)
entries, err := parser.Run()
if err != nil {
fmt.Print("failed to run parser")
os.Exit(1)
}
if file, err := os.Create(p2m.Config.OutputPath); err != nil {
fmt.Printf("failed to create output file: %v\n", err)
os.Exit(1)
} else {
p2m.Config.OutputFile = file
defer file.Close()
}
logs.Infof("start %s", os.Args[0])
prs := parser.ParserData{}
prs.Parse()
generator := parser.Generator{
PrinterIf: Printer{},
Data: &prs,
}
header := fmt.Sprintf(`/* SPDX-License-Identifier: GPL-2.0-only */
#ifndef CFG_GPIO_H
#define CFG_GPIO_H
#include <gpio.h>
/* Pad configuration was generated automatically using intelp2m %s */
static const struct pad_config gpio_table[] = {`, Version)
p2m.Config.OutputFile.WriteString(header + "\n")
// Add the pads map
if err := generator.Run(); err != nil {
fmt.Printf("Error: %v", err)
lines, err := generator.Run(entries)
if err != nil {
fmt.Print("failed to run generator")
os.Exit(1)
}
p2m.Config.OutputFile.WriteString(`};
lines = header.Add(lines)
#endif /* CFG_GPIO_H */
`)
logs.Infof("exit from %s\n", os.Args[0])
if err := printer.Do(lines); err != nil {
fmt.Print("printer error")
os.Exit(1)
}
logs.Infof("========== completed ==========")
os.Exit(0)
}

View file

@ -2,172 +2,127 @@ package parser
import (
"bufio"
"errors"
"fmt"
"os"
"strings"
"review.coreboot.org/coreboot.git/util/intelp2m/config/p2m"
"review.coreboot.org/coreboot.git/util/intelp2m/platforms/adl"
"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/logs"
"review.coreboot.org/coreboot.git/util/intelp2m/parser/template"
"review.coreboot.org/coreboot.git/util/intelp2m/platforms"
"review.coreboot.org/coreboot.git/util/intelp2m/platforms/common"
"review.coreboot.org/coreboot.git/util/intelp2m/platforms/ebg"
"review.coreboot.org/coreboot.git/util/intelp2m/platforms/jsl"
"review.coreboot.org/coreboot.git/util/intelp2m/platforms/lbg"
"review.coreboot.org/coreboot.git/util/intelp2m/platforms/mtl"
"review.coreboot.org/coreboot.git/util/intelp2m/platforms/snr"
"review.coreboot.org/coreboot.git/util/intelp2m/platforms/tgl"
"review.coreboot.org/coreboot.git/util/intelp2m/platforms/common/register/bits"
)
// PlatformSpecific - platform-specific interface
type PlatformSpecific interface {
GenMacro(id string, dw0 uint32, dw1 uint32, ownership uint8) string
KeywordCheck(line string) bool
type EntryType int
const (
EntryEmpty EntryType = iota
EntryPad
EntryGroup
EntryReserved
)
// Parser entry
// ID : pad id string
// Function : the string that means the pad function
// DW0 : DW0 register struct
// DW1 : DW1 register struct
// 0wnership : host software ownership
type Entry struct {
EType EntryType
ID string
Function string
DW0 uint32
DW1 uint32
Ownership uint8
}
// 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
func (e *Entry) ToMacro() []string {
platform := platforms.GetSpecificInterface()
line := platform.GenMacro(e.ID, e.DW0, e.DW1, e.Ownership)
slices := strings.Split(line, "\n")
return slices
}
// 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
}
// 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
if rc := UseTemplate(parser.line, &function, &id, &dw0, &dw1); rc != 0 {
return rc
// extractPad() extracts pad information from a string
func extractPad(line string) (Entry, error) {
function, id, dw0, dw1, err := template.Apply(line)
if err != nil {
logs.Errorf("%v", err)
return Entry{EType: EntryEmpty}, err
}
pad := padInfo{id: id,
function: function,
dw0: dw0,
dw1: dw1,
ownership: 0}
parser.padmap = append(parser.padmap, pad)
return 0
}
// 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() {
platform := map[p2m.PlatformType]PlatformSpecific{
p2m.Sunrise: snr.PlatformSpecific{},
// See platforms/lbg/macro.go
p2m.Lewisburg: lbg.PlatformSpecific{
InheritanceTemplate: snr.PlatformSpecific{},
},
p2m.Apollo: apl.PlatformSpecific{},
p2m.Cannon: cnl.PlatformSpecific{
InheritanceTemplate: snr.PlatformSpecific{},
},
p2m.Tiger: tgl.PlatformSpecific{},
p2m.Alder: adl.PlatformSpecific{},
p2m.Jasper: jsl.PlatformSpecific{},
p2m.Meteor: mtl.PlatformSpecific{},
// See platforms/ebg/macro.go
p2m.Emmitsburg: ebg.PlatformSpecific{},
pad := Entry{
EType: EntryPad,
Function: function,
ID: id,
DW0: dw0,
DW1: dw1,
Ownership: 0,
}
parser.platform = platform[p2m.Config.Platform]
if dw0 == bits.All32 {
pad.EType = EntryReserved
}
return pad, nil
}
// 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...")
// extractGroup() extracts information about the pad group from the string
func extractGroup(line string) Entry {
group := Entry{
EType: EntryGroup,
Function: line,
}
return group
}
// determine the platform type and set the interface for it
parser.PlatformSpecificInterfaceSet()
// Extract() extracts pad information from a string
func Extract(line string, platform platforms.SpecificIf) Entry {
if included, _ := common.KeywordsCheck(line, "GPIO Community", "GPIO Group"); included {
return extractGroup(line)
}
// map of thepad ownership registers for the GPIO controller
parser.ownership = make(map[string]uint32)
if platform.KeywordCheck(line) {
pad, err := extractPad(line)
if err != nil {
logs.Errorf("extract pad info from %s: %v", line, err)
return Entry{EType: EntryEmpty}
}
return pad
}
logs.Infof("skip line <%s>", line)
return Entry{EType: EntryEmpty}
}
file := p2m.Config.InputFile
// Run() starts the file parsing process
func Run() ([]Entry, error) {
entries := make([]Entry, 0)
platform := platforms.GetSpecificInterface()
if platform == nil {
return nil, fmt.Errorf("unknown platform")
}
file, err := os.Open(p2m.Config.InputPath)
if err != nil {
err = fmt.Errorf("input file error: %v", err)
logs.Errorf("%v", err)
return nil, err
}
defer file.Close()
logs.Infof("parse %s file", p2m.Config.InputPath)
scanner := bufio.NewScanner(file)
for scanner.Scan() {
parser.line = scanner.Text()
isIncluded, _ := common.KeywordsCheck(parser.line, "GPIO Community", "GPIO Group")
if isIncluded {
parser.communityGroupExtract()
} else if parser.platform.KeywordCheck(parser.line) {
if parser.padInfoExtract() != 0 {
fmt.Println("...error!")
}
line := scanner.Text()
entry := Extract(line, platform)
if entry.EType != EntryEmpty {
entries = append(entries, entry)
}
}
fmt.Println("...done!")
}
type PrinterIf interface {
Linef(lvl int, format string, args ...interface{})
Line(lvl int, str string)
}
type Generator struct {
Data *ParserData // information from the parser
PrinterIf // interface for printing
}
// Run - generate a new gpio file based on the information from the parser
func (g Generator) Run() error {
if g.PrinterIf == nil && g.Data == nil {
return errors.New("Generator: Incorrect initialization")
}
for _, pad := range g.Data.padmap {
switch pad.dw0 {
case 0x00000000:
// titleFprint - print GPIO group title to file
// /* ------- GPIO Group GPP_L ------- */
g.Linef(0, "\n\t/* %s */\n", pad.function)
case 0xffffffff:
// reservedFprint - print reserved GPIO to file as comment
// /* GPP_H17 - RESERVED */
g.Line(2, "\n")
// small comment about reserved port
g.Linef(0, "\t/* %s - %s */\n", pad.id, pad.function)
default:
// padInfoMacroFprint - print information about current pad to file using
// special macros:
// PAD_CFG_NF(GPP_F1, 20K_PU, PLTRST, NF1), /* SATAXPCIE4 */
platform := g.Data.platform
macro := platform.GenMacro(pad.id, pad.dw0, pad.dw1, pad.ownership)
g.Linef(2, "\n\t/* %s - %s */\n\t/* DW0: 0x%0.8x, DW1: 0x%0.8x */\n",
pad.id, pad.function, pad.dw0, pad.dw1)
g.Linef(0, "\t%s", macro)
if p2m.Config.GenLevel == 1 {
g.Linef(1, "\t/* %s */", pad.function)
}
g.Line(0, "\n")
}
}
return nil
logs.Infof("successfully completed: %d entries", len(entries))
return entries, nil
}

View file

@ -1,102 +1,32 @@
package parser_test
import (
"fmt"
"os"
"testing"
"review.coreboot.org/coreboot.git/util/intelp2m/config/p2m"
"review.coreboot.org/coreboot.git/util/intelp2m/parser"
"review.coreboot.org/coreboot.git/util/intelp2m/parser/test"
)
const testLogFilePath = "test/inteltool_test.log"
type Printer struct {
lines []string
}
func (p *Printer) Linef(lvl int, format string, args ...interface{}) {
if p2m.Config.GenLevel >= lvl {
p.lines = append(p.lines, fmt.Sprintf(format, args...))
}
}
func (p *Printer) Line(lvl int, str string) {
if p2m.Config.GenLevel >= lvl {
p.lines = append(p.lines, str)
}
}
const TestLogFilePath = "./testlog/inteltool_test.log"
func TestParser(t *testing.T) {
t.Run("PARSER/PARSE-INTELTOOL-FILE", func(t *testing.T) {
var err error
reference := []string{
"\n\t/* ------- GPIO Community 0 ------- */\n",
"\n\t/* ------- GPIO Group GPP_A ------- */\n",
"\tPAD_CFG_NF(GPP_A0, NONE, PLTRST, NF1),", "\t/* RCIN# */", "\n",
"\tPAD_CFG_NF(GPP_A1, UP_20K, PLTRST, NF1),", "\t/* LAD0 */", "\n",
"\tPAD_CFG_NF(GPP_A5, NONE, PLTRST, NF1),", "\t/* LFRAME# */", "\n",
"\tPAD_CFG_NF(GPP_A13, NONE, DEEP, NF1),", "\t/* SUSWARN#/SUSPWRDNACK */", "\n",
"\tPAD_CFG_GPI_TRIG_OWN(GPP_A23, NONE, PLTRST, OFF, ACPI),", "\t/* GPIO */", "\n",
"\n\t/* ------- GPIO Group GPP_B ------- */\n",
"\t/* GPP_C1 - RESERVED */\n",
"\tPAD_CFG_GPI_TRIG_OWN(GPP_B0, NONE, PLTRST, OFF, ACPI),", "\t/* GPIO */", "\n",
"\tPAD_CFG_NF(GPP_B23, DN_20K, PLTRST, NF2),", "\t/* PCHHOT# */", "\n",
"\n\t/* ------- GPIO Community 1 ------- */\n",
"\n\t/* ------- GPIO Group GPP_C ------- */\n",
"\tPAD_CFG_NF(GPP_C0, NONE, DEEP, NF1),", "\t/* SMBCLK */", "\n",
"\tPAD_CFG_GPI_TRIG_OWN(GPP_C5, NONE, PLTRST, OFF, ACPI),", "\t/* GPIO */", "\n",
"\t/* GPP_C6 - RESERVED */\n",
"\t/* GPP_C7 - RESERVED */\n",
"\tPAD_CFG_NF(GPP_C22, NONE, PLTRST, NF1),", "\t/* UART2_RTS# */", "\n",
"\n\t/* ------- GPIO Group GPP_D ------- */\n",
"\n\t/* ------- GPIO Group GPP_E ------- */\n",
"\tPAD_CFG_NF(GPP_E0, UP_20K, PLTRST, NF1),", "\t/* SATAXPCIE0 */", "\n",
"\n\t/* ------- GPIO Group GPP_G ------- */\n",
"\tPAD_CFG_NF(GPP_G19, NONE, PLTRST, NF1),", "\t/* SMI# */", "\n",
"\n\t/* ------- GPIO Community 2 ------- */\n",
"\n\t/* -------- GPIO Group GPD -------- */\n",
"\tPAD_CFG_NF(GPD9, NONE, PWROK, NF1),", "\t/* SLP_WLAN# */", "\n",
"\n\t/* ------- GPIO Community 3 ------- */\n",
"\n\t/* ------- GPIO Group GPP_I ------- */\n",
"\tPAD_CFG_NF(GPP_I0, NONE, PLTRST, NF1),", "\t/* DDPB_HPD0 */", "\n",
"\tPAD_CFG_NF(GPP_I1, NONE, PLTRST, NF1),", "\t/* DDPC_HPD1 */", "\n",
"\tPAD_CFG_NF(GPP_I2, NONE, PLTRST, NF1),", "\t/* DDPD_HPD2 */", "\n",
}
if p2m.Config.InputFile, err = os.Open(testLogFilePath); err != nil {
t.Errorf("Something is wrong with the test file - %s!\n", testLogFilePath)
os.Exit(1)
}
defer p2m.Config.InputFile.Close()
p2m.Config.AutoCheck = false
p2m.Config.Field = p2m.NoFlds
p2m.Config.GenLevel = 1
p2m.Config.InputPath = TestLogFilePath
prs := parser.ParserData{}
prs.Parse()
printer := Printer{lines: make([]string, 0)}
generator := parser.Generator{
PrinterIf: &printer,
Data: &prs,
entries, err := parser.Run()
if err != nil {
t.Errorf("failed to run parser: %v", err)
}
if err := generator.Run(); err != nil {
t.Errorf("Generator: %v", err)
os.Exit(1)
}
if len(printer.lines) == len(reference) {
for i := range printer.lines {
if printer.lines[i] != reference[i] {
t.Errorf("\nExpects: '%s'\nActually: '%s'\n\n", reference[i], printer.lines[i])
return
}
for i := range test.Suite {
if entries[i] != test.Suite[i] {
t.Errorf("\nExpects: '%v'\nActually: '%v'\n\n", test.Suite[i], entries[i])
}
} else {
t.Errorf("%d does not match the reference slice len - %d!",
len(reference), len(printer.lines))
}
})
}

View file

@ -1,64 +0,0 @@
package parser
import (
"fmt"
"strings"
"unicode"
)
const IntSelMask uint32 = 0xffffff00
type template func(string, *string, *string, *uint32, *uint32) int
// extractPadFuncFromComment
// line : string from file with pad config map
// return : pad function string
func extractPadFuncFromComment(line string) string {
if !strings.Contains(line, "/*") && !strings.Contains(line, "*/") {
return ""
}
fields := strings.Fields(line)
for i, field := range fields {
if field == "/*" && len(fields) >= i+2 {
return fields[i+1]
}
}
return ""
}
// tokenCheck
func tokenCheck(c rune) bool {
return c != '_' && c != '#' && !unicode.IsLetter(c) && !unicode.IsNumber(c)
}
// UseTemplate
// line : string from file with pad config map
// *function : the string that means the pad function
// *id : pad id string
// *dw0 : DW0 register value
// *dw1 : DW1 register value
//
// return
// error status
func UseTemplate(line string, function *string, id *string, dw0 *uint32, dw1 *uint32) int {
var val uint64
// 0x0520: 0x0000003c44000600 GPP_B12 SLP_S0#
// 0x0438: 0xffffffffffffffff GPP_C7 RESERVED
if fields := strings.FieldsFunc(line, tokenCheck); len(fields) >= 4 {
fmt.Sscanf(fields[1], "0x%x", &val)
*dw0 = uint32(val & 0xffffffff)
*dw1 = uint32(val >> 32)
*id = fields[2]
*function = fields[3]
// Sometimes the configuration file contains compound functions such as
// SUSWARN#/SUSPWRDNACK. Since the template does not take this into account,
// need to collect all parts of the pad function back into a single word
for i := 4; i < len(fields); i++ {
*function += "/" + fields[i]
}
// clear RO Interrupt Select (INTSEL)
*dw1 &= IntSelMask
}
return 0
}

View file

@ -0,0 +1,48 @@
package template
import (
"fmt"
"strings"
"unicode"
"review.coreboot.org/coreboot.git/util/intelp2m/logs"
"review.coreboot.org/coreboot.git/util/intelp2m/platforms/common/register/bits"
)
func token(c rune) bool {
return c != '_' && c != '#' && !unicode.IsLetter(c) && !unicode.IsNumber(c)
}
// Apply
// line : string from file with pad config map
// return
// function : the string that means the pad function
// id : pad id string
// dw0 : DW0 register value
// dw1 : DW1 register value
// err : error
func Apply(line string) (function string, id string, dw0 uint32, dw1 uint32, err error) {
// 0x0520: 0x0000003c44000600 GPP_B12 SLP_S0#
// 0x0438: 0xffffffffffffffff GPP_C7 RESERVED
slices := strings.FieldsFunc(line, token)
number := len(slices)
if number >= 4 {
var val uint64
fmt.Sscanf(slices[1], "0x%x", &val)
dw0 = uint32(val & 0xffffffff)
dw1 = uint32(val >> 32)
id = slices[2]
function = slices[3]
// Sometimes the configuration file contains compound functions such as
// SUSWARN#/SUSPWRDNACK. Since the template does not take this into account,
// need to collect all parts of the pad function back into a single word
for i := 4; i < len(slices); i++ {
function += "/" + slices[i]
}
// clear RO Interrupt Select (INTSEL)
dw1 &^= bits.DW1[bits.DW1InterruptSelect]
return function, id, dw0, dw1, nil
}
logs.Errorf("template: more than %d elements are needed", number)
return "", "", 0, 0, fmt.Errorf("template error")
}

View file

@ -1,26 +1,30 @@
package parser_test
package template_test
import (
"fmt"
"testing"
"review.coreboot.org/coreboot.git/util/intelp2m/parser"
"review.coreboot.org/coreboot.git/util/intelp2m/parser/template"
)
func TestTemp(t *testing.T) {
t.Run("TEMPLATE/INTELTOOL-LINE", func(t *testing.T) {
const (
ref_fn string = "SLP_S0#"
ref_id string = "GPP_B12"
ref_dw0 uint32 = 0x44000600
ref_dw1 uint32 = 0x0000003c
IntSelMask uint32 = 0xffffff00
ref_fn string = "SLP_S0#"
ref_id string = "GPP_B12"
ref_dw0 uint32 = 0x44000600
ref_dw1 uint32 = 0x0000003c
)
var (
fn, id string
dw0, dw1 uint32
)
line := fmt.Sprintf("0x0520: 0x%08x%08x %s %s", ref_dw1, ref_dw0, ref_id, ref_fn)
_ = parser.UseTemplate(line, &fn, &id, &dw0, &dw1)
fn, id, dw0, dw1, err := template.Apply(line)
if err != nil {
t.Errorf("template application failure: %d", err)
}
if fn != ref_fn {
t.Errorf("function from '%s':\nExpects: '%s'\nActually: '%s'\n\n",
line, ref_fn, fn)
@ -30,9 +34,9 @@ func TestTemp(t *testing.T) {
} else if dw0 != ref_dw0 {
t.Errorf("dw0 from '%s':\nExpects: '0x%08x'\nActually: '0x%08x'\n\n",
line, ref_dw0, dw0)
} else if dw1 != (ref_dw1 & parser.IntSelMask) {
} else if dw1 != (ref_dw1 & IntSelMask) {
t.Errorf("dw1 from '%s':\nExpects: '0x%08x'\nActually: '0x%08x'\n\n",
line, (ref_dw1 & parser.IntSelMask), dw1)
line, (ref_dw1 & IntSelMask), dw1)
}
})
}

View file

@ -0,0 +1,152 @@
package test
import (
"review.coreboot.org/coreboot.git/util/intelp2m/parser"
)
var Suite = []parser.Entry{
// {2 ------- GPIO Community 0 ------- 00000000 00000000 0}
{EType: parser.EntryGroup, Function: "------- GPIO Community 0 -------"},
// {2 ------- GPIO Group GPP_A ------- 00000000 00000000 0}
{EType: parser.EntryGroup, Function: "------- GPIO Group GPP_A -------"},
{ // {1 GPP_A0 RCIN# 84000502 00000000 0}
EType: parser.EntryPad,
Function: "RCIN#",
ID: "GPP_A0",
DW0: 0x84000502,
},
{ // {1 GPP_A1 LAD0 84000402 00003000 0}
EType: parser.EntryPad,
Function: "LAD0",
ID: "GPP_A1",
DW0: 0x84000402,
DW1: 0x00003000,
},
{ // {1 GPP_A5 LFRAME# 84000600 00000000 0}
EType: parser.EntryPad,
Function: "LFRAME#",
ID: "GPP_A5",
DW0: 0x84000600,
},
{ // {1 GPP_A13 SUSWARN#/SUSPWRDNACK 44000600 00000000 0}
EType: parser.EntryPad,
Function: "SUSWARN#/SUSPWRDNACK",
ID: "GPP_A13",
DW0: 0x44000600,
},
{ // {1 GPP_A23 GPIO 84000102 00000000 0}
EType: parser.EntryPad,
Function: "GPIO",
ID: "GPP_A23",
DW0: 0x84000102,
},
// {2 ------- GPIO Group GPP_B ------- 00000000 00000000 0}
{EType: parser.EntryGroup, Function: "------- GPIO Group GPP_B -------"},
{ // {3 GPP_C1 RESERVED ffffffff ffffff00 0}
EType: parser.EntryReserved,
Function: "RESERVED",
ID: "GPP_C1",
DW0: 0xffffffff,
DW1: 0xffffff00,
},
{ // {1 GPP_B0 GPIO 84000100 00000000 0}
EType: parser.EntryPad,
Function: "GPIO",
ID: "GPP_B0",
DW0: 0x84000100,
},
{ // {1 GPP_B23 PCHHOT# 84000a01 00001000 0}
EType: parser.EntryPad,
Function: "PCHHOT#",
ID: "GPP_B23",
DW0: 0x84000a01,
DW1: 0x00001000,
},
// {2 ------- GPIO Community 1 ------- 00000000 00000000 0}
{EType: parser.EntryGroup, Function: "------- GPIO Community 1 -------"},
// {2 ------- GPIO Group GPP_C ------- 00000000 00000000 0}
{EType: parser.EntryGroup, Function: "------- GPIO Group GPP_C -------"},
{ // {1 GPP_C0 SMBCLK 44000502 00000000 0}
EType: parser.EntryPad,
Function: "SMBCLK",
ID: "GPP_C0",
DW0: 0x44000502,
},
{ // {1 GPP_C5 GPIO 84000100 00000000 0}
EType: parser.EntryPad,
Function: "GPIO",
ID: "GPP_C5",
DW0: 0x84000100,
},
{ // {3 GPP_C6 RESERVED ffffffff ffffff00 0}
EType: parser.EntryReserved,
Function: "RESERVED",
ID: "GPP_C6",
DW0: 0xffffffff,
DW1: 0xffffff00,
},
{ // {3 GPP_C7 RESERVED ffffffff ffffff00 0}
EType: parser.EntryReserved,
Function: "RESERVED",
ID: "GPP_C7",
DW0: 0xffffffff,
DW1: 0xffffff00,
},
{ // {1 GPP_C22 UART2_RTS# 84000600 00000000 0}
EType: parser.EntryPad,
Function: "UART2_RTS#",
ID: "GPP_C22",
DW0: 0x84000600,
},
// {2 ------- GPIO Group GPP_D ------- 00000000 00000000 0}
{EType: parser.EntryGroup, Function: "------- GPIO Group GPP_D -------"},
// {2 ------- GPIO Group GPP_E ------- 00000000 00000000 0}
{EType: parser.EntryGroup, Function: "------- GPIO Group GPP_E -------"},
{ // {1 GPP_E0 SATAXPCIE0 84000502 00003000 0}
EType: parser.EntryPad,
Function: "SATAXPCIE0",
ID: "GPP_E0",
DW0: 0x84000502,
DW1: 0x00003000,
},
// {2 ------- GPIO Group GPP_G ------- 00000000 00000000 0}
{EType: parser.EntryGroup, Function: "------- GPIO Group GPP_G -------"},
{ // {1 GPP_G19 SMI# 84000500 00000000 0}
EType: parser.EntryPad,
Function: "SMI#",
ID: "GPP_G19",
DW0: 0x84000500,
},
// {2 ------- GPIO Community 2 ------- 00000000 00000000 0}
{EType: parser.EntryGroup, Function: "------- GPIO Community 2 -------"},
// {2 -------- GPIO Group GPD -------- 00000000 00000000 0}
{EType: parser.EntryGroup, Function: "-------- GPIO Group GPD --------"},
{ // {1 GPD9 SLP_WLAN# 04000600 00000000 0}
EType: parser.EntryPad,
Function: "SLP_WLAN#",
ID: "GPD9",
DW0: 0x04000600,
},
// {2 ------- GPIO Community 3 ------- 00000000 00000000 0}
{EType: parser.EntryGroup, Function: "------- GPIO Community 3 -------"},
// {2 ------- GPIO Group GPP_I ------- 00000000 00000000 0}
{EType: parser.EntryGroup, Function: "------- GPIO Group GPP_I -------"},
{ // {1 GPP_I0 DDPB_HPD0 84000500 00000000 0}
EType: parser.EntryPad,
Function: "DDPB_HPD0",
ID: "GPP_I0",
DW0: 0x84000500,
},
{ // {1 GPP_I1 DDPC_HPD1 84000502 00000000 0}
EType: parser.EntryPad,
Function: "DDPC_HPD1",
ID: "GPP_I1",
DW0: 0x84000502,
},
{ // {1 GPP_I2 DDPD_HPD2 84000502 00000000 0}
EType: parser.EntryPad,
Function: "DDPD_HPD2",
ID: "GPP_I2",
DW0: 0x84000502,
},
}

View file

@ -289,7 +289,7 @@ func (macro *Macro) DecodeIgnoredFieldsDW0() *Macro {
dw0.Value = ignored
macro.Add("/* DW0: ")
macro.Fields.DecodeDW0()
macro.Add(" - IGNORED */\n\t")
macro.Add(" - IGNORED */\n")
dw0.Value = saved
}
return macro
@ -305,7 +305,7 @@ func (macro *Macro) DecodeIgnoredFieldsDW1() *Macro {
dw1.Value = ignored
macro.Add("/* DW0: ")
macro.DecodeDW1()
macro.Add(" - IGNORED */\n\t")
macro.Add(" - IGNORED */\n")
dw1.Value = saved
}
return macro
@ -332,7 +332,7 @@ func (macro *Macro) GenerateFields() *Macro {
macro.DecodeIgnoredFieldsDW1()
if p2m.Config.GenLevel >= 4 {
/* PAD_CFG_NF(GPP_B23, 20K_PD, PLTRST, NF2), */
macro.Add("/* ").Add(reference).Add(" */\n\t")
macro.Add("/* ").Add(reference).Add(" */\n")
}
}
if p2m.Config.IgnoredFields {
@ -408,7 +408,7 @@ func (macro *Macro) Generate() string {
if p2m.Config.GenLevel >= 4 {
macro.Clear().Add("/* ")
macro.Fields.GenerateString()
macro.Add(" */\n\t")
macro.Add(" */\n")
comment += macro.Get()
}
return comment + body

View file

@ -0,0 +1,38 @@
package platforms
import (
"review.coreboot.org/coreboot.git/util/intelp2m/config/p2m"
"review.coreboot.org/coreboot.git/util/intelp2m/logs"
"review.coreboot.org/coreboot.git/util/intelp2m/platforms/adl"
"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/lbg"
"review.coreboot.org/coreboot.git/util/intelp2m/platforms/snr"
)
type SpecificIf interface {
GenMacro(id string, dw0 uint32, dw1 uint32, ownership uint8) string
KeywordCheck(line string) bool
}
func GetSpecificInterface() SpecificIf {
platforms := map[p2m.PlatformType]SpecificIf{
p2m.Alder: adl.PlatformSpecific{},
p2m.Apollo: apl.PlatformSpecific{},
p2m.Sunrise: snr.PlatformSpecific{},
p2m.Cannon: cnl.PlatformSpecific{
InheritanceTemplate: snr.PlatformSpecific{},
InheritanceMacro: snr.PlatformSpecific{},
},
p2m.Lewisburg: lbg.PlatformSpecific{
InheritanceTemplate: snr.PlatformSpecific{},
InheritanceMacro: snr.PlatformSpecific{},
},
}
platform, exist := platforms[p2m.Config.Platform]
if !exist {
logs.Errorf("unknown platform type %d", int(p2m.Config.Platform))
return nil
}
return platform
}