xref: /aosp_15_r20/external/coreboot/util/inteltool/iobp.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* inteltool - dump all registers on an Intel CPU + chipset based system */
2 /* SPDX-License-Identifier: GPL-2.0-only */
3 
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include "inteltool.h"
7 
8 #define RCBA16(rcba, x) (*((volatile u16 *)((rcba) + (x))))
9 #define RCBA32(rcba, x) (*((volatile u32 *)((rcba) + (x))))
10 /* IO Buffer Programming */
11 #define IOBPIRI		0x2330
12 #define IOBPD		0x2334
13 #define IOBPS		0x2338
14 #define  IOBPS_READY	0x0001
15 #define  IOBPS_TX_MASK	0x0006
16 #define  IOBPS_MASK	0xff00
17 #define  IOBPS_READ	0x0600
18 #define  IOBPS_WRITE	0x0700
19 #define IOBPU		0x233a
20 #define  IOBPU_MAGIC	0xf000
21 
22 #define IOBP_RETRY 1000
iobp_poll(volatile uint8_t * rcba)23 static inline int iobp_poll(volatile uint8_t *rcba)
24 {
25 	for (int try = IOBP_RETRY; try > 0; try--) {
26 		u16 status = RCBA16(rcba, IOBPS);
27 		if ((status & IOBPS_READY) == 0)
28 			return 1;
29 		// udelay(10);
30 	}
31 
32 	printf("IOBP: timeout waiting for transaction to complete\n");
33 	return 0;
34 }
35 
pch_iobp_read(volatile uint8_t * rcba,u32 address)36 static u32 pch_iobp_read(volatile uint8_t *rcba, u32 address)
37 {
38 	u16 status;
39 
40 	if (!iobp_poll(rcba))
41 		return 0;
42 
43 	/* Set the address */
44 	RCBA32(rcba, IOBPIRI) = address;
45 
46 	/* READ OPCODE */
47 	status = RCBA16(rcba, IOBPS);
48 	status &= ~IOBPS_MASK;
49 	status |= IOBPS_READ;
50 	RCBA16(rcba, IOBPS) = status;
51 
52 	/* Undocumented magic */
53 	RCBA16(rcba, IOBPU) = IOBPU_MAGIC;
54 
55 	/* Set ready bit */
56 	status = RCBA16(rcba, IOBPS);
57 	status |= IOBPS_READY;
58 	RCBA16(rcba, IOBPS) = status;
59 
60 	if (!iobp_poll(rcba))
61 		return 0;
62 
63 	/* Check for successful transaction */
64 	status = RCBA16(rcba, IOBPS);
65 	if (status & IOBPS_TX_MASK) {
66 		printf("IOBP: read 0x%08x failed\n", address);
67 		return 0;
68 	}
69 
70 	/* Read IOBP data */
71 	return RCBA32(rcba, IOBPD);
72 }
73 
74 struct iobp_register {
75 	u32 addr;
76 	const char *name;
77 };
78 
79 static const struct iobp_register lynxpoint_iobp_registers[] = {
80 	/* SATA Electrical Control Register */
81 	{0xea002488, "SECRT88P0"},
82 	{0xea00248c, "SECRT8CP0"},
83 	{0xea002490, "SECRT90P0"},
84 	{0xea002498, "SECRT98P0"},
85 	{0xea00251c, "SECRR1CP0"},
86 	{0xea002550, "SECRR50P0"},
87 	{0xea002554, "SECRR54P0"},
88 	{0xea002558, "SECRR58P0"},
89 
90 	{0xea002688, "SECRT88P1"},
91 	{0xea00268c, "SECRT8CP1"},
92 	{0xea002690, "SECRT90P1"},
93 	{0xea002698, "SECRT98P1"},
94 	{0xea00271c, "SECRR1CP1"},
95 	{0xea002750, "SECRR50P1"},
96 	{0xea002754, "SECRR54P1"},
97 	{0xea002758, "SECRR58P1"},
98 
99 	{0xea000888, "SECRT88P2"},
100 	{0xea00088c, "SECRT8CP2"},
101 	{0xea000890, "SECRT90P2"},
102 	{0xea000898, "SECRT98P2"},
103 	{0xea00091c, "SECRR1CP2"},
104 	{0xea000950, "SECRR50P2"},
105 	{0xea000954, "SECRR54P2"},
106 	{0xea000958, "SECRR58P2"},
107 
108 	{0xea000a88, "SECRT88P3"},
109 	{0xea000a8c, "SECRT8CP3"},
110 	{0xea000a90, "SECRT90P3"},
111 	{0xea000a98, "SECRT98P3"},
112 	{0xea000b1c, "SECRR1CP3"},
113 	{0xea000b50, "SECRR50P3"},
114 	{0xea000b54, "SECRR54P3"},
115 	{0xea000b58, "SECRR58P3"},
116 
117 	{0xea002088, "SECRT88P4"},
118 	{0xea00208c, "SECRT8CP4"},
119 	{0xea002090, "SECRT90P4"},
120 	{0xea002098, "SECRT98P4"},
121 	{0xea00211c, "SECRR1CP4"},
122 	{0xea002150, "SECRR50P4"},
123 	{0xea002154, "SECRR54P4"},
124 	{0xea002158, "SECRR58P4"},
125 
126 	{0xea002288, "SECRT88P5"},
127 	{0xea00228c, "SECRT8CP5"},
128 	{0xea002290, "SECRT90P5"},
129 	{0xea002298, "SECRT98P5"},
130 	{0xea00231c, "SECRR1CP5"},
131 	{0xea002350, "SECRR50P5"},
132 	{0xea002354, "SECRR54P5"},
133 	{0xea002358, "SECRR58P5"},
134 
135 	{0xea008100, "SECRF00"},
136 	{0xea008104, "SECRF04"},
137 
138 	/* USB 2.0 Electrical Control Register */
139 	{0xe5004100, "U2ECRP01"},
140 	{0xe5004200, "U2ECRP02"},
141 	{0xe5004300, "U2ECRP03"},
142 	{0xe5004400, "U2ECRP04"},
143 	{0xe5004500, "U2ECRP05"},
144 	{0xe5004600, "U2ECRP06"},
145 	{0xe5004700, "U2ECRP07"},
146 	{0xe5004800, "U2ECRP08"},
147 	{0xe5004900, "U2ECRP09"},
148 	{0xe5004a00, "U2ECRP10"},
149 	{0xe5004b00, "U2ECRP11"},
150 	{0xe5004c00, "U2ECRP12"},
151 	{0xe5004d00, "U2ECRP13"},
152 	{0xe5004e00, "U2ECRP14"},
153 
154 	/* IOBP related to USB 3.0 ports */
155 	/* port 1 */
156 	{0xe900175c, ""},
157 	{0xe9001760, ""},
158 	{0xe9001768, ""},
159 	{0xe9001770, ""},
160 	{0xe90017cc, ""},
161 	/* port 2 */
162 	{0xe900155c, ""},
163 	{0xe9001560, ""},
164 	{0xe9001568, ""},
165 	{0xe9001570, ""},
166 	{0xe90015cc, ""},
167 	/* port 3 */
168 	{0xe9002f5c, ""},
169 	{0xe9002f60, ""},
170 	{0xe9002f68, ""},
171 	{0xe9002f70, ""},
172 	{0xe9002fcc, ""},
173 	/* port 4 */
174 	{0xe9002d5c, ""},
175 	{0xe9002d60, ""},
176 	{0xe9002d68, ""},
177 	{0xe9002d70, ""},
178 	{0xe9002dcc, ""},
179 	/* port 5 */
180 	{0xe900335c, ""},
181 	{0xe9003360, ""},
182 	{0xe9003368, ""},
183 	{0xe9003370, ""},
184 	{0xe90033cc, ""},
185 	/* port 6 */
186 	{0xe900315c, ""},
187 	{0xe9003160, ""},
188 	{0xe9003168, ""},
189 	{0xe9003170, ""},
190 	{0xe90031cc, ""},
191 };
192 
193 static const struct iobp_register lynxpoint_lp_iobp_registers[] = {
194 	/* SATA Electrical Control Register */
195 	{0xea002688, "SECRT88P0"},
196 	{0xea00268c, "SECRT8CP0"},
197 	{0xea002690, "SECRT90P0"},
198 	{0xea002698, "SECRT98P0"},
199 	{0xea00271c, "SECRR1CP0"},
200 	{0xea002750, "SECRR50P0"},
201 	{0xea002754, "SECRR54P0"},
202 	{0xea002758, "SECRR58P0"},
203 
204 	{0xea002488, "SECRT88P1"},
205 	{0xea00248c, "SECRT8CP1"},
206 	{0xea002490, "SECRT90P1"},
207 	{0xea002498, "SECRT98P1"},
208 	{0xea00251c, "SECRR1CP1"},
209 	{0xea002550, "SECRR50P1"},
210 	{0xea002554, "SECRR54P1"},
211 	{0xea002558, "SECRR58P1"},
212 
213 	{0xea002288, "SECRT88P2"},
214 	{0xea00228c, "SECRT8CP2"},
215 	{0xea002290, "SECRT90P2"},
216 	{0xea002298, "SECRT98P2"},
217 	{0xea00231c, "SECRR1CP2"},
218 	{0xea002350, "SECRR50P2"},
219 	{0xea002354, "SECRR54P2"},
220 	{0xea002358, "SECRR58P2"},
221 
222 	{0xea002088, "SECRT88P3"},
223 	{0xea00208c, "SECRT8CP3"},
224 	{0xea002090, "SECRT90P3"},
225 	{0xea002098, "SECRT98P3"},
226 	{0xea00211c, "SECRR1CP3"},
227 	{0xea002150, "SECRR50P3"},
228 	{0xea002154, "SECRR54P3"},
229 	{0xea002158, "SECRR58P3"},
230 
231 	{0xea008100, "SECRF00"},
232 	{0xea008104, "SECRF04"},
233 
234 	/* USB 2.0 Electrical Control Register, 8 for -U SoC and 10 for Core-M */
235 	{0xe5004100, "U2ECRP01"},
236 	{0xe5004200, "U2ECRP02"},
237 	{0xe5004300, "U2ECRP03"},
238 	{0xe5004400, "U2ECRP04"},
239 	{0xe5004500, "U2ECRP05"},
240 	{0xe5004600, "U2ECRP06"},
241 	{0xe5004700, "U2ECRP07"},
242 	{0xe5004800, "U2ECRP08"},
243 	{0xe5004900, "U2ECRP09"},
244 	{0xe5004a00, "U2ECRP10"},
245 
246 	/* IOBP related to USB 3.0 ports */
247 	/* port 1 */
248 	{0xe900215c, ""},
249 	{0xe9002160, ""},
250 	{0xe9002168, ""},
251 	{0xe9002170, ""},
252 	{0xe90021cc, ""},
253 	/* port 2 */
254 	{0xe900235c, ""},
255 	{0xe9002360, ""},
256 	{0xe9002368, ""},
257 	{0xe9002370, ""},
258 	{0xe90023cc, ""},
259 	/* port 3 */
260 	{0xe900255c, ""},
261 	{0xe9002560, ""},
262 	{0xe9002568, ""},
263 	{0xe9002570, ""},
264 	{0xe90025cc, ""},
265 	/* port 4 */
266 	{0xe900275c, ""},
267 	{0xe9002760, ""},
268 	{0xe9002768, ""},
269 	{0xe9002770, ""},
270 	{0xe90027cc, ""},
271 };
272 
print_iobp(struct pci_dev * sb,volatile uint8_t * rcba)273 void print_iobp(struct pci_dev *sb, volatile uint8_t *rcba)
274 {
275 	const struct iobp_register *iobp_registers = NULL;
276 	size_t iobp_size = 0;
277 
278 	switch (sb->device_id) {
279 	case PCI_DEVICE_ID_INTEL_C8_MOBILE:
280 	case PCI_DEVICE_ID_INTEL_C8_DESKTOP:
281 	case PCI_DEVICE_ID_INTEL_Z87:
282 	case PCI_DEVICE_ID_INTEL_Z85:
283 	case PCI_DEVICE_ID_INTEL_HM86:
284 	case PCI_DEVICE_ID_INTEL_H87:
285 	case PCI_DEVICE_ID_INTEL_HM87:
286 	case PCI_DEVICE_ID_INTEL_Q85:
287 	case PCI_DEVICE_ID_INTEL_Q87:
288 	case PCI_DEVICE_ID_INTEL_QM87:
289 	case PCI_DEVICE_ID_INTEL_B85:
290 	case PCI_DEVICE_ID_INTEL_C222:
291 	case PCI_DEVICE_ID_INTEL_C224:
292 	case PCI_DEVICE_ID_INTEL_C226:
293 	case PCI_DEVICE_ID_INTEL_H81:
294 	case PCI_DEVICE_ID_INTEL_C9_MOBILE:
295 	case PCI_DEVICE_ID_INTEL_C9_DESKTOP:
296 	case PCI_DEVICE_ID_INTEL_HM97:
297 	case PCI_DEVICE_ID_INTEL_Z97:
298 	case PCI_DEVICE_ID_INTEL_H97:
299 		iobp_registers = lynxpoint_iobp_registers;
300 		iobp_size = ARRAY_SIZE(lynxpoint_iobp_registers);
301 		break;
302 	case PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_FULL:
303 	case PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_PREM:
304 	case PCI_DEVICE_ID_INTEL_LYNXPOINT_LP_BASE:
305 	case PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP_PREM:
306 	case PCI_DEVICE_ID_INTEL_WILDCATPOINT_LP:
307 		iobp_registers = lynxpoint_lp_iobp_registers;
308 		iobp_size = ARRAY_SIZE(lynxpoint_lp_iobp_registers);
309 		break;
310 	default:
311 		break;
312 	}
313 
314 	if (iobp_size == 0)
315 		return;
316 
317 	printf("\n============= IOBP ==============\n\n");
318 
319 	for (size_t i = 0; i < iobp_size; i++) {
320 		u32 address = iobp_registers[i].addr;
321 		const char *name = iobp_registers[i].name;
322 		u32 v = pch_iobp_read(rcba, address);
323 		printf("0x%08x: 0x%08x (%s)\n", address, v, name);
324 	}
325 }
326