aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Walle <michael@walle.cc>2021-03-16 11:40:15 +0100
committerDavid Oberhollenzer <david.oberhollenzer@sigma-star.at>2021-06-12 17:16:33 +0200
commit51d6820f49ca4a203cf30dd99bc83f25d569eb4b (patch)
treef7955ee2d8d27fb2b1325ad583ffce6f409a4fab
parent2ca0bbf296d6f7ce51b8255347c7fd08afa33651 (diff)
mtd-utils: Add flash_otp_erase
On some SPI NOR flashes you can actually erase the OTP region until its fully locked. Add a small utility for that. Signed-off-by: Michael Walle <michael@walle.cc> Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
-rw-r--r--.gitignore1
-rw-r--r--include/mtd/mtd-abi.h2
-rw-r--r--misc-utils/Makemodule.am4
-rw-r--r--misc-utils/flash_otp_erase.c64
4 files changed, 70 insertions, 1 deletions
diff --git a/.gitignore b/.gitignore
index 4c04c1a..1644ef0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,6 +24,7 @@ fectest
flash_erase
flash_lock
flash_otp_dump
+flash_otp_erase
flash_otp_info
flash_otp_lock
flash_otp_write
diff --git a/include/mtd/mtd-abi.h b/include/mtd/mtd-abi.h
index bcd7496..a54c386 100644
--- a/include/mtd/mtd-abi.h
+++ b/include/mtd/mtd-abi.h
@@ -201,6 +201,8 @@ struct otp_info {
* modes (see "struct mtd_write_req")
*/
#define MEMWRITE _IOWR('M', 24, struct mtd_write_req)
+/* Erase a given range of user data (must be in mode %MTD_FILE_MODE_OTP_USER) */
+#define OTPERASE _IOW('M', 25, struct otp_info)
/*
* Obsolete legacy interface. Keep it in order not to break userspace
diff --git a/misc-utils/Makemodule.am b/misc-utils/Makemodule.am
index b15c119..bc69b1c 100644
--- a/misc-utils/Makemodule.am
+++ b/misc-utils/Makemodule.am
@@ -32,6 +32,8 @@ flash_otp_dump_SOURCES = misc-utils/flash_otp_dump.c
flash_otp_lock_SOURCES = misc-utils/flash_otp_lock.c
+flash_otp_erase_SOURCES = misc-utils/flash_otp_erase.c
+
flash_otp_write_SOURCES = misc-utils/flash_otp_write.c
flashcp_SOURCES = misc-utils/flashcp.c
@@ -43,7 +45,7 @@ sbin_PROGRAMS += \
ftl_format doc_loadbios ftl_check mtd_debug docfdisk \
serve_image recv_image fectest flash_erase flash_lock \
flash_unlock flash_otp_info flash_otp_dump flash_otp_lock \
- flash_otp_write flashcp mtdpart
+ flash_otp_erase flash_otp_write flashcp mtdpart
MISC_SH = \
misc-utils/flash_eraseall
diff --git a/misc-utils/flash_otp_erase.c b/misc-utils/flash_otp_erase.c
new file mode 100644
index 0000000..771e230
--- /dev/null
+++ b/misc-utils/flash_otp_erase.c
@@ -0,0 +1,64 @@
+/*
+ * flash_otp_erase.c -- erase area of One-Time-Program data
+ */
+
+#define PROGRAM_NAME "flash_otp_erase"
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+
+#include <mtd/mtd-user.h>
+#include "common.h"
+
+int main(int argc,char *argv[])
+{
+ int fd, val, ret, offset, size;
+ struct otp_info info;
+ char *p;
+
+ if (argc != 5 || strcmp(argv[1], "-u")) {
+ fprintf(stderr, "Usage: %s -u <device> <offset> <size>\n", PROGRAM_NAME);
+ fprintf(stderr, "offset and size must match on OTP region boundaries\n");
+ return EINVAL;
+ }
+
+ fd = open(argv[2], O_WRONLY);
+ if (fd < 0) {
+ perror(argv[2]);
+ return errno;
+ }
+
+ val = MTD_OTP_USER;
+ ret = ioctl(fd, OTPSELECT, &val);
+ if (ret < 0) {
+ perror("OTPSELECT");
+ return errno;
+ }
+
+ offset = strtoul(argv[3], &p, 0);
+ if (argv[3][0] == 0 || *p != 0) {
+ fprintf(stderr, "%s: bad offset value\n", PROGRAM_NAME);
+ return ERANGE;
+ }
+
+ size = strtoul(argv[4], &p, 0);
+ if (argv[4][0] == 0 || *p != 0) {
+ fprintf(stderr, "%s: bad size value\n", PROGRAM_NAME);
+ return ERANGE;
+ }
+
+ info.start = offset;
+ info.length = size;
+ ret = ioctl(fd, OTPERASE, &info);
+ if (ret < 0) {
+ perror("OTPERASE");
+ return errno;
+ }
+
+ return 0;
+}