xref: /aosp_15_r20/external/coreboot/util/intelp2m/platforms/common/macro.go (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1package common
2
3import (
4	"strconv"
5	"sync"
6
7	"review.coreboot.org/coreboot.git/util/intelp2m/config"
8)
9
10type Fields interface {
11	DecodeDW0()
12	DecodeDW1()
13	GenerateString()
14}
15
16const (
17	PAD_OWN_ACPI   = 0
18	PAD_OWN_DRIVER = 1
19)
20
21const (
22	TxLASTRxE     = 0x0
23	Tx0RxDCRx0    = 0x1
24	Tx0RxDCRx1    = 0x2
25	Tx1RxDCRx0    = 0x3
26	Tx1RxDCRx1    = 0x4
27	Tx0RxE        = 0x5
28	Tx1RxE        = 0x6
29	HIZCRx0       = 0x7
30	HIZCRx1       = 0x8
31	TxDRxE        = 0x9
32	StandbyIgnore = 0xf
33)
34
35const (
36	IOSTERM_SAME	= 0x0
37	IOSTERM_DISPUPD	= 0x1
38	IOSTERM_ENPD	= 0x2
39	IOSTERM_ENPU    = 0x3
40)
41
42const (
43	TRIG_LEVEL       = 0
44	TRIG_EDGE_SINGLE = 1
45	TRIG_OFF         = 2
46	TRIG_EDGE_BOTH   = 3
47)
48
49const (
50	RST_PWROK  = 0
51	RST_DEEP   = 1
52	RST_PLTRST = 2
53	RST_RSMRST = 3
54)
55
56// PlatformSpecific - platform-specific interface
57type PlatformSpecific interface {
58	RemmapRstSrc()
59	Pull()
60	GpiMacroAdd()
61	GpoMacroAdd()
62	NativeFunctionMacroAdd()
63	NoConnMacroAdd()
64}
65
66// Macro - contains macro information and methods
67// Platform : platform-specific interface
68// padID    : pad ID string
69// str      : macro string entirely
70// Reg      : structure of configuration register values and their masks
71type Macro struct {
72	Platform  PlatformSpecific
73	Reg       [MAX_DW_NUM]Register
74	padID     string
75	str       string
76	ownership uint8
77	Fields
78}
79
80var	instanceMacro *Macro
81var	once           sync.Once
82
83// GetInstance returns singleton
84func GetInstanceMacro(p PlatformSpecific, f Fields) *Macro {
85	once.Do(func() {
86		instanceMacro = &Macro{ Platform : p, Fields : f }
87	})
88	return instanceMacro
89}
90
91func GetMacro() *Macro {
92	return GetInstanceMacro(nil, nil)
93}
94
95func (macro *Macro) PadIdGet() string {
96	return macro.padID
97}
98
99func (macro *Macro) PadIdSet(padid string) *Macro {
100	macro.padID = padid
101	return macro
102}
103
104func (macro *Macro) SetPadOwnership(own uint8) *Macro {
105	macro.ownership = own
106	return macro
107}
108
109func (macro *Macro) IsOwnershipDriver() bool {
110	return macro.ownership == PAD_OWN_DRIVER
111}
112
113// returns <Register> data configuration structure
114// number : register number
115func (macro *Macro) Register(number uint8) *Register {
116	return &macro.Reg[number]
117}
118
119// add a string to macro
120func (macro *Macro) Add(str string) *Macro {
121	macro.str += str
122	return macro
123}
124
125// set a string in a macro instead of its previous contents
126func (macro *Macro) Set(str string) *Macro {
127	macro.str = str
128	return macro
129}
130
131// get macro string
132func (macro *Macro) Get() string {
133	return macro.str
134}
135
136// set a string in a macro instead of its previous contents
137func (macro *Macro) Clear() *Macro {
138	macro.Set("")
139	return macro
140}
141
142// Adds PAD Id to the macro as a new argument
143// return: Macro
144func (macro *Macro) Id() *Macro {
145	return macro.Add(macro.padID)
146}
147
148// Add Separator to macro if needed
149func (macro *Macro) Separator() *Macro {
150	str := macro.Get()
151	c := str[len(str)-1]
152	if c != '(' && c != '_' {
153		macro.Add(", ")
154	}
155	return macro
156}
157
158// Adds the PADRSTCFG parameter from DW0 to the macro as a new argument
159// return: Macro
160func (macro *Macro) Rstsrc() *Macro {
161	dw0 := macro.Register(PAD_CFG_DW0)
162	var resetsrc = map[uint8]string {
163		0: "PWROK",
164		1: "DEEP",
165		2: "PLTRST",
166		3: "RSMRST",
167	}
168	return macro.Separator().Add(resetsrc[dw0.GetResetConfig()])
169}
170
171// Adds The Pad Termination (TERM) parameter from DW1 to the macro as a new argument
172// return: Macro
173func (macro *Macro) Pull() *Macro {
174	macro.Platform.Pull()
175	return macro
176}
177
178// Adds Pad GPO value to macro string as a new argument
179// return: Macro
180func (macro *Macro) Val() *Macro {
181	dw0 := macro.Register(PAD_CFG_DW0)
182	return macro.Separator().Add(strconv.Itoa(int(dw0.GetGPIOTXState())))
183}
184
185// Adds Pad GPO value to macro string as a new argument
186// return: Macro
187func (macro *Macro) Trig() *Macro {
188	dw0 := macro.Register(PAD_CFG_DW0)
189	var trig = map[uint8]string{
190		0x0: "LEVEL",
191		0x1: "EDGE_SINGLE",
192		0x2: "OFF",
193		0x3: "EDGE_BOTH",
194	}
195	return macro.Separator().Add(trig[dw0.GetRXLevelEdgeConfiguration()])
196}
197
198// Adds Pad Polarity Inversion Stage (RXINV) to macro string as a new argument
199// return: Macro
200func (macro *Macro) Invert() *Macro {
201	macro.Separator()
202	if macro.Register(PAD_CFG_DW0).GetRxInvert() !=0 {
203		return macro.Add("INVERT")
204	}
205	return macro.Add("NONE")
206}
207
208// Adds input/output buffer state
209// return: Macro
210func (macro *Macro) Bufdis() *Macro {
211	var buffDisStat = map[uint8]string{
212		0x0: "NO_DISABLE",    // both buffers are enabled
213		0x1: "TX_DISABLE",    // output buffer is disabled
214		0x2: "RX_DISABLE",    // input buffer is disabled
215		0x3: "TX_RX_DISABLE", // both buffers are disabled
216	}
217	state := macro.Register(PAD_CFG_DW0).GetGPIORxTxDisableStatus()
218	return macro.Separator().Add(buffDisStat[state])
219}
220
221// Adds macro to set the host software ownership
222// return: Macro
223func (macro *Macro) Own() *Macro {
224	if macro.IsOwnershipDriver() {
225		return macro.Separator().Add("DRIVER")
226	}
227	return macro.Separator().Add("ACPI")
228}
229
230//Adds pad native function (PMODE) as a new argument
231//return: Macro
232func (macro *Macro) Padfn() *Macro {
233	dw0 := macro.Register(PAD_CFG_DW0)
234	nfnum := int(dw0.GetPadMode())
235	if nfnum != 0 {
236		return macro.Separator().Add("NF" + strconv.Itoa(nfnum))
237	}
238	// GPIO used only for PAD_FUNC(x) macro
239	return macro.Add("GPIO")
240}
241
242// Add a line to the macro that defines IO Standby State
243// return: macro
244func (macro *Macro) IOSstate() *Macro {
245	var stateMacro = map[uint8]string{
246		TxLASTRxE:     "TxLASTRxE",
247		Tx0RxDCRx0:    "Tx0RxDCRx0",
248		Tx0RxDCRx1:    "Tx0RxDCRx1",
249		Tx1RxDCRx0:    "Tx1RxDCRx0",
250		Tx1RxDCRx1:    "Tx1RxDCRx1",
251		Tx0RxE:        "Tx0RxE",
252		Tx1RxE:        "Tx1RxE",
253		HIZCRx0:       "HIZCRx0",
254		HIZCRx1:       "HIZCRx1",
255		TxDRxE:        "TxDRxE",
256		StandbyIgnore: "IGNORE",
257	}
258	dw1 := macro.Register(PAD_CFG_DW1)
259	str, valid := stateMacro[dw1.GetIOStandbyState()]
260	if !valid {
261		// ignore setting for incorrect value
262		str = "IGNORE"
263	}
264	return macro.Separator().Add(str)
265}
266
267// Add a line to the macro that defines IO Standby Termination
268// return: macro
269func (macro *Macro) IOTerm() *Macro {
270	var ioTermMacro = map[uint8]string{
271		IOSTERM_SAME:    "SAME",
272		IOSTERM_DISPUPD: "DISPUPD",
273		IOSTERM_ENPD:    "ENPD",
274		IOSTERM_ENPU:    "ENPU",
275	}
276	dw1 := macro.Register(PAD_CFG_DW1)
277	return macro.Separator().Add(ioTermMacro[dw1.GetIOStandbyTermination()])
278}
279
280// Check created macro
281func (macro *Macro) check() *Macro {
282	if !macro.Register(PAD_CFG_DW0).MaskCheck() {
283		return macro.GenerateFields()
284	}
285	return macro
286}
287
288// or - Set " | " if its needed
289func (macro *Macro) Or() *Macro {
290
291		if str := macro.Get(); str[len(str) - 1] == ')' {
292			macro.Add(" | ")
293		}
294		return macro
295}
296
297// DecodeIgnored - Add info about ignored field mask
298// reg : PAD_CFG_DW0 or PAD_CFG_DW1 register
299func (macro *Macro) DecodeIgnored(reg uint8) *Macro {
300	var decode = map[uint8]func() {
301		PAD_CFG_DW0: macro.Fields.DecodeDW0,
302		PAD_CFG_DW1: macro.Fields.DecodeDW1,
303	}
304	decodefn, valid := decode[reg]
305	if !valid || config.IsFspStyleMacro() {
306		return macro
307	}
308	dw := macro.Register(reg)
309	ignored := dw.IgnoredFieldsGet()
310	if ignored != 0 {
311		temp := dw.ValueGet()
312		dw.ValueSet(ignored)
313		regnum := strconv.Itoa(int(reg))
314		macro.Add("/* DW" + regnum + ": ")
315		decodefn()
316		macro.Add(" - IGNORED */\n\t")
317		dw.ValueSet(temp)
318	}
319	return macro
320}
321
322// GenerateFields - generate bitfield macros
323func (macro *Macro) GenerateFields() *Macro {
324	dw0 := macro.Register(PAD_CFG_DW0)
325	dw1 := macro.Register(PAD_CFG_DW1)
326
327	// Get mask of ignored bit fields.
328	dw0Ignored := dw0.IgnoredFieldsGet()
329	dw1Ignored := dw1.IgnoredFieldsGet()
330
331	if config.InfoLevelGet() != 4 {
332		macro.Clear()
333	}
334	if config.InfoLevelGet() >= 3 {
335		// Add string of reference macro as a comment
336		reference := macro.Get()
337		macro.Clear()
338		/* DW0 : PAD_TRIG(OFF) | PAD_BUF(RX_DISABLE) | 1 - IGNORED */
339		macro.DecodeIgnored(PAD_CFG_DW0).DecodeIgnored(PAD_CFG_DW1)
340		if config.InfoLevelGet() >= 4 {
341			/* PAD_CFG_NF(GPP_B23, 20K_PD, PLTRST, NF2), */
342			macro.Add("/* ").Add(reference).Add(" */\n\t")
343		}
344	}
345	if config.AreFieldsIgnored() {
346		// Consider bit fields that should be ignored when regenerating
347		// advansed macros
348		var tempVal uint32 = dw0.ValueGet() & ^dw0Ignored
349		dw0.ValueSet(tempVal)
350
351		tempVal = dw1.ValueGet() & ^dw1Ignored
352		dw1.ValueSet(tempVal)
353	}
354
355	macro.Fields.GenerateString()
356	return macro
357}
358
359// Generate macro for bi-directional GPIO port
360func (macro *Macro) Bidirection() {
361	dw1 := macro.Register(PAD_CFG_DW1)
362	ios := dw1.GetIOStandbyState() != 0 || dw1.GetIOStandbyTermination() != 0
363	macro.Set("PAD_CFG_GPIO_BIDIRECT")
364	if ios {
365		macro.Add("_IOS")
366	}
367	// PAD_CFG_GPIO_BIDIRECT(pad, val, pull, rst, trig, own)
368	macro.Add("(").Id().Val().Pull().Rstsrc().Trig()
369	if ios {
370		// PAD_CFG_GPIO_BIDIRECT_IOS(pad, val, pull, rst, trig, iosstate, iosterm, own)
371		macro.IOSstate().IOTerm()
372	}
373	macro.Own().Add("),")
374}
375
376const (
377	rxDisable uint8 = 0x2
378	txDisable uint8 = 0x1
379)
380
381// Gets base string of current macro
382// return: string of macro
383func (macro *Macro) Generate() string {
384	dw0 := macro.Register(PAD_CFG_DW0)
385
386	macro.Platform.RemmapRstSrc()
387	macro.Set("PAD_CFG")
388	if dw0.GetPadMode() == 0 {
389		// GPIO
390		switch dw0.GetGPIORxTxDisableStatus() {
391		case txDisable:
392			macro.Platform.GpiMacroAdd() // GPI
393
394		case rxDisable:
395			macro.Platform.GpoMacroAdd() // GPO
396
397		case rxDisable | txDisable:
398			macro.Platform.NoConnMacroAdd() // NC
399
400		default:
401			macro.Bidirection()
402		}
403	} else {
404		macro.Platform.NativeFunctionMacroAdd()
405	}
406
407	if config.IsFieldsMacroUsed() {
408		// Clear control mask to generate advanced macro only
409		return macro.GenerateFields().Get()
410	}
411
412	if config.IsNonCheckingFlagUsed() {
413		body := macro.Get()
414		if config.InfoLevelGet() >= 3 {
415			macro.Clear().DecodeIgnored(PAD_CFG_DW0).DecodeIgnored(PAD_CFG_DW1)
416			comment := macro.Get()
417			if config.InfoLevelGet() >= 4 {
418				macro.Clear().Add("/* ")
419				macro.Fields.GenerateString()
420				macro.Add(" */\n\t")
421				comment += macro.Get()
422			}
423			return comment + body
424		}
425		return body
426	}
427
428	return macro.check().Get()
429}
430