[Skiboot] [PATCH 1/1] pflash option to retrieve PNOR partition flags

Michael Tritz mtritz at us.ibm.com
Mon May 8 08:23:09 AEST 2017


This commit extends pflash with an option to retrieve and print the
partition flags for a particular partition. In a separate commit,
the generate-squashfs tool will be updated to utilize this new
option.

Resolves openbmc/openbmc#1351

Signed-off-by: Michael Tritz <mtritz at us.ibm.com>
---
 external/pflash/pflash.c | 61 +++++++++++++++++++++++++++++++++++++++++++++---
 libflash/libffs.c        | 32 +++++++++++++++++++++++++
 libflash/libffs.h        |  5 ++++
 3 files changed, 95 insertions(+), 3 deletions(-)

diff --git a/external/pflash/pflash.c b/external/pflash/pflash.c
index a344987e..b9e5efd6 100644
--- a/external/pflash/pflash.c
+++ b/external/pflash/pflash.c
@@ -413,6 +413,50 @@ 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);
+
+	if(ecc)
+		printf("ECC%s", preserved||readonly||backup||reprovision ? "," : "");
+
+	if(preserved)
+		printf("PRESERVED%s", readonly || backup || reprovision ? "," : "");
+
+	if(readonly)
+		printf("READONLY%s", backup || reprovision ? "," : "");
+
+	if(backup)
+		printf("BACKUP%s", reprovision ? "," : "");
+
+	if(reprovision)
+		printf("REPROVISION");
+
+	return;
+}
+
 static void print_version(void)
 {
 	printf("Open-Power Flash tool %s\n", version);
@@ -457,6 +501,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 +555,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 +564,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 +591,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 +671,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 +704,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 +924,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 dca40188..208c322c 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);
-- 
2.11.0 (Apple Git-81)



More information about the Skiboot mailing list