Introduce FLASHPROG_FLAG_NON_VOLATILE_WRSR

Add a new flag to our flash context that tells us if we should use
volatile or non-volatile status-register writes by default. Use it
in the write-protection API. The logic to disable block protection
automatically stays as is for now, until we have established tools
to manually control the protection.

Change-Id: Ie9a41b6404991075e2bf76bcffbd4e9887c62c79
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.sourcearcade.org/c/flashprog/+/193
diff --git a/include/chipdrivers.h b/include/chipdrivers.h
index b38ac55..56644a0 100644
--- a/include/chipdrivers.h
+++ b/include/chipdrivers.h
@@ -71,6 +71,10 @@
 	WRSR_NON_VOLATILE_BITS	= 2,
 	WRSR_EITHER		= 3,
 };
+static inline enum wrsr_target default_wrsr_target(const struct flashctx *flash)
+{
+	return flash->flags.non_volatile_wrsr ? WRSR_NON_VOLATILE_BITS : WRSR_VOLATILE_BITS;
+}
 int spi_read_register(const struct flashctx *flash, enum flash_reg reg, uint8_t *value);
 int spi_write_register(const struct flashctx *flash, enum flash_reg reg, uint8_t value, enum wrsr_target);
 void spi_prettyprint_status_register_bit(uint8_t status, int bit);
diff --git a/include/flash.h b/include/flash.h
index 9743e3e..ed4a373 100644
--- a/include/flash.h
+++ b/include/flash.h
@@ -453,6 +453,7 @@
 		bool force_boardmismatch;
 		bool verify_after_write;
 		bool verify_whole_chip;
+		bool non_volatile_wrsr;
 	} flags;
 	/* We cache the state of the extended address register (highest byte
            of a 4BA for 3BA instructions) and the state of the 4BA mode here.
diff --git a/include/libflashprog.h b/include/libflashprog.h
index 40050e3..a2ea63c 100644
--- a/include/libflashprog.h
+++ b/include/libflashprog.h
@@ -65,6 +65,7 @@
 	FLASHPROG_FLAG_FORCE_BOARDMISMATCH,
 	FLASHPROG_FLAG_VERIFY_AFTER_WRITE,
 	FLASHPROG_FLAG_VERIFY_WHOLE_CHIP,
+	FLASHPROG_FLAG_NON_VOLATILE_WRSR,
 };
 void flashprog_flag_set(struct flashprog_flashctx *, enum flashprog_flag, bool value);
 bool flashprog_flag_get(const struct flashprog_flashctx *, enum flashprog_flag);
diff --git a/libflashprog.c b/libflashprog.c
index 2b389d1..5256657 100644
--- a/libflashprog.c
+++ b/libflashprog.c
@@ -309,6 +309,7 @@
 		case FLASHPROG_FLAG_FORCE_BOARDMISMATCH: flashctx->flags.force_boardmismatch = value; break;
 		case FLASHPROG_FLAG_VERIFY_AFTER_WRITE:	 flashctx->flags.verify_after_write = value; break;
 		case FLASHPROG_FLAG_VERIFY_WHOLE_CHIP:	 flashctx->flags.verify_whole_chip = value; break;
+		case FLASHPROG_FLAG_NON_VOLATILE_WRSR:	 flashctx->flags.non_volatile_wrsr = value; break;
 	}
 }
 
@@ -326,6 +327,7 @@
 		case FLASHPROG_FLAG_FORCE_BOARDMISMATCH: return flashctx->flags.force_boardmismatch;
 		case FLASHPROG_FLAG_VERIFY_AFTER_WRITE:	 return flashctx->flags.verify_after_write;
 		case FLASHPROG_FLAG_VERIFY_WHOLE_CHIP:	 return flashctx->flags.verify_whole_chip;
+		case FLASHPROG_FLAG_NON_VOLATILE_WRSR:	 return flashctx->flags.non_volatile_wrsr;
 		default:				 return false;
 	}
 }
diff --git a/writeprotect.c b/writeprotect.c
index 302451b..acc8714 100644
--- a/writeprotect.c
+++ b/writeprotect.c
@@ -169,7 +169,7 @@
 
 		value = (value & ~write_masks[reg]) | expected;
 
-		if (spi_write_register(flash, reg, value, WRSR_EITHER))
+		if (spi_write_register(flash, reg, value, default_wrsr_target(flash)))
 			return FLASHPROG_WP_ERR_WRITE_FAILED;
 	}