From patchwork Thu Aug 17 23:31:04 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stewart Smith X-Patchwork-Id: 802962 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3xYMtL37CTz9t2x for ; Fri, 18 Aug 2017 09:31:38 +1000 (AEST) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3xYMtL2GcQzDrLM for ; Fri, 18 Aug 2017 09:31:38 +1000 (AEST) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Received: from mx0a-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 3xYMt34bc5zDrJx for ; Fri, 18 Aug 2017 09:31:22 +1000 (AEST) Received: from pps.filterd (m0098413.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.21/8.16.0.21) with SMTP id v7HNSpGl104040 for ; Thu, 17 Aug 2017 19:31:19 -0400 Received: from e18.ny.us.ibm.com (e18.ny.us.ibm.com [129.33.205.208]) by mx0b-001b2d01.pphosted.com with ESMTP id 2cdhun0dah-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Thu, 17 Aug 2017 19:31:19 -0400 Received: from localhost by e18.ny.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 17 Aug 2017 19:31:18 -0400 Received: from b01cxnp22036.gho.pok.ibm.com (9.57.198.26) by e18.ny.us.ibm.com (146.89.104.205) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Thu, 17 Aug 2017 19:31:17 -0400 Received: from b01ledav001.gho.pok.ibm.com (b01ledav001.gho.pok.ibm.com [9.57.199.106]) by b01cxnp22036.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id v7HNVHhj24641670; Thu, 17 Aug 2017 23:31:17 GMT Received: from b01ledav001.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id AAD112803A; Thu, 17 Aug 2017 19:31:10 -0400 (EDT) Received: from birb.localdomain (unknown [9.83.4.169]) by b01ledav001.gho.pok.ibm.com (Postfix) with SMTP id E2DF228041; Thu, 17 Aug 2017 19:31:08 -0400 (EDT) Received: by birb.localdomain (Postfix, from userid 1000) id 0A3954EC747; Fri, 18 Aug 2017 09:31:06 +1000 (AEST) From: Stewart Smith To: skiboot@lists.ozlabs.org, cyrilbur@gmail.com Date: Fri, 18 Aug 2017 09:31:04 +1000 X-Mailer: git-send-email 2.13.5 X-TM-AS-GCONF: 00 x-cbid: 17081723-0044-0000-0000-0000037ED999 X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00007563; HX=3.00000241; KW=3.00000007; PH=3.00000004; SC=3.00000222; SDB=6.00903834; UDB=6.00452813; IPR=6.00684046; BA=6.00005538; NDR=6.00000001; ZLA=6.00000005; ZF=6.00000009; ZB=6.00000000; ZP=6.00000000; ZH=6.00000000; ZU=6.00000002; MB=3.00016747; XFM=3.00000015; UTC=2017-08-17 23:31:18 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 17081723-0045-0000-0000-000007ACF01F Message-Id: <20170817233104.16927-1-stewart@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2017-08-17_13:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=2 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1707230000 definitions=main-1708170380 Subject: [Skiboot] [RFC PATCH] pflash: support exporting layout as CSV for ffspart X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" We add a -I/--csv option to pflash that takes an existing PNOR image and exports a CSV file consumable by ffspart to create a binary identical PNOR image (when combined with files matching the contents of each partition). Signed-off-by: Stewart Smith --- external/pflash/pflash.c | 150 ++++++++++++++++++++++++++++++++++++++++++++++- libflash/libffs.c | 5 ++ libflash/libffs.h | 2 + 3 files changed, 155 insertions(+), 2 deletions(-) diff --git a/external/pflash/pflash.c b/external/pflash/pflash.c index a08ea946dc81..6e9d230822cf 100644 --- a/external/pflash/pflash.c +++ b/external/pflash/pflash.c @@ -158,6 +158,105 @@ static struct ffs_handle *open_ffs(struct flash_details *flash) return ffsh; } +static bool part_in_toc(struct flash_details *flash, uint32_t toc, const char *part) +{ + uint32_t saved_toc = flash->toc; + int i; + struct ffs_handle *ffsh; + bool part_exists = false; + + flash->toc = toc; + + if (saved_toc == toc) + return true; + + ffsh = open_ffs(flash); + if (!ffsh) { + flash->toc = saved_toc; + return false; + } + + for (i = 0;; i++) { + char *name = NULL; + int rc; + rc = ffs_part_info(ffsh, i, &name, NULL, NULL, NULL, NULL); + if (rc == FFS_ERR_PART_NOT_FOUND) + break; + + if (strcmp(name, part) == 0) { + part_exists = true; + } + free(name); + } + ffs_close(ffsh); + + flash->toc = saved_toc; + + return part_exists; +} + +static void print_ffs_csv_info(struct flash_details *flash, + uint32_t toc, uint32_t next_toc) +{ + struct ffs_entry *ent; + struct ffs_handle *ffsh; + int rc; + int i; + + ffsh = open_ffs(flash); + if (!ffsh) + return; + + for (i = 0;; i++) { + uint32_t start, size, act; + char *name = NULL, *flags; + const char *fname; + int l; + + rc = ffs_part_info(ffsh, i, &name, &start, &size, &act, NULL); + if (rc == FFS_ERR_PART_NOT_FOUND) + break; + + ent = ffs_entry_get(ffsh, i); + if (rc || !ent) { + fprintf(stderr, "Error %d scanning partitions\n", + !ent ? FFS_ERR_PART_NOT_FOUND : rc); + goto out; + } + + + l = asprintf(&flags, "%s%s%s%s%s%s%s%s", + has_ecc(ent) ? "E" : "", + has_vercheck_flag(ent, FFS_VERCHECK_SHA512V) ? "V" : "", + has_vercheck_flag(ent, FFS_VERCHECK_SHA512EC) ? "I" : "", + has_flag(ent, FFS_MISCFLAGS_PRESERVED) ? "P" : "", + has_flag(ent, FFS_MISCFLAGS_READONLY) ? "R" : "", + has_flag(ent, FFS_MISCFLAGS_BACKUP) ? "B" : "", + has_flag(ent, FFS_MISCFLAGS_REPROVISION) ? "F" : "", + (!part_in_toc(flash, next_toc, name)) ? "1" : "" + ); + if (l < 0) + goto out; + + if (strcmp(name, "BACKUP_PART") == 0) + fname = "/dev/null"; + else + fname = name; + + if (!(strcmp(name, "part") == 0) && + !(strcmp(name, "OTHER_SIDE") == 0)) + printf("%s,0x%08x,0x%08x,%s,%s\n", + name, start, size, flags, fname); + + free(flags); +out: + free(name); + } + + ffs_close(ffsh); + return; +} + static void print_flash_info(struct flash_details *flash) { struct ffs_handle *ffsh; @@ -194,6 +293,42 @@ static void print_flash_info(struct flash_details *flash) flash->toc = toc; } +static void print_flash_csv_info(struct flash_details *flash) +{ + struct ffs_handle *ffsh; + uint32_t toc; + + if (bmc_flash) + return; + + toc = flash->toc; + + ffsh = open_ffs(flash); + if (!ffsh) + return; + + uint32_t start; + uint32_t next_toc = toc; + int i; + + for (i = 0;; i++) { + char *name = NULL; + int rc; + + rc = ffs_part_info(ffsh, i, &name, &start, NULL, NULL, NULL); + if (rc == FFS_ERR_PART_NOT_FOUND) + break; + + if (strcmp(name, "OTHER_SIDE") == 0) { + next_toc = start; + } + free(name); + } + ffs_close(ffsh); + + print_ffs_csv_info(flash, toc, next_toc); +} + static struct ffs_handle *open_partition(struct flash_details *flash, const char *name, uint32_t *index) { @@ -667,6 +802,8 @@ static void print_help(const char *pname) printf("\t\tpartition and then set all the ECC bits as they should be\n\n"); printf("\t-i, --info\n"); printf("\t\tDisplay some information about the flash.\n\n"); + printf("\t-I, --csv\n"); + printf("\t\tSame as -i, but output as CSV consumable by ffspart\n\n"); printf("\t--detail\n"); printf("\t\tDisplays detailed info about a particular partition.\n"); printf("\t\tAccepts a numeric partition or can be used in conjuction\n"); @@ -684,6 +821,7 @@ int main(int argc, char *argv[]) uint32_t address = 0, read_size = 0, write_size = 0, detail_id = UINT_MAX; bool erase = false, do_clear = false; bool program = false, erase_all = false, info = false, do_read = false; + bool csv_info = false; bool enable_4B = false, disable_4B = false; bool show_help = false, show_version = false; bool no_action = false, tune = false; @@ -708,6 +846,7 @@ int main(int argc, char *argv[]) {"force", no_argument, NULL, 'f'}, {"flash-file", required_argument, NULL, 'F'}, {"info", no_argument, NULL, 'i'}, + {"csv", no_argument, NULL, 'I'}, {"detail", optional_argument, NULL, 'm'}, {"tune", no_argument, NULL, 't'}, {"dummy", no_argument, NULL, 'd'}, @@ -721,7 +860,7 @@ int main(int argc, char *argv[]) }; 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:fdiIhvbtgS:T:cF:", long_opts, &oidx); if (c == -1) break; @@ -784,6 +923,10 @@ int main(int argc, char *argv[]) case 'i': info = true; break; + case 'I': + info = true; + csv_info = true; + break; case 'b': bmc_flash = true; break; @@ -1099,7 +1242,10 @@ int main(int argc, char *argv[]) * because of --size, but still respect if it came from --toc (we * assume the user knows what they're doing in that case) */ - print_flash_info(&flash); + if (csv_info) + print_flash_csv_info(&flash); + else + print_flash_info(&flash); } if (print_detail) diff --git a/libflash/libffs.c b/libflash/libffs.c index 038f594258b7..62f455a62dda 100644 --- a/libflash/libffs.c +++ b/libflash/libffs.c @@ -193,6 +193,11 @@ bool has_flag(struct ffs_entry *ent, uint16_t flag) return ((ent->user.miscflags & flag) != 0); } +bool has_vercheck_flag(struct ffs_entry *ent, uint8_t flag) +{ + return ((ent->user.vercheck & flag) != 0); +} + struct ffs_entry *ffs_entry_get(struct ffs_handle *ffs, uint32_t index) { int i = 0; diff --git a/libflash/libffs.h b/libflash/libffs.h index a0f65a05c8d2..c9f8c950aa16 100644 --- a/libflash/libffs.h +++ b/libflash/libffs.h @@ -94,6 +94,8 @@ bool has_ecc(struct ffs_entry *ent); bool has_flag(struct ffs_entry *ent, uint16_t flag); +bool has_vercheck_flag(struct ffs_entry *ent, uint8_t flag); + /* Init */ int ffs_init(uint32_t offset, uint32_t max_size, struct blocklevel_device *bl,