430 lines
9.7 KiB
Go
430 lines
9.7 KiB
Go
package common
|
|
|
|
import (
|
|
"strconv"
|
|
"sync"
|
|
|
|
"review.coreboot.org/coreboot.git/util/intelp2m/config"
|
|
)
|
|
|
|
type Fields interface {
|
|
DecodeDW0()
|
|
DecodeDW1()
|
|
GenerateString()
|
|
}
|
|
|
|
const (
|
|
PAD_OWN_ACPI = 0
|
|
PAD_OWN_DRIVER = 1
|
|
)
|
|
|
|
const (
|
|
TxLASTRxE = 0x0
|
|
Tx0RxDCRx0 = 0x1
|
|
Tx0RxDCRx1 = 0x2
|
|
Tx1RxDCRx0 = 0x3
|
|
Tx1RxDCRx1 = 0x4
|
|
Tx0RxE = 0x5
|
|
Tx1RxE = 0x6
|
|
HIZCRx0 = 0x7
|
|
HIZCRx1 = 0x8
|
|
TxDRxE = 0x9
|
|
StandbyIgnore = 0xf
|
|
)
|
|
|
|
const (
|
|
IOSTERM_SAME = 0x0
|
|
IOSTERM_DISPUPD = 0x1
|
|
IOSTERM_ENPD = 0x2
|
|
IOSTERM_ENPU = 0x3
|
|
)
|
|
|
|
const (
|
|
TRIG_LEVEL = 0
|
|
TRIG_EDGE_SINGLE = 1
|
|
TRIG_OFF = 2
|
|
TRIG_EDGE_BOTH = 3
|
|
)
|
|
|
|
const (
|
|
RST_PWROK = 0
|
|
RST_DEEP = 1
|
|
RST_PLTRST = 2
|
|
RST_RSMRST = 3
|
|
)
|
|
|
|
// PlatformSpecific - platform-specific interface
|
|
type PlatformSpecific interface {
|
|
RemmapRstSrc()
|
|
Pull()
|
|
GpiMacroAdd()
|
|
GpoMacroAdd()
|
|
NativeFunctionMacroAdd()
|
|
NoConnMacroAdd()
|
|
}
|
|
|
|
// Macro - contains macro information and methods
|
|
// Platform : platform-specific interface
|
|
// padID : pad ID string
|
|
// str : macro string entirely
|
|
// Reg : structure of configuration register values and their masks
|
|
type Macro struct {
|
|
Platform PlatformSpecific
|
|
Reg [MAX_DW_NUM]Register
|
|
padID string
|
|
str string
|
|
ownership uint8
|
|
Fields
|
|
}
|
|
|
|
var instanceMacro *Macro
|
|
var once sync.Once
|
|
|
|
// GetInstance returns singleton
|
|
func GetInstanceMacro(p PlatformSpecific, f Fields) *Macro {
|
|
once.Do(func() {
|
|
instanceMacro = &Macro{ Platform : p, Fields : f }
|
|
})
|
|
return instanceMacro
|
|
}
|
|
|
|
func GetMacro() *Macro {
|
|
return GetInstanceMacro(nil, nil)
|
|
}
|
|
|
|
func (macro *Macro) PadIdGet() string {
|
|
return macro.padID
|
|
}
|
|
|
|
func (macro *Macro) PadIdSet(padid string) *Macro {
|
|
macro.padID = padid
|
|
return macro
|
|
}
|
|
|
|
func (macro *Macro) SetPadOwnership(own uint8) *Macro {
|
|
macro.ownership = own
|
|
return macro
|
|
}
|
|
|
|
func (macro *Macro) IsOwnershipDriver() bool {
|
|
return macro.ownership == PAD_OWN_DRIVER
|
|
}
|
|
|
|
// returns <Register> data configuration structure
|
|
// number : register number
|
|
func (macro *Macro) Register(number uint8) *Register {
|
|
return ¯o.Reg[number]
|
|
}
|
|
|
|
// 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
|
|
}
|
|
|
|
// set a string in a macro instead of its previous contents
|
|
func (macro *Macro) Clear() *Macro {
|
|
macro.Set("")
|
|
return macro
|
|
}
|
|
|
|
// 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 {
|
|
dw0 := macro.Register(PAD_CFG_DW0)
|
|
var resetsrc = map[uint8]string {
|
|
0: "PWROK",
|
|
1: "DEEP",
|
|
2: "PLTRST",
|
|
3: "RSMRST",
|
|
}
|
|
return macro.Separator().Add(resetsrc[dw0.GetResetConfig()])
|
|
}
|
|
|
|
// Adds The Pad Termination (TERM) parameter from DW1 to the macro as a new argument
|
|
// return: Macro
|
|
func (macro *Macro) Pull() *Macro {
|
|
macro.Platform.Pull()
|
|
return macro
|
|
}
|
|
|
|
// Adds Pad GPO value to macro string as a new argument
|
|
// return: Macro
|
|
func (macro *Macro) Val() *Macro {
|
|
dw0 := macro.Register(PAD_CFG_DW0)
|
|
return macro.Separator().Add(strconv.Itoa(int(dw0.GetGPIOTXState())))
|
|
}
|
|
|
|
// Adds Pad GPO value to macro string as a new argument
|
|
// return: Macro
|
|
func (macro *Macro) Trig() *Macro {
|
|
dw0 := macro.Register(PAD_CFG_DW0)
|
|
var trig = map[uint8]string{
|
|
0x0: "LEVEL",
|
|
0x1: "EDGE_SINGLE",
|
|
0x2: "OFF",
|
|
0x3: "EDGE_BOTH",
|
|
}
|
|
return macro.Separator().Add(trig[dw0.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.Register(PAD_CFG_DW0).GetRxInvert() !=0 {
|
|
return macro.Add("INVERT")
|
|
}
|
|
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.Register(PAD_CFG_DW0).GetGPIORxTxDisableStatus()
|
|
return macro.Separator().Add(buffDisStat[state])
|
|
}
|
|
|
|
// Adds macro to set the host software ownership
|
|
// return: Macro
|
|
func (macro *Macro) Own() *Macro {
|
|
if macro.IsOwnershipDriver() {
|
|
return macro.Separator().Add("DRIVER")
|
|
}
|
|
return macro.Separator().Add("ACPI")
|
|
}
|
|
|
|
//Adds pad native function (PMODE) as a new argument
|
|
//return: Macro
|
|
func (macro *Macro) Padfn() *Macro {
|
|
dw0 := macro.Register(PAD_CFG_DW0)
|
|
nfnum := int(dw0.GetPadMode())
|
|
if nfnum != 0 {
|
|
return macro.Separator().Add("NF" + strconv.Itoa(nfnum))
|
|
}
|
|
// GPIO used only for PAD_FUNC(x) macro
|
|
return macro.Add("GPIO")
|
|
}
|
|
|
|
// Add a line to the macro that defines IO Standby State
|
|
// return: macro
|
|
func (macro *Macro) IOSstate() *Macro {
|
|
var stateMacro = map[uint8]string{
|
|
TxLASTRxE: "TxLASTRxE",
|
|
Tx0RxDCRx0: "Tx0RxDCRx0",
|
|
Tx0RxDCRx1: "Tx0RxDCRx1",
|
|
Tx1RxDCRx0: "Tx1RxDCRx0",
|
|
Tx1RxDCRx1: "Tx1RxDCRx1",
|
|
Tx0RxE: "Tx0RxE",
|
|
Tx1RxE: "Tx1RxE",
|
|
HIZCRx0: "HIZCRx0",
|
|
HIZCRx1: "HIZCRx1",
|
|
TxDRxE: "TxDRxE",
|
|
StandbyIgnore: "IGNORE",
|
|
}
|
|
dw1 := macro.Register(PAD_CFG_DW1)
|
|
str, valid := stateMacro[dw1.GetIOStandbyState()]
|
|
if !valid {
|
|
// ignore setting for incorrect value
|
|
str = "IGNORE"
|
|
}
|
|
return macro.Separator().Add(str)
|
|
}
|
|
|
|
// Add a line to the macro that defines IO Standby Termination
|
|
// return: macro
|
|
func (macro *Macro) IOTerm() *Macro {
|
|
var ioTermMacro = map[uint8]string{
|
|
IOSTERM_SAME: "SAME",
|
|
IOSTERM_DISPUPD: "DISPUPD",
|
|
IOSTERM_ENPD: "ENPD",
|
|
IOSTERM_ENPU: "ENPU",
|
|
}
|
|
dw1 := macro.Register(PAD_CFG_DW1)
|
|
return macro.Separator().Add(ioTermMacro[dw1.GetIOStandbyTermination()])
|
|
}
|
|
|
|
// Check created macro
|
|
func (macro *Macro) check() *Macro {
|
|
if !macro.Register(PAD_CFG_DW0).MaskCheck() {
|
|
return macro.GenerateFields()
|
|
}
|
|
return macro
|
|
}
|
|
|
|
// or - Set " | " if its needed
|
|
func (macro *Macro) Or() *Macro {
|
|
|
|
if str := macro.Get(); str[len(str) - 1] == ')' {
|
|
macro.Add(" | ")
|
|
}
|
|
return macro
|
|
}
|
|
|
|
// DecodeIgnored - Add info about ignored field mask
|
|
// reg : PAD_CFG_DW0 or PAD_CFG_DW1 register
|
|
func (macro *Macro) DecodeIgnored(reg uint8) *Macro {
|
|
var decode = map[uint8]func() {
|
|
PAD_CFG_DW0: macro.Fields.DecodeDW0,
|
|
PAD_CFG_DW1: macro.Fields.DecodeDW1,
|
|
}
|
|
decodefn, valid := decode[reg]
|
|
if !valid || config.IsFspStyleMacro() {
|
|
return macro
|
|
}
|
|
dw := macro.Register(reg)
|
|
ignored := dw.IgnoredFieldsGet()
|
|
if ignored != 0 {
|
|
temp := dw.ValueGet()
|
|
dw.ValueSet(ignored)
|
|
regnum := strconv.Itoa(int(reg))
|
|
macro.Add("/* DW" + regnum + ": ")
|
|
decodefn()
|
|
macro.Add(" - IGNORED */\n\t")
|
|
dw.ValueSet(temp)
|
|
}
|
|
return macro
|
|
}
|
|
|
|
// GenerateFields - generate bitfield macros
|
|
func (macro *Macro) GenerateFields() *Macro {
|
|
dw0 := macro.Register(PAD_CFG_DW0)
|
|
dw1 := macro.Register(PAD_CFG_DW1)
|
|
|
|
// Get mask of ignored bit fields.
|
|
dw0Ignored := dw0.IgnoredFieldsGet()
|
|
dw1Ignored := dw1.IgnoredFieldsGet()
|
|
|
|
if config.InfoLevelGet() != 4 {
|
|
macro.Clear()
|
|
}
|
|
if config.InfoLevelGet() >= 3 {
|
|
// Add string of reference macro as a comment
|
|
reference := macro.Get()
|
|
macro.Clear()
|
|
/* DW0 : PAD_TRIG(OFF) | PAD_BUF(RX_DISABLE) | 1 - IGNORED */
|
|
macro.DecodeIgnored(PAD_CFG_DW0).DecodeIgnored(PAD_CFG_DW1)
|
|
if config.InfoLevelGet() >= 4 {
|
|
/* PAD_CFG_NF(GPP_B23, 20K_PD, PLTRST, NF2), */
|
|
macro.Add("/* ").Add(reference).Add(" */\n\t")
|
|
}
|
|
}
|
|
if config.AreFieldsIgnored() {
|
|
// Consider bit fields that should be ignored when regenerating
|
|
// advansed macros
|
|
var tempVal uint32 = dw0.ValueGet() & ^dw0Ignored
|
|
dw0.ValueSet(tempVal)
|
|
|
|
tempVal = dw1.ValueGet() & ^dw1Ignored
|
|
dw1.ValueSet(tempVal)
|
|
}
|
|
|
|
macro.Fields.GenerateString()
|
|
return macro
|
|
}
|
|
|
|
// Generate macro for bi-directional GPIO port
|
|
func (macro *Macro) Bidirection() {
|
|
dw1 := macro.Register(PAD_CFG_DW1)
|
|
ios := dw1.GetIOStandbyState() != 0 || dw1.GetIOStandbyTermination() != 0
|
|
macro.Set("PAD_CFG_GPIO_BIDIRECT")
|
|
if ios {
|
|
macro.Add("_IOS")
|
|
}
|
|
// PAD_CFG_GPIO_BIDIRECT(pad, val, pull, rst, trig, own)
|
|
macro.Add("(").Id().Val().Pull().Rstsrc().Trig()
|
|
if ios {
|
|
// PAD_CFG_GPIO_BIDIRECT_IOS(pad, val, pull, rst, trig, iosstate, iosterm, own)
|
|
macro.IOSstate().IOTerm()
|
|
}
|
|
macro.Own().Add("),")
|
|
}
|
|
|
|
const (
|
|
rxDisable uint8 = 0x2
|
|
txDisable uint8 = 0x1
|
|
)
|
|
|
|
// Gets base string of current macro
|
|
// return: string of macro
|
|
func (macro *Macro) Generate() string {
|
|
dw0 := macro.Register(PAD_CFG_DW0)
|
|
|
|
macro.Platform.RemmapRstSrc()
|
|
macro.Set("PAD_CFG")
|
|
if dw0.GetPadMode() == 0 {
|
|
// GPIO
|
|
switch dw0.GetGPIORxTxDisableStatus() {
|
|
case txDisable:
|
|
macro.Platform.GpiMacroAdd() // GPI
|
|
|
|
case rxDisable:
|
|
macro.Platform.GpoMacroAdd() // GPO
|
|
|
|
case rxDisable | txDisable:
|
|
macro.Platform.NoConnMacroAdd() // NC
|
|
|
|
default:
|
|
macro.Bidirection()
|
|
}
|
|
} else {
|
|
macro.Platform.NativeFunctionMacroAdd()
|
|
}
|
|
|
|
if config.IsFieldsMacroUsed() {
|
|
// Clear control mask to generate advanced macro only
|
|
return macro.GenerateFields().Get()
|
|
}
|
|
|
|
if config.IsNonCheckingFlagUsed() {
|
|
body := macro.Get()
|
|
if config.InfoLevelGet() >= 3 {
|
|
macro.Clear().DecodeIgnored(PAD_CFG_DW0).DecodeIgnored(PAD_CFG_DW1)
|
|
comment := macro.Get()
|
|
if config.InfoLevelGet() >= 4 {
|
|
macro.Clear().Add("/* ")
|
|
macro.Fields.GenerateString()
|
|
macro.Add(" */\n\t")
|
|
comment += macro.Get()
|
|
}
|
|
return comment + body
|
|
}
|
|
return body
|
|
}
|
|
|
|
return macro.check().Get()
|
|
}
|