[Skiboot] [PATCH] pflash option to retrieve PNOR partition flags
Michael Tritz
mtritz at us.ibm.com
Fri Jun 2 13:14:44 AEST 2017
This commit extends pflash with an option to retrieve and print the
miscellaneous partition flags for a particular partition. "pflash -i"
is also updated to print the miscellaneous flags in addition to the
ECC flag, with one character per flag. A test of the new option is
included in libflash/test.
Resolves openbmc/openbmc#1351
Change-Id: Iebb8a6d34c537cecd2eb44ddf41271c8fbe25258
Signed-off-by: Michael Tritz <mtritz at us.ibm.com>
---
external/pflash/pflash.c | 87 +++++++++++++++++++++++++++++++++++---
libflash/libffs.c | 32 ++++++++++++++
libflash/libffs.h | 5 +++
libflash/test/test-miscprint.pnor | Bin 0 -> 3072 bytes
libflash/test/test-miscprint.sh | 35 +++++++++++++++
5 files changed, 153 insertions(+), 6 deletions(-)
create mode 100644 libflash/test/test-miscprint.pnor
create mode 100644 libflash/test/test-miscprint.sh
diff --git a/external/pflash/pflash.c b/external/pflash/pflash.c
index a344987e..a0e5db7c 100644
--- a/external/pflash/pflash.c
+++ b/external/pflash/pflash.c
@@ -105,19 +105,41 @@ static void print_ffs_info(uint32_t toc_offset)
for (i = 0;; i++) {
uint32_t start, size, act, end;
- bool ecc;
+ bool ecc, preserved, readonly, backup, reprovision;
char *name;
- rc = ffs_part_info(ffs_handle, i, &name, &start, &size, &act, &ecc);
+ rc = ffs_part_info(ffs_handle, i, &name, &start, &size, &act, NULL);
if (rc == FFS_ERR_PART_NOT_FOUND)
break;
if (rc) {
fprintf(stderr, "Error %d scanning partitions\n", rc);
break;
}
+
+ rc = ffs_part_flags(ffs_handle, i, &ecc, &preserved, &readonly,
+ &backup, &reprovision);
+ if (rc == FFS_ERR_PART_NOT_FOUND){
+ return;
+ }
+ if (rc) {
+ fprintf(stderr, "Error %d scanning partitions\n", rc);
+ return;
+ }
+
+ char flags [strlen("[EPRBF]")];
+ int l;
+ l = snprintf(flags, sizeof(flags), "[%s%s%s%s%s]",
+ (ecc) ? "E" : "",
+ (preserved) ? "P" : "",
+ (readonly) ? "R" : "",
+ (backup) ? "B" : "",
+ (reprovision) ? "F" : "");
+ if (strcmp(flags, "[]") == 0)
+ flags[0] = '\0';
+
end = start + size;
printf("ID=%02d %15s %08x..%08x (actual=%08x) %s\n",
- i, name, start, end, act, ecc ? "[ECC]" : "");
+ i, name, start, end, act, flags);
if (strcmp(name, "OTHER_SIDE") == 0)
other_side_offset = start;
@@ -413,6 +435,48 @@ static void disable_4B_addresses(void)
}
}
+static void print_partition_flags(uint32_t part_ID)
+{
+ bool ecc, preserved, readonly, backup, reprovision;
+
+ struct ffs_handle *ffs_handle;
+ int rc;
+
+ rc = ffs_init(0, fl_total_size, bl, &ffs_handle, 0);
+ if (rc) {
+ fprintf(stderr, "Error %d opening ffs !\n", rc);
+ return;
+ }
+
+ rc = ffs_part_flags(ffs_handle, part_ID, &ecc, &preserved, &readonly,
+ &backup, &reprovision);
+ if (rc == FFS_ERR_PART_NOT_FOUND){
+ fprintf(stderr, "Partition not found! Can't read flags.\n");
+ return;
+ }
+ if (rc) {
+ fprintf(stderr, "Error %d scanning partitions\n", rc);
+ return;
+ }
+
+ ffs_close(ffs_handle);
+
+ char buf [strlen("ECC,PRESERVED,READONLY,BACKUP,REPROVISION.")];
+ int l;
+ l = snprintf(buf, sizeof(buf), "%s%s%s%s%s",
+ (ecc) ? "ECC," : "",
+ (preserved) ? "PRESERVED," : "",
+ (readonly) ? "READONLY," : "",
+ (backup) ? "BACKUP," : "",
+ (reprovision) ? "REPROVISION." : "");
+ if (l)
+ buf[l-1] = '\0';
+
+ printf(buf);
+
+ return;
+}
+
static void print_version(void)
{
printf("Open-Power Flash tool %s\n", version);
@@ -457,6 +521,9 @@ static void print_help(const char *pname)
printf("\t-T, --toc\n");
printf("\t\tlibffs TOC on which to operate, defaults to 0.\n");
printf("\t\tleading 0x is required for interpretation of a hex value\n\n");
+ printf("\t-m --misc\n");
+ printf("\t\tReturn the misc. flags for a particular partition of a\n");
+ printf("\t\tparticular file.\n\n");
printf(" Commands:\n");
printf("\t-4, --enable-4B\n");
printf("\t\tSwitch the flash and controller to 4-bytes address\n");
@@ -508,7 +575,7 @@ void exiting(void)
int main(int argc, char *argv[])
{
const char *pname = argv[0];
- uint32_t address = 0, read_size = 0, write_size = 0;
+ uint32_t address = 0, read_size = 0, write_size = 0, part_ID = 0;
uint32_t erase_start = 0, erase_size = 0;
bool erase = false, do_clear = false;
bool program = false, erase_all = false, info = false, do_read = false;
@@ -517,6 +584,7 @@ int main(int argc, char *argv[])
bool no_action = false, tune = false;
char *write_file = NULL, *read_file = NULL, *part_name = NULL;
bool ffs_toc_seen = false, direct = false;
+ bool print_flags = false;
int rc;
while(1) {
@@ -543,11 +611,12 @@ int main(int argc, char *argv[])
{"side", required_argument, NULL, 'S'},
{"toc", required_argument, NULL, 'T'},
{"clear", no_argument, NULL, 'c'},
+ {"misc", required_argument, NULL, 'm'},
{NULL, 0, NULL, 0 }
};
int c, oidx = 0;
- c = getopt_long(argc, argv, "+:a:s:P:r:43Eep:fdihvbtgS:T:cF:",
+ c = getopt_long(argc, argv, "+:a:s:P:r:43Eep:fdihvbtgS:T:cF:m:",
long_opts, &oidx);
if (c == -1)
break;
@@ -622,6 +691,10 @@ int main(int argc, char *argv[])
case 'c':
do_clear = true;
break;
+ case 'm':
+ print_flags = true;
+ part_ID = strtoul(optarg, NULL, 10);
+ break;
case ':':
fprintf(stderr, "Unrecognised option \"%s\" to '%c'\n", optarg, optopt);
no_action = true;
@@ -651,7 +724,7 @@ int main(int argc, char *argv[])
* also tune them as a side effect
*/
no_action = no_action || (!erase && !program && !info && !do_read &&
- !enable_4B && !disable_4B && !tune && !do_clear);
+ !enable_4B && !disable_4B && !tune && !do_clear && !print_flags);
/* Nothing to do, if we didn't already, print usage */
if (no_action && !show_version)
@@ -871,6 +944,8 @@ int main(int argc, char *argv[])
*/
print_flash_info(flash_side ? 0 : ffs_toc);
}
+ if (print_flags)
+ print_partition_flags(part_ID);
/* Unlock flash (PNOR only) */
if ((erase || program || do_clear) && !bmc_flash && !flashfilename) {
diff --git a/libflash/libffs.c b/libflash/libffs.c
index 763e061c..c7b43998 100644
--- a/libflash/libffs.c
+++ b/libflash/libffs.c
@@ -198,6 +198,11 @@ bool has_ecc(struct ffs_entry *ent)
return ((ent->user.datainteg & FFS_ENRY_INTEG_ECC) != 0);
}
+bool has_flag(struct ffs_entry *ent, uint8_t FLAG)
+{
+ return ((ent->user.miscflags & FLAG) != 0);
+}
+
int ffs_init(uint32_t offset, uint32_t max_size, struct blocklevel_device *bl,
struct ffs_handle **ffs, bool mark_ecc)
{
@@ -362,6 +367,33 @@ int ffs_lookup_part(struct ffs_handle *ffs, const char *name,
return ent ? 0 : FFS_ERR_PART_NOT_FOUND;
}
+int ffs_part_flags(struct ffs_handle *ffs, uint32_t part_idx, bool *ecc,
+ bool *preserved, bool *readonly, bool *backup, bool *reprovision)
+{
+ struct ffs_entry *ent;
+
+ ent = ffs_get_part(ffs, part_idx);
+ if (!ent)
+ return FFS_ERR_PART_NOT_FOUND;
+
+ if (ecc)
+ *ecc = has_ecc(ent);
+
+ if (preserved)
+ *preserved = has_flag(ent, FFS_MISCFLAGS_PRESERVED);
+
+ if (readonly)
+ *readonly = has_flag(ent, FFS_MISCFLAGS_READONLY);
+
+ if (backup)
+ *backup = has_flag(ent, FFS_MISCFLAGS_BACKUP);
+
+ if (reprovision)
+ *reprovision = has_flag(ent, FFS_MISCFLAGS_REPROVISION);
+
+ return 0;
+}
+
int ffs_part_info(struct ffs_handle *ffs, uint32_t part_idx,
char **name, uint32_t *start,
uint32_t *total_size, uint32_t *act_size, bool *ecc)
diff --git a/libflash/libffs.h b/libflash/libffs.h
index 2c1fbd83..973feea5 100644
--- a/libflash/libffs.h
+++ b/libflash/libffs.h
@@ -92,6 +92,8 @@ struct ffs_entry_user {
bool has_ecc(struct ffs_entry *ent);
+bool has_flag(struct ffs_entry *ent, uint8_t flag);
+
/* Init */
int ffs_init(uint32_t offset, uint32_t max_size, struct blocklevel_device *bl,
@@ -122,6 +124,9 @@ void ffs_close(struct ffs_handle *ffs);
int ffs_lookup_part(struct ffs_handle *ffs, const char *name,
uint32_t *part_idx);
+int ffs_part_flags(struct ffs_handle *ffs, uint32_t part_idx, bool *ecc,
+ bool *preserved, bool *readonly, bool *backup, bool *reprovision);
+
int ffs_part_info(struct ffs_handle *ffs, uint32_t part_idx,
char **name, uint32_t *start,
uint32_t *total_size, uint32_t *act_size, bool *ecc);
diff --git a/libflash/test/test-miscprint.pnor b/libflash/test/test-miscprint.pnor
new file mode 100644
index 0000000000000000000000000000000000000000..8a84ebaf079cb0af235ecd8568c3c990456d7764
GIT binary patch
literal 3072
zcmWG=3<_ajU|@ve1|ZGKz`zWo7+63AG6--CyjqZ0RDvu9Wi$Q<0w5b?4oEYQ2Actu
zrViCVudg#8$TiqCD9qIbVI;^-2B`f^Kqi<Erx5BOtOj%e;`!_9- at XoVb#(Ff^NB>#
zg=|06?;u&IGmsR5nGWaz#Pc6*`TQ`*H6X}8%rn^2-w&n{*?v%*;rG7)OdIL+>dh;E
zIXOCehX$bN1%){*{DEnQfc**})#QN}=k{&_#q%f_4S~@R7!85Z5Eu=C(GVC7fzc2k
GKLh~mR(fav
literal 0
HcmV?d00001
diff --git a/libflash/test/test-miscprint.sh b/libflash/test/test-miscprint.sh
new file mode 100644
index 00000000..d064cf10
--- /dev/null
+++ b/libflash/test/test-miscprint.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+
+# test-miscprint.pnor is constructed as follows:
+# PRESERVED,0x00000300,0x00000100,P,/dev/zero
+# READONLY,0x00000400,0x00000100,R,/dev/zero
+# REPROVISION,0x00000500,0x00000100,F,/dev/zero
+# BACKUP,0x00000600,0x00000100,B,/dev/zero
+
+pass=true
+
+output=$(pflash -m 1 -F "$(dirname -- "$0")/test-miscprint.pnor")
+if [[ $output != "PRESERVED" ]]; then
+ pass=false
+fi
+
+output=$(pflash -m 2 -F "$(dirname -- "$0")/test-miscprint.pnor")
+if [[ $output != "READONLY" ]]; then
+ pass=false
+fi
+
+output=$(pflash -m 3 -F "$(dirname -- "$0")/test-miscprint.pnor")
+if [[ $output != "REPROVISION" ]]; then
+ pass=false
+fi
+
+output=$(pflash -m 4 -F "$(dirname -- "$0")/test-miscprint.pnor")
+if [[ $output != "BACKUP" ]]; then
+ pass=false
+fi
+
+if [[ pass ]]; then
+ echo "Test passed!"
+else
+ echo "Test failed!"
+fi
--
2.11.0 (Apple Git-81)
More information about the Skiboot
mailing list