1 /*
2 * This file is part of the flashrom project.
3 *
4 * Copyright (c) 2010 Matthias Wenzel <bios at mazzoo dot de>
5 * Copyright (c) 2011 Stefan Tauner
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 */
17
18 #include "hwaccess_physmap.h"
19 #include "ich_descriptors.h"
20
21 #ifdef ICH_DESCRIPTORS_FROM_DUMP_ONLY
22 #include <stdio.h>
23 #include <string.h>
24 #define print(t, ...) printf(__VA_ARGS__)
25 #endif
26
27 #define DESCRIPTOR_MODE_SIGNATURE 0x0ff0a55a
28 /* The upper map is located in the word before the 256B-long OEM section at the
29 * end of the 4kB-long flash descriptor.
30 */
31 #define UPPER_MAP_OFFSET (4096 - 256 - 4)
32 #define getVTBA(flumap) (((flumap)->FLUMAP1 << 4) & 0x00000ff0)
33
34 #include <stdbool.h>
35 #include <sys/types.h>
36 #include <string.h>
37 #include "flash.h" /* for msg_* */
38 #include "programmer.h"
39
ich_number_of_regions(const enum ich_chipset cs,const struct ich_desc_content * const cont)40 ssize_t ich_number_of_regions(const enum ich_chipset cs, const struct ich_desc_content *const cont)
41 {
42 switch (cs) {
43 case CHIPSET_APOLLO_LAKE:
44 case CHIPSET_GEMINI_LAKE:
45 return 6;
46 case CHIPSET_C620_SERIES_LEWISBURG:
47 case CHIPSET_C740_SERIES_EMMITSBURG:
48 case CHIPSET_300_SERIES_CANNON_POINT:
49 case CHIPSET_400_SERIES_COMET_POINT:
50 case CHIPSET_500_SERIES_TIGER_POINT:
51 case CHIPSET_600_SERIES_ALDER_POINT:
52 case CHIPSET_700_SERIES_RAPTOR_POINT:
53 case CHIPSET_METEOR_LAKE:
54 case CHIPSET_PANTHER_LAKE:
55 case CHIPSET_ELKHART_LAKE:
56 case CHIPSET_JASPER_LAKE:
57 return 16;
58 case CHIPSET_100_SERIES_SUNRISE_POINT:
59 return 10;
60 case CHIPSET_9_SERIES_WILDCAT_POINT_LP:
61 case CHIPSET_9_SERIES_WILDCAT_POINT:
62 case CHIPSET_8_SERIES_LYNX_POINT_LP:
63 case CHIPSET_8_SERIES_LYNX_POINT:
64 case CHIPSET_8_SERIES_WELLSBURG:
65 if (cont->NR <= 6)
66 return cont->NR + 1;
67 else
68 return -1;
69 default:
70 if (cont->NR <= 4)
71 return cont->NR + 1;
72 else
73 return -1;
74 }
75 }
76
ich_number_of_masters(const enum ich_chipset cs,const struct ich_desc_content * const cont)77 ssize_t ich_number_of_masters(const enum ich_chipset cs, const struct ich_desc_content *const cont)
78 {
79 switch (cs) {
80 case CHIPSET_C620_SERIES_LEWISBURG:
81 case CHIPSET_C740_SERIES_EMMITSBURG:
82 case CHIPSET_APOLLO_LAKE:
83 case CHIPSET_600_SERIES_ALDER_POINT:
84 case CHIPSET_700_SERIES_RAPTOR_POINT:
85 case CHIPSET_METEOR_LAKE:
86 case CHIPSET_PANTHER_LAKE:
87 case CHIPSET_GEMINI_LAKE:
88 case CHIPSET_JASPER_LAKE:
89 case CHIPSET_ELKHART_LAKE:
90 if (cont->NM <= MAX_NUM_MASTERS)
91 return cont->NM;
92 break;
93 default:
94 if (cont->NM < MAX_NUM_MASTERS)
95 return cont->NM + 1;
96 }
97
98 return -1;
99 }
100
prettyprint_ich_reg_vscc(uint32_t reg_val,int verbosity,bool print_vcl)101 void prettyprint_ich_reg_vscc(uint32_t reg_val, int verbosity, bool print_vcl)
102 {
103 print(verbosity, "BES=0x%"PRIx32", ", (reg_val & VSCC_BES) >> VSCC_BES_OFF);
104 print(verbosity, "WG=%"PRId32", ", (reg_val & VSCC_WG) >> VSCC_WG_OFF);
105 print(verbosity, "WSR=%"PRId32", ", (reg_val & VSCC_WSR) >> VSCC_WSR_OFF);
106 print(verbosity, "WEWS=%"PRId32", ", (reg_val & VSCC_WEWS) >> VSCC_WEWS_OFF);
107 print(verbosity, "EO=0x%"PRIx32"", (reg_val & VSCC_EO) >> VSCC_EO_OFF);
108 if (print_vcl)
109 print(verbosity, ", VCL=%"PRId32"", (reg_val & VSCC_VCL) >> VSCC_VCL_OFF);
110 print(verbosity, "\n");
111 }
112
113 #define getFCBA(cont) (((cont)->FLMAP0 << 4) & 0x00000ff0)
114 #define getFRBA(cont) (((cont)->FLMAP0 >> 12) & 0x00000ff0)
115 #define getFMBA(cont) (((cont)->FLMAP1 << 4) & 0x00000ff0)
116 #define getFISBA(cont) (((cont)->FLMAP1 >> 12) & 0x00000ff0)
117 #define getFMSBA(cont) (((cont)->FLMAP2 << 4) & 0x00000ff0)
118
prettyprint_ich_chipset(enum ich_chipset cs)119 void prettyprint_ich_chipset(enum ich_chipset cs)
120 {
121 static const char *const chipset_names[] = {
122 "Unknown ICH", "ICH8", "ICH9", "ICH10",
123 "5 series Ibex Peak", "6 series Cougar Point", "7 series Panther Point",
124 "8 series Lynx Point", "Baytrail", "8 series Lynx Point LP", "8 series Wellsburg",
125 "9 series Wildcat Point", "9 series Wildcat Point LP", "100 series Sunrise Point",
126 "C620 series Lewisburg", "C740 series Emmitsburg", "300 series Cannon Point",
127 "400 series Comet Point", "500 series Tiger Point", "600 series Alder Point",
128 "Apollo Lake", "Gemini Lake", "Jasper Lake", "Elkhart Lake",
129 "Meteor Lake", "Panther Lake",
130 };
131 if (cs < CHIPSET_ICH8 || cs - CHIPSET_ICH8 + 1 >= ARRAY_SIZE(chipset_names))
132 cs = 0;
133 else
134 cs = cs - CHIPSET_ICH8 + 1;
135 msg_pdbg2("Assuming chipset '%s'.\n", chipset_names[cs]);
136 }
137
prettyprint_ich_descriptors(enum ich_chipset cs,const struct ich_descriptors * desc)138 void prettyprint_ich_descriptors(enum ich_chipset cs, const struct ich_descriptors *desc)
139 {
140 prettyprint_ich_descriptor_content(cs, &desc->content);
141 prettyprint_ich_descriptor_component(cs, desc);
142 prettyprint_ich_descriptor_region(cs, desc);
143 prettyprint_ich_descriptor_master(cs, desc);
144 #ifdef ICH_DESCRIPTORS_FROM_DUMP_ONLY
145 if (cs >= CHIPSET_ICH8) {
146 prettyprint_ich_descriptor_upper_map(&desc->upper);
147 prettyprint_ich_descriptor_straps(cs, desc);
148 }
149 #endif /* ICH_DESCRIPTORS_FROM_DUMP_ONLY */
150 }
151
prettyprint_ich_descriptor_content(enum ich_chipset cs,const struct ich_desc_content * cont)152 void prettyprint_ich_descriptor_content(enum ich_chipset cs, const struct ich_desc_content *cont)
153 {
154 msg_pdbg2("=== Content Section ===\n");
155 msg_pdbg2("FLVALSIG 0x%08"PRIx32"\n", cont->FLVALSIG);
156 msg_pdbg2("FLMAP0 0x%08"PRIx32"\n", cont->FLMAP0);
157 msg_pdbg2("FLMAP1 0x%08"PRIx32"\n", cont->FLMAP1);
158 msg_pdbg2("FLMAP2 0x%08"PRIx32"\n", cont->FLMAP2);
159 msg_pdbg2("\n");
160
161 msg_pdbg2("--- Details ---\n");
162 msg_pdbg2("NR (Number of Regions): %5zd\n", ich_number_of_regions(cs, cont));
163 msg_pdbg2("FRBA (Flash Region Base Address): 0x%03"PRIx32"\n", getFRBA(cont));
164 msg_pdbg2("NC (Number of Components): %5d\n", cont->NC + 1);
165 msg_pdbg2("FCBA (Flash Component Base Address): 0x%03"PRIx32"\n", getFCBA(cont));
166 msg_pdbg2("ISL (ICH/PCH/SoC Strap Length): %5d\n", cont->ISL);
167 msg_pdbg2("FISBA/FPSBA (Flash ICH/PCH/SoC Strap Base Addr): 0x%03"PRIx32"\n", getFISBA(cont));
168 msg_pdbg2("NM (Number of Masters): %5zd\n", ich_number_of_masters(cs, cont));
169 msg_pdbg2("FMBA (Flash Master Base Address): 0x%03"PRIx32"\n", getFMBA(cont));
170 msg_pdbg2("MSL/PSL (MCH/PROC Strap Length): %5d\n", cont->MSL);
171 msg_pdbg2("FMSBA (Flash MCH/PROC Strap Base Address): 0x%03"PRIx32"\n", getFMSBA(cont));
172 msg_pdbg2("\n");
173 }
174
pprint_density(enum ich_chipset cs,const struct ich_descriptors * desc,uint8_t idx)175 static const char *pprint_density(enum ich_chipset cs, const struct ich_descriptors *desc, uint8_t idx)
176 {
177 if (idx > 1) {
178 msg_perr("Only ICH SPI component index 0 or 1 are supported yet.\n");
179 return NULL;
180 }
181
182 if (desc->content.NC == 0 && idx > 0)
183 return "unused";
184
185 static const char * const size_str[] = {
186 "512 kB", /* 0000 */
187 "1 MB", /* 0001 */
188 "2 MB", /* 0010 */
189 "4 MB", /* 0011 */
190 "8 MB", /* 0100 */
191 "16 MB", /* 0101 */ /* Maximum up to Lynx Point (excl.) */
192 "32 MB", /* 0110 */
193 "64 MB", /* 0111 */
194 };
195
196 switch (cs) {
197 case CHIPSET_ICH8:
198 case CHIPSET_ICH9:
199 case CHIPSET_ICH10:
200 case CHIPSET_5_SERIES_IBEX_PEAK:
201 case CHIPSET_6_SERIES_COUGAR_POINT:
202 case CHIPSET_7_SERIES_PANTHER_POINT:
203 case CHIPSET_BAYTRAIL: {
204 uint8_t size_enc;
205 if (idx == 0) {
206 size_enc = desc->component.dens_old.comp1_density;
207 } else {
208 size_enc = desc->component.dens_old.comp2_density;
209 }
210 if (size_enc > 5)
211 return "reserved";
212 return size_str[size_enc];
213 }
214 case CHIPSET_8_SERIES_LYNX_POINT:
215 case CHIPSET_8_SERIES_LYNX_POINT_LP:
216 case CHIPSET_8_SERIES_WELLSBURG:
217 case CHIPSET_9_SERIES_WILDCAT_POINT:
218 case CHIPSET_9_SERIES_WILDCAT_POINT_LP:
219 case CHIPSET_100_SERIES_SUNRISE_POINT:
220 case CHIPSET_C620_SERIES_LEWISBURG:
221 case CHIPSET_C740_SERIES_EMMITSBURG:
222 case CHIPSET_300_SERIES_CANNON_POINT:
223 case CHIPSET_400_SERIES_COMET_POINT:
224 case CHIPSET_500_SERIES_TIGER_POINT:
225 case CHIPSET_600_SERIES_ALDER_POINT:
226 case CHIPSET_700_SERIES_RAPTOR_POINT:
227 case CHIPSET_METEOR_LAKE:
228 case CHIPSET_PANTHER_LAKE:
229 case CHIPSET_APOLLO_LAKE:
230 case CHIPSET_GEMINI_LAKE:
231 case CHIPSET_JASPER_LAKE:
232 case CHIPSET_ELKHART_LAKE: {
233 uint8_t size_enc;
234 if (idx == 0) {
235 size_enc = desc->component.dens_new.comp1_density;
236 } else {
237 size_enc = desc->component.dens_new.comp2_density;
238 }
239 if (size_enc > 7)
240 return "reserved";
241 return size_str[size_enc];
242 }
243 case CHIPSET_ICH_UNKNOWN:
244 default:
245 return "unknown";
246 }
247 }
248
pprint_freq(enum ich_chipset cs,uint8_t value)249 static const char *pprint_freq(enum ich_chipset cs, uint8_t value)
250 {
251 static const char *const freq_str[5][8] = { {
252 "20 MHz",
253 "33 MHz",
254 "reserved",
255 "reserved",
256 "50 MHz", /* New since Ibex Peak */
257 "reserved",
258 "reserved",
259 "reserved"
260 }, {
261 "reserved",
262 "reserved",
263 "48 MHz",
264 "reserved",
265 "30 MHz",
266 "reserved",
267 "17 MHz",
268 "reserved"
269 }, {
270 "reserved",
271 "50 MHz",
272 "40 MHz",
273 "reserved",
274 "25 MHz",
275 "reserved",
276 "14 MHz / 17 MHz",
277 "reserved"
278 }, {
279 "100 MHz",
280 "50 MHz",
281 "reserved",
282 "33 MHz",
283 "25 MHz",
284 "reserved",
285 "14 MHz",
286 "reserved"
287 }, {
288 "reserved",
289 "50 MHz",
290 "reserved",
291 "reserved",
292 "33 MHz",
293 "20 MHz",
294 "reserved",
295 "reserved",
296 }};
297
298 switch (cs) {
299 case CHIPSET_ICH8:
300 case CHIPSET_ICH9:
301 case CHIPSET_ICH10:
302 if (value > 1)
303 return "reserved";
304 /* Fall through. */
305 case CHIPSET_5_SERIES_IBEX_PEAK:
306 case CHIPSET_6_SERIES_COUGAR_POINT:
307 case CHIPSET_7_SERIES_PANTHER_POINT:
308 case CHIPSET_8_SERIES_LYNX_POINT:
309 case CHIPSET_BAYTRAIL:
310 case CHIPSET_8_SERIES_LYNX_POINT_LP:
311 case CHIPSET_8_SERIES_WELLSBURG:
312 case CHIPSET_9_SERIES_WILDCAT_POINT:
313 case CHIPSET_9_SERIES_WILDCAT_POINT_LP:
314 return freq_str[0][value];
315 case CHIPSET_100_SERIES_SUNRISE_POINT:
316 case CHIPSET_C620_SERIES_LEWISBURG:
317 case CHIPSET_300_SERIES_CANNON_POINT:
318 case CHIPSET_400_SERIES_COMET_POINT:
319 case CHIPSET_JASPER_LAKE:
320 return freq_str[1][value];
321 case CHIPSET_APOLLO_LAKE:
322 case CHIPSET_GEMINI_LAKE:
323 return freq_str[2][value];
324 case CHIPSET_500_SERIES_TIGER_POINT:
325 case CHIPSET_600_SERIES_ALDER_POINT:
326 case CHIPSET_700_SERIES_RAPTOR_POINT:
327 case CHIPSET_C740_SERIES_EMMITSBURG:
328 case CHIPSET_METEOR_LAKE:
329 case CHIPSET_PANTHER_LAKE:
330 return freq_str[3][value];
331 case CHIPSET_ELKHART_LAKE:
332 return freq_str[4][value];
333 case CHIPSET_ICH_UNKNOWN:
334 default:
335 return "unknown";
336 }
337 }
338
pprint_read_freq(enum ich_chipset cs,uint8_t value)339 static void pprint_read_freq(enum ich_chipset cs, uint8_t value)
340 {
341 static const char *const freq_str[1][8] = { {
342 "20 MHz",
343 "24 MHz",
344 "30 MHz",
345 "48 MHz",
346 "60 MHz",
347 "reserved",
348 "reserved",
349 "reserved"
350 }};
351
352 switch (cs) {
353 case CHIPSET_300_SERIES_CANNON_POINT:
354 case CHIPSET_400_SERIES_COMET_POINT:
355 msg_pdbg2("eSPI/EC Bus Clock Frequency: %s\n", freq_str[0][value]);
356 return;
357 case CHIPSET_500_SERIES_TIGER_POINT:
358 msg_pdbg2("Read Clock Frequency: %s\n", "reserved");
359 return;
360 default:
361 msg_pdbg2("Read Clock Frequency: %s\n", pprint_freq(cs, value));
362 return;
363 }
364 }
365
prettyprint_ich_descriptor_component(enum ich_chipset cs,const struct ich_descriptors * desc)366 void prettyprint_ich_descriptor_component(enum ich_chipset cs, const struct ich_descriptors *desc)
367 {
368 bool has_flill1;
369
370 switch (cs) {
371 case CHIPSET_100_SERIES_SUNRISE_POINT:
372 case CHIPSET_C620_SERIES_LEWISBURG:
373 case CHIPSET_C740_SERIES_EMMITSBURG:
374 case CHIPSET_300_SERIES_CANNON_POINT:
375 case CHIPSET_400_SERIES_COMET_POINT:
376 case CHIPSET_500_SERIES_TIGER_POINT:
377 case CHIPSET_600_SERIES_ALDER_POINT:
378 case CHIPSET_700_SERIES_RAPTOR_POINT:
379 case CHIPSET_METEOR_LAKE:
380 case CHIPSET_PANTHER_LAKE:
381 case CHIPSET_APOLLO_LAKE:
382 case CHIPSET_GEMINI_LAKE:
383 case CHIPSET_JASPER_LAKE:
384 case CHIPSET_ELKHART_LAKE:
385 has_flill1 = true;
386 break;
387 default:
388 has_flill1 = false;
389 break;
390 }
391
392 msg_pdbg2("=== Component Section ===\n");
393 msg_pdbg2("FLCOMP 0x%08"PRIx32"\n", desc->component.FLCOMP);
394 msg_pdbg2("FLILL 0x%08"PRIx32"\n", desc->component.FLILL );
395 if (has_flill1)
396 msg_pdbg2("FLILL1 0x%08"PRIx32"\n", desc->component.FLILL1);
397 msg_pdbg2("\n");
398
399 msg_pdbg2("--- Details ---\n");
400 msg_pdbg2("Component 1 density: %s\n", pprint_density(cs, desc, 0));
401 if (desc->content.NC)
402 msg_pdbg2("Component 2 density: %s\n", pprint_density(cs, desc, 1));
403 else
404 msg_pdbg2("Component 2 is not used.\n");
405
406 pprint_read_freq(cs, desc->component.modes.freq_read);
407
408 msg_pdbg2("Read ID and Status Clock Freq.: %s\n", pprint_freq(cs, desc->component.modes.freq_read_id));
409 msg_pdbg2("Write and Erase Clock Freq.: %s\n", pprint_freq(cs, desc->component.modes.freq_write));
410 msg_pdbg2("Fast Read is %ssupported.\n", desc->component.modes.fastread ? "" : "not ");
411 if (desc->component.modes.fastread)
412 msg_pdbg2("Fast Read Clock Frequency: %s\n",
413 pprint_freq(cs, desc->component.modes.freq_fastread));
414 if (cs > CHIPSET_6_SERIES_COUGAR_POINT)
415 msg_pdbg2("Dual Output Fast Read Support: %sabled\n",
416 desc->component.modes.dual_output ? "en" : "dis");
417
418 bool has_forbidden_opcode = false;
419 if (desc->component.FLILL != 0) {
420 has_forbidden_opcode = true;
421 msg_pdbg2("Invalid instruction 0: 0x%02x\n",
422 desc->component.invalid_instr0);
423 msg_pdbg2("Invalid instruction 1: 0x%02x\n",
424 desc->component.invalid_instr1);
425 msg_pdbg2("Invalid instruction 2: 0x%02x\n",
426 desc->component.invalid_instr2);
427 msg_pdbg2("Invalid instruction 3: 0x%02x\n",
428 desc->component.invalid_instr3);
429 }
430 if (has_flill1) {
431 if (desc->component.FLILL1 != 0) {
432 has_forbidden_opcode = true;
433 msg_pdbg2("Invalid instruction 4: 0x%02x\n",
434 desc->component.invalid_instr4);
435 msg_pdbg2("Invalid instruction 5: 0x%02x\n",
436 desc->component.invalid_instr5);
437 msg_pdbg2("Invalid instruction 6: 0x%02x\n",
438 desc->component.invalid_instr6);
439 msg_pdbg2("Invalid instruction 7: 0x%02x\n",
440 desc->component.invalid_instr7);
441 }
442 }
443 if (!has_forbidden_opcode)
444 msg_pdbg2("No forbidden opcodes.\n");
445
446 msg_pdbg2("\n");
447 }
448
pprint_freg(const struct ich_desc_region * reg,uint32_t i)449 static void pprint_freg(const struct ich_desc_region *reg, uint32_t i)
450 {
451 static const char *const region_names[] = {
452 "Descr.", "BIOS", "ME", "GbE", "Platf.", "DevExp", "BIOS2", "unknown",
453 "EC/BMC", "unknown", "IE", "10GbE0", "10GbE1", "unknown", "unknown", "PTT"
454 };
455 if (i >= ARRAY_SIZE(region_names)) {
456 msg_pdbg2("%s: region index too high.\n", __func__);
457 return;
458 }
459 uint32_t base = ICH_FREG_BASE(reg->FLREGs[i]);
460 uint32_t limit = ICH_FREG_LIMIT(reg->FLREGs[i]);
461 msg_pdbg2("Region %"PRId32" (%-7s) ", i, region_names[i]);
462 if (base > limit)
463 msg_pdbg2("is unused.\n");
464 else
465 msg_pdbg2("0x%08"PRIx32" - 0x%08"PRIx32"\n", base, limit);
466 }
467
prettyprint_ich_descriptor_region(const enum ich_chipset cs,const struct ich_descriptors * const desc)468 void prettyprint_ich_descriptor_region(const enum ich_chipset cs, const struct ich_descriptors *const desc)
469 {
470 ssize_t i;
471 const ssize_t nr = ich_number_of_regions(cs, &desc->content);
472 msg_pdbg2("=== Region Section ===\n");
473 if (nr < 0) {
474 msg_pdbg2("%s: number of regions too high (%d).\n", __func__,
475 desc->content.NR + 1);
476 return;
477 }
478 for (i = 0; i < nr; i++)
479 msg_pdbg2("FLREG%zd 0x%08"PRIx32"\n", i, desc->region.FLREGs[i]);
480 msg_pdbg2("\n");
481
482 msg_pdbg2("--- Details ---\n");
483 for (i = 0; i < nr; i++)
484 pprint_freg(&desc->region, (uint32_t)i);
485 msg_pdbg2("\n");
486 }
487
prettyprint_ich_descriptor_master(const enum ich_chipset cs,const struct ich_descriptors * const desc)488 void prettyprint_ich_descriptor_master(const enum ich_chipset cs, const struct ich_descriptors *const desc)
489 {
490 ssize_t i;
491 ssize_t nm = ich_number_of_masters(cs, &desc->content);
492 msg_pdbg2("=== Master Section ===\n");
493 if (nm < 0) {
494 msg_pdbg2("%s: number of masters too high (%d).\n", __func__,
495 desc->content.NM + 1);
496 return;
497 }
498 if (cs == CHIPSET_C740_SERIES_EMMITSBURG) {
499 /*
500 * The SPI programming guide says there are 6 masters (thus NM=6), but it
501 * can only name 5. If there's a 6th then it's undocumented.
502 * However the first 5 are matching '500 Series PCH' and since C740 is a
503 * 500 Series clone, this field probably was not updated when writing the
504 * document.
505 * Hardcode to 5 to be compatible with '500 Series PCH' below.
506 */
507 nm = 5;
508 }
509 for (i = 0; i < nm; i++)
510 msg_pdbg2("FLMSTR%zd 0x%08"PRIx32"\n", i + 1, desc->master.FLMSTRs[i]);
511
512 msg_pdbg2("\n");
513
514 msg_pdbg2("--- Details ---\n");
515 if (cs == CHIPSET_100_SERIES_SUNRISE_POINT ||
516 cs == CHIPSET_300_SERIES_CANNON_POINT ||
517 cs == CHIPSET_400_SERIES_COMET_POINT ||
518 cs == CHIPSET_500_SERIES_TIGER_POINT ||
519 cs == CHIPSET_600_SERIES_ALDER_POINT ||
520 cs == CHIPSET_700_SERIES_RAPTOR_POINT ||
521 cs == CHIPSET_C740_SERIES_EMMITSBURG ||
522 cs == CHIPSET_JASPER_LAKE ||
523 cs == CHIPSET_METEOR_LAKE ||
524 cs == CHIPSET_PANTHER_LAKE) {
525 const char *const master_names[] = {
526 "BIOS", "ME", "GbE", "DevE", "EC",
527 };
528
529 if (nm > (ssize_t)ARRAY_SIZE(master_names)) {
530 msg_pdbg2("%s: number of masters too high (%zd).\n", __func__, nm);
531 return;
532 }
533
534 size_t num_regions;
535 msg_pdbg2(" FD BIOS ME GbE Pltf DE BIOS2 Reg7 EC DE2 ");
536 if (cs == CHIPSET_100_SERIES_SUNRISE_POINT) {
537 num_regions = 10;
538 msg_pdbg2("\n");
539 } else {
540 num_regions = 16;
541 msg_pdbg2(" IE 10GbE0 10GbE1 RegD RegE PTT \n");
542 }
543 for (i = 0; i < nm; i++) {
544 const unsigned int ext_region_start = 12;
545 size_t j;
546 msg_pdbg2("%-4s", master_names[i]);
547 for (j = 0; j < (size_t)min(num_regions, ext_region_start); j++)
548 msg_pdbg2(" %c%c ",
549 desc->master.mstr[i].read & (1 << j) ? 'r' : ' ',
550 desc->master.mstr[i].write & (1 << j) ? 'w' : ' ');
551 for (j = ext_region_start; j < num_regions; j++)
552 msg_pdbg2(" %c%c ",
553 desc->master.mstr[i].ext_read & (1 << (j - ext_region_start)) ? 'r' : ' ',
554 desc->master.mstr[i].ext_write & (1 << (j - ext_region_start)) ? 'w' : ' ');
555 msg_pdbg2("\n");
556 }
557 } else if (cs == CHIPSET_C620_SERIES_LEWISBURG) {
558 const char *const master_names[] = {
559 "BIOS", "ME", "GbE", "DE", "BMC", "IE",
560 };
561 /* NM starts at 1 instead of 0 for LBG */
562 if (nm > (ssize_t)ARRAY_SIZE(master_names)) {
563 msg_pdbg2("%s: number of masters too high (%d).\n", __func__,
564 desc->content.NM);
565 return;
566 }
567
568 msg_pdbg2("%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s\n",
569 " ", /* width of master name (4 chars minimum) */
570 " FD ", " BIOS", " ME ", " GbE ", " Pltf",
571 " DE ", "BIOS2", " Reg7", " BMC ", " DE2 ",
572 " IE ", "10GbE", "OpROM", "Reg13", "Reg14",
573 "Reg15");
574 for (i = 0; i < nm; i++) {
575 size_t j;
576 msg_pdbg2("%-4s", master_names[i]);
577 for (j = 0; j < 16; j++)
578 msg_pdbg2(" %c%c ",
579 desc->master.mstr[i].read & (1 << j) ? 'r' : ' ',
580 desc->master.mstr[i].write & (1 << j) ? 'w' : ' ');
581 msg_pdbg2("\n");
582 }
583 } else if (cs == CHIPSET_APOLLO_LAKE || cs == CHIPSET_GEMINI_LAKE || cs == CHIPSET_ELKHART_LAKE) {
584 const char *const master_names[] = { "BIOS", "TXE", };
585 if (nm > (ssize_t)ARRAY_SIZE(master_names)) {
586 msg_pdbg2("%s: number of masters too high (%d).\n", __func__, desc->content.NM);
587 return;
588 }
589
590 msg_pdbg2(" FD IFWI TXE n/a Platf DevExp\n");
591 for (i = 0; i < nm; i++) {
592 ssize_t j;
593 msg_pdbg2("%-4s", master_names[i]);
594 for (j = 0; j < ich_number_of_regions(cs, &desc->content); j++)
595 msg_pdbg2(" %c%c ",
596 desc->master.mstr[i].read & (1 << j) ? 'r' : ' ',
597 desc->master.mstr[i].write & (1 << j) ? 'w' : ' ');
598 msg_pdbg2("\n");
599 }
600 } else {
601 const struct ich_desc_master *const mstr = &desc->master;
602 msg_pdbg2(" Descr. BIOS ME GbE Platf.\n");
603 msg_pdbg2("BIOS %c%c %c%c %c%c %c%c %c%c\n",
604 (mstr->BIOS_descr_r) ?'r':' ', (mstr->BIOS_descr_w) ?'w':' ',
605 (mstr->BIOS_BIOS_r) ?'r':' ', (mstr->BIOS_BIOS_w) ?'w':' ',
606 (mstr->BIOS_ME_r) ?'r':' ', (mstr->BIOS_ME_w) ?'w':' ',
607 (mstr->BIOS_GbE_r) ?'r':' ', (mstr->BIOS_GbE_w) ?'w':' ',
608 (mstr->BIOS_plat_r) ?'r':' ', (mstr->BIOS_plat_w) ?'w':' ');
609 msg_pdbg2("ME %c%c %c%c %c%c %c%c %c%c\n",
610 (mstr->ME_descr_r) ?'r':' ', (mstr->ME_descr_w) ?'w':' ',
611 (mstr->ME_BIOS_r) ?'r':' ', (mstr->ME_BIOS_w) ?'w':' ',
612 (mstr->ME_ME_r) ?'r':' ', (mstr->ME_ME_w) ?'w':' ',
613 (mstr->ME_GbE_r) ?'r':' ', (mstr->ME_GbE_w) ?'w':' ',
614 (mstr->ME_plat_r) ?'r':' ', (mstr->ME_plat_w) ?'w':' ');
615 msg_pdbg2("GbE %c%c %c%c %c%c %c%c %c%c\n",
616 (mstr->GbE_descr_r) ?'r':' ', (mstr->GbE_descr_w) ?'w':' ',
617 (mstr->GbE_BIOS_r) ?'r':' ', (mstr->GbE_BIOS_w) ?'w':' ',
618 (mstr->GbE_ME_r) ?'r':' ', (mstr->GbE_ME_w) ?'w':' ',
619 (mstr->GbE_GbE_r) ?'r':' ', (mstr->GbE_GbE_w) ?'w':' ',
620 (mstr->GbE_plat_r) ?'r':' ', (mstr->GbE_plat_w) ?'w':' ');
621 }
622 msg_pdbg2("\n");
623 }
624
prettyprint_ich_descriptor_straps_ich8(const struct ich_descriptors * desc)625 static void prettyprint_ich_descriptor_straps_ich8(const struct ich_descriptors *desc)
626 {
627 static const char * const str_GPIO12[4] = {
628 "GPIO12",
629 "LAN PHY Power Control Function (Native Output)",
630 "GLAN_DOCK# (Native Input)",
631 "invalid configuration",
632 };
633
634 msg_pdbg2("--- MCH details ---\n");
635 msg_pdbg2("ME B is %sabled.\n", desc->north.ich8.MDB ? "dis" : "en");
636 msg_pdbg2("\n");
637
638 msg_pdbg2("--- ICH details ---\n");
639 msg_pdbg2("ME SMBus Address 1: 0x%02x\n", desc->south.ich8.ASD);
640 msg_pdbg2("ME SMBus Address 2: 0x%02x\n", desc->south.ich8.ASD2);
641 msg_pdbg2("ME SMBus Controller is connected to the %s.\n",
642 desc->south.ich8.MESM2SEL ? "SMLink pins" : "SMBus pins");
643 msg_pdbg2("SPI CS1 is used for %s.\n",
644 desc->south.ich8.SPICS1_LANPHYPC_SEL ?
645 "LAN PHY Power Control Function" :
646 "SPI Chip Select");
647 msg_pdbg2("GPIO12 is used as %s.\n",
648 str_GPIO12[desc->south.ich8.GPIO12_SEL]);
649 msg_pdbg2("PCIe Port 6 is used for %s.\n",
650 desc->south.ich8.GLAN_PCIE_SEL ? "integrated LAN" : "PCI Express");
651 msg_pdbg2("%sn BMC Mode: "
652 "Intel AMT SMBus Controller 1 is connected to %s.\n",
653 desc->south.ich8.BMCMODE ? "I" : "Not i",
654 desc->south.ich8.BMCMODE ? "SMLink" : "SMBus");
655 msg_pdbg2("TCO is in %s Mode.\n",
656 desc->south.ich8.TCOMODE ? "Advanced TCO" : "Legacy/Compatible");
657 msg_pdbg2("ME A is %sabled.\n",
658 desc->south.ich8.ME_DISABLE ? "dis" : "en");
659 msg_pdbg2("\n");
660 }
661
prettyprint_ich_descriptor_straps_56_pciecs(uint8_t conf,uint8_t off)662 static void prettyprint_ich_descriptor_straps_56_pciecs(uint8_t conf, uint8_t off)
663 {
664 msg_pdbg2("PCI Express Port Configuration Strap %d: ", off+1);
665
666 off *= 4;
667 switch (conf){
668 case 0:
669 msg_pdbg2("4x1 Ports %d-%d (x1)", 1+off, 4+off);
670 break;
671 case 1:
672 msg_pdbg2("1x2, 2x1 Port %d (x2), Port %d (disabled), "
673 "Ports %d, %d (x1)", 1+off, 2+off, 3+off, 4+off);
674 break;
675 case 2:
676 msg_pdbg2("2x2 Port %d (x2), Port %d (x2), Ports "
677 "%d, %d (disabled)", 1+off, 3+off, 2+off, 4+off);
678 break;
679 case 3:
680 msg_pdbg2("1x4 Port %d (x4), Ports %d-%d (disabled)",
681 1+off, 2+off, 4+off);
682 break;
683 }
684 msg_pdbg2("\n");
685 }
686
prettyprint_ich_descriptor_pchstraps45678_56(const struct ich_desc_south_strap * s)687 static void prettyprint_ich_descriptor_pchstraps45678_56(const struct ich_desc_south_strap *s)
688 {
689 /* PCHSTRP4 */
690 msg_pdbg2("Intel PHY is %s.\n",
691 (s->ibex.PHYCON == 2) ? "connected" :
692 (s->ibex.PHYCON == 0) ? "disconnected" : "reserved");
693 msg_pdbg2("GbE MAC SMBus address is %sabled.\n",
694 s->ibex.GBEMAC_SMBUS_ADDR_EN ? "en" : "dis");
695 msg_pdbg2("GbE MAC SMBus address: 0x%02x\n",
696 s->ibex.GBEMAC_SMBUS_ADDR);
697 msg_pdbg2("GbE PHY SMBus address: 0x%02x\n",
698 s->ibex.GBEPHY_SMBUS_ADDR);
699
700 /* PCHSTRP5 */
701 /* PCHSTRP6 */
702 /* PCHSTRP7 */
703 msg_pdbg2("Intel ME SMBus Subsystem Vendor ID: 0x%04x\n",
704 s->ibex.MESMA2UDID_VENDOR);
705 msg_pdbg2("Intel ME SMBus Subsystem Device ID: 0x%04x\n",
706 s->ibex.MESMA2UDID_VENDOR);
707
708 /* PCHSTRP8 */
709 }
710
prettyprint_ich_descriptor_pchstraps111213_56(const struct ich_desc_south_strap * s)711 static void prettyprint_ich_descriptor_pchstraps111213_56(const struct ich_desc_south_strap *s)
712 {
713 /* PCHSTRP11 */
714 msg_pdbg2("SMLink1 GP Address is %sabled.\n",
715 s->ibex.SML1GPAEN ? "en" : "dis");
716 msg_pdbg2("SMLink1 controller General Purpose Target address: 0x%02x\n",
717 s->ibex.SML1GPA);
718 msg_pdbg2("SMLink1 I2C Target address is %sabled.\n",
719 s->ibex.SML1I2CAEN ? "en" : "dis");
720 msg_pdbg2("SMLink1 I2C Target address: 0x%02x\n",
721 s->ibex.SML1I2CA);
722
723 /* PCHSTRP12 */
724 /* PCHSTRP13 */
725 }
726
prettyprint_ich_descriptor_straps_ibex(const struct ich_desc_south_strap * s)727 static void prettyprint_ich_descriptor_straps_ibex(const struct ich_desc_south_strap *s)
728 {
729 static const uint8_t dec_t209min[4] = {
730 100,
731 50,
732 5,
733 1
734 };
735
736 msg_pdbg2("--- PCH ---\n");
737
738 /* PCHSTRP0 */
739 msg_pdbg2("Chipset configuration Softstrap 2: %d\n", s->ibex.cs_ss2);
740 msg_pdbg2("Intel ME SMBus Select is %sabled.\n",
741 s->ibex.SMB_EN ? "en" : "dis");
742 msg_pdbg2("SMLink0 segment is %sabled.\n",
743 s->ibex.SML0_EN ? "en" : "dis");
744 msg_pdbg2("SMLink1 segment is %sabled.\n",
745 s->ibex.SML1_EN ? "en" : "dis");
746 msg_pdbg2("SMLink1 Frequency: %s\n",
747 (s->ibex.SML1FRQ == 1) ? "100 kHz" : "reserved");
748 msg_pdbg2("Intel ME SMBus Frequency: %s\n",
749 (s->ibex.SMB0FRQ == 1) ? "100 kHz" : "reserved");
750 msg_pdbg2("SMLink0 Frequency: %s\n",
751 (s->ibex.SML0FRQ == 1) ? "100 kHz" : "reserved");
752 msg_pdbg2("GPIO12 is used as %s.\n", s->ibex.LANPHYPC_GP12_SEL ?
753 "LAN_PHY_PWR_CTRL" : "general purpose output");
754 msg_pdbg2("Chipset configuration Softstrap 1: %d\n", s->ibex.cs_ss1);
755 msg_pdbg2("DMI RequesterID Checks are %sabled.\n",
756 s->ibex.DMI_REQID_DIS ? "en" : "dis");
757 msg_pdbg2("BIOS Boot-Block size (BBBS): %d kB.\n",
758 1 << (6 + s->ibex.BBBS));
759
760 /* PCHSTRP1 */
761 msg_pdbg2("Chipset configuration Softstrap 3: 0x%x\n", s->ibex.cs_ss3);
762
763 /* PCHSTRP2 */
764 msg_pdbg2("ME SMBus ASD address is %sabled.\n",
765 s->ibex.MESMASDEN ? "en" : "dis");
766 msg_pdbg2("ME SMBus Controller ASD Target address: 0x%02x\n",
767 s->ibex.MESMASDA);
768 msg_pdbg2("ME SMBus I2C address is %sabled.\n",
769 s->ibex.MESMI2CEN ? "en" : "dis");
770 msg_pdbg2("ME SMBus I2C target address: 0x%02x\n",
771 s->ibex.MESMI2CA);
772
773 /* PCHSTRP3 */
774 prettyprint_ich_descriptor_pchstraps45678_56(s);
775 /* PCHSTRP9 */
776 prettyprint_ich_descriptor_straps_56_pciecs(s->ibex.PCIEPCS1, 0);
777 prettyprint_ich_descriptor_straps_56_pciecs(s->ibex.PCIEPCS1, 1);
778 msg_pdbg2("PCIe Lane Reversal 1: PCIe Lanes 0-3 are %sreserved.\n",
779 s->ibex.PCIELR1 ? "" : "not ");
780 msg_pdbg2("PCIe Lane Reversal 2: PCIe Lanes 4-7 are %sreserved.\n",
781 s->ibex.PCIELR2 ? "" : "not ");
782 msg_pdbg2("DMI Lane Reversal: DMI Lanes 0-3 are %sreserved.\n",
783 s->ibex.DMILR ? "" : "not ");
784 msg_pdbg2("Default PHY PCIe Port is %d.\n", s->ibex.PHY_PCIEPORTSEL+1);
785 msg_pdbg2("Integrated MAC/PHY communication over PCIe is %sabled.\n",
786 s->ibex.PHY_PCIE_EN ? "en" : "dis");
787
788 /* PCHSTRP10 */
789 msg_pdbg2("Management Engine will boot from %sflash.\n",
790 s->ibex.ME_BOOT_FLASH ? "" : "ROM, then ");
791 msg_pdbg2("Chipset configuration Softstrap 5: %d\n", s->ibex.cs_ss5);
792 msg_pdbg2("Virtualization Engine Enable 1 is %sabled.\n",
793 s->ibex.VE_EN ? "en" : "dis");
794 msg_pdbg2("ME Memory-attached Debug Display Device is %sabled.\n",
795 s->ibex.MMDDE ? "en" : "dis");
796 msg_pdbg2("ME Memory-attached Debug Display Device address: 0x%02x\n",
797 s->ibex.MMADDR);
798 msg_pdbg2("Chipset configuration Softstrap 7: %d\n", s->ibex.cs_ss7);
799 msg_pdbg2("Integrated Clocking Configuration is %d.\n",
800 (s->ibex.ICC_SEL == 7) ? 0 : s->ibex.ICC_SEL);
801 msg_pdbg2("PCH Signal CL_RST1# does %sassert when Intel ME performs a "
802 "reset.\n", s->ibex.MER_CL1 ? "" : "not ");
803
804 prettyprint_ich_descriptor_pchstraps111213_56(s);
805
806 /* PCHSTRP14 */
807 msg_pdbg2("Virtualization Engine Enable 2 is %sabled.\n",
808 s->ibex.VE_EN2 ? "en" : "dis");
809 msg_pdbg2("Virtualization Engine will boot from %sflash.\n",
810 s->ibex.VE_BOOT_FLASH ? "" : "ROM, then ");
811 msg_pdbg2("Braidwood SSD functionality is %sabled.\n",
812 s->ibex.BW_SSD ? "en" : "dis");
813 msg_pdbg2("Braidwood NVMHCI functionality is %sabled.\n",
814 s->ibex.NVMHCI_EN ? "en" : "dis");
815
816 /* PCHSTRP15 */
817 msg_pdbg2("Chipset configuration Softstrap 6: %d\n", s->ibex.cs_ss6);
818 msg_pdbg2("Integrated wired LAN Solution is %sabled.\n",
819 s->ibex.IWL_EN ? "en" : "dis");
820 msg_pdbg2("t209 min Timing: %d ms\n",
821 dec_t209min[s->ibex.t209min]);
822 msg_pdbg2("\n");
823 }
824
prettyprint_ich_descriptor_straps_cougar(const struct ich_desc_south_strap * s)825 static void prettyprint_ich_descriptor_straps_cougar(const struct ich_desc_south_strap *s)
826 {
827 msg_pdbg2("--- PCH ---\n");
828
829 /* PCHSTRP0 */
830 msg_pdbg2("Chipset configuration Softstrap 1: %d\n", s->cougar.cs_ss1);
831 msg_pdbg2("Intel ME SMBus Select is %sabled.\n",
832 s->ibex.SMB_EN ? "en" : "dis");
833 msg_pdbg2("SMLink0 segment is %sabled.\n",
834 s->ibex.SML0_EN ? "en" : "dis");
835 msg_pdbg2("SMLink1 segment is %sabled.\n",
836 s->ibex.SML1_EN ? "en" : "dis");
837 msg_pdbg2("SMLink1 Frequency: %s\n",
838 (s->ibex.SML1FRQ == 1) ? "100 kHz" : "reserved");
839 msg_pdbg2("Intel ME SMBus Frequency: %s\n",
840 (s->ibex.SMB0FRQ == 1) ? "100 kHz" : "reserved");
841 msg_pdbg2("SMLink0 Frequency: %s\n",
842 (s->ibex.SML0FRQ == 1) ? "100 kHz" : "reserved");
843 msg_pdbg2("GPIO12 is used as %s.\n", s->ibex.LANPHYPC_GP12_SEL ?
844 "LAN_PHY_PWR_CTRL" : "general purpose output");
845 msg_pdbg2("LinkSec is %sabled.\n",
846 s->cougar.LINKSEC_DIS ? "en" : "dis");
847 msg_pdbg2("DMI RequesterID Checks are %sabled.\n",
848 s->ibex.DMI_REQID_DIS ? "en" : "dis");
849 msg_pdbg2("BIOS Boot-Block size (BBBS): %d kB.\n",
850 1 << (6 + s->ibex.BBBS));
851
852 /* PCHSTRP1 */
853 msg_pdbg2("Chipset configuration Softstrap 3: 0x%x\n", s->ibex.cs_ss3);
854 msg_pdbg2("Chipset configuration Softstrap 2: 0x%x\n", s->ibex.cs_ss2);
855
856 /* PCHSTRP2 */
857 msg_pdbg2("ME SMBus ASD address is %sabled.\n",
858 s->ibex.MESMASDEN ? "en" : "dis");
859 msg_pdbg2("ME SMBus Controller ASD Target address: 0x%02x\n",
860 s->ibex.MESMASDA);
861 msg_pdbg2("ME SMBus MCTP Address is %sabled.\n",
862 s->cougar.MESMMCTPAEN ? "en" : "dis");
863 msg_pdbg2("ME SMBus MCTP target address: 0x%02x\n",
864 s->cougar.MESMMCTPA);
865 msg_pdbg2("ME SMBus I2C address is %sabled.\n",
866 s->ibex.MESMI2CEN ? "en" : "dis");
867 msg_pdbg2("ME SMBus I2C target address: 0x%02x\n",
868 s->ibex.MESMI2CA);
869
870 /* PCHSTRP3 */
871 prettyprint_ich_descriptor_pchstraps45678_56(s);
872 /* PCHSTRP9 */
873 prettyprint_ich_descriptor_straps_56_pciecs(s->ibex.PCIEPCS1, 0);
874 prettyprint_ich_descriptor_straps_56_pciecs(s->ibex.PCIEPCS1, 1);
875 msg_pdbg2("PCIe Lane Reversal 1: PCIe Lanes 0-3 are %sreserved.\n",
876 s->ibex.PCIELR1 ? "" : "not ");
877 msg_pdbg2("PCIe Lane Reversal 2: PCIe Lanes 4-7 are %sreserved.\n",
878 s->ibex.PCIELR2 ? "" : "not ");
879 msg_pdbg2("DMI Lane Reversal: DMI Lanes 0-3 are %sreserved.\n",
880 s->ibex.DMILR ? "" : "not ");
881 msg_pdbg2("ME Debug status writes over SMBUS are %sabled.\n",
882 s->cougar.MDSMBE_EN ? "en" : "dis");
883 msg_pdbg2("ME Debug SMBus Emergency Mode address: 0x%02x (raw)\n",
884 s->cougar.MDSMBE_ADD);
885 msg_pdbg2("Default PHY PCIe Port is %d.\n", s->ibex.PHY_PCIEPORTSEL+1);
886 msg_pdbg2("Integrated MAC/PHY communication over PCIe is %sabled.\n",
887 s->ibex.PHY_PCIE_EN ? "en" : "dis");
888 msg_pdbg2("PCIe ports Subtractive Decode Agent is %sabled.\n",
889 s->cougar.SUB_DECODE_EN ? "en" : "dis");
890 msg_pdbg2("GPIO74 is used as %s.\n", s->cougar.PCHHOT_SML1ALERT_SEL ?
891 "PCHHOT#" : "SML1ALERT#");
892
893 /* PCHSTRP10 */
894 msg_pdbg2("Management Engine will boot from %sflash.\n",
895 s->ibex.ME_BOOT_FLASH ? "" : "ROM, then ");
896
897 msg_pdbg2("ME Debug SMBus Emergency Mode is %sabled.\n",
898 s->cougar.MDSMBE_EN ? "en" : "dis");
899 msg_pdbg2("ME Debug SMBus Emergency Mode Address: 0x%02x\n",
900 s->cougar.MDSMBE_ADD);
901
902 msg_pdbg2("Integrated Clocking Configuration used: %d\n",
903 s->cougar.ICC_SEL);
904 msg_pdbg2("PCH Signal CL_RST1# does %sassert when Intel ME performs a reset.\n",
905 s->ibex.MER_CL1 ? "" : "not ");
906 msg_pdbg2("ICC Profile is selected by %s.\n",
907 s->cougar.ICC_PRO_SEL ? "Softstraps" : "BIOS");
908 msg_pdbg2("Deep SX is %ssupported on the platform.\n",
909 s->cougar.Deep_SX_EN ? "not " : "");
910 msg_pdbg2("ME Debug LAN Emergency Mode is %sabled.\n",
911 s->cougar.ME_DBG_LAN ? "en" : "dis");
912
913 prettyprint_ich_descriptor_pchstraps111213_56(s);
914
915 /* PCHSTRP14 */
916 /* PCHSTRP15 */
917 msg_pdbg2("Chipset configuration Softstrap 6: %d\n", s->cougar.cs_ss6);
918 msg_pdbg2("Integrated wired LAN is %sabled.\n",
919 s->cougar.IWL_EN ? "en" : "dis");
920 msg_pdbg2("Chipset configuration Softstrap 5: %d\n", s->cougar.cs_ss5);
921 msg_pdbg2("SMLink1 provides temperature from %s.\n",
922 s->cougar.SMLINK1_THERM_SEL ? "PCH only" : "the CPU, PCH and DIMMs");
923 msg_pdbg2("GPIO29 is used as %s.\n", s->cougar.SLP_LAN_GP29_SEL ?
924 "general purpose output" : "SLP_LAN#");
925
926 /* PCHSTRP16 */
927 /* PCHSTRP17 */
928 msg_pdbg2("Integrated Clock: %s Clock Mode\n",
929 s->cougar.ICML ? "Buffered Through" : "Full Integrated");
930 msg_pdbg2("\n");
931 }
932
prettyprint_ich_descriptor_straps(enum ich_chipset cs,const struct ich_descriptors * desc)933 void prettyprint_ich_descriptor_straps(enum ich_chipset cs, const struct ich_descriptors *desc)
934 {
935 unsigned int i, max_count;
936 msg_pdbg2("=== Softstraps ===\n");
937
938 max_count = MIN(ARRAY_SIZE(desc->north.STRPs), desc->content.MSL);
939 if (max_count < desc->content.MSL) {
940 msg_pdbg2("MSL (%u) is greater than the current maximum of %u entries.\n",
941 desc->content.MSL, max_count);
942 msg_pdbg2("Only the first %u entries will be printed.\n", max_count);
943 }
944
945 msg_pdbg2("--- North/MCH/PROC (%d entries) ---\n", max_count);
946 for (i = 0; i < max_count; i++)
947 msg_pdbg2("STRP%-2d = 0x%08"PRIx32"\n", i, desc->north.STRPs[i]);
948 msg_pdbg2("\n");
949
950 max_count = MIN(ARRAY_SIZE(desc->south.STRPs), desc->content.ISL);
951 if (max_count < desc->content.ISL) {
952 msg_pdbg2("ISL (%u) is greater than the current maximum of %u entries.\n",
953 desc->content.ISL, max_count);
954 msg_pdbg2("Only the first %u entries will be printed.\n", max_count);
955 }
956
957 msg_pdbg2("--- South/ICH/PCH (%d entries) ---\n", max_count);
958 for (i = 0; i < max_count; i++)
959 msg_pdbg2("STRP%-2d = 0x%08"PRIx32"\n", i, desc->south.STRPs[i]);
960 msg_pdbg2("\n");
961
962 switch (cs) {
963 case CHIPSET_ICH8:
964 if (sizeof(desc->north.ich8) / 4 != desc->content.MSL)
965 msg_pdbg2("Detailed North/MCH/PROC information is "
966 "probably not reliable, printing anyway.\n");
967 if (sizeof(desc->south.ich8) / 4 != desc->content.ISL)
968 msg_pdbg2("Detailed South/ICH/PCH information is "
969 "probably not reliable, printing anyway.\n");
970 prettyprint_ich_descriptor_straps_ich8(desc);
971 break;
972 case CHIPSET_5_SERIES_IBEX_PEAK:
973 /* PCH straps only. PROCSTRPs are unknown. */
974 if (sizeof(desc->south.ibex) / 4 != desc->content.ISL)
975 msg_pdbg2("Detailed South/ICH/PCH information is "
976 "probably not reliable, printing anyway.\n");
977 prettyprint_ich_descriptor_straps_ibex(&desc->south);
978 break;
979 case CHIPSET_6_SERIES_COUGAR_POINT:
980 /* PCH straps only. PROCSTRP0 is "reserved". */
981 if (sizeof(desc->south.cougar) / 4 != desc->content.ISL)
982 msg_pdbg2("Detailed South/ICH/PCH information is "
983 "probably not reliable, printing anyway.\n");
984 prettyprint_ich_descriptor_straps_cougar(&desc->south);
985 break;
986 case CHIPSET_ICH_UNKNOWN:
987 break;
988 default:
989 msg_pdbg2("The meaning of the descriptor straps are unknown yet.\n\n");
990 break;
991 }
992 }
993
prettyprint_rdid(uint32_t reg_val)994 static void prettyprint_rdid(uint32_t reg_val)
995 {
996 uint8_t mid = reg_val & 0xFF;
997 uint16_t did = ((reg_val >> 16) & 0xFF) | (reg_val & 0xFF00);
998 msg_pdbg2("Manufacturer ID 0x%02x, Device ID 0x%04x\n", mid, did);
999 }
1000
prettyprint_ich_descriptor_upper_map(const struct ich_desc_upper_map * umap)1001 void prettyprint_ich_descriptor_upper_map(const struct ich_desc_upper_map *umap)
1002 {
1003 int i;
1004 msg_pdbg2("=== Upper Map Section ===\n");
1005 msg_pdbg2("FLUMAP1 0x%08"PRIx32"\n", umap->FLUMAP1);
1006 msg_pdbg2("\n");
1007
1008 msg_pdbg2("--- Details ---\n");
1009 msg_pdbg2("VTL (length in DWORDS) = %d\n", umap->VTL);
1010 msg_pdbg2("VTBA (base address) = 0x%6.6"PRIx32"\n", getVTBA(umap));
1011 msg_pdbg2("\n");
1012
1013 msg_pdbg2("VSCC Table: %d entries\n", umap->VTL/2);
1014 for (i = 0; i < umap->VTL/2; i++) {
1015 uint32_t jid = umap->vscc_table[i].JID;
1016 uint32_t vscc = umap->vscc_table[i].VSCC;
1017 msg_pdbg2(" JID%d = 0x%08"PRIx32"\n", i, jid);
1018 msg_pdbg2(" VSCC%d = 0x%08"PRIx32"\n", i, vscc);
1019 msg_pdbg2(" "); /* indentation */
1020 prettyprint_rdid(jid);
1021 msg_pdbg2(" "); /* indentation */
1022 prettyprint_ich_reg_vscc(vscc, 0, false);
1023 }
1024 msg_pdbg2("\n");
1025 }
1026
warn_peculiar_desc(const char * const name)1027 static inline void warn_peculiar_desc(const char *const name)
1028 {
1029 msg_pwarn("Peculiar flash descriptor, assuming %s compatibility.\n", name);
1030 }
1031
1032 /*
1033 * Guesses a minimum chipset version based on the maximum number of
1034 * soft straps per generation and presence of the MIP base (MDTBA).
1035 */
guess_ich_chipset_from_content(const struct ich_desc_content * const content,const struct ich_desc_upper_map * const upper)1036 static enum ich_chipset guess_ich_chipset_from_content(const struct ich_desc_content *const content,
1037 const struct ich_desc_upper_map *const upper)
1038 {
1039 if (content->ICCRIBA == 0x00) {
1040 if (content->MSL == 0 && content->ISL <= 2)
1041 return CHIPSET_ICH8;
1042 if (content->ISL <= 2)
1043 return CHIPSET_ICH9;
1044 if (content->ISL <= 10)
1045 return CHIPSET_ICH10;
1046 if (content->ISL <= 16)
1047 return CHIPSET_5_SERIES_IBEX_PEAK;
1048 if (content->FLMAP2 == 0) {
1049 if (content->ISL == 19)
1050 return CHIPSET_APOLLO_LAKE;
1051 if (content->ISL == 23)
1052 return CHIPSET_GEMINI_LAKE;
1053 warn_peculiar_desc("Gemini Lake");
1054 return CHIPSET_GEMINI_LAKE;
1055 }
1056 if (content->ISL == 0x50)
1057 return CHIPSET_C740_SERIES_EMMITSBURG;
1058 warn_peculiar_desc("Ibex Peak");
1059 return CHIPSET_5_SERIES_IBEX_PEAK;
1060 } else if (upper->MDTBA == 0x00) {
1061 if (content->ICCRIBA < 0x31 && content->FMSBA < 0x30) {
1062 if (content->MSL == 0 && content->ISL <= 17)
1063 return CHIPSET_BAYTRAIL;
1064 if (content->MSL <= 1 && content->ISL <= 18)
1065 return CHIPSET_6_SERIES_COUGAR_POINT;
1066 if (content->MSL <= 1 && content->ISL <= 21)
1067 return CHIPSET_8_SERIES_LYNX_POINT;
1068 warn_peculiar_desc("Lynx Point");
1069 return CHIPSET_8_SERIES_LYNX_POINT;
1070 }
1071 if (content->NM == 6) {
1072 if (content->ICCRIBA <= 0x34)
1073 return CHIPSET_C620_SERIES_LEWISBURG;
1074 warn_peculiar_desc("C620 series");
1075 return CHIPSET_C620_SERIES_LEWISBURG;
1076 }
1077 if (content->ICCRIBA == 0x31)
1078 return CHIPSET_100_SERIES_SUNRISE_POINT;
1079 warn_peculiar_desc("100 series");
1080 return CHIPSET_100_SERIES_SUNRISE_POINT;
1081 } else {
1082 if (content->ICCRIBA == 0x34)
1083 return CHIPSET_300_SERIES_CANNON_POINT;
1084 if (content->CSSL == 0x11) {
1085 if (content->CSSO == 0x68)
1086 return CHIPSET_500_SERIES_TIGER_POINT;
1087 else if (content->CSSO == 0x5c)
1088 return CHIPSET_600_SERIES_ALDER_POINT;
1089 }
1090 if (content->CSSL == 0x14)
1091 return CHIPSET_600_SERIES_ALDER_POINT;
1092 if (content->CSSL == 0x03) {
1093 if (content->CSSO == 0x58)
1094 return CHIPSET_ELKHART_LAKE;
1095 else if (content->CSSO == 0x6c)
1096 return CHIPSET_JASPER_LAKE;
1097 else if (content->CSSO == 0x70)
1098 return CHIPSET_METEOR_LAKE;
1099 else if (content->CSSO == 0x60)
1100 return CHIPSET_PANTHER_LAKE;
1101 }
1102 msg_pwarn("Unknown flash descriptor, assuming 500 series compatibility.\n");
1103 return CHIPSET_500_SERIES_TIGER_POINT;
1104 }
1105 }
1106
1107 /*
1108 * As an additional measure, we check the read frequency like `ifdtool`.
1109 * The frequency value 6 (17MHz) was reserved before Skylake and is the
1110 * only valid value since. Skylake is currently the most important dis-
1111 * tinction because of the dropped number of regions field (NR).
1112 */
guess_ich_chipset(const struct ich_desc_content * const content,const struct ich_desc_component * const component,const struct ich_desc_upper_map * const upper)1113 static enum ich_chipset guess_ich_chipset(const struct ich_desc_content *const content,
1114 const struct ich_desc_component *const component,
1115 const struct ich_desc_upper_map *const upper)
1116 {
1117 const enum ich_chipset guess = guess_ich_chipset_from_content(content, upper);
1118
1119 switch (guess) {
1120 case CHIPSET_300_SERIES_CANNON_POINT:
1121 case CHIPSET_400_SERIES_COMET_POINT:
1122 case CHIPSET_500_SERIES_TIGER_POINT:
1123 case CHIPSET_600_SERIES_ALDER_POINT:
1124 case CHIPSET_700_SERIES_RAPTOR_POINT:
1125 case CHIPSET_METEOR_LAKE:
1126 case CHIPSET_PANTHER_LAKE:
1127 case CHIPSET_GEMINI_LAKE:
1128 case CHIPSET_JASPER_LAKE:
1129 case CHIPSET_ELKHART_LAKE:
1130 /* `freq_read` was repurposed, so can't check on it any more. */
1131 break;
1132 case CHIPSET_100_SERIES_SUNRISE_POINT:
1133 case CHIPSET_C620_SERIES_LEWISBURG:
1134 case CHIPSET_C740_SERIES_EMMITSBURG:
1135 case CHIPSET_APOLLO_LAKE:
1136 if (component->modes.freq_read != 6) {
1137 msg_pwarn("\nThe flash descriptor looks like a Skylake/Sunrise Point descriptor.\n"
1138 "However, the read frequency isn't set to 17MHz (the only valid value).\n"
1139 "Please report this message, the output of `ich_descriptors_tool` for\n"
1140 "your descriptor and the output of `lspci -nn` to [email protected]\n\n");
1141 }
1142 break;
1143 default:
1144 if (component->modes.freq_read == 6) {
1145 msg_pwarn("\nThe flash descriptor has the read frequency set to 17MHz. However,\n"
1146 "it doesn't look like a Skylake/Sunrise Point compatible descriptor.\n"
1147 "Please report this message, the output of `ich_descriptors_tool` for\n"
1148 "your descriptor and the output of `lspci -nn` to [email protected]\n\n");
1149 }
1150 }
1151 return guess;
1152 }
1153
1154 /* len is the length of dump in bytes */
read_ich_descriptors_from_dump(const uint32_t * const dump,const size_t len,enum ich_chipset * const cs,struct ich_descriptors * const desc)1155 int read_ich_descriptors_from_dump(const uint32_t *const dump, const size_t len,
1156 enum ich_chipset *const cs, struct ich_descriptors *const desc)
1157 {
1158 ssize_t i, max_count;
1159 size_t pch_bug_offset = 0;
1160
1161 if (dump == NULL || desc == NULL)
1162 return ICH_RET_PARAM;
1163
1164 if (dump[0] != DESCRIPTOR_MODE_SIGNATURE) {
1165 if (dump[4] == DESCRIPTOR_MODE_SIGNATURE)
1166 pch_bug_offset = 4;
1167 else
1168 return ICH_RET_ERR;
1169 }
1170
1171 /* map */
1172 if (len < (4 + pch_bug_offset) * 4)
1173 return ICH_RET_OOB;
1174 desc->content.FLVALSIG = dump[0 + pch_bug_offset];
1175 desc->content.FLMAP0 = dump[1 + pch_bug_offset];
1176 desc->content.FLMAP1 = dump[2 + pch_bug_offset];
1177 desc->content.FLMAP2 = dump[3 + pch_bug_offset];
1178
1179 /* component */
1180 if (len < getFCBA(&desc->content) + 3 * 4)
1181 return ICH_RET_OOB;
1182 desc->component.FLCOMP = dump[(getFCBA(&desc->content) >> 2) + 0];
1183 desc->component.FLILL = dump[(getFCBA(&desc->content) >> 2) + 1];
1184 desc->component.FLPB = dump[(getFCBA(&desc->content) >> 2) + 2];
1185
1186 /* upper map */
1187 desc->upper.FLUMAP1 = dump[(UPPER_MAP_OFFSET >> 2) + 0];
1188
1189 /* VTL is 8 bits long. Quote from the Ibex Peak SPI programming guide:
1190 * "Identifies the 1s based number of DWORDS contained in the VSCC
1191 * Table. Each SPI component entry in the table is 2 DWORDS long." So
1192 * the maximum of 255 gives us 127.5 SPI components(!?) 8 bytes each. A
1193 * check ensures that the maximum offset actually accessed is available.
1194 */
1195 if (len < getVTBA(&desc->upper) + (desc->upper.VTL / 2 * 8))
1196 return ICH_RET_OOB;
1197
1198 for (i = 0; i < desc->upper.VTL/2; i++) {
1199 desc->upper.vscc_table[i].JID = dump[(getVTBA(&desc->upper) >> 2) + i * 2 + 0];
1200 desc->upper.vscc_table[i].VSCC = dump[(getVTBA(&desc->upper) >> 2) + i * 2 + 1];
1201 }
1202
1203 if (*cs == CHIPSET_ICH_UNKNOWN) {
1204 *cs = guess_ich_chipset(&desc->content, &desc->component, &desc->upper);
1205 prettyprint_ich_chipset(*cs);
1206 }
1207
1208 /* region */
1209 const ssize_t nr = ich_number_of_regions(*cs, &desc->content);
1210 if (nr < 0 || len < getFRBA(&desc->content) + (size_t)nr * 4)
1211 return ICH_RET_OOB;
1212 for (i = 0; i < nr; i++)
1213 desc->region.FLREGs[i] = dump[(getFRBA(&desc->content) >> 2) + i];
1214
1215 /* master */
1216 const ssize_t nm = ich_number_of_masters(*cs, &desc->content);
1217 if (nm < 0 || len < getFMBA(&desc->content) + (size_t)nm * 4)
1218 return ICH_RET_OOB;
1219 for (i = 0; i < nm; i++)
1220 desc->master.FLMSTRs[i] = dump[(getFMBA(&desc->content) >> 2) + i];
1221
1222 /* MCH/PROC (aka. North) straps */
1223 if (len < getFMSBA(&desc->content) + desc->content.MSL * 4)
1224 return ICH_RET_OOB;
1225
1226 /* limit the range to be written */
1227 max_count = MIN(sizeof(desc->north.STRPs) / 4, desc->content.MSL);
1228 for (i = 0; i < max_count; i++)
1229 desc->north.STRPs[i] = dump[(getFMSBA(&desc->content) >> 2) + i];
1230
1231 /* ICH/PCH (aka. South) straps */
1232 if (len < getFISBA(&desc->content) + desc->content.ISL * 4)
1233 return ICH_RET_OOB;
1234
1235 /* limit the range to be written */
1236 max_count = MIN(sizeof(desc->south.STRPs) / 4, desc->content.ISL);
1237 for (i = 0; i < max_count; i++)
1238 desc->south.STRPs[i] = dump[(getFISBA(&desc->content) >> 2) + i];
1239
1240 return ICH_RET_OK;
1241 }
1242
1243 #ifndef ICH_DESCRIPTORS_FROM_DUMP_ONLY
1244
1245 /** Returns the integer representation of the component density with index
1246 \em idx in bytes or -1 if the correct size can not be determined. */
getFCBA_component_density(enum ich_chipset cs,const struct ich_descriptors * desc,uint8_t idx)1247 int getFCBA_component_density(enum ich_chipset cs, const struct ich_descriptors *desc, uint8_t idx)
1248 {
1249 if (idx > 1) {
1250 msg_perr("Only ICH SPI component index 0 or 1 are supported yet.\n");
1251 return -1;
1252 }
1253
1254 if (desc->content.NC == 0 && idx > 0)
1255 return 0;
1256
1257 uint8_t size_enc;
1258 uint8_t size_max;
1259
1260 switch (cs) {
1261 case CHIPSET_ICH8:
1262 case CHIPSET_ICH9:
1263 case CHIPSET_ICH10:
1264 case CHIPSET_5_SERIES_IBEX_PEAK:
1265 case CHIPSET_6_SERIES_COUGAR_POINT:
1266 case CHIPSET_7_SERIES_PANTHER_POINT:
1267 case CHIPSET_BAYTRAIL:
1268 if (idx == 0) {
1269 size_enc = desc->component.dens_old.comp1_density;
1270 } else {
1271 size_enc = desc->component.dens_old.comp2_density;
1272 }
1273 size_max = 5;
1274 break;
1275 case CHIPSET_8_SERIES_LYNX_POINT:
1276 case CHIPSET_8_SERIES_LYNX_POINT_LP:
1277 case CHIPSET_8_SERIES_WELLSBURG:
1278 case CHIPSET_9_SERIES_WILDCAT_POINT:
1279 case CHIPSET_9_SERIES_WILDCAT_POINT_LP:
1280 case CHIPSET_100_SERIES_SUNRISE_POINT:
1281 case CHIPSET_C620_SERIES_LEWISBURG:
1282 case CHIPSET_C740_SERIES_EMMITSBURG:
1283 case CHIPSET_300_SERIES_CANNON_POINT:
1284 case CHIPSET_400_SERIES_COMET_POINT:
1285 case CHIPSET_500_SERIES_TIGER_POINT:
1286 case CHIPSET_600_SERIES_ALDER_POINT:
1287 case CHIPSET_700_SERIES_RAPTOR_POINT:
1288 case CHIPSET_METEOR_LAKE:
1289 case CHIPSET_PANTHER_LAKE:
1290 case CHIPSET_APOLLO_LAKE:
1291 case CHIPSET_GEMINI_LAKE:
1292 case CHIPSET_JASPER_LAKE:
1293 case CHIPSET_ELKHART_LAKE:
1294 if (idx == 0) {
1295 size_enc = desc->component.dens_new.comp1_density;
1296 } else {
1297 size_enc = desc->component.dens_new.comp2_density;
1298 }
1299 size_max = 7;
1300 break;
1301 case CHIPSET_ICH_UNKNOWN:
1302 default:
1303 msg_pwarn("Density encoding is unknown on this chipset.\n");
1304 return -1;
1305 }
1306
1307 if (size_enc > size_max) {
1308 msg_perr("Density of ICH SPI component with index %d is invalid.\n"
1309 "Encoded density is 0x%x while maximum allowed is 0x%x.\n",
1310 idx, size_enc, size_max);
1311 return -1;
1312 }
1313
1314 return (1 << (19 + size_enc));
1315 }
1316
1317 /* Only used by ichspi.c */
1318 #if CONFIG_INTERNAL == 1 && (defined(__i386__) || defined(__x86_64__))
read_descriptor_reg(enum ich_chipset cs,uint8_t section,uint16_t offset,void * spibar)1319 static uint32_t read_descriptor_reg(enum ich_chipset cs, uint8_t section, uint16_t offset, void *spibar)
1320 {
1321 uint32_t control = 0;
1322 uint32_t woffset, roffset;
1323
1324 control |= (section << FDOC_FDSS_OFF) & FDOC_FDSS;
1325 control |= (offset << FDOC_FDSI_OFF) & FDOC_FDSI;
1326
1327 switch (cs) {
1328 case CHIPSET_100_SERIES_SUNRISE_POINT:
1329 case CHIPSET_C620_SERIES_LEWISBURG:
1330 case CHIPSET_C740_SERIES_EMMITSBURG:
1331 case CHIPSET_300_SERIES_CANNON_POINT:
1332 case CHIPSET_400_SERIES_COMET_POINT:
1333 case CHIPSET_500_SERIES_TIGER_POINT:
1334 case CHIPSET_600_SERIES_ALDER_POINT:
1335 case CHIPSET_700_SERIES_RAPTOR_POINT:
1336 case CHIPSET_METEOR_LAKE:
1337 case CHIPSET_PANTHER_LAKE:
1338 case CHIPSET_APOLLO_LAKE:
1339 case CHIPSET_GEMINI_LAKE:
1340 case CHIPSET_JASPER_LAKE:
1341 case CHIPSET_ELKHART_LAKE:
1342 woffset = PCH100_REG_FDOC;
1343 roffset = PCH100_REG_FDOD;
1344 break;
1345 default:
1346 woffset = ICH9_REG_FDOC;
1347 roffset = ICH9_REG_FDOD;
1348 }
1349
1350 mmio_le_writel(control, spibar + woffset);
1351 return mmio_le_readl(spibar + roffset);
1352 }
1353
read_ich_descriptors_via_fdo(enum ich_chipset cs,void * spibar,struct ich_descriptors * desc)1354 int read_ich_descriptors_via_fdo(enum ich_chipset cs, void *spibar, struct ich_descriptors *desc)
1355 {
1356 ssize_t i;
1357 struct ich_desc_region *r = &desc->region;
1358
1359 /* Test if bit-fields are working as expected.
1360 * FIXME: Replace this with dynamic bitfield fixup
1361 */
1362 for (i = 0; i < 4; i++)
1363 desc->region.FLREGs[i] = 0x5A << (i * 8);
1364 if (r->old_reg[0].base != 0x005A || r->old_reg[0].limit != 0x0000 ||
1365 r->old_reg[1].base != 0x1A00 || r->old_reg[1].limit != 0x0000 ||
1366 r->old_reg[2].base != 0x0000 || r->old_reg[2].limit != 0x005A ||
1367 r->old_reg[3].base != 0x0000 || r->old_reg[3].limit != 0x1A00) {
1368 msg_pdbg("The combination of compiler and CPU architecture used"
1369 "does not lay out bit-fields as expected, sorry.\n");
1370 msg_pspew("r->old_reg[0].base = 0x%04X (0x005A)\n", r->old_reg[0].base);
1371 msg_pspew("r->old_reg[0].limit = 0x%04X (0x0000)\n", r->old_reg[0].limit);
1372 msg_pspew("r->old_reg[1].base = 0x%04X (0x1A00)\n", r->old_reg[1].base);
1373 msg_pspew("r->old_reg[1].limit = 0x%04X (0x0000)\n", r->old_reg[1].limit);
1374 msg_pspew("r->old_reg[2].base = 0x%04X (0x0000)\n", r->old_reg[2].base);
1375 msg_pspew("r->old_reg[2].limit = 0x%04X (0x005A)\n", r->old_reg[2].limit);
1376 msg_pspew("r->old_reg[3].base = 0x%04X (0x0000)\n", r->old_reg[3].base);
1377 msg_pspew("r->old_reg[3].limit = 0x%04X (0x1A00)\n", r->old_reg[3].limit);
1378 return ICH_RET_ERR;
1379 }
1380
1381 msg_pdbg2("Reading flash descriptors mapped by the chipset via FDOC/FDOD...");
1382 /* content section */
1383 desc->content.FLVALSIG = read_descriptor_reg(cs, 0, 0, spibar);
1384 desc->content.FLMAP0 = read_descriptor_reg(cs, 0, 1, spibar);
1385 desc->content.FLMAP1 = read_descriptor_reg(cs, 0, 2, spibar);
1386 desc->content.FLMAP2 = read_descriptor_reg(cs, 0, 3, spibar);
1387
1388 /* component section */
1389 desc->component.FLCOMP = read_descriptor_reg(cs, 1, 0, spibar);
1390 desc->component.FLILL = read_descriptor_reg(cs, 1, 1, spibar);
1391 desc->component.FLPB = read_descriptor_reg(cs, 1, 2, spibar);
1392
1393 /* region section */
1394 const ssize_t nr = ich_number_of_regions(cs, &desc->content);
1395 if (nr < 0) {
1396 msg_pdbg2("%s: number of regions too high (%d) - failed\n",
1397 __func__, desc->content.NR + 1);
1398 return ICH_RET_ERR;
1399 }
1400 for (i = 0; i < nr; i++)
1401 desc->region.FLREGs[i] = read_descriptor_reg(cs, 2, i, spibar);
1402
1403 /* master section */
1404 const ssize_t nm = ich_number_of_masters(cs, &desc->content);
1405 if (nm < 0) {
1406 msg_pdbg2("%s: number of masters too high (%d) - failed\n",
1407 __func__, desc->content.NM + 1);
1408 return ICH_RET_ERR;
1409 }
1410 for (i = 0; i < nm; i++)
1411 desc->master.FLMSTRs[i] = read_descriptor_reg(cs, 3, i, spibar);
1412
1413 /* Accessing the strap section via FDOC/D is only possible on ICH8 and
1414 * reading the upper map is impossible on all chipsets, so don't bother.
1415 */
1416
1417 msg_pdbg2(" done.\n");
1418 return ICH_RET_OK;
1419 }
1420 #endif
1421
1422 /**
1423 * @brief Read a layout from the dump of an Intel ICH descriptor.
1424 *
1425 * @param layout Pointer where to store the layout.
1426 * @param dump The descriptor dump to read from.
1427 * @param len The length of the descriptor dump.
1428 *
1429 * @return 0 on success,
1430 * 1 if the descriptor couldn't be parsed,
1431 * 2 when out of memory.
1432 */
layout_from_ich_descriptors(struct flashrom_layout ** const layout,const void * const dump,const size_t len)1433 int layout_from_ich_descriptors(
1434 struct flashrom_layout **const layout,
1435 const void *const dump, const size_t len)
1436 {
1437 static const char *const regions[] = {
1438 "fd", "bios", "me", "gbe", "pd", "reg5", "bios2", "reg7", "ec", "reg9", "ie",
1439 "10gbe", "reg12", "reg13", "reg14", "reg15"
1440 };
1441
1442 struct ich_descriptors desc;
1443 enum ich_chipset cs = CHIPSET_ICH_UNKNOWN;
1444 int ret = read_ich_descriptors_from_dump(dump, len, &cs, &desc);
1445 if (ret) {
1446 msg_pdbg("%s():%d, returned with value %d.\n",
1447 __func__, __LINE__, ret);
1448 return 1;
1449 }
1450
1451 if (flashrom_layout_new(layout))
1452 return 2;
1453
1454 ssize_t i;
1455 const ssize_t nr = MIN(ich_number_of_regions(cs, &desc.content), (ssize_t)ARRAY_SIZE(regions));
1456 for (i = 0; i < nr; ++i) {
1457 const chipoff_t base = ICH_FREG_BASE(desc.region.FLREGs[i]);
1458 const chipoff_t limit = ICH_FREG_LIMIT(desc.region.FLREGs[i]);
1459 if (limit <= base)
1460 continue;
1461 if (flashrom_layout_add_region(*layout, base, limit, regions[i])) {
1462 flashrom_layout_release(*layout);
1463 *layout = NULL;
1464 return 2;
1465 }
1466 }
1467 return 0;
1468 }
1469
1470 #endif /* ICH_DESCRIPTORS_FROM_DUMP_ONLY */
1471