[flashrom] [PATCH] Add cli cmds to read/write raw status register values
Niklas Söderlund
niklas.soderlund at ericsson.com
Thu Apr 5 11:31:40 CEST 2012
When working with a lot of different flash chips it's sometimes useful
to be able to print and update the status register directly as a separate
operation.
Add --print-status and --write-status command line options to that maps
to spi_read_status_register and spi_write_status_register.
The print operation reads the status register and prints it content to
the user. While the write operation takes a parameter as a hex value
(0x00 to 0xff) or a decimal value (0 to 255) and tries to write it to
the status register.
This operation is limited to flash chips that have a SPI bustype.
Signed-off-by: Niklas Söderlund <niklas.soderlund at ericsson.com>
---
cli_classic.c | 37 ++++++++++++++++++++++++++++++++-----
flash.h | 2 +-
flashrom.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 81 insertions(+), 7 deletions(-)
diff --git a/cli_classic.c b/cli_classic.c
index 972043b..87af1f3 100644
--- a/cli_classic.c
+++ b/cli_classic.c
@@ -144,11 +144,17 @@ static void cli_classic_usage(const char *name)
"device\n");
list_programmers_linebreak(37, 80, 1);
+
+ printf("\nAdvance options (use at your own risk)\n"
+ " -P | --print-status print status register\n"
+ " -W | --write-status <value> write <value> to status "
+ "register\n");
+
printf("\nYou can specify one of -h, -R, -L, "
#if CONFIG_PRINT_WIKI == 1
"-z, "
#endif
- "-E, -r, -w, -v or no operation.\n"
+ "-E, -r, -w, -v -P, -W or no operation.\n"
"If no operation is specified, flashrom will only probe for "
"flash chips.\n\n");
}
@@ -173,15 +179,18 @@ int main(int argc, char *argv[])
int list_supported_wiki = 0;
#endif
int read_it = 0, write_it = 0, erase_it = 0, verify_it = 0;
+ int statusreg_op = 0;
int dont_verify_it = 0, list_supported = 0, operation_specified = 0;
enum programmer prog = PROGRAMMER_INVALID;
int ret = 0;
- static const char optstring[] = "r:Rw:v:nVEfc:l:i:p:Lzh";
+ static const char optstring[] = "r:Rw:v:nVEfc:l:i:p:LzhPW:";
static const struct option long_options[] = {
{"read", 1, NULL, 'r'},
{"write", 1, NULL, 'w'},
{"erase", 0, NULL, 'E'},
+ {"print-status", 0, NULL, 'P'},
+ {"write-status", 1, NULL, 'W'},
{"verify", 1, NULL, 'v'},
{"noverify", 0, NULL, 'n'},
{"chip", 1, NULL, 'c'},
@@ -201,6 +210,7 @@ int main(int argc, char *argv[])
char *layoutfile = NULL;
char *tempstr = NULL;
char *pparam = NULL;
+ char *statusreg_value = NULL;
print_version();
print_banner();
@@ -270,6 +280,23 @@ int main(int argc, char *argv[])
}
erase_it = 1;
break;
+ case 'P':
+ if (++operation_specified > 1) {
+ fprintf(stderr, "More than one operation "
+ "specified. Aborting.\n");
+ cli_classic_abort_usage();
+ }
+ statusreg_op = 1;
+ break;
+ case 'W':
+ if (++operation_specified > 1) {
+ fprintf(stderr, "More than one operation "
+ "specified. Aborting.\n");
+ cli_classic_abort_usage();
+ }
+ statusreg_op = 1;
+ statusreg_value = strdup(optarg);
+ break;
case 'f':
force = 1;
break;
@@ -511,12 +538,12 @@ int main(int argc, char *argv[])
goto out_shutdown;
}
- if (!(read_it | write_it | verify_it | erase_it)) {
+ if (!(read_it | write_it | verify_it | erase_it | statusreg_op)) {
printf("No operations were specified.\n");
goto out_shutdown;
}
- if (!filename && !erase_it) {
+ if (!filename && !erase_it && !statusreg_op) {
printf("Error: No filename specified.\n");
ret = 1;
goto out_shutdown;
@@ -531,7 +558,7 @@ int main(int argc, char *argv[])
* Give the chip time to settle.
*/
programmer_delay(100000);
- return doit(fill_flash, force, filename, read_it, write_it, erase_it, verify_it);
+ return doit(fill_flash, force, filename, read_it, write_it, erase_it, verify_it, statusreg_op, statusreg_value);
out_shutdown:
programmer_shutdown();
diff --git a/flash.h b/flash.h
index 0dac13d..65ee0af 100644
--- a/flash.h
+++ b/flash.h
@@ -247,7 +247,7 @@ void print_version(void);
void print_banner(void);
void list_programmers_linebreak(int startcol, int cols, int paren);
int selfcheck(void);
-int doit(struct flashctx *flash, int force, const char *filename, int read_it, int write_it, int erase_it, int verify_it);
+int doit(struct flashctx *flash, int force, const char *filename, int read_it, int write_it, int erase_it, int verify_it, int statureg_op, const char *statusreg_op);
int read_buf_from_file(unsigned char *buf, unsigned long size, const char *filename);
int write_buf_to_file(unsigned char *buf, unsigned long size, const char *filename);
diff --git a/flashrom.c b/flashrom.c
index cad043b..b3ba376 100644
--- a/flashrom.c
+++ b/flashrom.c
@@ -31,12 +31,14 @@
#include <stdlib.h>
#include <ctype.h>
#include <getopt.h>
+#include <errno.h>
#if HAVE_UTSNAME == 1
#include <sys/utsname.h>
#endif
#include "flash.h"
#include "flashchips.h"
#include "programmer.h"
+#include "chipdrivers.h"
const char flashrom_version[] = FLASHROM_VERSION;
char *chip_to_probe = NULL;
@@ -1396,6 +1398,45 @@ int erase_and_write_flash(struct flashctx *flash, uint8_t *oldcontents,
return ret;
}
+int operate_on_statusregister(struct flashctx *flash, const char* value) {
+ long status;
+ char *endptr;
+
+ if (flash->bustype != BUS_SPI) {
+ msg_cerr("Flash is not on SPI bus. Can't operate on status register\n");
+ return 1;
+ }
+
+ if (value) {
+ /* Try to parse as hex then dec */
+ errno = 0;
+ status = strtol(value, &endptr, 0);
+ if (endptr == value || *endptr != '\0' || errno != 0) {
+ msg_cerr("Error parsing value %s for status register\n",
+ value);
+ return 1;
+ }
+
+ if (status < 0 || status > 0xFF) {
+ msg_cerr("Invalid status register value: %s\n", value);
+ return 1;
+ }
+
+ if (spi_write_status_register(flash, status)) {
+ msg_cerr("spi_write_status_register failed\n");
+ return 1;
+ }
+
+ msg_cinfo("Wrote 0x%02lx to status register\n", status);
+ }
+
+ /* Read and print current value */
+ status = spi_read_status_register(flash);
+ msg_cinfo("Status register: 0x%02lx\n", status);
+
+ return 0;
+}
+
void nonfatal_help_message(void)
{
msg_gerr("Writing to the flash chip apparently didn't do anything.\n"
@@ -1705,7 +1746,8 @@ int chip_safety_check(struct flashctx *flash, int force, int read_it,
* Besides that, the function itself is a textbook example of abysmal code flow.
*/
int doit(struct flashctx *flash, int force, const char *filename, int read_it,
- int write_it, int erase_it, int verify_it)
+ int write_it, int erase_it, int verify_it,
+ int statusreg_op, const char *statusreg_value)
{
uint8_t *oldcontents;
uint8_t *newcontents;
@@ -1718,6 +1760,11 @@ int doit(struct flashctx *flash, int force, const char *filename, int read_it,
goto out_nofree;
}
+ if (statusreg_op) {
+ ret = operate_on_statusregister(flash, statusreg_value);
+ goto out_nofree;
+ }
+
/* Given the existence of read locks, we want to unlock for read,
* erase and write.
*/
--
1.7.7
More information about the flashrom
mailing list