[Skiboot] [RFC PATCH 02/13] libflash/libffs: Add helpers for the treatment of partition flags

Cyril Bur cyril.bur at au1.ibm.com
Tue Aug 29 16:24:55 AEST 2017


There is an increasing number of programs wanting to print partition
flags as strings or wanting to parse strings back into a binary
structure.

This patch introduces a to_string() function and its complement so that
there can be one place where the code exists.

Signed-off-by: Cyril Bur <cyril.bur at au1.ibm.com>
---
 libflash/ffs.h    |  1 +
 libflash/libffs.c | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 libflash/libffs.h |  7 +++++
 3 files changed, 101 insertions(+), 1 deletion(-)

diff --git a/libflash/ffs.h b/libflash/ffs.h
index 18722538..81818fdf 100644
--- a/libflash/ffs.h
+++ b/libflash/ffs.h
@@ -76,6 +76,7 @@ enum ffs_type {
 #define FFS_MISCFLAGS_READONLY 0x40
 #define FFS_MISCFLAGS_BACKUP 0x20
 #define FFS_MISCFLAGS_REPROVISION 0x10
+#define FFS_MISCFLAGS_GOLDEN 0x01
 
 /**
  * struct __ffs_entry_user - On flash user data entries
diff --git a/libflash/libffs.c b/libflash/libffs.c
index 038f5942..66b1d3f2 100644
--- a/libflash/libffs.c
+++ b/libflash/libffs.c
@@ -188,6 +188,88 @@ static int ffs_entry_to_cpu(struct ffs_hdr *hdr,
 	return rc;
 }
 
+char *ffs_entry_user_to_string(struct ffs_entry_user *user)
+{
+	char *ret;
+
+	if (!user)
+		return NULL;
+
+	ret = strdup("-------");
+	if (!ret)
+		return NULL;
+
+	if (user->datainteg & FFS_ENRY_INTEG_ECC)
+		ret[0] = 'E';
+
+	if (user->vercheck & FFS_VERCHECK_SHA512V)
+		ret[1] = 'V';
+
+	if (user->vercheck & FFS_VERCHECK_SHA512EC)
+		ret[2] = 'I';
+
+	if (user->miscflags & FFS_MISCFLAGS_PRESERVED)
+		ret[3] = 'P';
+
+	if (user->miscflags & FFS_MISCFLAGS_READONLY)
+		ret[4] = 'R';
+
+	if (user->miscflags & FFS_MISCFLAGS_BACKUP)
+		ret[5] = 'B';
+
+	if (user->miscflags & FFS_MISCFLAGS_REPROVISION)
+		ret[6] = 'F';
+
+	if (user->miscflags & FFS_MISCFLAGS_GOLDEN)
+		ret[7] = 'G';
+
+	return ret;
+}
+
+int ffs_string_to_entry_user(const char *flags, int nflags,
+		struct ffs_entry_user *user)
+{
+	int i;
+
+	if (!user || !flags)
+		return FLASH_ERR_PARM_ERROR;
+
+	memset(user, 0, sizeof(struct ffs_entry_user));
+	for (i = 0; i < nflags; i++) {
+		switch (flags[i]) {
+		case 'E':
+			user->datainteg |= FFS_ENRY_INTEG_ECC;
+			break;
+		case 'V':
+			user->vercheck |= FFS_VERCHECK_SHA512V;
+			break;
+		case 'I':
+			user->vercheck |= FFS_VERCHECK_SHA512EC;
+			break;
+		case 'P':
+			user->miscflags |= FFS_MISCFLAGS_PRESERVED;
+			break;
+		case 'R':
+			user->miscflags |= FFS_MISCFLAGS_READONLY;
+			break;
+		case 'B':
+			user->miscflags |= FFS_MISCFLAGS_BACKUP;
+			break;
+		case 'F':
+			user->miscflags |= FFS_MISCFLAGS_REPROVISION;
+			break;
+		case 'G':
+			user->miscflags |= FFS_MISCFLAGS_GOLDEN;
+			break;
+		default:
+			FL_DBG("Unknown flag '%c'\n", flags[i]);
+			return FLASH_ERR_PARM_ERROR;
+		}
+	}
+
+	return 0;
+}
+
 bool has_flag(struct ffs_entry *ent, uint16_t flag)
 {
 	return ((ent->user.miscflags & flag) != 0);
@@ -723,13 +805,23 @@ int ffs_entry_user_set(struct ffs_entry *ent, struct ffs_entry_user *user)
 	if (user->vercheck & ~(FFS_VERCHECK_SHA512V | FFS_VERCHECK_SHA512EC))
 		return -1;
 	if (user->miscflags & ~(FFS_MISCFLAGS_PRESERVED | FFS_MISCFLAGS_BACKUP |
-				FFS_MISCFLAGS_READONLY | FFS_MISCFLAGS_REPROVISION))
+				FFS_MISCFLAGS_READONLY | FFS_MISCFLAGS_REPROVISION | FFS_MISCFLAGS_GOLDEN))
 		return -1;
 
 	memcpy(&ent->user, user, sizeof(*user));
 	return 0;
 }
 
+struct ffs_entry_user ffs_entry_user_get(struct ffs_entry *ent)
+{
+	struct ffs_entry_user user = { 0 };
+
+	if (ent)
+		memcpy(&user, &ent->user, sizeof(user));
+
+	return user;
+}
+
 int ffs_entry_new(const char *name, uint32_t base, uint32_t size, struct ffs_entry **r)
 {
 	struct ffs_entry *ret;
diff --git a/libflash/libffs.h b/libflash/libffs.h
index a0f65a05..6f8e34e3 100644
--- a/libflash/libffs.h
+++ b/libflash/libffs.h
@@ -88,8 +88,13 @@ struct ffs_entry_user {
 #define FFS_MISCFLAGS_READONLY 0x40
 #define FFS_MISCFLAGS_BACKUP 0x20
 #define FFS_MISCFLAGS_REPROVISION 0x10
+#define FFS_MISCFLAGS_GOLDEN 0x01
 
 
+int ffs_string_to_entry_user(const char *flags, int nflags,
+		struct ffs_entry_user *user);
+char *ffs_entry_user_to_string(struct ffs_entry_user *user);
+
 bool has_ecc(struct ffs_entry *ent);
 
 bool has_flag(struct ffs_entry *ent, uint16_t flag);
@@ -144,6 +149,8 @@ int ffs_entry_user_set(struct ffs_entry *ent, struct ffs_entry_user *user);
 
 int ffs_entry_add(struct ffs_hdr *hdr, struct ffs_entry *entry, unsigned int side);
 
+struct ffs_entry_user ffs_entry_user_get(struct ffs_entry *ent);
+
 int ffs_hdr_create_backup(struct ffs_hdr *hdr);
 
 int ffs_hdr_finalise(struct blocklevel_device *bl, struct ffs_hdr *hdr);
-- 
2.14.1



More information about the Skiboot mailing list