xref: /aosp_15_r20/external/coreboot/util/inteltool/pcie.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 <inttypes.h>
7 #include "inteltool.h"
8 
9 /* 320766 */
10 static const io_register_t nehalem_dmi_registers[] = {
11 	{ 0x00, 4, "DMIVCH" },		// DMI Virtual Channel Capability Header
12 	{ 0x04, 4, "DMIVCCAP1" },	// DMI Port VC Capability Register 1
13 	{ 0x08, 4, "DMIVCCAP2" },	// DMI Port VC Capability Register 2
14 	{ 0x0C, 4, "DMIVCCTL" },	// DMI Port VC Control
15 	{ 0x10, 4, "DMIVC0RCAP" },	// DMI VC0 Resource Capability
16 	{ 0x14, 4, "DMIVC0RCTL" },	// DMI VC0 Resource Control
17 /*	{ 0x18, 2, "RSVD" }, // Reserved */
18 	{ 0x1A, 2, "DMIVC0RSTS" },	// DMI VC0 Resource Status
19 	{ 0x1C, 4, "DMIVC1RCAP" },	// DMI VC1 Resource Capability
20 	{ 0x20, 4, "DMIVC1RCTL" },	// DMI VC1 Resource Control
21 /*	{ 0x24, 2, "RSVD" }, // Reserved */
22 	{ 0x26, 2, "DMIVC1RSTS" },	// DMI VC1 Resource Status
23 /*	... - Reserved */
24 	{ 0x84, 4, "DMILCAP" },		// DMI Link Capabilities
25 	{ 0x88, 2, "DMILCTL" },		// DMI Link Control
26 	{ 0x8A, 2, "DMILSTS" },		// DMI Link Status
27 /*	... - Reserved */
28 };
29 
30 /* 322812 */
31 static const io_register_t westmere_dmi_registers[] = {
32 	{ 0x00, 4, "DMIVCECH" },	// DMI Virtual Channel Enhanced Capability
33 	{ 0x04, 4, "DMIPVCCAP1" },	// DMI Port VC Capability Register 1
34 	{ 0x08, 4, "DMIPVCCAP2" },	// DMI Port VC Capability Register 2
35 	{ 0x0C, 2, "DMIPVCCTL" },	// DMI Port VC Control
36 /*	{ 0x0E, 2, "RSVD" }, // Reserved */
37 	{ 0x10, 4, "DMIVC0RCAP" },	// DMI VC0 Resource Capability
38 	{ 0x14, 4, "DMIVC0RCTL" },	// DMI VC0 Resource Control
39 /*	{ 0x18, 2, "RSVD" }, // Reserved */
40 	{ 0x1A, 2, "DMIVC0RSTS" },	// DMI VC0 Resource Status
41 	{ 0x1C, 4, "DMIVC1RCAP" },	// DMI VC1 Resource Capability
42 	{ 0x20, 4, "DMIVC1RCTL1" },	// DMI VC1 Resource Control
43 /*	{ 0x24, 2, "RSVD" },	// Reserved */
44 	{ 0x26, 2, "DMIC1RSTS" },	// DMI VC1 Resource Status
45 /*	... - Reserved */
46 	{ 0x84, 4, "DMILCAP" },		// DMI Link Capabilities
47 	{ 0x88, 2, "DMILCTL" },		// DMI Link Control
48 	{ 0x8A, 2, "DMILSTS" },		// DMI Link Status
49 /*	... - Reserved */
50 };
51 
52 static const io_register_t sandybridge_dmi_registers[] = {
53 	{ 0x00, 4, "DMI VCECH" }, // DMI Virtual Channel Enhanced Capability
54 	{ 0x04, 4, "DMI PVCCAP1" }, // DMI Port VC Capability Register 1
55 	{ 0x08, 4, "DMI PVVAP2" }, // DMI Port VC Capability Register 2
56 	{ 0x0C, 2, "DMI PVCCTL" }, // DMI Port VC Control
57 /*	{ 0x0E, 2, "RSVD" }, // Reserved */
58 	{ 0x10, 4, "DMI VC0RCAP" }, // DMI VC0 Resource Capability
59 	{ 0x14, 4, "DMI VC0RCTL" }, // DMI VC0 Resource Control
60 /*	{ 0x18, 2, "RSVD" }, // Reserved */
61 	{ 0x1A, 2, "DMI VC0RSTS" }, // DMI VC0 Resource Status
62 	{ 0x1C, 4, "DMI VC1RCAP" }, // DMI VC1 Resource Capability
63 	{ 0x20, 4, "DMI VC1RCTL" }, // DMI VC1 Resource Control
64 /*	{ 0x24, 2, "RSVD" }, // Reserved */
65 	{ 0x26, 2, "DMI VC1RSTS" }, // DMI VC1 Resource Status
66 	{ 0x28, 4, "DMI VCPRCAP" }, // DMI VCp Resource Capability
67 	{ 0x2C, 4, "DMI VCPRCTL" }, // DMI VCp Resource Control
68 /*	{ 0x30, 2, "RSVD" }, // Reserved */
69 	{ 0x32, 2, "DMI VCPRSTS" }, // DMI VCp Resource Status
70 	{ 0x34, 4, "DMI VCMRCAP" }, // DMI VCm Resource Capability
71 	{ 0x38, 4, "DMI VCMRCTL" }, // DMI VCm Resource Control
72 /*	{ 0x3C, 2, "RSVD" }, // Reserved */
73 	{ 0x3E, 2, "DMI VCMRSTS" }, // DMI VCm Resource Status
74 /*	{ 0x40, 4, "RSVD" }, // Reserved */
75 	{ 0x44, 4, "DMI ESC" }, // DMI Element Self Description
76 /*	{ 0x48, 8, "RSVD" }, // Reserved */
77 	{ 0x50, 4, "DMI LE1D" }, // DMI Link Entry 1 Description
78 /*	{ 0x54, 4, "RSVD" }, // Reserved */
79 	{ 0x58, 4, "DMI LE1A" }, // DMI Link Entry 1 Address
80 	{ 0x5C, 4, "DMI LUE1A" }, // DMI Link Upper Entry 1 Address
81 	{ 0x60, 4, "DMI LE2D" }, // DMI Link Entry 2 Description
82 /*	{ 0x64, 4, "RSVD" }, // Reserved */
83 	{ 0x68, 4, "DMI LE2A" }, // DMI Link Entry 2 Address
84 /*	{ 0x6C, 4, "RSVD" }, // Reserved
85 	{ 0x70, 8, "RSVD" }, // Reserved
86 	{ 0x78, 8, "RSVD" }, // Reserved
87 	{ 0x80, 4, "RSVD" }, // Reserved */
88 	{ 0x84, 4, "LCAP" }, // Link Capabilities
89 	{ 0x88, 2, "LCTL" }, // Link Control
90 	{ 0x8A, 2, "LSTS" }, // Link Status
91 /*	{ 0x8C, 4, "RSVD" }, // Reserved
92 	{ 0x90, 4, "RSVD" }, // Reserved
93 	{ 0x94, 4, "RSVD" }, // Reserved */
94 	{ 0x98, 2, "LCTL2" }, // Link Control 2
95 	{ 0x9A, 2, "LSTS2" }, // Link Status 2
96 /*	... - Reserved */
97 	{ 0xBC0, 4, "AFE_BMUF0" }, // AFE BMU Configuration Function 0
98 	{ 0xBC4, 4, "RSVD" }, // Reserved
99 	{ 0xBC8, 4, "RSVD" }, // Reserved
100 	{ 0xBCC, 4, "AFE_BMUT0" }, // AFE BMU Configuration Test 0
101 /*	... - Reserved */
102 };
103 
104 /*
105  * All Haswell DMI Registers per
106  *
107  * Mobile 4th Generation Intel Core TM Processor Family, Mobile Intel Pentium Processor Family,
108  * and Mobile Intel Celeron Processor Family
109  * Datasheet Volume 2
110  * 329002-002
111  */
112 static const io_register_t haswell_ult_dmi_registers[] = {
113 	{ 0x00, 4, "DMIVCECH" }, // DMI Virtual Channel Enhanced Capability
114 	{ 0x04, 4, "DMIPVCCAP1" }, // DMI Port VC Capability Register 1
115 	{ 0x08, 4, "DMIPVCCAP2" }, // DMI Port VC Capability Register 2
116 	{ 0x0C, 2, "DMI PVCCTL" }, // DMI Port VC Control
117 /*	{ 0x0E, 2, "RSVD" }, // Reserved */
118 	{ 0x10, 4, "DMIVC0RCAP" }, // DMI VC0 Resource Capability
119 	{ 0x14, 4, "DMIVC0RCTL" }, // DMI VC0 Resource Control
120 /*	{ 0x18, 2, "RSVD" }, // Reserved */
121 	{ 0x1A, 2, "DMIVC0RSTS" }, // DMI VC0 Resource Status
122 	{ 0x1C, 4, "DMIVC1RCAP" }, // DMI VC1 Resource Capability
123 	{ 0x20, 4, "DMIVC1RCTL" }, // DMI VC1 Resource Control
124 /*	{ 0x24, 2, "RSVD" }, // Reserved */
125 	{ 0x26, 2, "DMIVC1RSTS" }, // DMI VC1 Resource Status
126 	{ 0x28, 4, "DMIVCPRCAP" }, // DMI VCp Resource Capability
127 	{ 0x2C, 4, "DMIVCPRCTL" }, // DMI VCp Resource Control
128 /*	{ 0x30, 2, "RSVD" }, // Reserved */
129 	{ 0x32, 2, "DMIVCPRSTS" }, // DMI VCp Resource Status
130 	{ 0x34, 4, "DMIVCMRCAP" }, // DMI VCm Resource Capability
131 	{ 0x38, 4, "DMIVCMRCTL" }, // DMI VCm Resource Control
132 /*	{ 0x3C, 2, "RSVD" }, // Reserved */
133 	{ 0x3E, 2, "DMIVCMRSTS" }, // DMI VCm Resource Status
134 	{ 0x40, 4, "DMIRCLDECH" }, // DMI Root Complex Link Declaration */
135 	{ 0x44, 4, "DMIESD" }, // DMI Element Self Description
136 /*	{ 0x48, 4, "RSVD" }, // Reserved */
137 /*	{ 0x4C, 4, "RSVD" }, // Reserved */
138 	{ 0x50, 4, "DMILE1D" }, // DMI Link Entry 1 Description
139 /*	{ 0x54, 4, "RSVD" }, // Reserved */
140 	{ 0x58, 4, "DMILE1A" }, // DMI Link Entry 1 Address
141 	{ 0x5C, 4, "DMILUE1A" }, // DMI Link Upper Entry 1 Address
142 	{ 0x60, 4, "DMILE2D" }, // DMI Link Entry 2 Description
143 /*	{ 0x64, 4, "RSVD" }, // Reserved */
144 	{ 0x68, 4, "DMILE2A" }, // DMI Link Entry 2 Address
145 /*	{ 0x6C, 4, "RSVD" }, // Reserved */
146 /*	{ 0x70, 4, "RSVD" }, // Reserved */
147 /*	{ 0x74, 4, "RSVD" }, // Reserved */
148 /*	{ 0x78, 4, "RSVD" }, // Reserved */
149 /*	{ 0x7C, 4, "RSVD" }, // Reserved */
150 /*	{ 0x80, 4, "RSVD" }, // Reserved */
151 /*	{ 0x84, 4, "RSVD" }, // Reserved */
152 	{ 0x88, 2, "LCTL" }, // Link Control
153 	/*  ... - Reserved */
154 	{ 0x1C4, 4, "DMIUESTS" }, // DMI Uncorrectable Error Status
155 	{ 0x1C8, 4, "DMIUEMSK" }, // DMI Uncorrectable Error Mask
156 	{ 0x1D0, 4, "DMICESTS" }, // DMI Correctable Error Status
157 	{ 0x1D4, 4, "DMICEMSK" }, // DMI Correctable Error Mask
158 /*  ... - Reserved */
159 };
160 
161 /*
162  * All Skylake-S/H DMI Registers per
163  *
164  * 6th Generation Intel Processor Families for S-Platform Volume 2 of 2
165  * Page 117
166  * 332688-003E
167  *
168  * 6th Generation Intel Processor Families for H-Platform Volume 2 of 2
169  * Page 117
170  * 332987-002EN
171  */
172 static const io_register_t skylake_dmi_registers[] = {
173 	{ 0x00, 4, "DMIVCECH"   }, // DMI Virtual Channel Enhanced Capability
174 	{ 0x04, 4, "DMIPVCCAP1" }, // DMI Port VC Capability Register 1
175 	{ 0x08, 4, "DMIPVCCAP2" }, // DMI Port VC Capability Register 2
176 	{ 0x0C, 2, "DMIPVCCTL"  }, // DMI Port VC Control
177 	{ 0x10, 4, "DMIVC0RCAP" }, // DMI VC0 Resource Capability
178 	{ 0x14, 4, "DMIVC0RCTL" }, // DMI VC0 Resource Control
179 	{ 0x1A, 2, "DMIVC0RSTS" }, // DMI VC0 Resource Status
180 	{ 0x1C, 4, "DMIVC1RCAP" }, // DMI VC1 Resource Capability
181 	{ 0x20, 4, "DMIVC1RCTL" }, // DMI VC1 Resource Control
182 	{ 0x26, 2, "DMIVC1RSTS" }, // DMI VC1 Resource Status
183 	{ 0x34, 4, "DMIVCMRCAP" }, // DMI VCm Resource Capability
184 	{ 0x38, 4, "DMIVCMRCTL" }, // DMI VCm Resource Control
185 	{ 0x3E, 2, "DMIVCMRSTS" }, // DMI VCm Resource Status
186 	{ 0x40, 4, "DMIRCLDECH" }, // DMI Root Complex Link Declaration */
187 	{ 0x44, 4, "DMIESD"     }, // DMI Element Self Description
188 	{ 0x50, 4, "DMILE1D"    }, // DMI Link Entry 1 Description
189 	{ 0x58, 4, "DMILE1A"    }, // DMI Link Entry 1 Address
190 	{ 0x5C, 4, "DMILUE1A"   }, // DMI Link Upper Entry 1 Address
191 	{ 0x60, 4, "DMILE2D"    }, // DMI Link Entry 2 Description
192 	{ 0x68, 4, "DMILE2A"    }, // DMI Link Entry 2 Address
193 	{ 0x84, 4, "LCAP"       }, // Link Capabilities
194 	{ 0x88, 2, "LCTL"       }, // Link Control
195 	{ 0x8A, 2, "LSTS"       }, // DMI Link Status
196 	{ 0x98, 2, "LCTL2"      }, // Link Control 2
197 	{ 0x9A, 2, "LSTS2"      }, // DMI Link Status 2
198 	{ 0x1C4, 4, "DMIUESTS"  }, // DMI Uncorrectable Error Status
199 	{ 0x1C8, 4, "DMIUEMSK"  }, // DMI Uncorrectable Error Mask
200 	{ 0x1CC, 4, "DMIUESEV"  }, // DMI Uncorrectable Error Mask
201 	{ 0x1D0, 4, "DMICESTS"  }, // DMI Correctable Error Status
202 	{ 0x1D4, 4, "DMICEMSK"  }, // DMI Correctable Error Mask
203 };
204 
205 static const io_register_t alderlake_dmi_registers[] = {
206 	{ 0x00, 4, "DMIVCECH"   }, // DMI Virtual Channel Enhanced Capability
207 	{ 0x04, 4, "DMIPVCCAP1" }, // DMI Port VC Capability Register 1
208 	{ 0x08, 4, "DMIPVCCAP2" }, // DMI Port VC Capability Register 2
209 	{ 0x0C, 2, "DMIPVCCTL"  }, // DMI Port VC Control
210 	{ 0x10, 4, "DMIVC0RCAP" }, // DMI VC0 Resource Capability
211 	{ 0x1C, 4, "DMIVC1RCAP" }, // DMI VC1 Resource Capability
212 	{ 0x26, 2, "DMIVC1RSTS" }, // DMI VC1 Resource Status
213 	{ 0x34, 4, "DMIVCMRCAP" }, // DMI VCm Resource Capability
214 	{ 0x38, 4, "DMIVCMRCTL" }, // DMI VCm Resource Control
215 	{ 0x3E, 2, "DMIVCMRSTS" }, // DMI VCm Resource Status
216 	{ 0x40, 4, "DMIRCLDECH" }, // DMI Root Complex Link Declaration */
217 	{ 0x44, 4, "DMIESD"     }, // DMI Element Self Description
218 	{ 0x50, 4, "DMILE1D"    }, // DMI Link Entry 1 Description
219 	{ 0x5C, 4, "DMILUE1A"   }, // DMI Link Upper Entry 1 Address
220 	{ 0x60, 4, "DMILE2D"    }, // DMI Link Entry 2 Description
221 	{ 0x68, 4, "DMILE2A"    }, // DMI Link Entry 2 Address
222 	{ 0x88, 2, "LCTL"       }, // Link Control
223 	{ 0x1C4, 4, "DMIUESTS"  }, // DMI Uncorrectable Error Status
224 	{ 0x1C8, 4, "DMIUEMSK"  }, // DMI Uncorrectable Error Mask
225 	{ 0x1CC, 4, "DMIUESEV"  }, // DMI Uncorrectable Error Mask
226 	{ 0x1D0, 4, "DMICESTS"  }, // DMI Correctable Error Status
227 	{ 0x1D4, 4, "DMICEMSK"  }, // DMI Correctable Error Mask
228 };
229 
230 /*
231  * Egress Port Root Complex MMIO configuration space
232  */
print_epbar(struct pci_dev * nb)233 int print_epbar(struct pci_dev *nb)
234 {
235 	int i, size = (4 * 1024);
236 	volatile uint8_t *epbar;
237 	uint64_t epbar_phys;
238 
239 	printf("\n============= EPBAR =============\n\n");
240 
241 	switch (nb->device_id) {
242 	case PCI_DEVICE_ID_INTEL_82915:
243 	case PCI_DEVICE_ID_INTEL_82945GM:
244 	case PCI_DEVICE_ID_INTEL_82945GSE:
245 	case PCI_DEVICE_ID_INTEL_82945P:
246 	case PCI_DEVICE_ID_INTEL_82946:
247 	case PCI_DEVICE_ID_INTEL_82975X:
248 		epbar_phys = pci_read_long(nb, 0x40) & 0xfffffffe;
249 		break;
250 	case PCI_DEVICE_ID_INTEL_82965PM:
251 	case PCI_DEVICE_ID_INTEL_82Q965:
252 	case PCI_DEVICE_ID_INTEL_82Q35:
253 	case PCI_DEVICE_ID_INTEL_82G33:
254 	case PCI_DEVICE_ID_INTEL_82Q33:
255 	case PCI_DEVICE_ID_INTEL_82X38:
256 	case PCI_DEVICE_ID_INTEL_32X0:
257 	case PCI_DEVICE_ID_INTEL_82XX4X:
258 	case PCI_DEVICE_ID_INTEL_82Q45:
259 	case PCI_DEVICE_ID_INTEL_82G45:
260 	case PCI_DEVICE_ID_INTEL_82G41:
261 	case PCI_DEVICE_ID_INTEL_82B43:
262 	case PCI_DEVICE_ID_INTEL_82B43_2:
263 	case PCI_DEVICE_ID_INTEL_ATOM_DXXX:
264 	case PCI_DEVICE_ID_INTEL_ATOM_NXXX:
265 	case PCI_DEVICE_ID_INTEL_CORE_2ND_GEN_D:
266 	case PCI_DEVICE_ID_INTEL_CORE_2ND_GEN_M:
267 	case PCI_DEVICE_ID_INTEL_CORE_2ND_GEN_E3:
268 	case PCI_DEVICE_ID_INTEL_CORE_3RD_GEN_D:
269 	case PCI_DEVICE_ID_INTEL_CORE_3RD_GEN_M:
270 	case PCI_DEVICE_ID_INTEL_CORE_3RD_GEN_E3:
271 	case PCI_DEVICE_ID_INTEL_CORE_3RD_GEN_015c:
272 	case PCI_DEVICE_ID_INTEL_CORE_4TH_GEN_D:
273 	case PCI_DEVICE_ID_INTEL_CORE_4TH_GEN_M:
274 	case PCI_DEVICE_ID_INTEL_CORE_4TH_GEN_E3:
275 	case PCI_DEVICE_ID_INTEL_CORE_4TH_GEN_U:
276 	case PCI_DEVICE_ID_INTEL_CORE_5TH_GEN_U:
277 	case PCI_DEVICE_ID_INTEL_CORE_5TH_GEN_D:
278 	case PCI_DEVICE_ID_INTEL_CORE_5TH_GEN_M:
279 	case PCI_DEVICE_ID_INTEL_CORE_6TH_GEN_D2:
280 	case PCI_DEVICE_ID_INTEL_CORE_6TH_GEN_U:
281 	case PCI_DEVICE_ID_INTEL_CORE_6TH_GEN_Y:
282 	case PCI_DEVICE_ID_INTEL_CORE_6TH_GEN_M:
283 	case PCI_DEVICE_ID_INTEL_CORE_6TH_GEN_WST:
284 	case PCI_DEVICE_ID_INTEL_CORE_6TH_GEN_D:
285 	case PCI_DEVICE_ID_INTEL_CORE_6TH_GEN_E:
286 	case PCI_DEVICE_ID_INTEL_CORE_7TH_GEN_U:
287 	case PCI_DEVICE_ID_INTEL_CORE_7TH_GEN_Y:
288 	case PCI_DEVICE_ID_INTEL_CORE_7TH_GEN_U_Q:
289 	case PCI_DEVICE_ID_INTEL_CORE_7TH_GEN_E3:
290 	case PCI_DEVICE_ID_INTEL_CORE_8TH_GEN_U_1:
291 	case PCI_DEVICE_ID_INTEL_CORE_8TH_GEN_U_2:
292 	case PCI_DEVICE_ID_INTEL_CORE_ADL_ID_N_0_8:
293 	case PCI_DEVICE_ID_INTEL_CORE_ADL_ID_N_0_4:
294 	case PCI_DEVICE_ID_INTEL_CORE_ADL_ID_N_0_4_1:
295 		epbar_phys = pci_read_long(nb, 0x40) & 0xfffffffe;
296 		epbar_phys |= ((uint64_t)pci_read_long(nb, 0x44)) << 32;
297 		break;
298 	case PCI_DEVICE_ID_INTEL_82810:
299 	case PCI_DEVICE_ID_INTEL_82810_DC:
300 	case PCI_DEVICE_ID_INTEL_82810E_DC:
301 	case PCI_DEVICE_ID_INTEL_82830M:
302 	case PCI_DEVICE_ID_INTEL_82865:
303 		printf("This northbridge does not have EPBAR.\n");
304 		return 1;
305 	default:
306 		printf("Error: Dumping EPBAR on this northbridge is not (yet) supported.\n");
307 		return 1;
308 	}
309 
310 	epbar = map_physical(epbar_phys, size);
311 
312 	if (epbar == NULL) {
313 		perror("Error mapping EPBAR");
314 		exit(1);
315 	}
316 
317 	printf("EPBAR = 0x%08" PRIx64 " (MEM)\n\n", epbar_phys);
318 	for (i = 0; i < size; i += 4) {
319 		if (read32(epbar + i))
320 			printf("0x%04x: 0x%08x\n", i, read32(epbar+i));
321 	}
322 
323 	unmap_physical((void *)epbar, size);
324 	return 0;
325 }
326 
327 /*
328  * MCH-ICH Serial Interconnect Ingress Root Complex MMIO configuration space
329  */
print_dmibar(struct pci_dev * nb)330 int print_dmibar(struct pci_dev *nb)
331 {
332 	int i, size = (4 * 1024);
333 	volatile uint8_t *dmibar;
334 	uint64_t dmibar_phys;
335 	const io_register_t *dmi_registers = NULL;
336 
337 	printf("\n============= DMIBAR ============\n\n");
338 
339 	switch (nb->device_id) {
340 	case PCI_DEVICE_ID_INTEL_82915:
341 	case PCI_DEVICE_ID_INTEL_82945GM:
342 	case PCI_DEVICE_ID_INTEL_82945GSE:
343 	case PCI_DEVICE_ID_INTEL_82945P:
344 	case PCI_DEVICE_ID_INTEL_82975X:
345 		dmibar_phys = pci_read_long(nb, 0x4c) & 0xfffffffe;
346 		break;
347 	case PCI_DEVICE_ID_INTEL_82946:
348 	case PCI_DEVICE_ID_INTEL_82965PM:
349 	case PCI_DEVICE_ID_INTEL_82Q965:
350 	case PCI_DEVICE_ID_INTEL_82Q35:
351 	case PCI_DEVICE_ID_INTEL_82G33:
352 	case PCI_DEVICE_ID_INTEL_82Q33:
353 	case PCI_DEVICE_ID_INTEL_82X38:
354 	case PCI_DEVICE_ID_INTEL_32X0:
355 	case PCI_DEVICE_ID_INTEL_82XX4X:
356 	case PCI_DEVICE_ID_INTEL_82Q45:
357 	case PCI_DEVICE_ID_INTEL_82G45:
358 	case PCI_DEVICE_ID_INTEL_82G41:
359 	case PCI_DEVICE_ID_INTEL_82B43:
360 	case PCI_DEVICE_ID_INTEL_82B43_2:
361 	case PCI_DEVICE_ID_INTEL_ATOM_DXXX:
362 	case PCI_DEVICE_ID_INTEL_ATOM_NXXX:
363 		dmibar_phys = pci_read_long(nb, 0x68) & 0xfffffffe;
364 		dmibar_phys |= ((uint64_t)pci_read_long(nb, 0x6c)) << 32;
365 		break;
366 	case PCI_DEVICE_ID_INTEL_82810:
367 	case PCI_DEVICE_ID_INTEL_82810_DC:
368 	case PCI_DEVICE_ID_INTEL_82810E_DC:
369 	case PCI_DEVICE_ID_INTEL_82865:
370 		printf("This northbridge does not have DMIBAR.\n");
371 		return 1;
372 	case PCI_DEVICE_ID_INTEL_82X58:
373 		dmibar_phys = pci_read_long(nb, 0x50) & 0xfffff000;
374 		break;
375 	case PCI_DEVICE_ID_INTEL_CORE_0TH_GEN:
376 		/* DMIBAR is called DMIRCBAR in Nehalem */
377 		dmibar_phys = pci_read_long(nb, 0x50) & 0xfffff000; /* 31:12 */
378 		dmi_registers = nehalem_dmi_registers;
379 		size = ARRAY_SIZE(nehalem_dmi_registers);
380 		break;
381 	case PCI_DEVICE_ID_INTEL_CORE_1ST_GEN_D:
382 	case PCI_DEVICE_ID_INTEL_CORE_1ST_GEN_M:
383 	case PCI_DEVICE_ID_INTEL_CORE_1ST_GEN_0048:
384 		dmibar_phys = pci_read_long(nb, 0x68);
385 		dmibar_phys |= ((uint64_t)pci_read_long(nb, 0x6c)) << 32;
386 		dmibar_phys &= 0x0000000ffffff000UL; /* 35:12 */
387 		dmi_registers = westmere_dmi_registers;
388 		size = ARRAY_SIZE(westmere_dmi_registers);
389 		break;
390 	case PCI_DEVICE_ID_INTEL_CORE_2ND_GEN_D:
391 	case PCI_DEVICE_ID_INTEL_CORE_2ND_GEN_M:
392 	case PCI_DEVICE_ID_INTEL_CORE_2ND_GEN_E3:
393 		dmi_registers = sandybridge_dmi_registers;
394 		size = ARRAY_SIZE(sandybridge_dmi_registers);
395 		/* fall through */
396 	case PCI_DEVICE_ID_INTEL_CORE_3RD_GEN_D: /* pretty printing not implemented yet */
397 	case PCI_DEVICE_ID_INTEL_CORE_3RD_GEN_M:
398 	case PCI_DEVICE_ID_INTEL_CORE_3RD_GEN_E3:
399 	case PCI_DEVICE_ID_INTEL_CORE_3RD_GEN_015c:
400 	case PCI_DEVICE_ID_INTEL_CORE_4TH_GEN_D:
401 	case PCI_DEVICE_ID_INTEL_CORE_4TH_GEN_M:
402 	case PCI_DEVICE_ID_INTEL_CORE_4TH_GEN_E3:
403 	case PCI_DEVICE_ID_INTEL_CORE_5TH_GEN_D:
404 	case PCI_DEVICE_ID_INTEL_CORE_5TH_GEN_M:
405 		dmibar_phys = pci_read_long(nb, 0x68);
406 		dmibar_phys |= ((uint64_t)pci_read_long(nb, 0x6c)) << 32;
407 		dmibar_phys &= 0x0000007ffffff000UL; /* 38:12 */
408 		break;
409 	case PCI_DEVICE_ID_INTEL_CORE_4TH_GEN_U:
410 	case PCI_DEVICE_ID_INTEL_CORE_5TH_GEN_U:
411 		dmi_registers = haswell_ult_dmi_registers;
412 		size = ARRAY_SIZE(haswell_ult_dmi_registers);
413 		dmibar_phys = pci_read_long(nb, 0x68);
414 		dmibar_phys |= ((uint64_t)pci_read_long(nb, 0x6c)) << 32;
415 		dmibar_phys &= 0x0000007ffffff000UL; /* 38:12 */
416 		break;
417 	case PCI_DEVICE_ID_INTEL_CORE_6TH_GEN_D2:
418 	case PCI_DEVICE_ID_INTEL_CORE_6TH_GEN_U:
419 	case PCI_DEVICE_ID_INTEL_CORE_6TH_GEN_Y:
420 	case PCI_DEVICE_ID_INTEL_CORE_6TH_GEN_M:
421 	case PCI_DEVICE_ID_INTEL_CORE_6TH_GEN_WST:
422 	case PCI_DEVICE_ID_INTEL_CORE_6TH_GEN_D:
423 	case PCI_DEVICE_ID_INTEL_CORE_6TH_GEN_E:
424 	case PCI_DEVICE_ID_INTEL_CORE_7TH_GEN_U:
425 	case PCI_DEVICE_ID_INTEL_CORE_7TH_GEN_Y:
426 	case PCI_DEVICE_ID_INTEL_CORE_7TH_GEN_U_Q:
427 	case PCI_DEVICE_ID_INTEL_CORE_7TH_GEN_E3:
428 	case PCI_DEVICE_ID_INTEL_CORE_8TH_GEN_U_1:
429 	case PCI_DEVICE_ID_INTEL_CORE_8TH_GEN_U_2:
430 		dmi_registers = skylake_dmi_registers;
431 		size = ARRAY_SIZE(skylake_dmi_registers);
432 		dmibar_phys = pci_read_long(nb, 0x68);
433 		dmibar_phys |= ((uint64_t)pci_read_long(nb, 0x6c)) << 32;
434 		dmibar_phys &= 0x0000007ffffff000UL; /* 38:12 */
435 		break;
436 	case PCI_DEVICE_ID_INTEL_CORE_ADL_ID_N_0_8:
437 	case PCI_DEVICE_ID_INTEL_CORE_ADL_ID_N_0_4:
438 	case PCI_DEVICE_ID_INTEL_CORE_ADL_ID_N_0_4_1:
439 		dmibar_phys = pci_read_long(nb, 0x68) & 0xfffffffe;
440 		dmibar_phys |= ((uint64_t)pci_read_long(nb, 0x6c)) << 32;
441 		dmi_registers = alderlake_dmi_registers;
442 		size = ARRAY_SIZE(alderlake_dmi_registers);
443 		break;
444 	default:
445 		printf("Error: Dumping DMIBAR on this northbridge is not (yet) supported.\n");
446 		return 1;
447 	}
448 
449 	dmibar = map_physical(dmibar_phys, size);
450 
451 	if (dmibar == NULL) {
452 		perror("Error mapping DMIBAR");
453 		exit(1);
454 	}
455 
456 	printf("DMIBAR = 0x%08" PRIx64 " (MEM)\n\n", dmibar_phys);
457 	if (dmi_registers != NULL) {
458 		for (i = 0; i < size; i++) {
459 			switch (dmi_registers[i].size) {
460 				case 4:
461 					printf("dmibase+0x%04x: 0x%08x (%s)\n",
462 						dmi_registers[i].addr,
463 						read32(dmibar+dmi_registers[i].addr),
464 						dmi_registers[i].name);
465 					break;
466 				case 2:
467 					printf("dmibase+0x%04x: 0x%04x     (%s)\n",
468 						dmi_registers[i].addr,
469 						read16(dmibar+dmi_registers[i].addr),
470 						dmi_registers[i].name);
471 					break;
472 				case 1:
473 					printf("dmibase+0x%04x: 0x%02x       (%s)\n",
474 						dmi_registers[i].addr,
475 						read8(dmibar+dmi_registers[i].addr),
476 						dmi_registers[i].name);
477 					break;
478 			}
479 		}
480 	} else {
481 		for (i = 0; i < size; i += 4) {
482 			if (read32(dmibar + i))
483 				printf("0x%04x: 0x%08x\n", i, read32(dmibar+i));
484 		}
485 	}
486 
487 	unmap_physical((void *)dmibar, size);
488 	return 0;
489 }
490 
491 /*
492  * PCIe MMIO configuration space
493  */
print_pciexbar(struct pci_dev * nb)494 int print_pciexbar(struct pci_dev *nb)
495 {
496 	uint64_t pciexbar_reg;
497 	uint64_t pciexbar_phys;
498 	volatile uint8_t *pciexbar;
499 	int max_busses, devbase, i;
500 	int bus, dev, fn;
501 
502 	printf("========= PCIEXBAR ========\n\n");
503 
504 	switch (nb->device_id) {
505 	case PCI_DEVICE_ID_INTEL_82915:
506 	case PCI_DEVICE_ID_INTEL_82945GM:
507 	case PCI_DEVICE_ID_INTEL_82945GSE:
508 	case PCI_DEVICE_ID_INTEL_82945P:
509 	case PCI_DEVICE_ID_INTEL_82975X:
510 		pciexbar_reg = pci_read_long(nb, 0x48);
511 		break;
512 	case PCI_DEVICE_ID_INTEL_82946:
513 	case PCI_DEVICE_ID_INTEL_82965PM:
514 	case PCI_DEVICE_ID_INTEL_82Q965:
515 	case PCI_DEVICE_ID_INTEL_82Q35:
516 	case PCI_DEVICE_ID_INTEL_82G33:
517 	case PCI_DEVICE_ID_INTEL_82Q33:
518 	case PCI_DEVICE_ID_INTEL_82X38:
519 	case PCI_DEVICE_ID_INTEL_32X0:
520 	case PCI_DEVICE_ID_INTEL_82XX4X:
521 	case PCI_DEVICE_ID_INTEL_82Q45:
522 	case PCI_DEVICE_ID_INTEL_82G45:
523 	case PCI_DEVICE_ID_INTEL_82G41:
524 	case PCI_DEVICE_ID_INTEL_82B43:
525 	case PCI_DEVICE_ID_INTEL_82B43_2:
526 	case PCI_DEVICE_ID_INTEL_ATOM_DXXX:
527 	case PCI_DEVICE_ID_INTEL_ATOM_NXXX:
528 	case PCI_DEVICE_ID_INTEL_CORE_2ND_GEN_D:
529 	case PCI_DEVICE_ID_INTEL_CORE_2ND_GEN_M:
530 	case PCI_DEVICE_ID_INTEL_CORE_2ND_GEN_E3:
531 	case PCI_DEVICE_ID_INTEL_CORE_3RD_GEN_D:
532 	case PCI_DEVICE_ID_INTEL_CORE_3RD_GEN_M:
533 	case PCI_DEVICE_ID_INTEL_CORE_3RD_GEN_E3:
534 	case PCI_DEVICE_ID_INTEL_CORE_3RD_GEN_015c:
535 	case PCI_DEVICE_ID_INTEL_CORE_4TH_GEN_D:
536 	case PCI_DEVICE_ID_INTEL_CORE_4TH_GEN_M:
537 	case PCI_DEVICE_ID_INTEL_CORE_4TH_GEN_E3:
538 	case PCI_DEVICE_ID_INTEL_CORE_4TH_GEN_U:
539 	case PCI_DEVICE_ID_INTEL_CORE_5TH_GEN_U:
540 	case PCI_DEVICE_ID_INTEL_CORE_5TH_GEN_D:
541 	case PCI_DEVICE_ID_INTEL_CORE_5TH_GEN_M:
542 	case PCI_DEVICE_ID_INTEL_CORE_6TH_GEN_D2:
543 	case PCI_DEVICE_ID_INTEL_CORE_6TH_GEN_U:
544 	case PCI_DEVICE_ID_INTEL_CORE_6TH_GEN_Y:
545 	case PCI_DEVICE_ID_INTEL_CORE_6TH_GEN_M:
546 	case PCI_DEVICE_ID_INTEL_CORE_6TH_GEN_WST:
547 	case PCI_DEVICE_ID_INTEL_CORE_6TH_GEN_D:
548 	case PCI_DEVICE_ID_INTEL_CORE_6TH_GEN_E:
549 	case PCI_DEVICE_ID_INTEL_CORE_7TH_GEN_U:
550 	case PCI_DEVICE_ID_INTEL_CORE_7TH_GEN_Y:
551 	case PCI_DEVICE_ID_INTEL_CORE_7TH_GEN_U_Q:
552 	case PCI_DEVICE_ID_INTEL_CORE_7TH_GEN_E3:
553 	case PCI_DEVICE_ID_INTEL_CORE_8TH_GEN_U_1:
554 	case PCI_DEVICE_ID_INTEL_CORE_8TH_GEN_U_2:
555 	case PCI_DEVICE_ID_INTEL_CORE_ADL_ID_N_0_8:
556 	case PCI_DEVICE_ID_INTEL_CORE_ADL_ID_N_0_4:
557 	case PCI_DEVICE_ID_INTEL_CORE_ADL_ID_N_0_4_1:
558 		pciexbar_reg = pci_read_long(nb, 0x60);
559 		pciexbar_reg |= ((uint64_t)pci_read_long(nb, 0x64)) << 32;
560 		break;
561 	case PCI_DEVICE_ID_INTEL_82810:
562 	case PCI_DEVICE_ID_INTEL_82810_DC:
563 	case PCI_DEVICE_ID_INTEL_82810E_DC:
564 	case PCI_DEVICE_ID_INTEL_82865:
565 		printf("Error: This northbridge does not have PCIEXBAR.\n");
566 		return 1;
567 	default:
568 		printf("Error: Dumping PCIEXBAR on this northbridge is not (yet) supported.\n");
569 		return 1;
570 	}
571 
572 	if (!(pciexbar_reg & (1 << 0))) {
573 		printf("PCIEXBAR register is disabled.\n");
574 		return 0;
575 	}
576 
577 	switch ((pciexbar_reg >> 1) & 3) {
578 	case 0: // 256MB
579 		pciexbar_phys = pciexbar_reg & (0xffULL << 28);
580 		max_busses = 256;
581 		break;
582 	case 1: // 128M
583 		pciexbar_phys = pciexbar_reg & (0x1ffULL << 27);
584 		max_busses = 128;
585 		break;
586 	case 2: // 64M
587 		pciexbar_phys = pciexbar_reg & (0x3ffULL << 26);
588 		max_busses = 64;
589 		break;
590 	default: // RSVD
591 		printf("Undefined address base. Bailing out.\n");
592 		return 1;
593 	}
594 
595 	printf("PCIEXBAR: 0x%08" PRIx64 "\n", pciexbar_phys);
596 
597 	pciexbar = map_physical(pciexbar_phys, (max_busses * 1024 * 1024));
598 
599 	if (pciexbar == NULL) {
600 		perror("Error mapping PCIEXBAR");
601 		exit(1);
602 	}
603 
604 	for (bus = 0; bus < max_busses; bus++) {
605 		for (dev = 0; dev < 32; dev++) {
606 			for (fn = 0; fn < 8; fn++) {
607 				devbase = (bus * 1024 * 1024) + (dev * 32 * 1024) + (fn * 4 * 1024);
608 
609 				if (read16(pciexbar + devbase) == 0xffff)
610 					continue;
611 
612 				/* This is a heuristics. Anyone got a better check? */
613 				if( (read32(pciexbar + devbase + 256) == 0xffffffff) &&
614 					(read32(pciexbar + devbase + 512) == 0xffffffff) ) {
615 #if DEBUG
616 					printf("Skipped non-PCIe device %02x:%02x.%01x\n", bus, dev, fn);
617 #endif
618 					continue;
619 				}
620 
621 				printf("\nPCIe %02x:%02x.%01x extended config space:", bus, dev, fn);
622 				for (i = 0; i < 4096; i++) {
623 					if((i % 0x10) == 0)
624 						printf("\n%04x:", i);
625 					printf(" %02x", *(pciexbar+devbase+i));
626 				}
627 				printf("\n");
628 			}
629 		}
630 	}
631 
632 	unmap_physical((void *)pciexbar, (max_busses * 1024 * 1024));
633 
634 	return 0;
635 }
636