writeprotect.c: Split register value/mask calculation into pure func

Extract the code that converts `struct wp_bits` into a collection of
register values and bit masks out of `write_wp_bits()` into a new
function.

This avoids monadic transformer stacks where unit-testing cannot
penetrate well to give suitable coverage, therefore keep the bit
logic in a separate pure function.

Tested: ninja test
Tested: flashrom --wp-{{dis,en}able,range,list,status} on dedede

Change-Id: I604478ecbb70392c5584bf5d87c76b6f20f882b1
Signed-off-by: Nikolai Artemiev <nartemiev@google.com>
Original-Reviewed-on: https://review.coreboot.org/c/flashrom/+/69846
Original-Reviewed-by: Sergii Dmytruk <sergii.dmytruk@3mdeb.com>
Original-Reviewed-by: Edward O'Callaghan <quasisec@chromium.org>
Reviewed-on: https://review.coreboot.org/c/flashrom-stable/+/71013
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Nico Huber <nico.h@gmx.de>
diff --git a/writeprotect.c b/writeprotect.c
index e3a1410..a3c9ce2 100644
--- a/writeprotect.c
+++ b/writeprotect.c
@@ -105,7 +105,7 @@
 	return ret;
 }
 
-/** Helper function for write_wp_bits(). */
+/** Helper function for get_wp_bits_reg_values(). */
 static void set_reg_bit(
 		uint8_t *reg_values, uint8_t *bit_masks, uint8_t *write_masks,
 		struct reg_bit_info bit, uint8_t value)
@@ -120,17 +120,16 @@
 	}
 }
 
-/** Write WP configuration bits to the flash's registers. */
-static enum flashrom_wp_result write_wp_bits(struct flashctx *flash, struct wp_bits bits)
+/** Convert wp_bits to register values and write masks */
+static void get_wp_bits_reg_values(
+		uint8_t *reg_values, uint8_t *bit_masks, uint8_t *write_masks,
+		const struct reg_bit_map *reg_bits, struct wp_bits bits)
 {
 	size_t i;
-	enum flash_reg reg;
-	const struct reg_bit_map *reg_bits = &flash->chip->reg_bits;
 
-	/* Convert wp_bits to register values and masks */
-	uint8_t reg_values[MAX_REGISTERS] = {0};
-	uint8_t bit_masks[MAX_REGISTERS] = {0};		/* masks of valid bits */
-	uint8_t write_masks[MAX_REGISTERS] = {0};	/* masks of written bits */
+	memset(reg_values, 0, sizeof(uint8_t) * MAX_REGISTERS);
+	memset(bit_masks, 0, sizeof(uint8_t) * MAX_REGISTERS);
+	memset(write_masks, 0, sizeof(uint8_t) * MAX_REGISTERS);
 
 	for (i = 0; i < bits.bp_bit_count; i++)
 		set_reg_bit(reg_values, bit_masks, write_masks, reg_bits->bp[i], bits.bp[i]);
@@ -142,6 +141,16 @@
 	set_reg_bit(reg_values, bit_masks, write_masks, reg_bits->srl, bits.srl);
 	/* Note: always setting WPS bit to zero until its fully supported. */
 	set_reg_bit(reg_values, bit_masks, write_masks, reg_bits->wps, 0);
+}
+
+/** Write WP configuration bits to the flash's registers. */
+static enum flashrom_wp_result write_wp_bits(struct flashctx *flash, struct wp_bits bits)
+{
+	enum flash_reg reg;
+	uint8_t reg_values[MAX_REGISTERS];
+	uint8_t bit_masks[MAX_REGISTERS];	/* masks of valid bits */
+	uint8_t write_masks[MAX_REGISTERS];	/* masks of written bits */
+	get_wp_bits_reg_values(reg_values, bit_masks, write_masks, &flash->chip->reg_bits, bits);
 
 	/* Write each register whose value was updated */
 	for (reg = STATUS1; reg < MAX_REGISTERS; reg++) {