Maxim Polyakov has uploaded this change for review.

View Change

util/intelp2m: initial commit

intelp2m - Intel Pad to Macro

A small utility for converting a pad configuration from an inteltool
dump to a PAD_CFG_ * macro coreboot.

Tested on Asroch-H110M-DVS motherboard [2]

[1] https://github.com/maxpoliak/pch-pads-parser
[2] https://review.coreboot.org/c/coreboot/+/33565

Change-Id: If3e3b523c4f63dc2f91e9ccd16934e3a1b6e21fa
Signed-off-by: Maxim Polyakov <max.senia.poliak@gmail.com>
---
A util/intelp2m/main.go
A util/intelp2m/parser/parser.go
A util/intelp2m/sunrise/dw.go
A util/intelp2m/sunrise/macro.go
4 files changed, 871 insertions(+), 0 deletions(-)

git pull ssh://review.coreboot.org:29418/coreboot refs/changes/43/35643/1
diff --git a/util/intelp2m/main.go b/util/intelp2m/main.go
new file mode 100644
index 0000000..0881e10
--- /dev/null
+++ b/util/intelp2m/main.go
@@ -0,0 +1,129 @@
+package main
+
+import (
+ "flag"
+ "fmt"
+ "os"
+)
+
+import "./parser"
+
+// HdrInfoAdd - adds license header to file f
+func HdrInfoAdd(f *os.File) {
+ f.WriteString(`/*
+ * This file is part of the coreboot project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+`)
+}
+
+// CreateHdrFile - generates include file
+func CreateHdrFile() (err error) {
+ hrdFile, err := os.Create("generate/gpio.h")
+ if err != nil {
+ fmt.Printf("Error!\n")
+ return err
+ }
+ defer hrdFile.Close()
+
+ HdrInfoAdd(hrdFile)
+ hrdFile.WriteString(`#ifndef PCH_GPIO_H
+#define PCH_GPIO_H
+
+#include <soc/gpe.h>
+#include <soc/gpio.h>
+
+const struct pad_config *get_gpio_table(size_t *num);
+const struct pad_config *get_early_gpio_table(size_t *num);
+
+#endif /* PCH_GPIO_H */
+`)
+ return nil
+}
+
+// CreateGpioFile - generates gpio_raw.c file
+// parser : parser data structure
+// showRawDataFlag : raw data flag
+// in the case when this flag is false, pad information will
+// be create as macro
+func CreateGpioFile(parser *parser.ParserData, showRawDataFlag bool) (err error) {
+ var name = "generate/gpio"
+ if showRawDataFlag {
+ name += "_raw"
+ }
+ name += ".c"
+ gpio, err := os.Create(name)
+ if err != nil {
+ fmt.Printf("Error!\n")
+ return err
+ }
+ defer gpio.Close()
+
+ HdrInfoAdd(gpio)
+ gpio.WriteString(`
+#include <commonlib/helpers.h>
+#include "include/gpio.h"
+`)
+ // Add the pads map to gpio.h file
+ parser.PadMapFprint(gpio, showRawDataFlag)
+ return nil
+}
+
+// main
+func main() {
+ // Command line arguments
+ wordPtr := flag.String("file",
+ "inteltool.log",
+ "the path to the inteltool log file")
+ dbgPtr := flag.Bool("dbg", false, "debug flag")
+ flag.Parse()
+
+ fmt.Println("dbg:", *dbgPtr)
+ fmt.Println("file:", *wordPtr)
+
+ var parser parser.ParserData
+ parser.DbgFlag = *dbgPtr
+ err := parser.Parse(*wordPtr)
+ if err != nil {
+ fmt.Printf("Parser: Error!\n")
+ os.Exit(1)
+ }
+
+ // create dir for output files
+ err = os.MkdirAll("generate", os.ModePerm)
+ if err != nil {
+ fmt.Printf("Create a directory of generated files: Error!\n")
+ os.Exit(1)
+ }
+
+ // gpio.h
+ err = CreateHdrFile()
+ if err != nil {
+ fmt.Printf("Create pch_gpio.h: Error!\n")
+ os.Exit(1)
+ }
+
+ // gpio_raw.c
+ err = CreateGpioFile(&parser, true)
+ if err != nil {
+ fmt.Printf("Create gpio_raw.c: Error!\n")
+ os.Exit(1)
+ }
+
+ // gpio.c with macros
+ err = CreateGpioFile(&parser, false)
+ if err != nil {
+ fmt.Printf("Create gpio.c: Error!\n")
+ os.Exit(1)
+ }
+}
diff --git a/util/intelp2m/parser/parser.go b/util/intelp2m/parser/parser.go
new file mode 100644
index 0000000..b684653
--- /dev/null
+++ b/util/intelp2m/parser/parser.go
@@ -0,0 +1,189 @@
+package parser
+
+import (
+ "bufio"
+ "fmt"
+ "os"
+ "strings"
+)
+
+import "../sunrise"
+
+// 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
+type padInfo struct {
+ id string
+ offset uint16
+ function string
+ community uint8
+ dw0 uint32
+ dw1 uint32
+}
+
+// add - add information about pad to data structure
+// line : string from inteltool log file
+func (info *padInfo) add(line string) {
+ var val uint64
+ if strings.HasPrefix(line, "----") {
+ // ------- GPIO Group GPP_A -------
+ // ------- GPIO Community 0 -------
+ // Add header to define GPIO group or community
+ info.function = line
+ return
+ }
+ // 0x0520: 0x0000003c44000600 GPP_B12 SLP_S0#
+ // 0x0438: 0xffffffffffffffff GPP_C7 RESERVED
+ fmt.Sscanf(line,
+ "0x%x: 0x%x %s %s",
+ &info.offset,
+ &val,
+ &info.id,
+ &info.function)
+ info.dw0 = uint32(val & 0xffffffff)
+ info.dw1 = uint32(val >> 32)
+}
+
+// titleFprint - print GPIO group title to file
+// gpio : gpio.c file descriptor
+func (info *padInfo) titleFprint(gpio *os.File) {
+ fmt.Fprintf(gpio, "\n\t/* %s */\n", info.function)
+}
+
+// reservedFprint - print reserved GPIO to file as comment
+// gpio : gpio.c file descriptor
+func (info *padInfo) reservedFprint(gpio *os.File) {
+ // small comment about reserved port
+ fmt.Fprintf(gpio, "\t/* %s - %s */\n", info.id, info.function)
+}
+
+// padInfoRawFprint - print information about current pad to file using
+// raw format:
+// _PAD_CFG_STRUCT(GPP_F1, 0x84000502, 0x00003026), /* SATAXPCIE4 */
+// gpio : gpio.c file descriptor
+func (info *padInfo) padInfoRawFprint(gpio *os.File) {
+ fmt.Fprintf(gpio,
+ "\t_PAD_CFG_STRUCT(%s, 0x%0.8x, 0x%0.8x), /* %s */\n",
+ info.id,
+ info.dw0,
+ (info.dw1 & 0xffffff00), // Interrupt Select - RO
+ 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
+func (info *padInfo) padInfoMacroFprint(gpio *os.File) {
+ fmt.Fprintf(gpio, "\t/* %s - %s */\n\t%s\n",
+ info.id,
+ info.function,
+ sunrise.GetMacro(info.id, info.dw0, info.dw1))
+}
+
+// ParserData - global data
+// padmap : pad info map
+// dbgFlag : gebug flag, currently not used
+type ParserData struct {
+ padmap []padInfo
+ DbgFlag bool
+}
+
+// padInfoAdd - adds a new entry to pad info map
+// line : string/line from the inteltool log file
+// community : pads community number
+func (parser *ParserData) padInfoAdd(line string, community uint8) {
+ pad := padInfo{community : community}
+ pad.add(line)
+ parser.padmap = append(parser.padmap, pad)
+}
+
+// getCommunity - scans the string and returns the pads community number
+// line : string from inteltool log file
+// return
+// community number
+func (parser *ParserData) getCommunity(line string) uint8 {
+ var comm uint8
+ fmt.Sscanf(line, "------- GPIO Community %d -------", &comm)
+ return comm
+}
+
+// PadMapFprint - print pad info map to file
+// gpio : gpio.c descriptor file
+// raw : in the case when this flag is false, pad information will be print
+// as macro
+func (parser *ParserData) PadMapFprint(gpio *os.File, raw bool) {
+ gpio.WriteString("\n/* Pad configuration in ramstage */\n")
+ gpio.WriteString("static const struct pad_config gpio_table[] = {\n")
+ for _, pad := range parser.padmap {
+ switch pad.dw0 {
+ case 0:
+ pad.titleFprint(gpio)
+ case 0xffffffff:
+ pad.reservedFprint(gpio)
+ default:
+ if raw {
+ pad.padInfoRawFprint(gpio)
+ } else {
+ pad.padInfoMacroFprint(gpio)
+ }
+ }
+ }
+ gpio.WriteString("};\n")
+
+ // FIXME: need to add early configuration
+ gpio.WriteString(`/* Early pad configuration in romstage. */
+static const struct pad_config early_gpio_table[] = {
+ /* TODO: Add early pad configuration */
+};
+
+const struct pad_config *get_gpio_table(size_t *num)
+{
+ *num = ARRAY_SIZE(gpio_table);
+ return gpio_table;
+}
+
+const struct pad_config *get_early_gpio_table(size_t *num)
+{
+ *num = ARRAY_SIZE(early_gpio_table);
+ return early_gpio_table;
+}
+
+`)
+}
+
+// Parse pads groupe information in the inteltool log file
+// logFile : name of inteltool log file
+// return
+// err : error
+func (parser *ParserData) Parse(logFile string) (err error) {
+ file, err := os.Open(logFile)
+ if err != nil {
+ return err
+ }
+ defer file.Close()
+
+ // Read all lines from inteltool log file
+ fmt.Println("Parse IntelTool Log File...")
+ scanner := bufio.NewScanner(file)
+ var line string
+ var community uint8 = 0
+ for scanner.Scan() {
+ line = scanner.Text()
+ // Use only the string that contains the GPP information
+ if !strings.Contains(line, "GPP_") && !strings.Contains(line, "GPD") {
+ // ------- GPIO Community 0 -------
+ if strings.Contains(line, "Community") {
+ community = parser.getCommunity(line)
+ } else {
+ continue
+ }
+ }
+ parser.padInfoAdd(line, community)
+ }
+ fmt.Println("...done!")
+ return nil
+}
\ No newline at end of file
diff --git a/util/intelp2m/sunrise/dw.go b/util/intelp2m/sunrise/dw.go
new file mode 100644
index 0000000..f3623b0
--- /dev/null
+++ b/util/intelp2m/sunrise/dw.go
@@ -0,0 +1,198 @@
+package sunrise
+
+// Bit field constants for DW0 register
+const (
+ padRstCfgShift uint8 = 30
+ padRstCfgMask uint32 = 0x3 << padRstCfgShift
+
+ rxPadStateSelectShift uint8 = 29
+ rxPadStateSelectMask uint32 = 0x1 << rxPadStateSelectShift
+
+ rxRawOverrideTo1Shift uint8 = 28
+ rxRawOverrideTo1Mask uint32 = 0x1 << rxRawOverrideTo1Shift
+
+ rxLevelEdgeConfigurationShift uint8 = 25
+ rxLevelEdgeConfigurationMask uint32 = 0x3 << rxLevelEdgeConfigurationShift
+
+ rxInvertShift uint8 = 23
+ rxInvertMask uint32 = 0x1 << rxInvertShift
+
+ gpioInputRouteIOxApicShift uint8 = 20
+ gpioInputRouteIOxApicMask uint32 = 0x1 << gpioInputRouteIOxApicShift
+
+ gpioInputRouteSCIShift uint8 = 19
+ gpioInputRouteSCIMask uint32 = 0x1 << gpioInputRouteSCIShift
+
+ gpioInputRouteSMIShift uint8 = 18
+ gpioInputRouteSMIMask uint32 = 0x1 << gpioInputRouteSMIShift
+
+ gpioInputRouteNMIShift uint8 = 17
+ gpioInputRouteNMIMask uint32 = 0x1 << gpioInputRouteNMIShift
+
+ padModeShift uint8 = 10
+ padModeMask uint32 = 0x7 << padModeShift
+
+ gpioRxTxDisableShift uint8 = 8
+ gpioRxTxDisableMask uint32 = 0x3 << gpioRxTxDisableShift
+
+ gpioRxStateShift uint8 = 1
+ gpioRxStateMask uint32 = 0x1 << gpioRxStateShift
+
+ gpioTxStateMask uint32 = 0x1
+)
+
+// Bit field constants for DW1 register
+const (
+ termShift uint8 = 10
+ termMask uint32 = 0xF << termShift
+ interruptSelectShift uint32 = 0xFF
+)
+
+// Maximum numbers of the config DW register for Sunrise chipset
+const (
+ MaxDWNum = 2
+)
+
+// dwcfg - configuration data structure based on DW0/1 reg value
+// reg : register value
+// mask : bit fileds mask
+type dwcfg struct {
+ reg [MaxDWNum]uint32
+ mask [MaxDWNum]uint32
+}
+
+// getResetConfig - get Reset Configuration from PADRSTCFG field in PAD_CFG_DW0_GPx register
+func (dw *dwcfg) getFieldVal(regNum uint8, mask uint32, shift uint8) uint8 {
+ if regNum < MaxDWNum {
+ dw.mask[regNum] |= mask
+ return uint8((dw.reg[regNum] & mask) >> shift)
+ }
+ return 0
+}
+
+// Check the mask of the new macro
+// regNum : DW register number
+// Returns true if the macro is generated correctly
+func (dw *dwcfg) maskCheck(regNum uint8) bool {
+ if regNum >= MaxDWNum {
+ return false
+ }
+
+ // Take into account the bits that are read-only
+ readonly := [MaxDWNum]uint32{
+ (0x1 << 27) | (0x1 << 24) | (0x3 << 21) | (0xf << 16) | 0xfe,
+ 0xfffffc3f,
+ }
+ mask := ^(dw.mask[regNum] | readonly[regNum])
+ return dw.reg[regNum]&mask == 0
+}
+
+// Fix Pad Reset Config field in mask for DW0 register
+// Returns *dwcfg
+func (dw *dwcfg) maskResetFix() *dwcfg {
+ dw.mask[0] |= padRstCfgMask
+ return dw
+}
+
+// Fix RX Level/Edge Configuration field in mask for DW0 register
+// Returns *dwcfg
+func (dw *dwcfg) maskTrigFix() *dwcfg {
+ dw.mask[0] |= rxLevelEdgeConfigurationMask
+ return dw
+}
+
+// getResetConfig - returns type reset source for corresponding pad
+// PADRSTCFG field in PAD_CFG_DW0 register
+// 00 = RSMRST#, 01 = DEEP#, 10 = PLTRST#, 11 = RSMRST# for GPDx pads
+// and Reserved for others
+func (dw *dwcfg) getResetConfig() uint8 {
+ return dw.getFieldVal(0, padRstCfgMask, padRstCfgShift)
+}
+
+// getRXPadStateSelect - returns RX Pad State (RXINV)
+// 0 = Raw RX pad state directly from RX buffer
+// 1 = Internal RX pad state
+func (dw *dwcfg) getRXPadStateSelect() uint8 {
+ return dw.getFieldVal(0, rxPadStateSelectMask, rxPadStateSelectShift)
+}
+
+// getRXRawOverrideStatus - returns 1 if the selected pad state is being
+// overridden to '1' (RXRAW1 field)
+func (dw *dwcfg) getRXRawOverrideStatus() uint8 {
+ return dw.getFieldVal(0, rxRawOverrideTo1Mask, rxRawOverrideTo1Shift)
+}
+
+// getRXLevelEdgeConfiguration - returns RX Level/Edge Configuration (RXEVCFG)
+// 0h = Level, 1h = Edge, 2h = Drive '0', 3h = Reserved (implement as setting 0h)
+func (dw *dwcfg) getRXLevelEdgeConfiguration() uint8 {
+ return dw.getFieldVal(0, rxLevelEdgeConfigurationMask, rxLevelEdgeConfigurationShift)
+}
+
+// getRXLevelConfiguration - returns RX Invert state (RXINV)
+// 1 - Inversion, 0 - No inversion
+func (dw *dwcfg) getRXLevelConfiguration() bool {
+ return dw.getFieldVal(0, rxInvertMask, rxInvertShift) != 0
+}
+
+// getGPIOInputRouteIOxAPIC - returns 1 if the pad can be routed to cause
+// peripheral IRQ when configured in GPIO input mode.
+func (dw *dwcfg) getGPIOInputRouteIOxAPIC() bool {
+ return dw.getFieldVal(0, gpioInputRouteIOxApicMask, gpioInputRouteIOxApicShift) != 0
+}
+
+// getGPIOInputRouteSCI - returns 1 if the pad can be routed to cause SCI when
+// configured in GPIO input mode.
+func (dw *dwcfg) getGPIOInputRouteSCI() bool {
+ return dw.getFieldVal(0, gpioInputRouteSCIMask, gpioInputRouteSCIShift) != 0
+}
+
+// getGPIOInputRouteSMI - returns 1 if the pad can be routed to cause SMI when
+// configured in GPIO input mode
+func (dw *dwcfg) getGPIOInputRouteSMI() bool {
+ return dw.getFieldVal(0, gpioInputRouteSMIMask, gpioInputRouteSMIShift) != 0
+}
+
+// getGPIOInputRouteNMI - returns 1 if the pad can be routed to cause NMI when
+// configured in GPIO input mode
+func (dw *dwcfg) getGPIOInputRouteNMI() bool {
+ return dw.getFieldVal(0, gpioInputRouteNMIMask, gpioInputRouteNMIShift) != 0
+}
+
+// getPadMode - reutrns pad mode or one of the native functions
+// 0h = GPIO control the Pad.
+// 1h = native function 1, if applicable, controls the Pad
+// 2h = native function 2, if applicable, controls the Pad
+// 3h = native function 3, if applicable, controls the Pad
+// 4h = enable GPIO blink/PWM capability if applicable
+func (dw *dwcfg) getPadMode() uint8 {
+ return dw.getFieldVal(0, padModeMask, padModeShift)
+}
+
+// getGPIORxTxDisableStatus - returns GPIO RX/TX buffer state (GPIORXDIS | GPIOTXDIS)
+// 0 - both are enabled, 1 - TX Disable, 2 - RX Disable, 3 - both are disabled
+func (dw *dwcfg) getGPIORxTxDisableStatus() uint8 {
+ return dw.getFieldVal(0, gpioRxTxDisableMask, gpioRxTxDisableShift)
+}
+
+// getGPIORXState - returns GPIO RX State (GPIORXSTATE)
+func (dw *dwcfg) getGPIORXState() uint8 {
+ return dw.getFieldVal(0, gpioRxStateMask, gpioRxStateShift)
+}
+
+// getGPIOTXState - returns GPIO TX State (GPIOTXSTATE)
+func (dw *dwcfg) getGPIOTXState() int {
+ return int(dw.getFieldVal(0, gpioTxStateMask, 0))
+}
+
+// getTermination - returns the pad termination state defines the different weak
+// pull-up and pull-down settings that are supported by the buffer
+// 0000 = none; 0010 = 5k PD; 0100 = 20k PD; 1010 = 5k PU; 1100 = 20k PU;
+// 1111 = Native controller selected
+func (dw *dwcfg) getTermination() uint8 {
+ return dw.getFieldVal(1, termMask, termShift)
+}
+
+// getInterruptSelect - returns Interrupt Line number from the GPIO controller
+func (dw *dwcfg) getInterruptSelect() uint8 {
+ return dw.getFieldVal(1, interruptSelectShift, 0)
+}
diff --git a/util/intelp2m/sunrise/macro.go b/util/intelp2m/sunrise/macro.go
new file mode 100644
index 0000000..7489709
--- /dev/null
+++ b/util/intelp2m/sunrise/macro.go
@@ -0,0 +1,355 @@
+package sunrise
+
+import (
+ "fmt"
+ "strconv"
+ "strings"
+)
+
+// macro - contains macro information and methods
+// padID : pad ID string
+// str : macro string entirely
+// dwcfg : configuration data structure
+type macro struct {
+ padID string
+ str string
+ dwcfg
+}
+
+// dw - returns dwcfg data configuration structure with PAD_CFG_DW0/1 register
+// values
+func (macro *macro) dw() *dwcfg {
+ return &macro.dwcfg
+}
+
+// add a string to macro
+func (macro *macro) add(str string) *macro {
+ macro.str += str
+ return macro
+}
+
+// set a string in a macro instead of its previous contents
+func (macro *macro) set(str string) *macro {
+ macro.str = str
+ return macro
+}
+
+// get macro string
+func (macro *macro) get() string {
+ return macro.str
+}
+
+// Adds PAD Id to the macro as a new argument
+// return: macro
+func (macro *macro) id() *macro {
+ return macro.add(macro.padID)
+}
+
+// Add separator to macro if needed
+func (macro *macro) separator() *macro {
+ str := macro.get()
+ c := str[len(str)-1]
+ if c != '(' && c != '_' {
+ macro.add(", ")
+ }
+ return macro
+}
+
+// Adds the PADRSTCFG parameter from DW0 to the macro as a new argument
+// return: macro
+func (macro *macro) rstsrc() *macro {
+ var resetSrc = map[uint8]string{
+ 0x0: "PWROK",
+ 0x1: "DEEP",
+ 0x2: "PLTRST",
+ }
+ str, valid := resetSrc[macro.dw().getResetConfig()]
+ if !valid {
+ // Pad Reset Config field in DW0 register should implements 3h value
+ // as RSMRST for GPD pads group, but this value is reserved for other
+ // groups
+ if strings.Contains(macro.padID, "GPD") {
+ str = "RSMRST"
+ } else {
+ str = resetSrc[0]
+ fmt.Println("Warning:", macro.padID, "PADRSTCFG = 3h Reserved")
+ fmt.Println("It is implemented as setting 0h (PWROK) for Sunrise PCH")
+ }
+ }
+ return macro.separator().add(str)
+}
+
+// Adds The Pad Termination (TERM) parameter from DW1 to the macro as a new argument
+// return: macro
+func (macro *macro) pull() *macro {
+ var pull = map[uint8]string{
+ 0x0: "NONE",
+ 0x2: "5K_PD",
+ 0x4: "20K_PD",
+ 0x9: "1K_PU",
+ 0xa: "5K_PU",
+ 0xb: "2K_PU",
+ 0xc: "20K_PU",
+ 0xd: "667_PU",
+ 0xf: "NATIVE",
+ }
+ str, valid := pull[macro.dw().getTermination()]
+ if !valid {
+ str = "INVALID"
+ fmt.Println("Error",
+ macro.padID,
+ " invalid TERM value = ",
+ int(macro.dw().getTermination()))
+ }
+ return macro.separator().add(str)
+}
+
+// Adds Pad GPO value to macro string as a new argument
+// return: macro
+func (macro *macro) val() *macro {
+ return macro.separator().add(strconv.Itoa(macro.dw().getGPIOTXState()))
+}
+
+// Adds Pad GPO value to macro string as a new argument
+// return: macro
+func (macro *macro) trig() *macro {
+ var dw = macro.dw()
+ var trig = map[uint8]string{
+ 0x0: "LEVEL",
+ 0x1: "EDGE_SINGLE",
+ 0x2: "OFF",
+ 0x3: "EDGE_BOTH",
+ }
+ return macro.separator().add(trig[dw.getRXLevelEdgeConfiguration()])
+}
+
+// Adds Pad Polarity Inversion Stage (RXINV) to macro string as a new argument
+// return: macro
+func (macro *macro) invert() *macro {
+ macro.separator()
+ if macro.dw().getRXLevelConfiguration() {
+ return macro.add("YES")
+ }
+ return macro.add("NONE")
+}
+
+// Adds input/output buffer state
+// return: macro
+func (macro *macro) bufdis() *macro {
+ var buffDisStat = map[uint8]string{
+ 0x0: "NO_DISABLE", // both buffers are enabled
+ 0x1: "TX_DISABLE", // output buffer is disabled
+ 0x2: "RX_DISABLE", // input buffer is disabled
+ 0x3: "TX_RX_DISABLE", // both buffers are disabled
+ }
+ state := macro.dw().getGPIORxTxDisableStatus()
+ return macro.separator().add(buffDisStat[state])
+}
+
+//Adds pad native function (PMODE) as a new argument
+//return: macro
+func (macro *macro) padfn() *macro {
+ nfnum := int(macro.dw().getPadMode())
+ if nfnum != 0 {
+ return macro.separator().add("NF" + strconv.Itoa(nfnum))
+ }
+ // GPIO used only for PAD_FUNC(x) macro
+ return macro.add("GPIO")
+}
+
+// Adds suffix to GPI macro with arguments
+func (macro *macro) addSuffixInput() {
+ dw := macro.dw()
+ isEdge := dw.getRXLevelEdgeConfiguration()
+ macro.add("_GPI")
+ switch {
+ case dw.getGPIOInputRouteNMI():
+ // e.g. PAD_CFG_GPI_NMI(GPIO_24, UP_20K, DEEP, LEVEL, INVERT),
+ macro.add("_NMI").add("(").id().pull().rstsrc().trig().invert()
+
+ case dw.getGPIOInputRouteIOxAPIC():
+ // e.g. PAD_CFG_GPI_APIC(GPP_B3, NONE, PLTRST)
+ macro.add("_APIC")
+ if isEdge == 0 {
+ if dw.getRXLevelConfiguration() {
+ // e.g. PAD_CFG_GPI_APIC_INVERT(GPP_C5, DN_20K, DEEP),
+ macro.add("_INVERT")
+ }
+ macro.add("(").id().pull().rstsrc()
+ } else {
+ // PAD_CFG_GPI_APIC_IOS(GPP_C20, NONE, DEEP, LEVEL, INVERT,
+ // TxDRxE, DISPUPD) macro isn't used for this chipset. But, in
+ // the case when SOC_INTEL_COMMON_BLOCK_GPIO_LEGACY_MACROS is
+ // defined in the config, this macro allows you to set trig and
+ // invert parameters.
+ macro.add("_IOS").add("(").id().pull().rstsrc().trig().invert()
+ // IOStandby Config will be ignored for the Sunrise PCH, so use
+ // any values
+ macro.add(", TxDRxE, DISPUPD")
+ }
+
+ case dw.getGPIOInputRouteSCI():
+
+ // e.g. PAD_CFG_GPI_SCI(GPP_B18, UP_20K, PLTRST, LEVEL, INVERT),
+ if (isEdge & 0x1) != 0 {
+ // e.g. PAD_CFG_GPI_ACPI_SCI(GPP_G2, NONE, DEEP, YES),
+ macro.add("_ACPI")
+ }
+ macro.add("_SCI").add("(").id().pull().rstsrc()
+ if (isEdge & 0x1) == 0 {
+ macro.trig()
+ }
+ macro.invert()
+
+ case dw.getGPIOInputRouteSMI():
+ if (isEdge & 0x1) != 0 {
+ // e.g. PAD_CFG_GPI_ACPI_SMI(GPP_I3, NONE, DEEP, YES),
+ macro.add("_ACPI")
+ }
+ macro.add("_SMI").add("(").id().pull().rstsrc().invert()
+
+ case isEdge != 0:
+ // e.g. ISH_SPI_CS#
+ // PAD_CFG_GPI_INT(GPP_D9, NONE, PLTRST, EDGE),
+ macro.add("_INT").add("(").id().pull().rstsrc().trig()
+
+ default:
+ // e.g. PAD_CFG_GPI(GPP_A7, NONE, DEEP),
+ macro.add("(").id().pull().rstsrc()
+ }
+}
+
+// Adds suffix to GPO macro with arguments
+func (macro *macro) addSuffixOutput() {
+ term := macro.dw().getTermination()
+ // FIXME: don`t understand how to get PAD_CFG_GPI_GPIO_DRIVER(..)
+ if term != 0 {
+ // e.g. PAD_CFG_TERM_GPO(GPP_B23, 1, DN_20K, DEEP),
+ macro.add("_TERM")
+ }
+ macro.add("_GPO").add("(").id().val()
+ if term != 0 {
+ macro.pull()
+ }
+ macro.rstsrc()
+
+ // Fix mask for RX Level/Edge Configuration (RXEVCFG)
+ // See https://github.com/coreboot/coreboot/commit/3820e3c
+ macro.dw().maskTrigFix()
+}
+
+const (
+ rxDisable uint8 = 0x2
+ txDisable uint8 = 0x1
+)
+
+// Set common macros macros if the standard ones can't define the values from
+// the DW0/1 register
+func (macro *macro) common() *macro {
+ macro.set("_PAD_CFG_STRUCT(").id().
+ add(",\n\t\tPAD_FUNC(").padfn().
+ add(") | PAD_RESET(").rstsrc().add(") |\n\t\t")
+
+ var str string
+ var argument = true
+ switch dw := macro.dw(); {
+ case dw.getGPIOInputRouteIOxAPIC():
+ str = "IOAPIC"
+ case dw.getGPIOInputRouteSCI():
+ str = "SCI"
+ case dw.getGPIOInputRouteSMI():
+ str = "SMI"
+ case dw.getGPIOInputRouteNMI():
+ str = "NMI"
+ default:
+ argument = false
+ }
+
+ if argument {
+ macro.add("PAD_IRQ_CFG(").add(str).trig().invert().add(")")
+ } else {
+ macro.add("PAD_CFG0_TRIG_").trig().add(" | PAD_CFG0_RX_POL_").invert()
+ }
+
+ macro.add(" |\n\t\t").add("PAD_BUF(").bufdis().add(")")
+ if macro.dw().getGPIOTXState() != 0 {
+ macro.add(" | 1")
+ }
+ return macro.add(",\n\t\tPAD_PULL(").pull().add(")),")
+}
+
+// Check created macro
+func (macro *macro) check() {
+ if !macro.dw().maskCheck(0) {
+ macro.common()
+ // Debug message about this
+ fmt.Printf(
+ "\nCoreboot macros can't define the configuration for pad: %s\n",
+ macro.padID)
+ fmt.Printf("Use %s\n", macro.get())
+ }
+}
+
+// Gets base string of current macro
+// return: string of macro
+// error
+func (macro *macro) generate(id string, dw0 uint32, dw1 uint32) string {
+ macro.dwcfg.reg[0] = dw0
+ macro.dwcfg.reg[1] = dw1
+ dw := &macro.dwcfg
+
+ macro.set("PAD_CFG")
+ if dw.getPadMode() == 0 {
+ // GPIO
+ switch dw.getGPIORxTxDisableStatus() {
+ case rxDisable:
+ // GPI
+ macro.addSuffixInput()
+
+ case txDisable:
+ // GPO
+ macro.addSuffixOutput()
+
+ case rxDisable | txDisable:
+ // NC
+ macro.set("PAD_NC").add("(").id().pull()
+ // Fix mask for RX Level/Edge Configuration (RXEVCFG)
+ // and Pad Reset Config (PADRSTCFG)
+ // There is no need to check these fields if the pad
+ // is in the NC state
+ macro.dw().maskResetFix().maskTrigFix()
+
+ default:
+ // In case the rule isn't found, a common macro is used
+ // to create the pad configuration
+ return macro.common().get()
+ }
+ } else {
+ isEdge := dw.getRXLevelEdgeConfiguration() != 0
+ isTxRxBufDis := dw.getGPIORxTxDisableStatus() != 0
+ // e.g. PAD_CFG_NF(GPP_D23, NONE, DEEP, NF1)
+ macro.add("_NF")
+ if isEdge || isTxRxBufDis {
+ // e.g. PCHHOT#
+ // PAD_CFG_NF_BUF_TRIG(GPP_B23, 20K_PD, PLTRST, NF2, RX_DIS, OFF),
+ macro.add("_BUF_TRIG")
+ }
+ macro.add("(").id().pull().rstsrc().padfn()
+ if isEdge || isTxRxBufDis {
+ macro.bufdis().trig()
+ }
+ }
+ macro.add("),")
+ macro.check()
+ return macro.get()
+}
+
+// GetMacro - get pad macro
+// dw0 : DW0 config register value
+// dw1 : DW1 config register value
+// return: string of macro
+// error
+func GetMacro(id string, dw0 uint32, dw1 uint32) string {
+ macro := macro{padID : id}
+ return macro.generate(id, dw0, dw1)
+}

To view, visit change 35643. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: If3e3b523c4f63dc2f91e9ccd16934e3a1b6e21fa
Gerrit-Change-Number: 35643
Gerrit-PatchSet: 1
Gerrit-Owner: Maxim Polyakov <max.senia.poliak@gmail.com>
Gerrit-MessageType: newchange