util/intelp2m: Update cli options
- Redesign the options format. - Add automatic completion of arguments for bash. [complete -C `pwd`/intelp2m ./intelp2m] to enable TEST: make test = PASS Change-Id: I08ff379b99b018b1099aa5d70fea47026bc84045 Signed-off-by: Maxim Polyakov <max.senia.poliak@gmail.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/70310 Reviewed-by: David Hendricks <david.hendricks@gmail.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
a581660031
commit
2e9dd0ade2
5 changed files with 270 additions and 81 deletions
22
util/intelp2m/cli/completion.go
Normal file
22
util/intelp2m/cli/completion.go
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
package cli
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func UseComplete() bool {
|
||||
if _, ok := os.LookupEnv("COMP_LINE"); ok {
|
||||
argument := os.Args[2]
|
||||
argument = strings.TrimLeft(argument, "-")
|
||||
flag.VisitAll(func(f *flag.Flag) {
|
||||
if argument == "" || strings.HasPrefix(f.Name, argument) {
|
||||
fmt.Println("-" + f.Name)
|
||||
}
|
||||
})
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
232
util/intelp2m/cli/options.go
Normal file
232
util/intelp2m/cli/options.go
Normal file
|
|
@ -0,0 +1,232 @@
|
|||
package cli
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"review.coreboot.org/coreboot.git/util/intelp2m/config/p2m"
|
||||
)
|
||||
|
||||
var name = filepath.Base(os.Args[0])
|
||||
|
||||
const usagePlatform = `usage: -platform <type>
|
||||
type: adl | apl | cnl | ebg | jsl | lbg | mtl | snr | tgl | ?
|
||||
adl - Alder Lake PCH
|
||||
apl - Apollo Lake SoC
|
||||
cnl - CannonLake-LP or Whiskeylake/Coffeelake/Cometlake-U SoC
|
||||
ebg - Emmitsburg PCH with Xeon SP
|
||||
jsl - Jasper Lake SoC
|
||||
lbg - Lewisburg PCH with Xeon SP
|
||||
mtl - MeteorLake SoC
|
||||
snr - Sunrise PCH or Skylake/Kaby Lake SoC
|
||||
tgl - TigerLake-H SoC
|
||||
? - show details
|
||||
`
|
||||
const usageFields = `usage: -fields <type>
|
||||
type: cb | fsp | raw | ?
|
||||
cb - coreboot style
|
||||
fsp - Intel FSP style
|
||||
raw - raw register value (don't convert, print as is)
|
||||
? - show details
|
||||
`
|
||||
const usageExclude = `usage: -e | -exclude
|
||||
Exclude fields that should be ignored to generate "short" macro.
|
||||
Details:
|
||||
The utility should ignore "PAD_TRIG(OFF)" field in the "_PAD_CFG_STRUCT(GPP_I12,
|
||||
PAD_FUNC(GPIO) | PAD_RESET(PLTRST) | PAD_TRIG(OFF) | PAD_BUF(RX_DISABLE) | 1, 0)"
|
||||
"long" macro to generate the "PAD_CFG_GPO(GPP_I12, 1, PLTRST)" macro.
|
||||
|
||||
The utility with this option generates the "long" macro with only those fields that are
|
||||
required to create the "short" one (in thia case without the "PAD_TRIG(OFF)" field):
|
||||
"_PAD_CFG_STRUCT(GPP_I12, PAD_FUNC(GPIO) | PAD_RESET(PLTRST) | PAD_BUF(RX_DISABLE) | 1, 0)"
|
||||
`
|
||||
|
||||
const usageUnchecked = `usage: -u | -unchecked
|
||||
Disable automatic bitfield checking before generating.
|
||||
Details:
|
||||
The utility automatically checks the bit fields of the DW registers before generating
|
||||
the macro. If a bit is set in the register and it is not used in the "short" macro, the
|
||||
utility will generate the "long" one instead of the first one.
|
||||
|
||||
This option is used to disable automatic verification. In this case, all macros are
|
||||
generated in the "short" format:
|
||||
PAD_NC(GPP_F18, NONE),
|
||||
PAD_CFG_NF(GPP_F19, NONE, PLTRST, NF1),
|
||||
...
|
||||
`
|
||||
|
||||
const usageInfo = `usage: -i | -ii | -iii | -iiii
|
||||
Generate additional information about macros.
|
||||
Level 1 information (-i):
|
||||
_PAD_CFG_STRUCT(GPP_A4, PAD_FUNC(NF1) | PAD_RESET(PLTRST) | (1 << 1), 0), /* LAD3 */
|
||||
|
||||
Level 2 information (-ii):
|
||||
/* GPP_A4 - LAD3 */
|
||||
/* DW0: 0x80000402, DW1: 0x00000000 */
|
||||
_PAD_CFG_STRUCT(GPP_A4, PAD_FUNC(NF1) | PAD_RESET(PLTRST) | (1 << 1), 0),
|
||||
|
||||
Level 3 information (-iii):
|
||||
/* GPP_A3 - LAD2 */
|
||||
/* DW0: 0x80000402, DW1: 0x00000000 */
|
||||
/* DW0: (1 << 1) - IGNORED */
|
||||
_PAD_CFG_STRUCT(GPP_A3, PAD_FUNC(NF1) | PAD_RESET(PLTRST) | (1 << 1), 0),
|
||||
|
||||
Level 4 information (-iiii):
|
||||
/* GPP_A4 - LAD3 */
|
||||
/* DW0: 0x80000402, DW1: 0x00000000 */
|
||||
/* DW0: (1 << 1) - IGNORED */
|
||||
/* PAD_CFG_NF(GPP_A4, NONE, PLTRST, NF1), */
|
||||
_PAD_CFG_STRUCT(GPP_A4, PAD_FUNC(NF1) | PAD_RESET(PLTRST) | (1 << 1), 0),
|
||||
`
|
||||
|
||||
const usage = `
|
||||
basic functions:
|
||||
-h | -help Print help
|
||||
-v | -version Print version
|
||||
-file <path> Set path to the inteltool file. <inteltool.log> by default
|
||||
-out <path> Set path to the generated file. <generate/gpio.h> by default
|
||||
-p | -platform <type> Set the PCH platform type. <sunrise> by default
|
||||
(enter ? to show datails)
|
||||
|
||||
generation of long composite macros with bit field definitions:
|
||||
-f | -fields <type> Set the bitfield type for the generated long macro
|
||||
(enter ? to show datails)
|
||||
|
||||
control flags:
|
||||
-e | -exclude Exclude fields that should be ignored to generate short macro
|
||||
-u | -unchecked Disable automatic bitfield checking before generating
|
||||
(enter ? to show datails)
|
||||
|
||||
generate additional information:
|
||||
-i Add function to the comments
|
||||
-ii Add DW0/DW1 register value to the comments
|
||||
-iii Add ignored bitfields to the comments
|
||||
-iiii Add target PAD_CFG() macro to the comments
|
||||
(enter ? to show datails)
|
||||
`
|
||||
|
||||
func Usage() {
|
||||
fmt.Printf(`usage: %s <switches> %s`, name, usage)
|
||||
}
|
||||
|
||||
func cbOptionsPlatform(value string) error {
|
||||
if value == "?" {
|
||||
fmt.Printf("%s", usagePlatform)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
if err := p2m.SetPlatformType(value); err != nil {
|
||||
fmt.Printf("error: %v\n%s", err, usagePlatform)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func cbOptionsFields(value string) error {
|
||||
if value == "?" {
|
||||
fmt.Printf("%s", usageFields)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
if err := p2m.SetFieldType(value); err != nil {
|
||||
fmt.Printf("error: %v\n%s", err, usageFields)
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func cbOptionsExclude(_ string) error {
|
||||
if numArgs := flag.NArg(); numArgs == 1 {
|
||||
if flag.Arg(0) == "?" {
|
||||
fmt.Printf("%s", usageExclude)
|
||||
}
|
||||
Usage()
|
||||
os.Exit(0)
|
||||
}
|
||||
p2m.Config.IgnoredFields = true
|
||||
return nil
|
||||
}
|
||||
|
||||
func cbOptionsUnchecked(_ string) error {
|
||||
if numArgs := flag.NArg(); numArgs == 1 {
|
||||
if flag.Arg(0) == "?" {
|
||||
fmt.Printf("%s", usageUnchecked)
|
||||
}
|
||||
Usage()
|
||||
os.Exit(0)
|
||||
}
|
||||
p2m.Config.AutoCheck = false
|
||||
return nil
|
||||
}
|
||||
|
||||
func cbOptionsInfo(_ string) error {
|
||||
if numArgs := flag.NArg(); numArgs == 1 {
|
||||
if flag.Arg(0) == "?" {
|
||||
fmt.Printf("%s", usageInfo)
|
||||
os.Exit(0)
|
||||
}
|
||||
Usage()
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
table := map[string]int{
|
||||
"-i": 1,
|
||||
"-ii": 2,
|
||||
"-iii": 3,
|
||||
"-iiii": 4,
|
||||
}
|
||||
for _, arg := range os.Args {
|
||||
if level, exist := table[arg]; exist {
|
||||
p2m.Config.GenLevel = level
|
||||
return nil
|
||||
}
|
||||
}
|
||||
Usage()
|
||||
return nil
|
||||
}
|
||||
|
||||
func ParseOptions() {
|
||||
flag.Usage = Usage
|
||||
flag.StringVar(&p2m.Config.InputPath, "file", "inteltool.log", "")
|
||||
flag.StringVar(&p2m.Config.OutputPath, "out", "generate/gpio.h", "")
|
||||
help := flag.Bool("help", false, "")
|
||||
|
||||
vers, v := flag.Bool("version", false, ""), flag.Bool("v", false, "")
|
||||
|
||||
flag.Func("platform", usagePlatform, cbOptionsPlatform)
|
||||
flag.Func("p", usagePlatform, cbOptionsPlatform)
|
||||
|
||||
flag.Func("fields", usageFields, cbOptionsFields)
|
||||
flag.Func("f", usageFields, cbOptionsFields)
|
||||
|
||||
flag.BoolFunc("exclude", usageExclude, cbOptionsExclude)
|
||||
flag.BoolFunc("e", usageExclude, cbOptionsExclude)
|
||||
|
||||
flag.BoolFunc("unchecked", usageUnchecked, cbOptionsUnchecked)
|
||||
flag.BoolFunc("u", usageUnchecked, cbOptionsUnchecked)
|
||||
|
||||
flag.BoolFunc("i", usageInfo, cbOptionsInfo)
|
||||
flag.BoolFunc("ii", usageInfo, cbOptionsInfo)
|
||||
flag.BoolFunc("iii", usageInfo, cbOptionsInfo)
|
||||
flag.BoolFunc("iiii", usageInfo, cbOptionsInfo)
|
||||
|
||||
if UseComplete() {
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
flag.Parse()
|
||||
|
||||
if *help {
|
||||
Usage()
|
||||
os.Exit(0)
|
||||
}
|
||||
|
||||
if *vers || *v {
|
||||
fmt.Println(p2m.Config.Version)
|
||||
os.Exit(0)
|
||||
}
|
||||
}
|
||||
|
|
@ -50,6 +50,8 @@ type Settings struct {
|
|||
Version string
|
||||
Platform PlatformType
|
||||
Field FieldType
|
||||
InputPath string
|
||||
OutputPath string
|
||||
InputFile *os.File
|
||||
OutputFile *os.File
|
||||
IgnoredFields bool
|
||||
|
|
@ -60,7 +62,7 @@ type Settings struct {
|
|||
var Config = Settings{
|
||||
Version: "unknown",
|
||||
Platform: Sunrise,
|
||||
Field: CbFlds,
|
||||
Field: NoFlds,
|
||||
IgnoredFields: false,
|
||||
AutoCheck: true,
|
||||
GenLevel: 0,
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"review.coreboot.org/coreboot.git/util/intelp2m/cli"
|
||||
"review.coreboot.org/coreboot.git/util/intelp2m/config/p2m"
|
||||
"review.coreboot.org/coreboot.git/util/intelp2m/parser"
|
||||
)
|
||||
|
|
@ -24,101 +24,34 @@ func (Printer) Line(lvl int, str string) {
|
|||
}
|
||||
}
|
||||
|
||||
var (
|
||||
// Version is injected into main during project build
|
||||
Version string = "Unknown"
|
||||
)
|
||||
|
||||
// printVersion - print the utility version in the console
|
||||
func printVersion() {
|
||||
fmt.Printf("[ intelp2m ] Version: %s\n", Version)
|
||||
}
|
||||
// Version is injected into main during project build
|
||||
var Version string = "Unknown"
|
||||
|
||||
// main
|
||||
func main() {
|
||||
// Command line arguments
|
||||
inputFilePath := flag.String("file", "inteltool.log",
|
||||
"the path to the inteltool log file\n")
|
||||
|
||||
outputFilePath := flag.String("o",
|
||||
"generate/gpio.h",
|
||||
"the path to the generated file with GPIO configuration\n")
|
||||
|
||||
ignored := flag.Bool("ign", false,
|
||||
"exclude fields that should be ignored from advanced macros\n")
|
||||
|
||||
unchecking := flag.Bool("n", false,
|
||||
"Generate macros without checking.\n"+
|
||||
"\tIn this case, some fields of the configuration registers\n"+
|
||||
"\tDW0 will be ignored.\n")
|
||||
|
||||
levels := []*bool{
|
||||
flag.Bool("i", false, "Show pads function in the comments"),
|
||||
flag.Bool("ii", false, "Show DW0/DW1 value in the comments"),
|
||||
flag.Bool("iii", false, "Show ignored bit fields in the comments"),
|
||||
flag.Bool("iiii", false, "Show target PAD_CFG() macro in the comments"),
|
||||
}
|
||||
|
||||
platform := flag.String("p", "snr", "set platform:\n"+
|
||||
"\tsnr - Sunrise PCH or Skylake/Kaby Lake SoC\n"+
|
||||
"\tlbg - Lewisburg PCH with Xeon SP\n"+
|
||||
"\tapl - Apollo Lake SoC\n"+
|
||||
"\tcnl - CannonLake-LP or Whiskeylake/Coffeelake/Cometlake-U SoC\n"+
|
||||
"\ttgl - TigerLake-H SoC\n"+
|
||||
"\tadl - AlderLake PCH\n"+
|
||||
"\tjsl - Jasper Lake SoC\n"+
|
||||
"\tmtl - MeteorLake SoC\n"+
|
||||
"\tebg - Emmitsburg PCH with Xeon SP\n")
|
||||
|
||||
field := flag.String("fld", "none", "set fields macros style:\n"+
|
||||
"\tcb - use coreboot style for bit fields macros\n"+
|
||||
"\tfsp - use fsp style\n"+
|
||||
"\traw - do not convert, print as is\n")
|
||||
|
||||
flag.Parse()
|
||||
printVersion()
|
||||
|
||||
// settings
|
||||
p2m.Config.Version = Version
|
||||
p2m.Config.IgnoredFields = *ignored
|
||||
p2m.Config.AutoCheck = !(*unchecking)
|
||||
for level, set := range levels {
|
||||
if *set {
|
||||
p2m.Config.GenLevel = level + 1
|
||||
fmt.Printf("Info level: Use level %d!\n", level+1)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if err := p2m.SetPlatformType(*platform); err != nil {
|
||||
fmt.Printf("Error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
cli.ParseOptions()
|
||||
|
||||
if err := p2m.SetFieldType(*field); err != nil {
|
||||
fmt.Printf("Error: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if file, err := os.Open(*inputFilePath); err != nil {
|
||||
fmt.Printf("input file error: %v", err)
|
||||
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()
|
||||
}
|
||||
defer p2m.Config.InputFile.Close()
|
||||
|
||||
if err := os.MkdirAll(filepath.Dir(*outputFilePath), os.ModePerm); err != nil {
|
||||
fmt.Printf("failed to create output directory: %v", err)
|
||||
if err := os.MkdirAll(filepath.Dir(p2m.Config.OutputPath), os.ModePerm); err != nil {
|
||||
fmt.Printf("failed to create output directory: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
if file, err := os.Create(*outputFilePath); err != nil {
|
||||
fmt.Printf("failed to create output file: %v", err)
|
||||
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()
|
||||
}
|
||||
defer p2m.Config.OutputFile.Close()
|
||||
|
||||
prs := parser.ParserData{}
|
||||
prs.Parse()
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
1.2
|
||||
1.3
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue