Bill XIE has uploaded this change for review. ( https://review.coreboot.org/21437
Change subject: ifdtool: port the feature to set AltMeDisable/HAP bit here ......................................................................
ifdtool: port the feature to set AltMeDisable/HAP bit here
Port the newest feature of me_cleaner to ifdtool (https://github.com/corna/me_cleaner/ , Discussed in https://github.com/corna/me_cleaner/issues/53 ) to set AltMeDisable (or HAP for skylake/ME11) bit to the IFD to disable ME.
In this commit I use (ifd_version >= IFD_VERSION_2) to judge whether HAP instead AltMeDisable should be set, since this condition is only fulfilled on skylake or newer platforms.
Change-Id: I9a2ecc60cfbb9ee9d96f15be3d53226cb428729a Signed-off-by: Bill XIE persmule@gmail.com --- M util/ifdtool/ifdtool.c 1 file changed, 54 insertions(+), 5 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/37/21437/1
diff --git a/util/ifdtool/ifdtool.c b/util/ifdtool/ifdtool.c index 66848c0..8ff41a4 100644 --- a/util/ifdtool/ifdtool.c +++ b/util/ifdtool/ifdtool.c @@ -95,6 +95,14 @@ return (frba_t *) (image + (((fdb->flmap0 >> 16) & 0xff) << 4)); }
+static fpsba_t *find_fpsba(char *image, int size) +{ + fdbar_t *fdb = find_fd(image, size); + if (!fdb) + return NULL; + return (fpsba_t *) (image + (((fdb->flmap1 >> 16) & 0xff) << 4)); +} + /* * There is no version field in the descriptor so to determine * if this is a new descriptor format we check the hardcoded SPI @@ -595,8 +603,7 @@ dump_oem((const uint8_t *)image + 0xf00); dump_frba(find_frba(image, size)); dump_fcba(find_fcba(image, size)); - dump_fpsba((const fpsba_t *) - (image + (((fdb->flmap1 >> 16) & 0xff) << 4))); + dump_fpsba(find_fpsba(image, size)); dump_fmba(find_fmba(image, size)); dump_fmsba((const fmsba_t *) (image + (((fdb->flmap2) & 0xff) << 4))); } @@ -845,6 +852,29 @@ fmba->flmstr3 = 0x08080000 | (fmba->flmstr3 & 0xffff); } + } +} + +/* Toggle the AltMeDisable (or HAP for >= IFD_VERSION_2) */ +void fpsba_toggle_altmedisable(fpsba_t *fpsba, + enum toggle_mode altmedisable) +{ + if (ifd_version >= IFD_VERSION_2) { + printf("%sting the HAP bit to %s Intel ME...\n", + altmedisable?"Set":"Unset", + altmedisable?"disable":"enable"); + if (altmedisable == TM_set) + fpsba->pchstrp[0] |= (1 << 16); + else + fpsba->pchstrp[0] &= ~(1 << 16); + } else { + printf("%sting the AltMeDisable to %s Intel ME...\n", + altmedisable?"Set":"Unset", + altmedisable?"disable":"enable"); + if (altmedisable == TM_set) + fpsba->pchstrp[10] |= (1 << 7); + else + fpsba->pchstrp[10] &= ~(1 << 7); } }
@@ -1166,6 +1196,8 @@ " -j | --jail Unlock firmware descriptor and ME region,\n" " and remove the ME/TXE's Read/Write permissions\n" " to the other regions\n" + " -A | --altmedisable <0|1> Toggle the AltMeDisable (or HAP for skylake or\n" + " newer platform) bit to disable ME\n" " -p | --platform Add platform-specific quirks\n" " aplk - Apollo Lake\n" " -v | --version: print the version\n" @@ -1180,6 +1212,7 @@ int mode_dump = 0, mode_extract = 0, mode_inject = 0, mode_spifreq = 0; int mode_em100 = 0, mode_locked = 0, mode_unlocked = 0, mode_jail = 0; int mode_layout = 0, mode_newlayout = 0, mode_density = 0; + int mode_altmedisable = 0, altmedisable = 0; char *region_type_string = NULL, *region_fname = NULL; const char *layout_fname = NULL; int region_type = -1, inputfreq = 0; @@ -1195,6 +1228,7 @@ {"spifreq", 1, NULL, 's'}, {"density", 1, NULL, 'D'}, {"chip", 1, NULL, 'C'}, + {"altmedisable", 1, NULL, 'A'}, {"em100", 0, NULL, 'e'}, {"lock", 0, NULL, 'l'}, {"unlock", 0, NULL, 'u'}, @@ -1205,7 +1239,7 @@ {0, 0, 0, 0} };
- while ((opt = getopt_long(argc, argv, "df:D:C:xi:n:s:p:elujvh?", + while ((opt = getopt_long(argc, argv, "df:D:C:A:xi:n:s:p:elujvh?", long_options, &option_index)) != EOF) { switch (opt) { case 'd': @@ -1309,6 +1343,15 @@ exit(EXIT_FAILURE); } break; + case 'A': + mode_altmedisable = 1; + altmedisable = strtol(optarg, NULL, 0); + if (selected_chip > 1) { + fprintf(stderr, "error: Illegal value\n"); + print_usage(argv[0]); + exit(EXIT_FAILURE); + } + break; case 's': // Parse the requested SPI frequency inputfreq = strtol(optarg, NULL, 0); @@ -1387,7 +1430,7 @@
if ((mode_dump + mode_layout + mode_extract + mode_inject + mode_newlayout + (mode_spifreq | mode_em100 | mode_unlocked | - mode_locked)) > 1) { + mode_locked) + mode_altmedisable) > 1) { fprintf(stderr, "You may not specify more than one mode.\n\n"); print_usage(argv[0]); exit(EXIT_FAILURE); @@ -1395,7 +1438,7 @@
if ((mode_dump + mode_layout + mode_extract + mode_inject + mode_newlayout + mode_spifreq + mode_em100 + mode_locked + - mode_unlocked + mode_density) == 0) { + mode_unlocked + mode_density + mode_altmedisable) == 0) { fprintf(stderr, "You need to specify a mode.\n\n"); print_usage(argv[0]); exit(EXIT_FAILURE); @@ -1468,6 +1511,12 @@ write_image(filename, image, size); }
+ if (mode_altmedisable) { + fpsba_t* fpsba = find_fpsba(image, size); + fpsba_toggle_altmedisable(fpsba, altmedisable); + write_image(filename, image, size); + } + free(image);
return 0;