blob: 461dbd642b03c6bc2c11f88a495272f997e8a74d [file] [log] [blame]
Iru Caiab5cac22019-07-14 23:04:05 +08001/* 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
23static 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
36static 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
74struct iobp_register {
75 u32 addr;
76 const char *name;
77};
78
79static 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
193static 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
273void 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:
Angel Ponsaa4cd732022-10-07 00:18:04 +0200294 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:
Iru Caiab5cac22019-07-14 23:04:05 +0800299 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}