Vladimir Serbinenko (phcoder@gmail.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/4799
-gerrit
commit 942f369945af73b17e9e78c55a7abcff85f49ca2 Author: Vladimir Serbinenko phcoder@gmail.com Date: Fri Jan 24 23:26:58 2014 +0100
Check option checksumming
Change-Id: I31b881a24baadfee9a3de2be0ea64c64f2421184 Signed-off-by: Vladimir Serbinenko phcoder@gmail.com --- util/nvramtool/layout.c | 78 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+)
diff --git a/util/nvramtool/layout.c b/util/nvramtool/layout.c index 1872e2c..6c4fee3 100644 --- a/util/nvramtool/layout.c +++ b/util/nvramtool/layout.c @@ -433,6 +433,53 @@ int is_checksum_name(const char name[]) && !strcmp(name, version_param_name); }
+static int +should_be_checksummed(const char *name) +{ + if (strcmp (name, "check_sum") == 0) + return 0; + /* clock & co. Shouldn't be checksummed. */ + if (strcmp (name, "reserved_memory") == 0) + return 0; + + /* Reboot byte. modified by coreboot without updating checksum. */ + if (strcmp (name, "boot_option") == 0) + return 0; + if (strcmp (name, "last_boot") == 0) + return 0; + if (strcmp (name, "ECC_memory") == 0) + return 0; + if (strcmp (name, "reboot_bits") == 0) + return 0; + + /* AMD stuff. Not to be checksummed. */ + if (strcmp (name, "amd_reserved") == 0) + return 0; + + /* i945 S3 registers. Should be checksummed eventually. */ + if (strcmp (name, "C0WL0REOST") == 0 + || strcmp (name, "C1WL0REOST") == 0 + || strcmp (name, "RCVENMT") == 0 + || strcmp (name, "C0DRT1") == 0 + || strcmp (name, "C1DRT1") == 0) + return 0; + + /* Same for ivy/sandy. */ + if (strcmp (name, "mrc_scrambler_seed") == 0 + || strcmp (name, "mrc_scrambler_seed_s3") == 0 + || strcmp (name, "mrc_scrambler_seed_chk") == 0) + return 0; + + /* And GM45. */ + if (strcmp (name, "read_training_results") == 0) + return 0; + + /* ChromeOS. */ + if (strcmp (name, "vbnv") == 0) + return 0; + return 1; +} + /**************************************************************************** * checksum_layout_to_bytes * @@ -444,6 +491,8 @@ int is_checksum_name(const char name[]) int checksum_layout_to_bytes(cmos_checksum_layout_t * layout) { unsigned start, end, index; + struct cmos_entry_item_t *item; + int not_checksummed_options = 0;
start = layout->summed_area_start; end = layout->summed_area_end; @@ -476,6 +525,35 @@ int checksum_layout_to_bytes(cmos_checksum_layout_t * layout) if (areas_overlap(start, end - start + 1, index, index + 1)) return LAYOUT_CHECKSUM_OVERLAPS_SUMMED_AREA;
+ for (item = cmos_entry_list; + (item != NULL); + item = item->next) { + int expected; + /* Only one possible value would be valid for "version", + so it's verified anyway and we don't care if it's in + checksummed region or not. + */ + if (strcmp (item->item.name, "version") == 0) + continue; + + /* Problem with intel/jarell and sitemp/g1p1. */ + if (strcmp (item->item.name, "power_up_watchdog") == 0 + || strcmp (item->item.name, "cmos_defaults_loaded") == 0) + continue; + + expected = should_be_checksummed(item->item.name); + if (expected != areas_overlap(8 * start, 8 * end - 8 * start + 7, + item->item.bit, + item->item.length)) { + fprintf (stderr, "option %s is%s checksummed\n", + item->item.name, + expected ? " not" : ""); + not_checksummed_options = 1; + } + } + if (not_checksummed_options) + exit(1); + layout->summed_area_start = start; layout->summed_area_end = end; layout->checksum_at = index;