mirror of
https://codeberg.org/libreboot/lbmk.git
synced 2026-07-15 08:20:59 +02:00
util/nvmutil: unified checksum update
setchecksum and setmac update the checksum. other commands don't. this patch unified the logic, handling it in write_gbe based on command[].chksum_write Signed-off-by: Leah Rowe <leah@libreboot.org>
This commit is contained in:
+88
-85
@@ -52,7 +52,6 @@
|
||||
|
||||
static void sanitize_command_list(void);
|
||||
static void sanitize_command_index(size_t c);
|
||||
static void check_bin(size_t a, const char *a_name);
|
||||
static void check_enum_bin(size_t a, const char *a_name,
|
||||
size_t b, const char *b_name);
|
||||
static void set_cmd(int argc, char *argv[]);
|
||||
@@ -83,21 +82,21 @@ static void write_mac_part(size_t partnum);
|
||||
static void cmd_dump(void);
|
||||
static void print_mac_from_nvm(size_t partnum);
|
||||
static void hexdump(size_t partnum);
|
||||
static void cmd_setchecksum(void);
|
||||
static void set_checksum(size_t part);
|
||||
static void cmd_brick(void);
|
||||
static int good_checksum(size_t partnum);
|
||||
static uint16_t nvm_word(size_t pos16, size_t part);
|
||||
static void set_nvm_word(size_t pos16, size_t part, uint16_t val16);
|
||||
static void check_nvm_bound(size_t pos16, size_t part);
|
||||
static void write_gbe_file(void);
|
||||
static void override_part_modified(void);
|
||||
static void set_checksum(size_t part);
|
||||
static uint16_t nvm_word(size_t pos16, size_t part);
|
||||
static void set_nvm_word(size_t pos16, size_t part, uint16_t val16);
|
||||
static void set_part_modified(size_t p);
|
||||
static void check_nvm_bound(size_t pos16, size_t part);
|
||||
static void check_bin(size_t a, const char *a_name);
|
||||
static void write_gbe_file_part(size_t part);
|
||||
static off_t gbe_file_offset(size_t part, const char *f_op);
|
||||
static void *gbe_mem_offset(size_t part, const char *f_op);
|
||||
static off_t gbe_x_offset(size_t part, const char *f_op,
|
||||
const char *d_type, off_t nsize, off_t ncmp);
|
||||
static void set_part_modified(size_t p);
|
||||
static void usage(uint8_t usage_exit);
|
||||
static size_t xstrxlen(const char *scmp, size_t maxlen);
|
||||
static int xstrxcmp(const char *a, const char *b, size_t maxlen);
|
||||
@@ -293,8 +292,8 @@ static const struct commands command[] = {
|
||||
/*
|
||||
* The non-target part will not be read.
|
||||
*/
|
||||
{ CMD_SETCHECKSUM, "setchecksum", cmd_setchecksum, ARGC_4,
|
||||
NO_INVERT, SET_MOD_OFF,
|
||||
{ CMD_SETCHECKSUM, "setchecksum", NULL, ARGC_4,
|
||||
NO_INVERT, SET_MOD_N,
|
||||
ARG_PART,
|
||||
SKIP_CHECKSUM_READ, CHECKSUM_WRITE,
|
||||
NVM_SIZE },
|
||||
@@ -907,8 +906,6 @@ write_mac_part(size_t partnum)
|
||||
|
||||
printf("Wrote MAC address to part %zu: ", partnum);
|
||||
print_mac_from_nvm(partnum);
|
||||
|
||||
set_checksum(partnum);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -964,24 +961,6 @@ hexdump(size_t partnum)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cmd_setchecksum(void)
|
||||
{
|
||||
set_checksum(part);
|
||||
}
|
||||
|
||||
static void
|
||||
set_checksum(size_t p)
|
||||
{
|
||||
size_t c;
|
||||
uint16_t val16 = 0;
|
||||
|
||||
for (c = 0; c < NVM_CHECKSUM_WORD; c++)
|
||||
val16 += nvm_word(c, p);
|
||||
|
||||
set_nvm_word(NVM_CHECKSUM_WORD, p, NVM_CHECKSUM - val16);
|
||||
}
|
||||
|
||||
static void
|
||||
cmd_brick(void)
|
||||
{
|
||||
@@ -1008,6 +987,76 @@ good_checksum(size_t partnum)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
write_gbe_file(void)
|
||||
{
|
||||
size_t p;
|
||||
size_t partnum;
|
||||
uint8_t update_checksum;
|
||||
|
||||
if (gbe_flags == O_RDONLY)
|
||||
return;
|
||||
|
||||
update_checksum = command[cmd_index].chksum_write;
|
||||
|
||||
override_part_modified();
|
||||
|
||||
for (p = 0; p < 2; p++) {
|
||||
partnum = p ^ command[cmd_index].invert;
|
||||
|
||||
if (!part_modified[partnum])
|
||||
continue;
|
||||
|
||||
if (update_checksum)
|
||||
set_checksum(partnum);
|
||||
|
||||
write_gbe_file_part(partnum);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
override_part_modified(void)
|
||||
{
|
||||
uint8_t mod_type = command[cmd_index].set_modified;
|
||||
|
||||
switch (mod_type) {
|
||||
case SET_MOD_0:
|
||||
set_part_modified(0);
|
||||
break;
|
||||
case SET_MOD_1:
|
||||
set_part_modified(1);
|
||||
break;
|
||||
case SET_MOD_N:
|
||||
set_part_modified(part ^ command[cmd_index].invert);
|
||||
break;
|
||||
case SET_MOD_BOTH:
|
||||
set_part_modified(0);
|
||||
set_part_modified(1);
|
||||
break;
|
||||
case SET_MOD_OFF:
|
||||
break;
|
||||
default:
|
||||
err(EINVAL, "Unsupported set_mod type: %u",
|
||||
mod_type);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
set_checksum(size_t p)
|
||||
{
|
||||
size_t c;
|
||||
uint16_t val16;
|
||||
|
||||
check_bin(p, "part number");
|
||||
|
||||
val16 = 0;
|
||||
|
||||
for (c = 0; c < NVM_CHECKSUM_WORD; c++)
|
||||
val16 += nvm_word(c, p);
|
||||
|
||||
set_nvm_word(NVM_CHECKSUM_WORD, p, NVM_CHECKSUM - val16);
|
||||
}
|
||||
|
||||
/*
|
||||
* GbE NVM files store 16-bit (2-byte) little-endian words.
|
||||
* We must therefore swap the order when reading or writing.
|
||||
@@ -1041,6 +1090,13 @@ set_nvm_word(size_t pos16, size_t p, uint16_t val16)
|
||||
set_part_modified(p);
|
||||
}
|
||||
|
||||
static void
|
||||
set_part_modified(size_t p)
|
||||
{
|
||||
check_bin(p, "part number");
|
||||
part_modified[p] = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
check_nvm_bound(size_t c, size_t p)
|
||||
{
|
||||
@@ -1057,49 +1113,10 @@ check_nvm_bound(size_t c, size_t p)
|
||||
}
|
||||
|
||||
static void
|
||||
write_gbe_file(void)
|
||||
check_bin(size_t a, const char *a_name)
|
||||
{
|
||||
size_t p;
|
||||
size_t partnum;
|
||||
|
||||
if (gbe_flags == O_RDONLY)
|
||||
return;
|
||||
|
||||
override_part_modified();
|
||||
|
||||
for (p = 0; p < 2; p++) {
|
||||
partnum = p ^ command[cmd_index].invert;
|
||||
|
||||
if (part_modified[partnum])
|
||||
write_gbe_file_part(partnum);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
override_part_modified(void)
|
||||
{
|
||||
uint8_t mod_type = command[cmd_index].set_modified;
|
||||
|
||||
switch (mod_type) {
|
||||
case SET_MOD_0:
|
||||
set_part_modified(0);
|
||||
break;
|
||||
case SET_MOD_1:
|
||||
set_part_modified(1);
|
||||
break;
|
||||
case SET_MOD_N:
|
||||
set_part_modified(part ^ command[cmd_index].invert);
|
||||
break;
|
||||
case SET_MOD_BOTH:
|
||||
set_part_modified(0);
|
||||
set_part_modified(1);
|
||||
break;
|
||||
case SET_MOD_OFF:
|
||||
break;
|
||||
default:
|
||||
err(EINVAL, "Unsupported set_mod type: %u",
|
||||
mod_type);
|
||||
}
|
||||
if (a > 1)
|
||||
err(ECANCELED, "%s must be 0 or 1, but is %zu", a_name, a);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1190,20 +1207,6 @@ gbe_x_offset(size_t p, const char *f_op, const char *d_type,
|
||||
return off;
|
||||
}
|
||||
|
||||
static void
|
||||
set_part_modified(size_t p)
|
||||
{
|
||||
check_bin(p, "part number");
|
||||
part_modified[p] = 1;
|
||||
}
|
||||
|
||||
static void
|
||||
check_bin(size_t a, const char *a_name)
|
||||
{
|
||||
if (a > 1)
|
||||
err(ECANCELED, "%s must be 0 or 1, but is %zu", a_name, a);
|
||||
}
|
||||
|
||||
static void
|
||||
usage(uint8_t usage_exit)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user