summaryrefslogtreecommitdiffstats
path: root/util
diff options
context:
space:
mode:
authorPatrick Rudolph <patrick.rudolph@9elements.com>2020-05-25 12:18:11 +0200
committerPatrick Georgi <pgeorgi@google.com>2020-06-17 09:16:51 +0000
commit802cbee78956afa6fad209d279f6d99e33ea85dd (patch)
tree57a725392cbb47b1b5b8d5e80081c9d9575ee68c /util
parentaeacf8b444d575abdaf52acf23edf8bc89f52d21 (diff)
downloadcoreboot-802cbee78956afa6fad209d279f6d99e33ea85dd.tar.gz
coreboot-802cbee78956afa6fad209d279f6d99e33ea85dd.tar.bz2
coreboot-802cbee78956afa6fad209d279f6d99e33ea85dd.zip
ifdtool: Improve PCH strap handling
Read the PCH Strap Length field in FLMAP1 as described in the "SPI Programming Guide" and print the number of fields specified there. This code dumps the following straps: * Intel GM45: 8 straps * Intel C216: 72 straps * Intel C240: 360 straps Add a new function to easily set PCH straps, which is useful for debugging. Change-Id: Ieb7891b214d82c984379794de9b3fe1a6d0d3466 Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/41693 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Philipp Hug <philipp@hug.cx> Reviewed-by: Christian Walter <christian.walter@9elements.com> Reviewed-by: Philipp Deppenwiese <zaolin.daisuki@gmail.com>
Diffstat (limited to 'util')
-rw-r--r--util/ifdtool/ifdtool.c63
-rw-r--r--util/ifdtool/ifdtool.h2
2 files changed, 54 insertions, 11 deletions
diff --git a/util/ifdtool/ifdtool.c b/util/ifdtool/ifdtool.c
index fcc760e807f1..3db3977bf501 100644
--- a/util/ifdtool/ifdtool.c
+++ b/util/ifdtool/ifdtool.c
@@ -145,7 +145,11 @@ static fpsba_t *find_fpsba(char *image, int size)
return NULL;
fpsba_t *fpsba =
(fpsba_t *) (image + (((fdb->flmap1 >> 16) & 0xff) << 4));
- return PTR_IN_RANGE(fpsba, image, size) ? fpsba : NULL;
+
+ int SSL = ((fdb->flmap1 >> 24) & 0xff) * sizeof(uint32_t);
+ if ((((char *)fpsba) + SSL) >= (image + size))
+ return NULL;
+ return fpsba;
}
static fmsba_t *find_fmsba(char *image, int size)
@@ -516,13 +520,15 @@ static void dump_fcba(const fcba_t *fcba)
(fcba->flpb & 0xfff) << 12);
}
-static void dump_fpsba(const fpsba_t *fpsba)
+static void dump_fpsba(const fdbar_t *fdb, const fpsba_t *fpsba)
{
unsigned int i;
+ /* SoC Strap Length, aka PSL, aka ISL */
+ unsigned int SSL = ((fdb->flmap1 >> 24) & 0xff) * sizeof(uint32_t);
+
printf("Found PCH Strap Section\n");
- for (i = 0; i < ARRAY_SIZE(fpsba->pchstrp); i++)
- printf("PCHSTRP%u:%s 0x%08x\n", i,
- i < 10 ? " " : "", fpsba->pchstrp[i]);
+ for (i = 0; i < SSL; i++)
+ printf("PCHSTRP%-3u: 0x%08x\n", i, fpsba->pchstrp[i]);
if (ifd_version >= IFD_VERSION_2) {
printf("HAP bit is %sset\n",
@@ -751,7 +757,7 @@ static void dump_fd(char *image, int size)
if (frba && fcba && fpsba && fmba && fmsba) {
dump_frba(frba);
dump_fcba(fcba);
- dump_fpsba(fpsba);
+ dump_fpsba(fdb, fpsba);
dump_fmba(fmba);
dump_fmsba(fmsba);
} else {
@@ -1099,6 +1105,23 @@ static void unlock_descriptor(const char *filename, char *image, int size)
write_image(filename, image, size);
}
+static void set_pchstrap(fpsba_t *fpsba, const fdbar_t *fdb, const int strap,
+ const unsigned int value)
+{
+ if (!fpsba || !fdb) {
+ fprintf(stderr, "Internal error\n");
+ exit(EXIT_FAILURE);
+ }
+
+ /* SoC Strap Length, aka PSL, aka ISL */
+ int SSL = ((fdb->flmap1 >> 24) & 0xff) * sizeof(uint32_t);
+ if (strap >= SSL) {
+ fprintf(stderr, "Strap index %d out of range (max: %d)\n", strap, SSL);
+ exit(EXIT_FAILURE);
+ }
+ fpsba->pchstrp[strap] = value;
+}
+
/* Set the AltMeDisable (or HAP for >= IFD_VERSION_2) */
static void fpsba_set_altmedisable(fpsba_t *fpsba, fmsba_t *fmsba, bool altmedisable)
{
@@ -1428,6 +1451,8 @@ static void print_usage(const char *name)
" cnl - Cannon Lake\n"
" glk - Gemini Lake\n"
" sklkbl - Skylake/Kaby Lake\n"
+ " -S | --setpchstrap Write a PCH strap\n"
+ " -V | --newvalue The new value to write into PCH strap specified by -S\n"
" -v | --version: print the version\n"
" -h | --help: print this help\n\n"
"<region> is one of Descriptor, BIOS, ME, GbE, Platform\n"
@@ -1439,12 +1464,14 @@ int main(int argc, char *argv[])
int opt, option_index = 0;
int mode_dump = 0, mode_extract = 0, mode_inject = 0, mode_spifreq = 0;
int mode_em100 = 0, mode_locked = 0, mode_unlocked = 0, mode_validate = 0;
- int mode_layout = 0, mode_newlayout = 0, mode_density = 0;
+ int mode_layout = 0, mode_newlayout = 0, mode_density = 0, mode_setstrap = 0;
int mode_altmedisable = 0, altmedisable = 0;
char *region_type_string = NULL, *region_fname = NULL;
const char *layout_fname = NULL;
char *new_filename = NULL;
int region_type = -1, inputfreq = 0;
+ unsigned int value = 0;
+ unsigned int pchstrap = 0;
unsigned int new_density = 0;
enum spi_frequency spifreq = SPI_FREQUENCY_20MHZ;
@@ -1466,15 +1493,24 @@ int main(int argc, char *argv[])
{"help", 0, NULL, 'h'},
{"platform", 0, NULL, 'p'},
{"validate", 0, NULL, 't'},
+ {"setpchstrap", 1, NULL, 'S'},
+ {"newvalue", 1, NULL, 'V'},
{0, 0, 0, 0}
};
- while ((opt = getopt_long(argc, argv, "df:D:C:M:xi:n:O:s:p:eluvth?",
+ while ((opt = getopt_long(argc, argv, "S:V:df:D:C:M:xi:n:O:s:p:eluvth?",
long_options, &option_index)) != EOF) {
switch (opt) {
case 'd':
mode_dump = 1;
break;
+ case 'S':
+ mode_setstrap = 1;
+ pchstrap = strtoul(optarg, NULL, 0);
+ break;
+ case 'V':
+ value = strtoul(optarg, NULL, 0);
+ break;
case 'f':
mode_layout = 1;
layout_fname = strdup(optarg);
@@ -1674,7 +1710,7 @@ int main(int argc, char *argv[])
}
}
- if ((mode_dump + mode_layout + mode_extract + mode_inject +
+ if ((mode_dump + mode_layout + mode_extract + mode_inject + mode_setstrap +
mode_newlayout + (mode_spifreq | mode_em100 | mode_unlocked |
mode_locked) + mode_altmedisable + mode_validate) > 1) {
fprintf(stderr, "You may not specify more than one mode.\n\n");
@@ -1682,7 +1718,7 @@ int main(int argc, char *argv[])
exit(EXIT_FAILURE);
}
- if ((mode_dump + mode_layout + mode_extract + mode_inject +
+ if ((mode_dump + mode_layout + mode_extract + mode_inject + mode_setstrap +
mode_newlayout + mode_spifreq + mode_em100 + mode_locked +
mode_unlocked + mode_density + mode_altmedisable + mode_validate) == 0) {
fprintf(stderr, "You need to specify a mode.\n\n");
@@ -1772,6 +1808,13 @@ int main(int argc, char *argv[])
if (mode_unlocked)
unlock_descriptor(new_filename, image, size);
+ if (mode_setstrap) {
+ fpsba_t *fpsba = find_fpsba(image, size);
+ const fdbar_t *fdb = find_fd(image, size);
+ set_pchstrap(fpsba, fdb, pchstrap, value);
+ write_image(new_filename, image, size);
+ }
+
if (mode_altmedisable) {
fpsba_t *fpsba = find_fpsba(image, size);
fmsba_t *fmsba = find_fmsba(image, size);
diff --git a/util/ifdtool/ifdtool.h b/util/ifdtool/ifdtool.h
index 5af98cf2ce10..3b16d4984aa0 100644
--- a/util/ifdtool/ifdtool.h
+++ b/util/ifdtool/ifdtool.h
@@ -105,7 +105,7 @@ typedef struct {
} __attribute__((packed)) fcba_t;
// pch strap
-#define MAX_PCHSTRP 18
+#define MAX_PCHSTRP 1024
typedef struct {
uint32_t pchstrp[MAX_PCHSTRP];