blob: 3f2930687f0baf4e6134f45ed70f79865bdedbbc [file] [log] [blame]
David Hendricksce6b2fa2011-07-11 22:12:43 -07001/*
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.
David Hendricksce6b2fa2011-07-11 22:12:43 -070016 */
17
stefanct1fc3a732011-09-15 23:52:55 +000018#include "ich_descriptors.h"
Stefan Tauner34f6f5a2016-08-03 11:20:38 -070019
Edward O'Callaghanb76b4e62020-07-26 13:03:12 +100020#ifdef ICH_DESCRIPTORS_FROM_DUMP_ONLY
Stefan Tauner34f6f5a2016-08-03 11:20:38 -070021#include <stdio.h>
Edward O'Callaghan568cd262020-05-26 23:10:45 +100022#include <string.h>
Stefan Tauner34f6f5a2016-08-03 11:20:38 -070023#define print(t, ...) printf(__VA_ARGS__)
Edward O'Callaghanb76b4e62020-07-26 13:03:12 +100024#endif
25
Stefan Tauner34f6f5a2016-08-03 11:20:38 -070026#define DESCRIPTOR_MODE_SIGNATURE 0x0ff0a55a
27/* The upper map is located in the word before the 256B-long OEM section at the
28 * end of the 4kB-long flash descriptor.
29 */
30#define UPPER_MAP_OFFSET (4096 - 256 - 4)
31#define getVTBA(flumap) (((flumap)->FLUMAP1 << 4) & 0x00000ff0)
32
Edward O'Callaghan01e8d322020-07-09 18:26:43 +100033#include <sys/types.h>
34#include <string.h>
David Hendricksce6b2fa2011-07-11 22:12:43 -070035#include "flash.h" /* for msg_* */
stefanct1fc3a732011-09-15 23:52:55 +000036#include "programmer.h"
David Hendricksce6b2fa2011-07-11 22:12:43 -070037
Edward O'Callaghane7efd052020-07-03 14:57:28 +100038ssize_t ich_number_of_regions(const enum ich_chipset cs, const struct ich_desc_content *const cont)
39{
40 switch (cs) {
41 case CHIPSET_APOLLO_LAKE:
42 return 6;
43 case CHIPSET_C620_SERIES_LEWISBURG:
44 case CHIPSET_300_SERIES_CANNON_POINT:
Matt DeVillier81bc4d32020-08-12 12:48:06 -050045 case CHIPSET_400_SERIES_COMET_POINT:
Edward O'Callaghane7efd052020-07-03 14:57:28 +100046 return 16;
47 case CHIPSET_100_SERIES_SUNRISE_POINT:
48 return 10;
49 case CHIPSET_9_SERIES_WILDCAT_POINT_LP:
50 case CHIPSET_9_SERIES_WILDCAT_POINT:
51 case CHIPSET_8_SERIES_LYNX_POINT_LP:
52 case CHIPSET_8_SERIES_LYNX_POINT:
53 case CHIPSET_8_SERIES_WELLSBURG:
54 if (cont->NR <= 6)
55 return cont->NR + 1;
56 else
57 return -1;
58 default:
59 if (cont->NR <= 4)
60 return cont->NR + 1;
61 else
62 return -1;
63 }
64}
Stefan Tauner34f6f5a2016-08-03 11:20:38 -070065
Edward O'Callaghanaef44cb2020-07-03 15:31:14 +100066ssize_t ich_number_of_masters(const enum ich_chipset cs, const struct ich_desc_content *const cont)
67{
68 switch (cs) {
69 case CHIPSET_C620_SERIES_LEWISBURG:
70 case CHIPSET_APOLLO_LAKE:
71 if (cont->NM <= MAX_NUM_MASTERS)
72 return cont->NM;
73 break;
74 default:
75 if (cont->NM < MAX_NUM_MASTERS)
76 return cont->NM + 1;
77 }
78
79 return -1;
80}
Stefan Tauner34f6f5a2016-08-03 11:20:38 -070081
Edward O'Callaghand757b422020-05-26 21:22:12 +100082void prettyprint_ich_reg_vscc(uint32_t reg_val, int verbosity, bool print_vcl)
David Hendricksce6b2fa2011-07-11 22:12:43 -070083{
stefanct1fc3a732011-09-15 23:52:55 +000084 print(verbosity, "BES=0x%x, ", (reg_val & VSCC_BES) >> VSCC_BES_OFF);
85 print(verbosity, "WG=%d, ", (reg_val & VSCC_WG) >> VSCC_WG_OFF);
86 print(verbosity, "WSR=%d, ", (reg_val & VSCC_WSR) >> VSCC_WSR_OFF);
87 print(verbosity, "WEWS=%d, ", (reg_val & VSCC_WEWS) >> VSCC_WEWS_OFF);
Edward O'Callaghand757b422020-05-26 21:22:12 +100088 print(verbosity, "EO=0x%x", (reg_val & VSCC_EO) >> VSCC_EO_OFF);
89 if (print_vcl)
90 print(verbosity, ", VCL=%d", (reg_val & VSCC_VCL) >> VSCC_VCL_OFF);
91 print(verbosity, "\n");
David Hendricksce6b2fa2011-07-11 22:12:43 -070092}
93
stefanct1fc3a732011-09-15 23:52:55 +000094#define getFCBA(cont) (((cont)->FLMAP0 << 4) & 0x00000ff0)
95#define getFRBA(cont) (((cont)->FLMAP0 >> 12) & 0x00000ff0)
96#define getFMBA(cont) (((cont)->FLMAP1 << 4) & 0x00000ff0)
97#define getFISBA(cont) (((cont)->FLMAP1 >> 12) & 0x00000ff0)
98#define getFMSBA(cont) (((cont)->FLMAP2 << 4) & 0x00000ff0)
99
Edward O'Callaghan01e8d322020-07-09 18:26:43 +1000100void prettyprint_ich_chipset(enum ich_chipset cs)
101{
102 static const char *const chipset_names[] = {
103 "Unknown ICH", "ICH8", "ICH9", "ICH10",
104 "5 series Ibex Peak", "6 series Cougar Point", "7 series Panther Point",
105 "8 series Lynx Point", "Baytrail", "8 series Lynx Point LP", "8 series Wellsburg",
106 "9 series Wildcat Point", "9 series Wildcat Point LP", "100 series Sunrise Point",
107 "C620 series Lewisburg", "300 series Cannon Point", "Apollo Lake",
108 };
109 if (cs < CHIPSET_ICH8 || cs - CHIPSET_ICH8 + 1 >= ARRAY_SIZE(chipset_names))
110 cs = 0;
111 else
112 cs = cs - CHIPSET_ICH8 + 1;
113 msg_pdbg2("Assuming chipset '%s'.\n", chipset_names[cs]);
114}
115
stefanct1fc3a732011-09-15 23:52:55 +0000116void prettyprint_ich_descriptors(enum ich_chipset cs, const struct ich_descriptors *desc)
David Hendricksce6b2fa2011-07-11 22:12:43 -0700117{
Edward O'Callaghane7efd052020-07-03 14:57:28 +1000118 prettyprint_ich_descriptor_content(cs, &desc->content);
Edward O'Callaghan87595e12020-07-03 13:09:18 +1000119 prettyprint_ich_descriptor_component(cs, desc);
Edward O'Callaghane7efd052020-07-03 14:57:28 +1000120 prettyprint_ich_descriptor_region(cs, desc);
Edward O'Callaghanaef44cb2020-07-03 15:31:14 +1000121 prettyprint_ich_descriptor_master(cs, desc);
Edward O'Callaghanb76b4e62020-07-26 13:03:12 +1000122#ifdef ICH_DESCRIPTORS_FROM_DUMP_ONLY
Stefan Tauner34f6f5a2016-08-03 11:20:38 -0700123 if (cs >= CHIPSET_ICH8) {
124 prettyprint_ich_descriptor_upper_map(&desc->upper);
125 prettyprint_ich_descriptor_straps(cs, desc);
126 }
Edward O'Callaghanb76b4e62020-07-26 13:03:12 +1000127#endif /* ICH_DESCRIPTORS_FROM_DUMP_ONLY */
David Hendricksce6b2fa2011-07-11 22:12:43 -0700128}
129
Edward O'Callaghane7efd052020-07-03 14:57:28 +1000130void prettyprint_ich_descriptor_content(enum ich_chipset cs, const struct ich_desc_content *cont)
David Hendricksce6b2fa2011-07-11 22:12:43 -0700131{
stefanct1fc3a732011-09-15 23:52:55 +0000132 msg_pdbg2("=== Content Section ===\n");
133 msg_pdbg2("FLVALSIG 0x%08x\n", cont->FLVALSIG);
134 msg_pdbg2("FLMAP0 0x%08x\n", cont->FLMAP0);
135 msg_pdbg2("FLMAP1 0x%08x\n", cont->FLMAP1);
136 msg_pdbg2("FLMAP2 0x%08x\n", cont->FLMAP2);
137 msg_pdbg2("\n");
138
139 msg_pdbg2("--- Details ---\n");
Edward O'Callaghane7efd052020-07-03 14:57:28 +1000140 msg_pdbg2("NR (Number of Regions): %5zd\n", ich_number_of_regions(cs, cont));
Edward O'Callaghan86bd8da2020-07-09 18:17:42 +1000141 msg_pdbg2("FRBA (Flash Region Base Address): 0x%03x\n", getFRBA(cont));
142 msg_pdbg2("NC (Number of Components): %5d\n", cont->NC + 1);
143 msg_pdbg2("FCBA (Flash Component Base Address): 0x%03x\n", getFCBA(cont));
144 msg_pdbg2("ISL (ICH/PCH/SoC Strap Length): %5d\n", cont->ISL);
145 msg_pdbg2("FISBA/FPSBA (Flash ICH/PCH/SoC Strap Base Addr): 0x%03x\n", getFISBA(cont));
Edward O'Callaghanaef44cb2020-07-03 15:31:14 +1000146 msg_pdbg2("NM (Number of Masters): %5zd\n", ich_number_of_masters(cs, cont));
Edward O'Callaghan86bd8da2020-07-09 18:17:42 +1000147 msg_pdbg2("FMBA (Flash Master Base Address): 0x%03x\n", getFMBA(cont));
148 msg_pdbg2("MSL/PSL (MCH/PROC Strap Length): %5d\n", cont->MSL);
149 msg_pdbg2("FMSBA (Flash MCH/PROC Strap Base Address): 0x%03x\n", getFMSBA(cont));
stefanct1fc3a732011-09-15 23:52:55 +0000150 msg_pdbg2("\n");
David Hendricksce6b2fa2011-07-11 22:12:43 -0700151}
152
Edward O'Callaghan87595e12020-07-03 13:09:18 +1000153static const char *pprint_density(enum ich_chipset cs, const struct ich_descriptors *desc, uint8_t idx)
David Hendricksce6b2fa2011-07-11 22:12:43 -0700154{
Edward O'Callaghan87595e12020-07-03 13:09:18 +1000155 if (idx > 1) {
156 msg_perr("Only ICH SPI component index 0 or 1 are supported yet.\n");
157 return NULL;
158 }
159
160 if (desc->content.NC == 0 && idx > 0)
161 return "unused";
162
163 static const char * const size_str[] = {
164 "512 kB", /* 0000 */
165 "1 MB", /* 0001 */
166 "2 MB", /* 0010 */
167 "4 MB", /* 0011 */
168 "8 MB", /* 0100 */
169 "16 MB", /* 0101 */ /* Maximum up to Lynx Point (excl.) */
170 "32 MB", /* 0110 */
171 "64 MB", /* 0111 */
David Hendricksce6b2fa2011-07-11 22:12:43 -0700172 };
173
Edward O'Callaghan87595e12020-07-03 13:09:18 +1000174 switch (cs) {
175 case CHIPSET_ICH8:
176 case CHIPSET_ICH9:
177 case CHIPSET_ICH10:
178 case CHIPSET_5_SERIES_IBEX_PEAK:
179 case CHIPSET_6_SERIES_COUGAR_POINT:
180 case CHIPSET_7_SERIES_PANTHER_POINT:
181 case CHIPSET_BAYTRAIL: {
182 uint8_t size_enc;
183 if (idx == 0) {
184 size_enc = desc->component.dens_old.comp1_density;
185 } else {
186 size_enc = desc->component.dens_old.comp2_density;
187 }
188 if (size_enc > 5)
189 return "reserved";
190 return size_str[size_enc];
191 }
192 case CHIPSET_8_SERIES_LYNX_POINT:
193 case CHIPSET_8_SERIES_LYNX_POINT_LP:
194 case CHIPSET_8_SERIES_WELLSBURG:
195 case CHIPSET_9_SERIES_WILDCAT_POINT:
196 case CHIPSET_9_SERIES_WILDCAT_POINT_LP:
197 case CHIPSET_100_SERIES_SUNRISE_POINT:
198 case CHIPSET_C620_SERIES_LEWISBURG:
199 case CHIPSET_300_SERIES_CANNON_POINT:
Matt DeVillier81bc4d32020-08-12 12:48:06 -0500200 case CHIPSET_400_SERIES_COMET_POINT:
Edward O'Callaghan87595e12020-07-03 13:09:18 +1000201 case CHIPSET_APOLLO_LAKE: {
202 uint8_t size_enc;
203 if (idx == 0) {
204 size_enc = desc->component.dens_new.comp1_density;
205 } else {
206 size_enc = desc->component.dens_new.comp2_density;
207 }
208 if (size_enc > 7)
209 return "reserved";
210 return size_str[size_enc];
211 }
212 case CHIPSET_ICH_UNKNOWN:
213 default:
214 return "unknown";
215 }
216}
217
218static const char *pprint_freq(enum ich_chipset cs, uint8_t value)
219{
220 static const char *const freq_str[3][8] = { {
221 "20 MHz",
222 "33 MHz",
223 "reserved",
224 "reserved",
225 "50 MHz", /* New since Ibex Peak */
226 "reserved",
227 "reserved",
228 "reserved"
229 }, {
230 "reserved",
231 "reserved",
232 "48 MHz",
233 "reserved",
234 "30 MHz",
235 "reserved",
236 "17 MHz",
237 "reserved"
238 }, {
239 "reserved",
240 "50 MHz",
241 "40 MHz",
242 "reserved",
243 "25 MHz",
244 "reserved",
245 "14 MHz / 17 MHz",
246 "reserved"
247 } };
248
249 switch (cs) {
250 case CHIPSET_ICH8:
251 case CHIPSET_ICH9:
252 case CHIPSET_ICH10:
253 if (value > 1)
254 return "reserved";
255 /* Fall through. */
256 case CHIPSET_5_SERIES_IBEX_PEAK:
257 case CHIPSET_6_SERIES_COUGAR_POINT:
258 case CHIPSET_7_SERIES_PANTHER_POINT:
259 case CHIPSET_8_SERIES_LYNX_POINT:
260 case CHIPSET_BAYTRAIL:
261 case CHIPSET_8_SERIES_LYNX_POINT_LP:
262 case CHIPSET_8_SERIES_WELLSBURG:
263 case CHIPSET_9_SERIES_WILDCAT_POINT:
264 case CHIPSET_9_SERIES_WILDCAT_POINT_LP:
265 return freq_str[0][value];
266 case CHIPSET_100_SERIES_SUNRISE_POINT:
267 case CHIPSET_C620_SERIES_LEWISBURG:
268 case CHIPSET_300_SERIES_CANNON_POINT:
Matt DeVillier81bc4d32020-08-12 12:48:06 -0500269 case CHIPSET_400_SERIES_COMET_POINT:
Edward O'Callaghan87595e12020-07-03 13:09:18 +1000270 return freq_str[1][value];
271 case CHIPSET_APOLLO_LAKE:
272 return freq_str[2][value];
273 case CHIPSET_ICH_UNKNOWN:
274 default:
275 return "unknown";
276 }
277}
278
279void prettyprint_ich_descriptor_component(enum ich_chipset cs, const struct ich_descriptors *desc)
280{
Edward O'Callaghan224e6ba2020-07-09 18:19:36 +1000281 bool has_flill1;
282
283 switch (cs) {
284 case CHIPSET_100_SERIES_SUNRISE_POINT:
285 case CHIPSET_C620_SERIES_LEWISBURG:
286 case CHIPSET_300_SERIES_CANNON_POINT:
Matt DeVillier81bc4d32020-08-12 12:48:06 -0500287 case CHIPSET_400_SERIES_COMET_POINT:
Edward O'Callaghan224e6ba2020-07-09 18:19:36 +1000288 case CHIPSET_APOLLO_LAKE:
289 has_flill1 = true;
290 break;
291 default:
292 has_flill1 = false;
293 break;
294 }
295
stefanct1fc3a732011-09-15 23:52:55 +0000296 msg_pdbg2("=== Component Section ===\n");
297 msg_pdbg2("FLCOMP 0x%08x\n", desc->component.FLCOMP);
298 msg_pdbg2("FLILL 0x%08x\n", desc->component.FLILL );
Edward O'Callaghan224e6ba2020-07-09 18:19:36 +1000299 if (has_flill1)
300 msg_pdbg2("FLILL1 0x%08x\n", desc->component.FLILL1);
stefanct1fc3a732011-09-15 23:52:55 +0000301 msg_pdbg2("\n");
David Hendricksce6b2fa2011-07-11 22:12:43 -0700302
stefanct1fc3a732011-09-15 23:52:55 +0000303 msg_pdbg2("--- Details ---\n");
Edward O'Callaghan87595e12020-07-03 13:09:18 +1000304 msg_pdbg2("Component 1 density: %s\n", pprint_density(cs, desc, 0));
stefanct1fc3a732011-09-15 23:52:55 +0000305 if (desc->content.NC)
Edward O'Callaghan87595e12020-07-03 13:09:18 +1000306 msg_pdbg2("Component 2 density: %s\n", pprint_density(cs, desc, 1));
David Hendricksce6b2fa2011-07-11 22:12:43 -0700307 else
stefanct1fc3a732011-09-15 23:52:55 +0000308 msg_pdbg2("Component 2 is not used.\n");
Edward O'Callaghan87595e12020-07-03 13:09:18 +1000309 msg_pdbg2("Read Clock Frequency: %s\n", pprint_freq(cs, desc->component.modes.freq_read));
310 msg_pdbg2("Read ID and Status Clock Freq.: %s\n", pprint_freq(cs, desc->component.modes.freq_read_id));
311 msg_pdbg2("Write and Erase Clock Freq.: %s\n", pprint_freq(cs, desc->component.modes.freq_write));
312 msg_pdbg2("Fast Read is %ssupported.\n", desc->component.modes.fastread ? "" : "not ");
313 if (desc->component.modes.fastread)
stefanct1fc3a732011-09-15 23:52:55 +0000314 msg_pdbg2("Fast Read Clock Frequency: %s\n",
Edward O'Callaghan87595e12020-07-03 13:09:18 +1000315 pprint_freq(cs, desc->component.modes.freq_fastread));
316 if (cs > CHIPSET_6_SERIES_COUGAR_POINT)
317 msg_pdbg2("Dual Output Fast Read Support: %sabled\n",
318 desc->component.modes.dual_output ? "dis" : "en");
319
320 int has_forbidden_opcode = 0;
321 if (desc->component.FLILL != 0) {
322 has_forbidden_opcode = 1;
stefanct1fc3a732011-09-15 23:52:55 +0000323 msg_pdbg2("Invalid instruction 0: 0x%02x\n",
324 desc->component.invalid_instr0);
325 msg_pdbg2("Invalid instruction 1: 0x%02x\n",
326 desc->component.invalid_instr1);
327 msg_pdbg2("Invalid instruction 2: 0x%02x\n",
328 desc->component.invalid_instr2);
329 msg_pdbg2("Invalid instruction 3: 0x%02x\n",
330 desc->component.invalid_instr3);
331 }
Edward O'Callaghan224e6ba2020-07-09 18:19:36 +1000332 if (has_flill1) {
333 if (desc->component.FLILL1 != 0) {
334 has_forbidden_opcode = 1;
335 msg_pdbg2("Invalid instruction 4: 0x%02x\n",
336 desc->component.invalid_instr4);
337 msg_pdbg2("Invalid instruction 5: 0x%02x\n",
338 desc->component.invalid_instr5);
339 msg_pdbg2("Invalid instruction 6: 0x%02x\n",
340 desc->component.invalid_instr6);
341 msg_pdbg2("Invalid instruction 7: 0x%02x\n",
342 desc->component.invalid_instr7);
343 }
344 }
Edward O'Callaghan87595e12020-07-03 13:09:18 +1000345 if (!has_forbidden_opcode)
346 msg_pdbg2("No forbidden opcodes.\n");
347
stefanct1fc3a732011-09-15 23:52:55 +0000348 msg_pdbg2("\n");
David Hendricksce6b2fa2011-07-11 22:12:43 -0700349}
350
stefanct1fc3a732011-09-15 23:52:55 +0000351static void pprint_freg(const struct ich_desc_region *reg, uint32_t i)
David Hendricksce6b2fa2011-07-11 22:12:43 -0700352{
Edward O'Callaghan133ef002020-05-26 23:15:56 +1000353 static const char *const region_names[] = {
354 "Descr.", "BIOS", "ME", "GbE", "Platf.", "DevExp", "BIOS2", "unknown",
355 "EC/BMC", "unknown", "IE", "10GbE", "unknown", "unknown", "unknown", "unknown"
David Hendricksce6b2fa2011-07-11 22:12:43 -0700356 };
Edward O'Callaghan133ef002020-05-26 23:15:56 +1000357 if (i >= ARRAY_SIZE(region_names)) {
stefanct1fc3a732011-09-15 23:52:55 +0000358 msg_pdbg2("%s: region index too high.\n", __func__);
359 return;
David Hendricksce6b2fa2011-07-11 22:12:43 -0700360 }
stefanct1fc3a732011-09-15 23:52:55 +0000361 uint32_t base = ICH_FREG_BASE(reg->FLREGs[i]);
362 uint32_t limit = ICH_FREG_LIMIT(reg->FLREGs[i]);
Edward O'Callaghan133ef002020-05-26 23:15:56 +1000363 msg_pdbg2("Region %d (%-7s) ", i, region_names[i]);
stefanct1fc3a732011-09-15 23:52:55 +0000364 if (base > limit)
365 msg_pdbg2("is unused.\n");
366 else
Edward O'Callaghan133ef002020-05-26 23:15:56 +1000367 msg_pdbg2("0x%08x - 0x%08x\n", base, limit);
David Hendricksce6b2fa2011-07-11 22:12:43 -0700368}
369
Edward O'Callaghane7efd052020-07-03 14:57:28 +1000370void prettyprint_ich_descriptor_region(const enum ich_chipset cs, const struct ich_descriptors *const desc)
David Hendricksce6b2fa2011-07-11 22:12:43 -0700371{
Edward O'Callaghande5dd912020-07-26 13:04:18 +1000372 ssize_t i;
Edward O'Callaghane7efd052020-07-03 14:57:28 +1000373 const ssize_t nr = ich_number_of_regions(cs, &desc->content);
stefanct1fc3a732011-09-15 23:52:55 +0000374 msg_pdbg2("=== Region Section ===\n");
Edward O'Callaghane7efd052020-07-03 14:57:28 +1000375 if (nr < 0) {
stefanct1fc3a732011-09-15 23:52:55 +0000376 msg_pdbg2("%s: number of regions too high (%d).\n", __func__,
Edward O'Callaghane7efd052020-07-03 14:57:28 +1000377 desc->content.NR + 1);
stefanct1fc3a732011-09-15 23:52:55 +0000378 return;
379 }
Edward O'Callaghane7efd052020-07-03 14:57:28 +1000380 for (i = 0; i < nr; i++)
Edward O'Callaghande5dd912020-07-26 13:04:18 +1000381 msg_pdbg2("FLREG%zd 0x%08x\n", i, desc->region.FLREGs[i]);
stefanct1fc3a732011-09-15 23:52:55 +0000382 msg_pdbg2("\n");
383
384 msg_pdbg2("--- Details ---\n");
Edward O'Callaghane7efd052020-07-03 14:57:28 +1000385 for (i = 0; i < nr; i++)
Edward O'Callaghande5dd912020-07-26 13:04:18 +1000386 pprint_freg(&desc->region, (uint32_t)i);
stefanct1fc3a732011-09-15 23:52:55 +0000387 msg_pdbg2("\n");
David Hendricksce6b2fa2011-07-11 22:12:43 -0700388}
389
Edward O'Callaghanaef44cb2020-07-03 15:31:14 +1000390void prettyprint_ich_descriptor_master(const enum ich_chipset cs, const struct ich_descriptors *const desc)
David Hendricksce6b2fa2011-07-11 22:12:43 -0700391{
Edward O'Callaghanaef44cb2020-07-03 15:31:14 +1000392 ssize_t i;
393 const ssize_t nm = ich_number_of_masters(cs, &desc->content);
stefanct1fc3a732011-09-15 23:52:55 +0000394 msg_pdbg2("=== Master Section ===\n");
Edward O'Callaghanaef44cb2020-07-03 15:31:14 +1000395 if (nm < 0) {
396 msg_pdbg2("%s: number of masters too high (%d).\n", __func__,
397 desc->content.NM + 1);
398 return;
399 }
400 for (i = 0; i < nm; i++)
401 msg_pdbg2("FLMSTR%zd 0x%08x\n", i + 1, desc->master.FLMSTRs[i]);
stefanct1fc3a732011-09-15 23:52:55 +0000402 msg_pdbg2("\n");
David Hendricksce6b2fa2011-07-11 22:12:43 -0700403
stefanct1fc3a732011-09-15 23:52:55 +0000404 msg_pdbg2("--- Details ---\n");
Edward O'Callaghanaef44cb2020-07-03 15:31:14 +1000405 if (cs == CHIPSET_100_SERIES_SUNRISE_POINT ||
Matt DeVillier81bc4d32020-08-12 12:48:06 -0500406 cs == CHIPSET_300_SERIES_CANNON_POINT ||
407 cs == CHIPSET_400_SERIES_COMET_POINT) {
Edward O'Callaghanaef44cb2020-07-03 15:31:14 +1000408 const char *const master_names[] = {
409 "BIOS", "ME", "GbE", "unknown", "EC",
410 };
411 if (nm >= (ssize_t)ARRAY_SIZE(master_names)) {
412 msg_pdbg2("%s: number of masters too high (%d).\n", __func__,
413 desc->content.NM + 1);
414 return;
415 }
David Hendricksce6b2fa2011-07-11 22:12:43 -0700416
Edward O'Callaghanaef44cb2020-07-03 15:31:14 +1000417 size_t num_regions;
418 msg_pdbg2(" FD BIOS ME GbE Pltf Reg5 Reg6 Reg7 EC Reg9");
419 if (cs == CHIPSET_100_SERIES_SUNRISE_POINT) {
420 num_regions = 10;
421 msg_pdbg2("\n");
422 } else {
423 num_regions = 16;
424 msg_pdbg2(" RegA RegB RegC RegD RegE RegF\n");
425 }
426 for (i = 0; i < nm; i++) {
427 size_t j;
428 msg_pdbg2("%-4s", master_names[i]);
429 for (j = 0; j < (size_t)MIN(num_regions, 12); j++)
430 msg_pdbg2(" %c%c ",
431 desc->master.mstr[i].read & (1 << j) ? 'r' : ' ',
432 desc->master.mstr[i].write & (1 << j) ? 'w' : ' ');
433 for (; j < num_regions; j++)
434 msg_pdbg2(" %c%c ",
435 desc->master.mstr[i].ext_read & (1 << (j - 12)) ? 'r' : ' ',
436 desc->master.mstr[i].ext_write & (1 << (j - 12)) ? 'w' : ' ');
437 msg_pdbg2("\n");
438 }
439 } else if (cs == CHIPSET_C620_SERIES_LEWISBURG) {
440 const char *const master_names[] = {
441 "BIOS", "ME", "GbE", "DE", "BMC", "IE",
442 };
443 /* NM starts at 1 instead of 0 for LBG */
444 if (nm > (ssize_t)ARRAY_SIZE(master_names)) {
445 msg_pdbg2("%s: number of masters too high (%d).\n", __func__,
446 desc->content.NM);
447 return;
448 }
Duncan Lauriedbbf2222019-04-25 12:06:19 -0700449
Edward O'Callaghanaef44cb2020-07-03 15:31:14 +1000450 msg_pdbg2("%s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s\n",
451 " ", /* width of master name (4 chars minimum) */
452 " FD ", " BIOS", " ME ", " GbE ", " Pltf",
453 " DE ", "BIOS2", " Reg7", " BMC ", " DE2 ",
454 " IE ", "10GbE", "OpROM", "Reg13", "Reg14",
455 "Reg15");
456 for (i = 0; i < nm; i++) {
457 size_t j;
458 msg_pdbg2("%-4s", master_names[i]);
459 for (j = 0; j < 16; j++)
460 msg_pdbg2(" %c%c ",
461 desc->master.mstr[i].read & (1 << j) ? 'r' : ' ',
462 desc->master.mstr[i].write & (1 << j) ? 'w' : ' ');
463 msg_pdbg2("\n");
464 }
465 } else if (cs == CHIPSET_APOLLO_LAKE) {
466 const char *const master_names[] = { "BIOS", "TXE", };
467 if (nm > (ssize_t)ARRAY_SIZE(master_names)) {
468 msg_pdbg2("%s: number of masters too high (%d).\n", __func__, desc->content.NM);
469 return;
470 }
Duncan Lauriedbbf2222019-04-25 12:06:19 -0700471
Edward O'Callaghanaef44cb2020-07-03 15:31:14 +1000472 msg_pdbg2(" FD IFWI TXE n/a Platf DevExp\n");
473 for (i = 0; i < nm; i++) {
474 ssize_t j;
475 msg_pdbg2("%-4s", master_names[i]);
476 for (j = 0; j < ich_number_of_regions(cs, &desc->content); j++)
477 msg_pdbg2(" %c%c ",
478 desc->master.mstr[i].read & (1 << j) ? 'r' : ' ',
479 desc->master.mstr[i].write & (1 << j) ? 'w' : ' ');
480 msg_pdbg2("\n");
481 }
482 } else {
483 const struct ich_desc_master *const mstr = &desc->master;
484 msg_pdbg2(" Descr. BIOS ME GbE Platf.\n");
485 msg_pdbg2("BIOS %c%c %c%c %c%c %c%c %c%c\n",
486 (mstr->BIOS_descr_r) ?'r':' ', (mstr->BIOS_descr_w) ?'w':' ',
487 (mstr->BIOS_BIOS_r) ?'r':' ', (mstr->BIOS_BIOS_w) ?'w':' ',
488 (mstr->BIOS_ME_r) ?'r':' ', (mstr->BIOS_ME_w) ?'w':' ',
489 (mstr->BIOS_GbE_r) ?'r':' ', (mstr->BIOS_GbE_w) ?'w':' ',
490 (mstr->BIOS_plat_r) ?'r':' ', (mstr->BIOS_plat_w) ?'w':' ');
491 msg_pdbg2("ME %c%c %c%c %c%c %c%c %c%c\n",
492 (mstr->ME_descr_r) ?'r':' ', (mstr->ME_descr_w) ?'w':' ',
493 (mstr->ME_BIOS_r) ?'r':' ', (mstr->ME_BIOS_w) ?'w':' ',
494 (mstr->ME_ME_r) ?'r':' ', (mstr->ME_ME_w) ?'w':' ',
495 (mstr->ME_GbE_r) ?'r':' ', (mstr->ME_GbE_w) ?'w':' ',
496 (mstr->ME_plat_r) ?'r':' ', (mstr->ME_plat_w) ?'w':' ');
497 msg_pdbg2("GbE %c%c %c%c %c%c %c%c %c%c\n",
498 (mstr->GbE_descr_r) ?'r':' ', (mstr->GbE_descr_w) ?'w':' ',
499 (mstr->GbE_BIOS_r) ?'r':' ', (mstr->GbE_BIOS_w) ?'w':' ',
500 (mstr->GbE_ME_r) ?'r':' ', (mstr->GbE_ME_w) ?'w':' ',
501 (mstr->GbE_GbE_r) ?'r':' ', (mstr->GbE_GbE_w) ?'w':' ',
502 (mstr->GbE_plat_r) ?'r':' ', (mstr->GbE_plat_w) ?'w':' ');
503 }
504 msg_pdbg2("\n");
Duncan Lauriedbbf2222019-04-25 12:06:19 -0700505}
506
Edward O'Callaghan568cd262020-05-26 23:10:45 +1000507static void prettyprint_ich_descriptor_straps_ich8(const struct ich_descriptors *desc)
Stefan Tauner34f6f5a2016-08-03 11:20:38 -0700508{
509 static const char * const str_GPIO12[4] = {
510 "GPIO12",
511 "LAN PHY Power Control Function (Native Output)",
512 "GLAN_DOCK# (Native Input)",
513 "invalid configuration",
514 };
515
516 msg_pdbg2("--- MCH details ---\n");
517 msg_pdbg2("ME B is %sabled.\n", desc->north.ich8.MDB ? "dis" : "en");
518 msg_pdbg2("\n");
519
520 msg_pdbg2("--- ICH details ---\n");
521 msg_pdbg2("ME SMBus Address 1: 0x%02x\n", desc->south.ich8.ASD);
522 msg_pdbg2("ME SMBus Address 2: 0x%02x\n", desc->south.ich8.ASD2);
523 msg_pdbg2("ME SMBus Controller is connected to the %s.\n",
524 desc->south.ich8.MESM2SEL ? "SMLink pins" : "SMBus pins");
525 msg_pdbg2("SPI CS1 is used for %s.\n",
526 desc->south.ich8.SPICS1_LANPHYPC_SEL ?
527 "LAN PHY Power Control Function" :
528 "SPI Chip Select");
529 msg_pdbg2("GPIO12 is used as %s.\n",
530 str_GPIO12[desc->south.ich8.GPIO12_SEL]);
531 msg_pdbg2("PCIe Port 6 is used for %s.\n",
532 desc->south.ich8.GLAN_PCIE_SEL ? "integrated LAN" : "PCI Express");
533 msg_pdbg2("%sn BMC Mode: "
534 "Intel AMT SMBus Controller 1 is connected to %s.\n",
535 desc->south.ich8.BMCMODE ? "I" : "Not i",
536 desc->south.ich8.BMCMODE ? "SMLink" : "SMBus");
537 msg_pdbg2("TCO is in %s Mode.\n",
538 desc->south.ich8.TCOMODE ? "Advanced TCO" : "Legacy/Compatible");
539 msg_pdbg2("ME A is %sabled.\n",
540 desc->south.ich8.ME_DISABLE ? "dis" : "en");
541 msg_pdbg2("\n");
542}
543
544static void prettyprint_ich_descriptor_straps_56_pciecs(uint8_t conf, uint8_t off)
545{
546 msg_pdbg2("PCI Express Port Configuration Strap %d: ", off+1);
547
548 off *= 4;
Edward O'Callaghan568cd262020-05-26 23:10:45 +1000549 switch (conf){
Stefan Tauner34f6f5a2016-08-03 11:20:38 -0700550 case 0:
551 msg_pdbg2("4x1 Ports %d-%d (x1)", 1+off, 4+off);
552 break;
553 case 1:
554 msg_pdbg2("1x2, 2x1 Port %d (x2), Port %d (disabled), "
555 "Ports %d, %d (x1)", 1+off, 2+off, 3+off, 4+off);
556 break;
557 case 2:
558 msg_pdbg2("2x2 Port %d (x2), Port %d (x2), Ports "
559 "%d, %d (disabled)", 1+off, 3+off, 2+off, 4+off);
560 break;
561 case 3:
562 msg_pdbg2("1x4 Port %d (x4), Ports %d-%d (disabled)",
563 1+off, 2+off, 4+off);
564 break;
565 }
566 msg_pdbg2("\n");
567}
568
Edward O'Callaghan568cd262020-05-26 23:10:45 +1000569static void prettyprint_ich_descriptor_pchstraps45678_56(const struct ich_desc_south_strap *s)
Stefan Tauner34f6f5a2016-08-03 11:20:38 -0700570{
571 /* PCHSTRP4 */
572 msg_pdbg2("Intel PHY is %s.\n",
573 (s->ibex.PHYCON == 2) ? "connected" :
574 (s->ibex.PHYCON == 0) ? "disconnected" : "reserved");
575 msg_pdbg2("GbE MAC SMBus address is %sabled.\n",
576 s->ibex.GBEMAC_SMBUS_ADDR_EN ? "en" : "dis");
577 msg_pdbg2("GbE MAC SMBus address: 0x%02x\n",
578 s->ibex.GBEMAC_SMBUS_ADDR);
579 msg_pdbg2("GbE PHY SMBus address: 0x%02x\n",
580 s->ibex.GBEPHY_SMBUS_ADDR);
581
582 /* PCHSTRP5 */
583 /* PCHSTRP6 */
584 /* PCHSTRP7 */
585 msg_pdbg2("Intel ME SMBus Subsystem Vendor ID: 0x%04x\n",
586 s->ibex.MESMA2UDID_VENDOR);
587 msg_pdbg2("Intel ME SMBus Subsystem Device ID: 0x%04x\n",
588 s->ibex.MESMA2UDID_VENDOR);
589
590 /* PCHSTRP8 */
591}
592
Edward O'Callaghan568cd262020-05-26 23:10:45 +1000593static void prettyprint_ich_descriptor_pchstraps111213_56(const struct ich_desc_south_strap *s)
Stefan Tauner34f6f5a2016-08-03 11:20:38 -0700594{
595 /* PCHSTRP11 */
596 msg_pdbg2("SMLink1 GP Address is %sabled.\n",
597 s->ibex.SML1GPAEN ? "en" : "dis");
598 msg_pdbg2("SMLink1 controller General Purpose Target address: 0x%02x\n",
599 s->ibex.SML1GPA);
600 msg_pdbg2("SMLink1 I2C Target address is %sabled.\n",
601 s->ibex.SML1I2CAEN ? "en" : "dis");
602 msg_pdbg2("SMLink1 I2C Target address: 0x%02x\n",
603 s->ibex.SML1I2CA);
604
605 /* PCHSTRP12 */
606 /* PCHSTRP13 */
607}
608
Edward O'Callaghan568cd262020-05-26 23:10:45 +1000609static void prettyprint_ich_descriptor_straps_ibex(const struct ich_desc_south_strap *s)
Stefan Tauner34f6f5a2016-08-03 11:20:38 -0700610{
Patrick Georgi3a5bcb92017-04-11 20:45:07 +0200611 static const uint8_t dec_t209min[4] = {
Stefan Tauner34f6f5a2016-08-03 11:20:38 -0700612 100,
613 50,
614 5,
615 1
616 };
617
618 msg_pdbg2("--- PCH ---\n");
619
620 /* PCHSTRP0 */
621 msg_pdbg2("Chipset configuration Softstrap 2: %d\n", s->ibex.cs_ss2);
622 msg_pdbg2("Intel ME SMBus Select is %sabled.\n",
623 s->ibex.SMB_EN ? "en" : "dis");
624 msg_pdbg2("SMLink0 segment is %sabled.\n",
625 s->ibex.SML0_EN ? "en" : "dis");
626 msg_pdbg2("SMLink1 segment is %sabled.\n",
627 s->ibex.SML1_EN ? "en" : "dis");
628 msg_pdbg2("SMLink1 Frequency: %s\n",
629 (s->ibex.SML1FRQ == 1) ? "100 kHz" : "reserved");
630 msg_pdbg2("Intel ME SMBus Frequency: %s\n",
631 (s->ibex.SMB0FRQ == 1) ? "100 kHz" : "reserved");
632 msg_pdbg2("SMLink0 Frequency: %s\n",
633 (s->ibex.SML0FRQ == 1) ? "100 kHz" : "reserved");
634 msg_pdbg2("GPIO12 is used as %s.\n", s->ibex.LANPHYPC_GP12_SEL ?
635 "LAN_PHY_PWR_CTRL" : "general purpose output");
636 msg_pdbg2("Chipset configuration Softstrap 1: %d\n", s->ibex.cs_ss1);
637 msg_pdbg2("DMI RequesterID Checks are %sabled.\n",
638 s->ibex.DMI_REQID_DIS ? "en" : "dis");
639 msg_pdbg2("BIOS Boot-Block size (BBBS): %d kB.\n",
640 1 << (6 + s->ibex.BBBS));
641
642 /* PCHSTRP1 */
643 msg_pdbg2("Chipset configuration Softstrap 3: 0x%x\n", s->ibex.cs_ss3);
644
645 /* PCHSTRP2 */
646 msg_pdbg2("ME SMBus ASD address is %sabled.\n",
647 s->ibex.MESMASDEN ? "en" : "dis");
648 msg_pdbg2("ME SMBus Controller ASD Target address: 0x%02x\n",
649 s->ibex.MESMASDA);
650 msg_pdbg2("ME SMBus I2C address is %sabled.\n",
651 s->ibex.MESMI2CEN ? "en" : "dis");
652 msg_pdbg2("ME SMBus I2C target address: 0x%02x\n",
653 s->ibex.MESMI2CA);
654
655 /* PCHSTRP3 */
656 prettyprint_ich_descriptor_pchstraps45678_56(s);
657 /* PCHSTRP9 */
658 prettyprint_ich_descriptor_straps_56_pciecs(s->ibex.PCIEPCS1, 0);
659 prettyprint_ich_descriptor_straps_56_pciecs(s->ibex.PCIEPCS1, 1);
660 msg_pdbg2("PCIe Lane Reversal 1: PCIe Lanes 0-3 are %sreserved.\n",
661 s->ibex.PCIELR1 ? "" : "not ");
662 msg_pdbg2("PCIe Lane Reversal 2: PCIe Lanes 4-7 are %sreserved.\n",
663 s->ibex.PCIELR2 ? "" : "not ");
664 msg_pdbg2("DMI Lane Reversal: DMI Lanes 0-3 are %sreserved.\n",
665 s->ibex.DMILR ? "" : "not ");
666 msg_pdbg2("Default PHY PCIe Port is %d.\n", s->ibex.PHY_PCIEPORTSEL+1);
667 msg_pdbg2("Integrated MAC/PHY communication over PCIe is %sabled.\n",
668 s->ibex.PHY_PCIE_EN ? "en" : "dis");
669
670 /* PCHSTRP10 */
671 msg_pdbg2("Management Engine will boot from %sflash.\n",
672 s->ibex.ME_BOOT_FLASH ? "" : "ROM, then ");
673 msg_pdbg2("Chipset configuration Softstrap 5: %d\n", s->ibex.cs_ss5);
674 msg_pdbg2("Virtualization Engine Enable 1 is %sabled.\n",
675 s->ibex.VE_EN ? "en" : "dis");
676 msg_pdbg2("ME Memory-attached Debug Display Device is %sabled.\n",
677 s->ibex.MMDDE ? "en" : "dis");
678 msg_pdbg2("ME Memory-attached Debug Display Device address: 0x%02x\n",
679 s->ibex.MMADDR);
680 msg_pdbg2("Chipset configuration Softstrap 7: %d\n", s->ibex.cs_ss7);
681 msg_pdbg2("Integrated Clocking Configuration is %d.\n",
682 (s->ibex.ICC_SEL == 7) ? 0 : s->ibex.ICC_SEL);
683 msg_pdbg2("PCH Signal CL_RST1# does %sassert when Intel ME performs a "
684 "reset.\n", s->ibex.MER_CL1 ? "" : "not ");
685
686 prettyprint_ich_descriptor_pchstraps111213_56(s);
687
688 /* PCHSTRP14 */
689 msg_pdbg2("Virtualization Engine Enable 2 is %sabled.\n",
690 s->ibex.VE_EN2 ? "en" : "dis");
691 msg_pdbg2("Virtualization Engine will boot from %sflash.\n",
692 s->ibex.VE_BOOT_FLASH ? "" : "ROM, then ");
693 msg_pdbg2("Braidwood SSD functionality is %sabled.\n",
694 s->ibex.BW_SSD ? "en" : "dis");
695 msg_pdbg2("Braidwood NVMHCI functionality is %sabled.\n",
696 s->ibex.NVMHCI_EN ? "en" : "dis");
697
698 /* PCHSTRP15 */
699 msg_pdbg2("Chipset configuration Softstrap 6: %d\n", s->ibex.cs_ss6);
700 msg_pdbg2("Integrated wired LAN Solution is %sabled.\n",
701 s->ibex.IWL_EN ? "en" : "dis");
702 msg_pdbg2("t209 min Timing: %d ms\n",
703 dec_t209min[s->ibex.t209min]);
704 msg_pdbg2("\n");
705}
706
Edward O'Callaghan568cd262020-05-26 23:10:45 +1000707static void prettyprint_ich_descriptor_straps_cougar(const struct ich_desc_south_strap *s)
Stefan Tauner34f6f5a2016-08-03 11:20:38 -0700708{
709 msg_pdbg2("--- PCH ---\n");
710
711 /* PCHSTRP0 */
712 msg_pdbg2("Chipset configuration Softstrap 1: %d\n", s->cougar.cs_ss1);
713 msg_pdbg2("Intel ME SMBus Select is %sabled.\n",
714 s->ibex.SMB_EN ? "en" : "dis");
715 msg_pdbg2("SMLink0 segment is %sabled.\n",
716 s->ibex.SML0_EN ? "en" : "dis");
717 msg_pdbg2("SMLink1 segment is %sabled.\n",
718 s->ibex.SML1_EN ? "en" : "dis");
719 msg_pdbg2("SMLink1 Frequency: %s\n",
720 (s->ibex.SML1FRQ == 1) ? "100 kHz" : "reserved");
721 msg_pdbg2("Intel ME SMBus Frequency: %s\n",
722 (s->ibex.SMB0FRQ == 1) ? "100 kHz" : "reserved");
723 msg_pdbg2("SMLink0 Frequency: %s\n",
724 (s->ibex.SML0FRQ == 1) ? "100 kHz" : "reserved");
725 msg_pdbg2("GPIO12 is used as %s.\n", s->ibex.LANPHYPC_GP12_SEL ?
726 "LAN_PHY_PWR_CTRL" : "general purpose output");
727 msg_pdbg2("LinkSec is %sabled.\n",
728 s->cougar.LINKSEC_DIS ? "en" : "dis");
729 msg_pdbg2("DMI RequesterID Checks are %sabled.\n",
730 s->ibex.DMI_REQID_DIS ? "en" : "dis");
731 msg_pdbg2("BIOS Boot-Block size (BBBS): %d kB.\n",
732 1 << (6 + s->ibex.BBBS));
733
734 /* PCHSTRP1 */
735 msg_pdbg2("Chipset configuration Softstrap 3: 0x%x\n", s->ibex.cs_ss3);
736 msg_pdbg2("Chipset configuration Softstrap 2: 0x%x\n", s->ibex.cs_ss2);
737
738 /* PCHSTRP2 */
739 msg_pdbg2("ME SMBus ASD address is %sabled.\n",
740 s->ibex.MESMASDEN ? "en" : "dis");
741 msg_pdbg2("ME SMBus Controller ASD Target address: 0x%02x\n",
742 s->ibex.MESMASDA);
743 msg_pdbg2("ME SMBus MCTP Address is %sabled.\n",
744 s->cougar.MESMMCTPAEN ? "en" : "dis");
745 msg_pdbg2("ME SMBus MCTP target address: 0x%02x\n",
746 s->cougar.MESMMCTPA);
747 msg_pdbg2("ME SMBus I2C address is %sabled.\n",
748 s->ibex.MESMI2CEN ? "en" : "dis");
749 msg_pdbg2("ME SMBus I2C target address: 0x%02x\n",
750 s->ibex.MESMI2CA);
751
752 /* PCHSTRP3 */
753 prettyprint_ich_descriptor_pchstraps45678_56(s);
754 /* PCHSTRP9 */
755 prettyprint_ich_descriptor_straps_56_pciecs(s->ibex.PCIEPCS1, 0);
756 prettyprint_ich_descriptor_straps_56_pciecs(s->ibex.PCIEPCS1, 1);
757 msg_pdbg2("PCIe Lane Reversal 1: PCIe Lanes 0-3 are %sreserved.\n",
758 s->ibex.PCIELR1 ? "" : "not ");
759 msg_pdbg2("PCIe Lane Reversal 2: PCIe Lanes 4-7 are %sreserved.\n",
760 s->ibex.PCIELR2 ? "" : "not ");
761 msg_pdbg2("DMI Lane Reversal: DMI Lanes 0-3 are %sreserved.\n",
762 s->ibex.DMILR ? "" : "not ");
763 msg_pdbg2("ME Debug status writes over SMBUS are %sabled.\n",
764 s->cougar.MDSMBE_EN ? "en" : "dis");
765 msg_pdbg2("ME Debug SMBus Emergency Mode address: 0x%02x (raw)\n",
766 s->cougar.MDSMBE_ADD);
767 msg_pdbg2("Default PHY PCIe Port is %d.\n", s->ibex.PHY_PCIEPORTSEL+1);
768 msg_pdbg2("Integrated MAC/PHY communication over PCIe is %sabled.\n",
769 s->ibex.PHY_PCIE_EN ? "en" : "dis");
770 msg_pdbg2("PCIe ports Subtractive Decode Agent is %sabled.\n",
771 s->cougar.SUB_DECODE_EN ? "en" : "dis");
772 msg_pdbg2("GPIO74 is used as %s.\n", s->cougar.PCHHOT_SML1ALERT_SEL ?
773 "PCHHOT#" : "SML1ALERT#");
774
775 /* PCHSTRP10 */
776 msg_pdbg2("Management Engine will boot from %sflash.\n",
777 s->ibex.ME_BOOT_FLASH ? "" : "ROM, then ");
778
779 msg_pdbg2("ME Debug SMBus Emergency Mode is %sabled.\n",
780 s->cougar.MDSMBE_EN ? "en" : "dis");
781 msg_pdbg2("ME Debug SMBus Emergency Mode Address: 0x%02x\n",
782 s->cougar.MDSMBE_ADD);
783
784 msg_pdbg2("Integrated Clocking Configuration used: %d\n",
785 s->cougar.ICC_SEL);
Edward O'Callaghan568cd262020-05-26 23:10:45 +1000786 msg_pdbg2("PCH Signal CL_RST1# does %sassert when Intel ME performs a reset.\n",
787 s->ibex.MER_CL1 ? "" : "not ");
Stefan Tauner34f6f5a2016-08-03 11:20:38 -0700788 msg_pdbg2("ICC Profile is selected by %s.\n",
789 s->cougar.ICC_PRO_SEL ? "Softstraps" : "BIOS");
790 msg_pdbg2("Deep SX is %ssupported on the platform.\n",
791 s->cougar.Deep_SX_EN ? "not " : "");
792 msg_pdbg2("ME Debug LAN Emergency Mode is %sabled.\n",
793 s->cougar.ME_DBG_LAN ? "en" : "dis");
794
795 prettyprint_ich_descriptor_pchstraps111213_56(s);
796
797 /* PCHSTRP14 */
798 /* PCHSTRP15 */
799 msg_pdbg2("Chipset configuration Softstrap 6: %d\n", s->cougar.cs_ss6);
800 msg_pdbg2("Integrated wired LAN is %sabled.\n",
801 s->cougar.IWL_EN ? "en" : "dis");
802 msg_pdbg2("Chipset configuration Softstrap 5: %d\n", s->cougar.cs_ss5);
803 msg_pdbg2("SMLink1 provides temperature from %s.\n",
Edward O'Callaghan568cd262020-05-26 23:10:45 +1000804 s->cougar.SMLINK1_THERM_SEL ? "PCH only" : "the CPU, PCH and DIMMs");
Stefan Tauner34f6f5a2016-08-03 11:20:38 -0700805 msg_pdbg2("GPIO29 is used as %s.\n", s->cougar.SLP_LAN_GP29_SEL ?
806 "general purpose output" : "SLP_LAN#");
807
808 /* PCHSTRP16 */
809 /* PCHSTRP17 */
810 msg_pdbg2("Integrated Clock: %s Clock Mode\n",
811 s->cougar.ICML ? "Buffered Through" : "Full Integrated");
812 msg_pdbg2("\n");
813}
814
815void prettyprint_ich_descriptor_straps(enum ich_chipset cs, const struct ich_descriptors *desc)
816{
Edward O'Callaghanc172e172020-05-26 23:19:02 +1000817 unsigned int i, max_count;
Stefan Tauner34f6f5a2016-08-03 11:20:38 -0700818 msg_pdbg2("=== Softstraps ===\n");
819
Edward O'Callaghanc172e172020-05-26 23:19:02 +1000820 max_count = MIN(ARRAY_SIZE(desc->north.STRPs), desc->content.MSL);
821 if (max_count < desc->content.MSL) {
822 msg_pdbg2("MSL (%u) is greater than the current maximum of %u entries.\n",
823 desc->content.MSL, max_count);
824 msg_pdbg2("Only the first %u entries will be printed.\n", max_count);
825 }
Stefan Tauner34f6f5a2016-08-03 11:20:38 -0700826
Edward O'Callaghanc172e172020-05-26 23:19:02 +1000827 msg_pdbg2("--- North/MCH/PROC (%d entries) ---\n", max_count);
828 for (i = 0; i < max_count; i++)
Stefan Tauner34f6f5a2016-08-03 11:20:38 -0700829 msg_pdbg2("STRP%-2d = 0x%08x\n", i, desc->north.STRPs[i]);
830 msg_pdbg2("\n");
831
Edward O'Callaghanc172e172020-05-26 23:19:02 +1000832 max_count = MIN(ARRAY_SIZE(desc->south.STRPs), desc->content.ISL);
833 if (max_count < desc->content.ISL) {
834 msg_pdbg2("ISL (%u) is greater than the current maximum of %u entries.\n",
835 desc->content.ISL, max_count);
836 msg_pdbg2("Only the first %u entries will be printed.\n", max_count);
837 }
Stefan Tauner34f6f5a2016-08-03 11:20:38 -0700838
Edward O'Callaghanc172e172020-05-26 23:19:02 +1000839 msg_pdbg2("--- South/ICH/PCH (%d entries) ---\n", max_count);
840 for (i = 0; i < max_count; i++)
Stefan Tauner34f6f5a2016-08-03 11:20:38 -0700841 msg_pdbg2("STRP%-2d = 0x%08x\n", i, desc->south.STRPs[i]);
842 msg_pdbg2("\n");
843
844 switch (cs) {
845 case CHIPSET_ICH8:
846 if (sizeof(desc->north.ich8) / 4 != desc->content.MSL)
847 msg_pdbg2("Detailed North/MCH/PROC information is "
848 "probably not reliable, printing anyway.\n");
849 if (sizeof(desc->south.ich8) / 4 != desc->content.ISL)
850 msg_pdbg2("Detailed South/ICH/PCH information is "
851 "probably not reliable, printing anyway.\n");
852 prettyprint_ich_descriptor_straps_ich8(desc);
853 break;
854 case CHIPSET_5_SERIES_IBEX_PEAK:
855 /* PCH straps only. PROCSTRPs are unknown. */
856 if (sizeof(desc->south.ibex) / 4 != desc->content.ISL)
857 msg_pdbg2("Detailed South/ICH/PCH information is "
858 "probably not reliable, printing anyway.\n");
859 prettyprint_ich_descriptor_straps_ibex(&desc->south);
860 break;
861 case CHIPSET_6_SERIES_COUGAR_POINT:
862 /* PCH straps only. PROCSTRP0 is "reserved". */
863 if (sizeof(desc->south.cougar) / 4 != desc->content.ISL)
864 msg_pdbg2("Detailed South/ICH/PCH information is "
865 "probably not reliable, printing anyway.\n");
866 prettyprint_ich_descriptor_straps_cougar(&desc->south);
867 break;
868 case CHIPSET_ICH_UNKNOWN:
869 break;
870 default:
Edward O'Callaghan568cd262020-05-26 23:10:45 +1000871 msg_pdbg2("The meaning of the descriptor straps are unknown yet.\n\n");
Stefan Tauner34f6f5a2016-08-03 11:20:38 -0700872 break;
873 }
874}
875
Edward O'Callaghan568cd262020-05-26 23:10:45 +1000876static void prettyprint_rdid(uint32_t reg_val)
Stefan Tauner34f6f5a2016-08-03 11:20:38 -0700877{
878 uint8_t mid = reg_val & 0xFF;
879 uint16_t did = ((reg_val >> 16) & 0xFF) | (reg_val & 0xFF00);
880 msg_pdbg2("Manufacturer ID 0x%02x, Device ID 0x%04x\n", mid, did);
881}
882
883void prettyprint_ich_descriptor_upper_map(const struct ich_desc_upper_map *umap)
884{
885 int i;
886 msg_pdbg2("=== Upper Map Section ===\n");
887 msg_pdbg2("FLUMAP1 0x%08x\n", umap->FLUMAP1);
888 msg_pdbg2("\n");
889
890 msg_pdbg2("--- Details ---\n");
891 msg_pdbg2("VTL (length in DWORDS) = %d\n", umap->VTL);
892 msg_pdbg2("VTBA (base address) = 0x%6.6x\n", getVTBA(umap));
893 msg_pdbg2("\n");
894
895 msg_pdbg2("VSCC Table: %d entries\n", umap->VTL/2);
Edward O'Callaghan568cd262020-05-26 23:10:45 +1000896 for (i = 0; i < umap->VTL/2; i++) {
Stefan Tauner34f6f5a2016-08-03 11:20:38 -0700897 uint32_t jid = umap->vscc_table[i].JID;
898 uint32_t vscc = umap->vscc_table[i].VSCC;
899 msg_pdbg2(" JID%d = 0x%08x\n", i, jid);
900 msg_pdbg2(" VSCC%d = 0x%08x\n", i, vscc);
901 msg_pdbg2(" "); /* indention */
902 prettyprint_rdid(jid);
903 msg_pdbg2(" "); /* indention */
Edward O'Callaghand757b422020-05-26 21:22:12 +1000904 prettyprint_ich_reg_vscc(vscc, 0, false);
Stefan Tauner34f6f5a2016-08-03 11:20:38 -0700905 }
906 msg_pdbg2("\n");
907}
908
Edward O'Callaghan01e8d322020-07-09 18:26:43 +1000909/*
910 * Guesses a minimum chipset version based on the maximum number of
911 * soft straps per generation.
912 */
913static enum ich_chipset guess_ich_chipset_from_content(const struct ich_desc_content *const content)
914{
915 if (content->ICCRIBA == 0x00) {
916 if (content->MSL == 0 && content->ISL <= 2)
917 return CHIPSET_ICH8;
918 else if (content->ISL <= 2)
919 return CHIPSET_ICH9;
920 else if (content->ISL <= 10)
921 return CHIPSET_ICH10;
922 else if (content->ISL <= 16)
923 return CHIPSET_5_SERIES_IBEX_PEAK;
924 else if (content->FLMAP2 == 0) {
925 if (content->ISL != 19)
926 msg_pwarn("Peculiar firmware descriptor, assuming Apollo Lake compatibility.\n");
927 return CHIPSET_APOLLO_LAKE;
928 }
929 msg_pwarn("Peculiar firmware descriptor, assuming Ibex Peak compatibility.\n");
930 return CHIPSET_5_SERIES_IBEX_PEAK;
931 } else if (content->ICCRIBA < 0x31 && content->FMSBA < 0x30) {
932 if (content->MSL == 0 && content->ISL <= 17)
933 return CHIPSET_BAYTRAIL;
934 else if (content->MSL <= 1 && content->ISL <= 18)
935 return CHIPSET_6_SERIES_COUGAR_POINT;
936 else if (content->MSL <= 1 && content->ISL <= 21)
937 return CHIPSET_8_SERIES_LYNX_POINT;
938 msg_pwarn("Peculiar firmware descriptor, assuming Wildcat Point compatibility.\n");
939 return CHIPSET_9_SERIES_WILDCAT_POINT;
940 } else if (content->ICCRIBA < 0x34) {
941 if (content->NM == 6)
942 return CHIPSET_C620_SERIES_LEWISBURG;
943 else
944 return CHIPSET_100_SERIES_SUNRISE_POINT;
Jonathan Zhangee234f92020-08-19 12:19:06 -0700945 } else if (content->ICCRIBA == 0x34) {
946 if (content->NM == 6)
947 return CHIPSET_C620_SERIES_LEWISBURG;
948 else
949 return CHIPSET_300_SERIES_CANNON_POINT;
Edward O'Callaghan01e8d322020-07-09 18:26:43 +1000950 } else {
Jonathan Zhangee234f92020-08-19 12:19:06 -0700951 msg_pwarn("Unknown firmware descriptor, assuming 300 series compatibility.\n");
Edward O'Callaghan01e8d322020-07-09 18:26:43 +1000952 return CHIPSET_300_SERIES_CANNON_POINT;
953 }
954}
955
956/*
957 * As an additional measure, we check the read frequency like `ifdtool`.
958 * The frequency value 6 (17MHz) was reserved before Skylake and is the
959 * only valid value since. Skylake is currently the most important dis-
960 * tinction because of the dropped number of regions field (NR).
961 */
962static enum ich_chipset guess_ich_chipset(const struct ich_desc_content *const content,
963 const struct ich_desc_component *const component)
964{
965 const enum ich_chipset guess = guess_ich_chipset_from_content(content);
966
967 switch (guess) {
968 case CHIPSET_300_SERIES_CANNON_POINT:
Matt DeVillier81bc4d32020-08-12 12:48:06 -0500969 case CHIPSET_400_SERIES_COMET_POINT:
Edward O'Callaghan01e8d322020-07-09 18:26:43 +1000970 /* `freq_read` was repurposed, so can't check on it any more. */
971 return guess;
972 case CHIPSET_100_SERIES_SUNRISE_POINT:
973 case CHIPSET_C620_SERIES_LEWISBURG:
974 case CHIPSET_APOLLO_LAKE:
975 if (component->modes.freq_read != 6) {
976 msg_pwarn("\nThe firmware descriptor looks like a Skylake/Sunrise Point descriptor.\n"
977 "However, the read frequency isn't set to 17MHz (the only valid value).\n"
978 "Please report this message, the output of `ich_descriptors_tool` for\n"
979 "your descriptor and the output of `lspci -nn` to flashrom@flashrom.org\n\n");
980 return CHIPSET_9_SERIES_WILDCAT_POINT;
981 }
982 return guess;
983 default:
984 if (component->modes.freq_read == 6) {
985 msg_pwarn("\nThe firmware descriptor has the read frequency set to 17MHz. However,\n"
986 "it doesn't look like a Skylake/Sunrise Point compatible descriptor.\n"
987 "Please report this message, the output of `ich_descriptors_tool` for\n"
988 "your descriptor and the output of `lspci -nn` to flashrom@flashrom.org\n\n");
989 return CHIPSET_100_SERIES_SUNRISE_POINT;
990 }
991 return guess;
992 }
993}
994
Stefan Tauner34f6f5a2016-08-03 11:20:38 -0700995/* len is the length of dump in bytes */
Edward O'Callaghanaef44cb2020-07-03 15:31:14 +1000996int read_ich_descriptors_from_dump(const uint32_t *const dump, const size_t len,
997 enum ich_chipset *const cs, struct ich_descriptors *const desc)
Stefan Tauner34f6f5a2016-08-03 11:20:38 -0700998{
Edward O'Callaghan01e8d322020-07-09 18:26:43 +1000999 ssize_t i, max_count;
1000 size_t pch_bug_offset = 0;
Stefan Tauner34f6f5a2016-08-03 11:20:38 -07001001
1002 if (dump == NULL || desc == NULL)
1003 return ICH_RET_PARAM;
1004
1005 if (dump[0] != DESCRIPTOR_MODE_SIGNATURE) {
1006 if (dump[4] == DESCRIPTOR_MODE_SIGNATURE)
1007 pch_bug_offset = 4;
1008 else
1009 return ICH_RET_ERR;
1010 }
1011
1012 /* map */
Nico Huber61b10c72017-03-28 17:08:46 +02001013 if (len < (4 + pch_bug_offset) * 4)
Stefan Tauner34f6f5a2016-08-03 11:20:38 -07001014 return ICH_RET_OOB;
1015 desc->content.FLVALSIG = dump[0 + pch_bug_offset];
1016 desc->content.FLMAP0 = dump[1 + pch_bug_offset];
1017 desc->content.FLMAP1 = dump[2 + pch_bug_offset];
1018 desc->content.FLMAP2 = dump[3 + pch_bug_offset];
1019
1020 /* component */
Nico Huber61b10c72017-03-28 17:08:46 +02001021 if (len < getFCBA(&desc->content) + 3 * 4)
Stefan Tauner34f6f5a2016-08-03 11:20:38 -07001022 return ICH_RET_OOB;
1023 desc->component.FLCOMP = dump[(getFCBA(&desc->content) >> 2) + 0];
1024 desc->component.FLILL = dump[(getFCBA(&desc->content) >> 2) + 1];
1025 desc->component.FLPB = dump[(getFCBA(&desc->content) >> 2) + 2];
1026
Edward O'Callaghan01e8d322020-07-09 18:26:43 +10001027 if (*cs == CHIPSET_ICH_UNKNOWN) {
1028 *cs = guess_ich_chipset(&desc->content, &desc->component);
1029 prettyprint_ich_chipset(*cs);
1030 }
1031
Stefan Tauner34f6f5a2016-08-03 11:20:38 -07001032 /* region */
Edward O'Callaghanaef44cb2020-07-03 15:31:14 +10001033 const ssize_t nr = ich_number_of_regions(*cs, &desc->content);
Edward O'Callaghane7efd052020-07-03 14:57:28 +10001034 if (nr < 0 || len < getFRBA(&desc->content) + (size_t)nr * 4)
Stefan Tauner34f6f5a2016-08-03 11:20:38 -07001035 return ICH_RET_OOB;
Edward O'Callaghane7efd052020-07-03 14:57:28 +10001036 for (i = 0; i < nr; i++)
1037 desc->region.FLREGs[i] = dump[(getFRBA(&desc->content) >> 2) + i];
Stefan Tauner34f6f5a2016-08-03 11:20:38 -07001038
1039 /* master */
Edward O'Callaghanaef44cb2020-07-03 15:31:14 +10001040 const ssize_t nm = ich_number_of_masters(*cs, &desc->content);
1041 if (nm < 0 || len < getFMBA(&desc->content) + (size_t)nm * 4)
Stefan Tauner34f6f5a2016-08-03 11:20:38 -07001042 return ICH_RET_OOB;
Edward O'Callaghanaef44cb2020-07-03 15:31:14 +10001043 for (i = 0; i < nm; i++)
1044 desc->master.FLMSTRs[i] = dump[(getFMBA(&desc->content) >> 2) + i];
Stefan Tauner34f6f5a2016-08-03 11:20:38 -07001045
1046 /* upper map */
1047 desc->upper.FLUMAP1 = dump[(UPPER_MAP_OFFSET >> 2) + 0];
1048
1049 /* VTL is 8 bits long. Quote from the Ibex Peak SPI programming guide:
1050 * "Identifies the 1s based number of DWORDS contained in the VSCC
1051 * Table. Each SPI component entry in the table is 2 DWORDS long." So
1052 * the maximum of 255 gives us 127.5 SPI components(!?) 8 bytes each. A
1053 * check ensures that the maximum offset actually accessed is available.
1054 */
Nico Huber61b10c72017-03-28 17:08:46 +02001055 if (len < getVTBA(&desc->upper) + (desc->upper.VTL / 2 * 8))
Stefan Tauner34f6f5a2016-08-03 11:20:38 -07001056 return ICH_RET_OOB;
1057
1058 for (i = 0; i < desc->upper.VTL/2; i++) {
Edward O'Callaghan568cd262020-05-26 23:10:45 +10001059 desc->upper.vscc_table[i].JID = dump[(getVTBA(&desc->upper) >> 2) + i * 2 + 0];
1060 desc->upper.vscc_table[i].VSCC = dump[(getVTBA(&desc->upper) >> 2) + i * 2 + 1];
Stefan Tauner34f6f5a2016-08-03 11:20:38 -07001061 }
1062
1063 /* MCH/PROC (aka. North) straps */
1064 if (len < getFMSBA(&desc->content) + desc->content.MSL * 4)
1065 return ICH_RET_OOB;
1066
1067 /* limit the range to be written */
Edward O'Callaghan01e8d322020-07-09 18:26:43 +10001068 max_count = MIN(sizeof(desc->north.STRPs) / 4, desc->content.MSL);
1069 for (i = 0; i < max_count; i++)
Edward O'Callaghan568cd262020-05-26 23:10:45 +10001070 desc->north.STRPs[i] = dump[(getFMSBA(&desc->content) >> 2) + i];
Stefan Tauner34f6f5a2016-08-03 11:20:38 -07001071
1072 /* ICH/PCH (aka. South) straps */
1073 if (len < getFISBA(&desc->content) + desc->content.ISL * 4)
1074 return ICH_RET_OOB;
1075
1076 /* limit the range to be written */
Edward O'Callaghan01e8d322020-07-09 18:26:43 +10001077 max_count = MIN(sizeof(desc->south.STRPs) / 4, desc->content.ISL);
1078 for (i = 0; i < max_count; i++)
Edward O'Callaghan568cd262020-05-26 23:10:45 +10001079 desc->south.STRPs[i] = dump[(getFISBA(&desc->content) >> 2) + i];
Stefan Tauner34f6f5a2016-08-03 11:20:38 -07001080
1081 return ICH_RET_OK;
1082}
1083
Edward O'Callaghanb76b4e62020-07-26 13:03:12 +10001084#ifndef ICH_DESCRIPTORS_FROM_DUMP_ONLY
Stefan Tauner34f6f5a2016-08-03 11:20:38 -07001085
stefanct3d3b6ee2011-10-20 12:57:14 +00001086/** Returns the integer representation of the component density with index
Edward O'Callaghane0845d72020-07-05 13:28:03 +10001087\em idx in bytes or -1 if the correct size can not be determined. */
1088int getFCBA_component_density(enum ich_chipset cs, const struct ich_descriptors *desc, uint8_t idx)
stefanct3d3b6ee2011-10-20 12:57:14 +00001089{
Edward O'Callaghane0845d72020-07-05 13:28:03 +10001090 if (idx > 1) {
1091 msg_perr("Only ICH SPI component index 0 or 1 are supported yet.\n");
1092 return -1;
1093 }
Edward O'Callaghan1229b212020-07-05 13:28:03 +10001094
Edward O'Callaghane0845d72020-07-05 13:28:03 +10001095 if (desc->content.NC == 0 && idx > 0)
1096 return 0;
1097
1098 uint8_t size_enc;
1099 uint8_t size_max;
1100
1101 switch (cs) {
1102 case CHIPSET_ICH8:
1103 case CHIPSET_ICH9:
1104 case CHIPSET_ICH10:
1105 case CHIPSET_5_SERIES_IBEX_PEAK:
1106 case CHIPSET_6_SERIES_COUGAR_POINT:
1107 case CHIPSET_7_SERIES_PANTHER_POINT:
1108 case CHIPSET_BAYTRAIL:
1109 if (idx == 0) {
1110 size_enc = desc->component.dens_old.comp1_density;
1111 } else {
1112 size_enc = desc->component.dens_old.comp2_density;
1113 }
1114 size_max = 5;
stefanct3d3b6ee2011-10-20 12:57:14 +00001115 break;
Edward O'Callaghane0845d72020-07-05 13:28:03 +10001116 case CHIPSET_8_SERIES_LYNX_POINT:
1117 case CHIPSET_8_SERIES_LYNX_POINT_LP:
1118 case CHIPSET_8_SERIES_WELLSBURG:
1119 case CHIPSET_9_SERIES_WILDCAT_POINT:
1120 case CHIPSET_9_SERIES_WILDCAT_POINT_LP:
1121 case CHIPSET_100_SERIES_SUNRISE_POINT:
1122 case CHIPSET_C620_SERIES_LEWISBURG:
1123 case CHIPSET_300_SERIES_CANNON_POINT:
Matt DeVillier81bc4d32020-08-12 12:48:06 -05001124 case CHIPSET_400_SERIES_COMET_POINT:
Edward O'Callaghane0845d72020-07-05 13:28:03 +10001125 case CHIPSET_APOLLO_LAKE:
1126 if (idx == 0) {
1127 size_enc = desc->component.dens_new.comp1_density;
1128 } else {
1129 size_enc = desc->component.dens_new.comp2_density;
1130 }
1131 size_max = 7;
stefanct3d3b6ee2011-10-20 12:57:14 +00001132 break;
Edward O'Callaghane0845d72020-07-05 13:28:03 +10001133 case CHIPSET_ICH_UNKNOWN:
stefanct3d3b6ee2011-10-20 12:57:14 +00001134 default:
Edward O'Callaghane0845d72020-07-05 13:28:03 +10001135 msg_pwarn("Density encoding is unknown on this chipset.\n");
1136 return -1;
stefanct3d3b6ee2011-10-20 12:57:14 +00001137 }
Edward O'Callaghane0845d72020-07-05 13:28:03 +10001138
1139 if (size_enc > size_max) {
1140 msg_perr("Density of ICH SPI component with index %d is invalid.\n"
1141 "Encoded density is 0x%x while maximum allowed is 0x%x.\n",
1142 idx, size_enc, size_max);
1143 return -1;
stefanct3d3b6ee2011-10-20 12:57:14 +00001144 }
Edward O'Callaghane0845d72020-07-05 13:28:03 +10001145
stefanct3d3b6ee2011-10-20 12:57:14 +00001146 return (1 << (19 + size_enc));
1147}
1148
Edward O'Callaghanb76b4e62020-07-26 13:03:12 +10001149/* Only used by ichspi.c */
1150#if CONFIG_INTERNAL == 1 && (defined(__i386__) || defined(__x86_64__))
Edward O'Callaghan5a7ae7a2020-05-18 16:29:45 +10001151static uint32_t read_descriptor_reg(enum ich_chipset cs, uint8_t section, uint16_t offset, void *spibar)
David Hendricksce6b2fa2011-07-11 22:12:43 -07001152{
1153 uint32_t control = 0;
1154 control |= (section << FDOC_FDSS_OFF) & FDOC_FDSS;
1155 control |= (offset << FDOC_FDSI_OFF) & FDOC_FDSI;
Edward O'Callaghan9e6046c2020-05-26 23:24:08 +10001156 switch (cs) {
1157 case CHIPSET_100_SERIES_SUNRISE_POINT:
1158 case CHIPSET_C620_SERIES_LEWISBURG:
1159 case CHIPSET_300_SERIES_CANNON_POINT:
Matt DeVillier81bc4d32020-08-12 12:48:06 -05001160 case CHIPSET_400_SERIES_COMET_POINT:
Edward O'Callaghan9e6046c2020-05-26 23:24:08 +10001161 case CHIPSET_APOLLO_LAKE:
Ramya Vijaykumara9a64f92015-04-15 15:26:22 +05301162 mmio_le_writel(control, spibar + PCH100_REG_FDOC);
1163 return mmio_le_readl(spibar + PCH100_REG_FDOD);
Edward O'Callaghan9e6046c2020-05-26 23:24:08 +10001164 default:
Ramya Vijaykumara9a64f92015-04-15 15:26:22 +05301165 mmio_le_writel(control, spibar + ICH9_REG_FDOC);
1166 return mmio_le_readl(spibar + ICH9_REG_FDOD);
1167 }
David Hendricksce6b2fa2011-07-11 22:12:43 -07001168}
1169
Edward O'Callaghan4b90b622020-05-18 16:20:56 +10001170int read_ich_descriptors_via_fdo(enum ich_chipset cs, void *spibar, struct ich_descriptors *desc)
David Hendricksce6b2fa2011-07-11 22:12:43 -07001171{
Edward O'Callaghan0f6a2e52020-07-09 18:16:16 +10001172 ssize_t i;
stefanct1fc3a732011-09-15 23:52:55 +00001173 struct ich_desc_region *r = &desc->region;
1174
1175 /* Test if bit-fields are working as expected.
1176 * FIXME: Replace this with dynamic bitfield fixup
1177 */
1178 for (i = 0; i < 4; i++)
1179 desc->region.FLREGs[i] = 0x5A << (i * 8);
Edward O'Callaghan0f6a2e52020-07-09 18:16:16 +10001180 if (r->old_reg[0].base != 0x005A || r->old_reg[0].limit != 0x0000 ||
1181 r->old_reg[1].base != 0x1A00 || r->old_reg[1].limit != 0x0000 ||
1182 r->old_reg[2].base != 0x0000 || r->old_reg[2].limit != 0x005A ||
1183 r->old_reg[3].base != 0x0000 || r->old_reg[3].limit != 0x1A00) {
stefanct1fc3a732011-09-15 23:52:55 +00001184 msg_pdbg("The combination of compiler and CPU architecture used"
1185 "does not lay out bit-fields as expected, sorry.\n");
Edward O'Callaghan0f6a2e52020-07-09 18:16:16 +10001186 msg_pspew("r->old_reg[0].base = 0x%04X (0x005A)\n", r->old_reg[0].base);
1187 msg_pspew("r->old_reg[0].limit = 0x%04X (0x0000)\n", r->old_reg[0].limit);
1188 msg_pspew("r->old_reg[1].base = 0x%04X (0x1A00)\n", r->old_reg[1].base);
1189 msg_pspew("r->old_reg[1].limit = 0x%04X (0x0000)\n", r->old_reg[1].limit);
1190 msg_pspew("r->old_reg[2].base = 0x%04X (0x0000)\n", r->old_reg[2].base);
1191 msg_pspew("r->old_reg[2].limit = 0x%04X (0x005A)\n", r->old_reg[2].limit);
1192 msg_pspew("r->old_reg[3].base = 0x%04X (0x0000)\n", r->old_reg[3].base);
1193 msg_pspew("r->old_reg[3].limit = 0x%04X (0x1A00)\n", r->old_reg[3].limit);
stefanct1fc3a732011-09-15 23:52:55 +00001194 return ICH_RET_ERR;
1195 }
1196
Edward O'Callaghan568cd262020-05-26 23:10:45 +10001197 msg_pdbg2("Reading flash descriptors mapped by the chipset via FDOC/FDOD...");
stefanct1fc3a732011-09-15 23:52:55 +00001198 /* content section */
Edward O'Callaghan5a7ae7a2020-05-18 16:29:45 +10001199 desc->content.FLVALSIG = read_descriptor_reg(cs, 0, 0, spibar);
1200 desc->content.FLMAP0 = read_descriptor_reg(cs, 0, 1, spibar);
1201 desc->content.FLMAP1 = read_descriptor_reg(cs, 0, 2, spibar);
1202 desc->content.FLMAP2 = read_descriptor_reg(cs, 0, 3, spibar);
David Hendricksce6b2fa2011-07-11 22:12:43 -07001203
1204 /* component section */
Edward O'Callaghan5a7ae7a2020-05-18 16:29:45 +10001205 desc->component.FLCOMP = read_descriptor_reg(cs, 1, 0, spibar);
1206 desc->component.FLILL = read_descriptor_reg(cs, 1, 1, spibar);
1207 desc->component.FLPB = read_descriptor_reg(cs, 1, 2, spibar);
David Hendricksce6b2fa2011-07-11 22:12:43 -07001208
1209 /* region section */
Edward O'Callaghane7efd052020-07-03 14:57:28 +10001210 const ssize_t nr = ich_number_of_regions(cs, &desc->content);
1211 if (nr < 0) {
stefanct1fc3a732011-09-15 23:52:55 +00001212 msg_pdbg2("%s: number of regions too high (%d) - failed\n",
Edward O'Callaghane7efd052020-07-03 14:57:28 +10001213 __func__, desc->content.NR + 1);
stefanct1fc3a732011-09-15 23:52:55 +00001214 return ICH_RET_ERR;
1215 }
Edward O'Callaghane7efd052020-07-03 14:57:28 +10001216 for (i = 0; i < nr; i++)
Edward O'Callaghan5a7ae7a2020-05-18 16:29:45 +10001217 desc->region.FLREGs[i] = read_descriptor_reg(cs, 2, i, spibar);
David Hendricksce6b2fa2011-07-11 22:12:43 -07001218
1219 /* master section */
Edward O'Callaghanaef44cb2020-07-03 15:31:14 +10001220 const ssize_t nm = ich_number_of_masters(cs, &desc->content);
1221 if (nm < 0) {
1222 msg_pdbg2("%s: number of masters too high (%d) - failed\n",
1223 __func__, desc->content.NM + 1);
1224 return ICH_RET_ERR;
Duncan Lauriedbbf2222019-04-25 12:06:19 -07001225 }
Edward O'Callaghanaef44cb2020-07-03 15:31:14 +10001226 for (i = 0; i < nm; i++)
1227 desc->master.FLMSTRs[i] = read_descriptor_reg(cs, 3, i, spibar);
David Hendricksce6b2fa2011-07-11 22:12:43 -07001228
stefanct1fc3a732011-09-15 23:52:55 +00001229 /* Accessing the strap section via FDOC/D is only possible on ICH8 and
1230 * reading the upper map is impossible on all chipsets, so don't bother.
1231 */
1232
1233 msg_pdbg2(" done.\n");
1234 return ICH_RET_OK;
David Hendricksce6b2fa2011-07-11 22:12:43 -07001235}
Edward O'Callaghanb76b4e62020-07-26 13:03:12 +10001236#endif
1237
Edward O'Callaghan0055dc42020-12-06 10:33:45 +11001238/**
1239 * @brief Read a layout from the dump of an Intel ICH descriptor.
1240 *
1241 * @param layout Pointer where to store the layout.
1242 * @param dump The descriptor dump to read from.
1243 * @param len The length of the descriptor dump.
1244 *
1245 * @return 0 on success,
1246 * 1 if the descriptor couldn't be parsed,
1247 * 2 when out of memory.
1248 */
1249int layout_from_ich_descriptors(struct ich_layout *const layout, const void *const dump, const size_t len)
1250{
1251 static const char *const regions[] = {
1252 "fd", "bios", "me", "gbe", "pd", "reg5", "bios2", "reg7", "ec", "reg9", "ie",
1253 "10gbe", "reg12", "reg13", "reg14", "reg15"
1254 };
1255
1256 struct ich_descriptors desc;
1257 enum ich_chipset cs = CHIPSET_ICH_UNKNOWN;
1258 int ret = read_ich_descriptors_from_dump(dump, len, &cs, &desc);
1259 if (ret) {
1260 msg_pdbg("%s():%d, returned with value %d.\n",
1261 __func__, __LINE__, ret);
1262 return 1;
1263 }
1264
1265 memset(layout, 0x00, sizeof(*layout));
1266
1267 ssize_t i, j;
1268 const ssize_t nr = MIN(ich_number_of_regions(cs, &desc.content), (ssize_t)ARRAY_SIZE(regions));
1269 for (i = 0, j = 0; i < nr; ++i) {
1270 const chipoff_t base = ICH_FREG_BASE(desc.region.FLREGs[i]);
1271 const chipoff_t limit = ICH_FREG_LIMIT(desc.region.FLREGs[i]);
1272 if (limit <= base)
1273 continue;
1274 layout->entries[j].start = base;
1275 layout->entries[j].end = limit;
1276 layout->entries[j].included = false;
1277 layout->entries[j].name = strdup(regions[i]);
1278 if (!layout->entries[j].name)
1279 return 2;
1280 ++j;
1281 }
1282 layout->base.entries = layout->entries;
1283 layout->base.num_entries = j;
1284 return 0;
1285}
1286
Edward O'Callaghanb76b4e62020-07-26 13:03:12 +10001287#endif /* ICH_DESCRIPTORS_FROM_DUMP_ONLY */