diff options
| author | Leah Rowe <leah@libreboot.org> | 2026-03-10 04:56:23 +0000 |
|---|---|---|
| committer | Leah Rowe <leah@libreboot.org> | 2026-03-10 04:58:24 +0000 |
| commit | f53a8d4f18f1d03cafd2933a112af6fef5fa98da (patch) | |
| tree | 1112afaf68f3a3601ea50633295a68d43fd38f1c /util/nvmutil/nvmutil.c | |
| parent | baca2d8883ff1a0362ea5f55bc75c013b678a889 (diff) | |
util/nvmutil: unified gbe file part I/O
Signed-off-by: Leah Rowe <leah@libreboot.org>
Diffstat (limited to 'util/nvmutil/nvmutil.c')
| -rw-r--r-- | util/nvmutil/nvmutil.c | 140 |
1 files changed, 70 insertions, 70 deletions
diff --git a/util/nvmutil/nvmutil.c b/util/nvmutil/nvmutil.c index e2864b89..d2b7ce11 100644 --- a/util/nvmutil/nvmutil.c +++ b/util/nvmutil/nvmutil.c @@ -95,7 +95,6 @@ static void open_dev_urandom(void); static void open_gbe_file(void); static void xopen(int *fd, const char *path, int flags, struct stat *st); static void read_gbe_file(void); -static void read_gbe_file_part(size_t part); static void read_checksums(void); static int good_checksum(size_t partnum); static void run_cmd(size_t c); @@ -124,13 +123,14 @@ 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 void rw_file_exact(int fd, uint8_t *mem, size_t len, - off_t off, int rw_type, const char *path, const char *rw_type_str); -static off_t gbe_file_offset(size_t part, const char *f_op); +static void rw_gbe_file_part(size_t p, int rw_type, + const char *rw_type_str); static uint8_t *gbe_mem_offset(size_t part, const char *f_op); +static off_t gbe_file_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 rw_file_exact(int fd, uint8_t *mem, size_t len, + off_t off, int rw_type, const char *path, const char *rw_type_str); static void err(int nvm_errval, const char *msg, ...); static void close_files(void); static const char *getnvmprogname(void); @@ -691,23 +691,11 @@ read_gbe_file(void) for (p = 0; p < 2; p++) { if (do_read[p]) - read_gbe_file_part(p); + rw_gbe_file_part(p, PLESEN, "pread"); } } static void -read_gbe_file_part(size_t p) -{ - size_t gbe_rw_size = command[cmd_index].rw_size; - uint8_t *mem_offset = - gbe_mem_offset(p ^ command[cmd_index].invert, "pread"); - - rw_file_exact(gbe_fd, mem_offset, - gbe_rw_size, gbe_file_offset(p, "pread"), - PLESEN, fname, "pread"); -} - -static void read_checksums(void) { size_t p; @@ -1077,7 +1065,7 @@ write_gbe_file(void) if (update_checksum) set_checksum(partnum); - write_gbe_file_part(partnum); + rw_gbe_file_part(partnum, PSCHREIB, "pwrite"); } } @@ -1191,51 +1179,40 @@ check_bin(size_t a, const char *a_name) } static void -write_gbe_file_part(size_t p) +rw_gbe_file_part(size_t p, int rw_type, + const char *rw_type_str) { size_t gbe_rw_size = command[cmd_index].rw_size; - uint8_t *mem_offset = gbe_mem_offset(p, "pwrite"); + uint8_t invert = command[cmd_index].invert; - rw_file_exact(gbe_fd, mem_offset, - gbe_rw_size, gbe_file_offset(p, "pwrite"), - PSCHREIB, fname, "pwrite"); -} - -static void -rw_file_exact(int fd, uint8_t *mem, size_t len, - off_t off, int rw_type, const char *path, - const char *rw_type_str) -{ - ssize_t rval = -1; - ssize_t rc = 0; + uint8_t *mem_offset; - if (fd < 0) - err(EIO, "%s: %s: Bad fd %d", path, rw_type_str, fd); - if (!len) - err(EIO, "%s: %s: Zero length", path, rw_type_str); + if (rw_type == SCHREIB || rw_type == PSCHREIB) + invert = 0; - for (rc = 0; rc != (ssize_t)len; rc += rval) { - if (rw_type == PSCHREIB) - rval = pwrite(fd, mem + rc, len - rc, off + rc); - else if (rw_type == SCHREIB) - rval = write(fd, mem + rc, len - rc); - else if (rw_type == PLESEN) - rval = pread(fd, mem + rc, len - rc, off + rc); - else if (rw_type == LESEN) - rval = read(fd, mem + rc, len - rc); + /* + * Inverted reads are used by copy/swap. + * E.g. read from p0 (file) to p1 (mem). + */ + mem_offset = gbe_mem_offset(p ^ invert, rw_type_str); - if (rval > -1) { - if (!rval) /* prevent infinite loop */ - err(EIO, "%s: %s: 0-byte return", - path, rw_type_str); - continue; - } + rw_file_exact(gbe_fd, mem_offset, + gbe_rw_size, gbe_file_offset(p, rw_type_str), + rw_type, fname, rw_type_str); +} - if (errno != EINTR || rval < -1) - err(EIO, "%s: %s", path, rw_type_str); +/* + * This one is similar to gbe_file_offset, + * but used to check Gbe bounds in memory, + * and it is *also* used during file I/O. + */ +static uint8_t * +gbe_mem_offset(size_t p, const char *f_op) +{ + off_t gbe_off = gbe_x_offset(p, f_op, "mem", + GBE_PART_SIZE, GBE_FILE_SIZE); - errno = 0; - } + return (uint8_t *)(buf + gbe_off); } /* @@ -1255,20 +1232,6 @@ gbe_file_offset(size_t p, const char *f_op) gbe_file_half_size, gbe_file_size); } -/* - * This one is similar to gbe_file_offset, - * but used to check Gbe bounds in memory, - * and it is *also* used during file I/O. - */ -static uint8_t * -gbe_mem_offset(size_t p, const char *f_op) -{ - off_t gbe_off = gbe_x_offset(p, f_op, "mem", - GBE_PART_SIZE, GBE_FILE_SIZE); - - return (uint8_t *)(buf + gbe_off); -} - static off_t gbe_x_offset(size_t p, const char *f_op, const char *d_type, off_t nsize, off_t ncmp) @@ -1291,6 +1254,43 @@ gbe_x_offset(size_t p, const char *f_op, const char *d_type, } static void +rw_file_exact(int fd, uint8_t *mem, size_t len, + off_t off, int rw_type, const char *path, + const char *rw_type_str) +{ + ssize_t rval = -1; + ssize_t rc = 0; + + if (fd < 0) + err(EIO, "%s: %s: Bad fd %d", path, rw_type_str, fd); + if (!len) + err(EIO, "%s: %s: Zero length", path, rw_type_str); + + for (rc = 0; rc != (ssize_t)len; rc += rval) { + if (rw_type == PSCHREIB) + rval = pwrite(fd, mem + rc, len - rc, off + rc); + else if (rw_type == SCHREIB) + rval = write(fd, mem + rc, len - rc); + else if (rw_type == PLESEN) + rval = pread(fd, mem + rc, len - rc, off + rc); + else if (rw_type == LESEN) + rval = read(fd, mem + rc, len - rc); + + if (rval > -1) { + if (!rval) /* prevent infinite loop */ + err(EIO, "%s: %s: 0-byte return", + path, rw_type_str); + continue; + } + + if (errno != EINTR || rval < -1) + err(EIO, "%s: %s", path, rw_type_str); + + errno = 0; + } +} + +static void err(int nvm_errval, const char *msg, ...) { if (nvm_errval != -1) |
