From e08899fcf4127de5cb2ad2dd134539d41f7e33b0 Mon Sep 17 00:00:00 2001 From: Brian Norris Date: Thu, 22 Jun 2023 11:07:18 -0700 Subject: [PATCH] libflashrom: Add layout "exclude" API Layouts can be expensive to derive (reading from flash), so we might want to reuse a layout for different purposes. Today, it's not possible to undo a flashrom_layout_include_region() operation (to, say, operate on a different region). Add such an API. Change-Id: I7ea3e0674f25e34bf2cfc8f464ae7ca1c1a3fbfd Signed-off-by: Brian Norris Reviewed-on: https://review.coreboot.org/c/flashrom/+/76005 Tested-by: build bot (Jenkins) Reviewed-by: Edward O'Callaghan Reviewed-by: Nikolai Artemiev --- bindings/rust/libflashrom/src/lib.rs | 26 ++++++++++++++++++++++++++ include/libflashrom.h | 10 ++++++++++ layout.c | 16 ++++++++++++++++ libflashrom.map | 1 + tests/layout.c | 5 +++++ 5 files changed, 58 insertions(+) diff --git a/bindings/rust/libflashrom/src/lib.rs b/bindings/rust/libflashrom/src/lib.rs index 95fde56e9..3f3fbc076 100644 --- a/bindings/rust/libflashrom/src/lib.rs +++ b/bindings/rust/libflashrom/src/lib.rs @@ -879,6 +879,32 @@ impl Layout { } } + /// Exclude a region + /// + /// # Errors + /// + /// This function will return an error if the region is not a valid CString, + /// or if libflashrom returns an error. + pub fn exclude_region(&mut self, region: &str) -> std::result::Result<(), RegionError> { + let err = { + let region = CString::new(region)?; + unsafe { + libflashrom_sys::flashrom_layout_exclude_region( + self.layout.as_mut(), + region.as_ptr(), + ) + } + }; + if err != 0 { + Err(RegionError::ErrorCode(ErrorCode { + function: "flashrom_layout_exclude_region", + code: err, + })) + } else { + Ok(()) + } + } + /// Get the [`Range`] for the given region /// /// # Errors diff --git a/include/libflashrom.h b/include/libflashrom.h index 490ef03b7..e87776be1 100644 --- a/include/libflashrom.h +++ b/include/libflashrom.h @@ -420,6 +420,16 @@ int flashrom_layout_add_region(struct flashrom_layout *layout, size_t start, siz * 1 if the given name can't be found. */ int flashrom_layout_include_region(struct flashrom_layout *layout, const char *name); +/** + * @brief Mark given region as not included. + * + * @param layout The layout to alter. + * @param name The name of the region to exclude. + * + * @return 0 on success, + * 1 if the given name can't be found. + */ +int flashrom_layout_exclude_region(struct flashrom_layout *layout, const char *name); /** * @brief Get given region's offset and length. * diff --git a/layout.c b/layout.c index cddd9087e..e46e61ae5 100644 --- a/layout.c +++ b/layout.c @@ -217,6 +217,17 @@ static int include_region(struct flashrom_layout *const l, const char *name, return 1; } +/* returns 0 to indicate success, 1 to indicate failure */ +static int exclude_region(struct flashrom_layout *const l, const char *name) +{ + struct romentry *const entry = _layout_entry_by_name(l, name); + if (entry) { + entry->included = false; + return 0; + } + return 1; +} + /* returns -1 if an entry is not found, 0 if found. */ static int romentry_exists(struct flashrom_layout *const l, char *name, char *file) { @@ -441,6 +452,11 @@ int flashrom_layout_include_region(struct flashrom_layout *const layout, const c return include_region(layout, name, NULL); } +int flashrom_layout_exclude_region(struct flashrom_layout *const layout, const char *name) +{ + return exclude_region(layout, name); +} + int flashrom_layout_get_region_range(struct flashrom_layout *const l, const char *name, unsigned int *start, unsigned int *len) { diff --git a/libflashrom.map b/libflashrom.map index e3c7a769f..77abf727d 100644 --- a/libflashrom.map +++ b/libflashrom.map @@ -15,6 +15,7 @@ LIBFLASHROM_1.0 { flashrom_image_write; flashrom_init; flashrom_layout_add_region; + flashrom_layout_exclude_region; flashrom_layout_get_region_range; flashrom_layout_include_region; flashrom_layout_new; diff --git a/tests/layout.c b/tests/layout.c index e71debfe2..917d77e24 100644 --- a/tests/layout.c +++ b/tests/layout.c @@ -110,6 +110,8 @@ void layout_pass_sanity_checks_test_success(void **state) unsigned int region_start = 0x00021000; unsigned int region_end = 0x00031000; + unsigned int region2_start = 0x00041000; + unsigned int region2_end = 0x00051000; unsigned int start = 0; unsigned int len = 0; @@ -119,6 +121,9 @@ void layout_pass_sanity_checks_test_success(void **state) assert_int_equal(0, flashrom_layout_new(&layout)); assert_int_equal(0, flashrom_layout_add_region(layout, region_start, region_end, "region")); assert_int_equal(0, flashrom_layout_include_region(layout, "region")); + assert_int_equal(0, flashrom_layout_add_region(layout, region2_start, region2_end, "region2")); + assert_int_equal(0, flashrom_layout_include_region(layout, "region2")); + assert_int_equal(0, flashrom_layout_exclude_region(layout, "region2")); printf("done\n"); printf("Asserting region range... ");