From 7367f77aa45bfbbb826b6f8cbc2318dfe5a689c7 Mon Sep 17 00:00:00 2001
From: Daniel Campello <campello@chromium.org>
Date: Mon, 19 Apr 2021 18:43:09 -0600
Subject: cli_classic.c: implement set_wp_region operation

set_wp_region allows to set the wp_range based on a layout region.

Signed-off-by: Daniel Campello <campello@chromium.org>
Change-Id: Ibad68a038ab38b9986b0d8b5f5eb6c73b20ef381
Reviewed-on: https://review.coreboot.org/c/flashrom/+/52531
Reviewed-by: Edward O'Callaghan <quasisec@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
---
 cli_classic.c | 15 +++++++++++++++
 layout.c      | 14 ++++++++++++++
 layout.h      |  2 ++
 3 files changed, 31 insertions(+)

diff --git a/cli_classic.c b/cli_classic.c
index 58e81cd9..5fd80927 100644
--- a/cli_classic.c
+++ b/cli_classic.c
@@ -65,6 +65,7 @@ static void cli_classic_usage(const char *name)
 	       "      --wp-list                     list write protect range\n"
 	       "      --wp-status                   show write protect status\n"
 	       "      --wp-range=<start>,<len>      set write protect range\n"
+	       "      --wp-region <region>          set write protect region\n"
 	       "      --flash-name                  read out the detected flash name\n"
 	       "      --flash-size                  read out the detected flash size\n"
 	       "      --fmap                        read ROM layout from fmap embedded in ROM\n"
@@ -236,6 +237,7 @@ int main(int argc, char *argv[])
 	char *pparam = NULL;
 	struct layout_include_args *include_args = NULL;
 	char *wp_mode_opt = NULL;
+	char *wp_region = NULL;
 
 	/*
 	 * Safety-guard against a user who has (mistakenly) closed
@@ -462,6 +464,10 @@ int main(int argc, char *argv[])
 			}
 #endif /* STANDALONE */
 			break;
+		case OPTION_WP_SET_REGION:
+			set_wp_region = 1;
+			wp_region = strdup(optarg);
+			break;
 		default:
 			cli_classic_abort_usage(NULL);
 			break;
@@ -772,6 +778,15 @@ int main(int argc, char *argv[])
 		ret |= wp->set_range(fill_flash, wp_start, wp_len);
 	}
 
+	if (set_wp_region && wp_region) {
+		if (get_region_range(layout, wp_region, &wp_start, &wp_len)) {
+			ret = 1;
+			goto out_release;
+		}
+		ret |= wp->set_range(fill_flash, wp_start, wp_len);
+		free(wp_region);
+	}
+
 	if (!ret && set_wp_enable) {
 		enum wp_mode wp_mode;
 
diff --git a/layout.c b/layout.c
index 7fd203d1..4d1dd560 100644
--- a/layout.c
+++ b/layout.c
@@ -184,6 +184,20 @@ static int find_romentry(struct flashrom_layout *const l, char *name, char *file
 	return 0;
 }
 
+int get_region_range(struct flashrom_layout *const l, const char *name,
+		     unsigned int *start, unsigned int *len)
+{
+	size_t i;
+	for (i = 0; i < l->num_entries; ++i) {
+		if (!strcmp(l->entries[i].name, name)) {
+			*start = l->entries[i].start;
+			*len = l->entries[i].end - l->entries[i].start + 1;
+			return 0;
+		}
+	}
+	return 1;
+}
+
 /* process -i arguments
  * returns 0 to indicate success, >0 to indicate failure
  */
diff --git a/layout.h b/layout.h
index 327f5bf8..f5740978 100644
--- a/layout.h
+++ b/layout.h
@@ -65,6 +65,8 @@ struct flashrom_layout *get_global_layout(void);
 struct flashrom_flashctx;
 const struct flashrom_layout *get_layout(const struct flashrom_flashctx *const flashctx);
 
+int get_region_range(struct flashrom_layout *const l, const char *name,
+		     unsigned int *start, unsigned int *len);
 int process_include_args(struct flashrom_layout *l, const struct layout_include_args *const args);
 const struct romentry *layout_next_included_region(const struct flashrom_layout *, chipoff_t);
 const struct romentry *layout_next_included(const struct flashrom_layout *, const struct romentry *);
-- 
cgit v1.2.3