diff options
author | Michael Tritz <mtritz@us.ibm.com> | 2017-07-12 15:31:49 -0500 |
---|---|---|
committer | Stewart Smith <stewart@linux.vnet.ibm.com> | 2017-07-19 15:49:39 +1000 |
commit | f2c87a3d2f6df0886124636239d9950ef0abcab0 (patch) | |
tree | f696ffe06dc199d5f339f9a0e14ba034002a27f9 /external | |
parent | eae86789c72e61288514eace206588d9d1633a25 (diff) | |
download | skiboot-f2c87a3d2f6df0886124636239d9950ef0abcab0.zip skiboot-f2c87a3d2f6df0886124636239d9950ef0abcab0.tar.gz skiboot-f2c87a3d2f6df0886124636239d9950ef0abcab0.tar.bz2 |
pflash option to retrieve PNOR partition flags
This commit extends pflash with an option to retrieve and print
information for a particular partition, including the content from
"pflash -i" and a verbose list of set miscellaneous flags. -i option
is also updated to print a short list of flags in addition to the
ECC flag, with one character per flag. A test of the new option is
included in libflash/test.
Signed-off-by: Michael Tritz <mtritz@us.ibm.com>
Reviewed-by: Cyril Bur <cyril.bur@au1.ibm.com>
[stewart@linux.vnet.ibm.com: various test fixes, enable gcov]
Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'external')
-rw-r--r-- | external/pflash/pflash.c | 134 |
1 files changed, 123 insertions, 11 deletions
diff --git a/external/pflash/pflash.c b/external/pflash/pflash.c index a344987..3d172d7 100644 --- a/external/pflash/pflash.c +++ b/external/pflash/pflash.c @@ -14,6 +14,8 @@ * limitations under the License. */ +#define _GNU_SOURCE + #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -90,6 +92,7 @@ static void print_ffs_info(uint32_t toc_offset) { struct ffs_handle *ffs_handle; uint32_t other_side_offset = 0; + struct ffs_entry *ent; int rc; uint32_t i; @@ -103,25 +106,40 @@ static void print_ffs_info(uint32_t toc_offset) return; } - for (i = 0;; i++) { + for (i = 0; rc == 0; i++) { uint32_t start, size, act, end; - bool ecc; - char *name; + char *name = NULL, *flags; + int l; - 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; + + ent = ffs_entry_get(ffs_handle, i); + if (rc || !ent) { + fprintf(stderr, "Error %d scanning partitions\n", + !ent ? FFS_ERR_PART_NOT_FOUND : rc); + goto out; } + + l = asprintf(&flags, "[%c%c%c%c%c]", + has_ecc(ent) ? 'E' : '-', + 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' : '-'); + if (l < 0) + goto out; + 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; + free(flags); +out: free(name); } @@ -413,6 +431,81 @@ static void disable_4B_addresses(void) } } +static void print_partition_detail(uint32_t toc_offset, uint32_t part_id, char *name) +{ + uint32_t start, size, act, end; + struct ffs_handle *ffs_handle; + char *ent_name = NULL, *flags; + struct ffs_entry *ent; + int rc, l; + + rc = ffs_init(toc_offset, fl_total_size, bl, &ffs_handle, 0); + if (rc) { + fprintf(stderr, "Error %d opening ffs !\n", rc); + return; + } + + if (name) { + uint32_t i; + + for (i = 0;;i++) { + rc = ffs_part_info(ffs_handle, i, &ent_name, &start, &size, &act, + NULL); + if (rc == FFS_ERR_PART_NOT_FOUND) { + fprintf(stderr, "Partition with name %s doesn't exist within TOC at 0x%08x\n", name, toc_offset); + goto out; + } + if (rc || strncmp(ent_name, name, FFS_PART_NAME_MAX) == 0) { + part_id = i; + break; + } + free(ent_name); + ent_name = NULL; + } + } else { + rc = ffs_part_info(ffs_handle, part_id, &ent_name, &start, &size, &act, + NULL); + if (rc == FFS_ERR_PART_NOT_FOUND) { + fprintf(stderr, "Partition with ID %d doesn't exist within TOC at 0x%08x\n", + part_id, toc_offset); + goto out; + } + } + ent = ffs_entry_get(ffs_handle, part_id); + if (rc || !ent) { + fprintf(stderr, "Error %d scanning partitions\n", !ent ? + FFS_ERR_PART_NOT_FOUND : rc); + goto out; + } + + printf("Detailed partition information\n"); + end = start + size; + printf("Name:\n"); + printf("%s (ID=%02d)\n\n", ent_name, part_id); + printf("%-10s %-10s %-10s\n", "Start", "End", "Actual"); + printf("0x%08x 0x%08x 0x%08x\n\n", start, end, act); + + printf("Flags:\n"); + + l = asprintf(&flags, "%s%s%s%s%s", has_ecc(ent) ? "ECC [E]\n" : "", + has_flag(ent, FFS_MISCFLAGS_PRESERVED) ? "PRESERVED [P]\n" : "", + has_flag(ent, FFS_MISCFLAGS_READONLY) ? "READONLY [R]\n" : "", + has_flag(ent, FFS_MISCFLAGS_BACKUP) ? "BACKUP [B]\n" : "", + has_flag(ent, FFS_MISCFLAGS_REPROVISION) ? + "REPROVISION [F]\n" : ""); + if (l < 0) { + fprintf(stderr, "Memory allocation failure printing flags!\n"); + goto out; + } + + printf("%s", flags); + free(flags); + +out: + ffs_close(ffs_handle); + free(ent_name); +} + static void print_version(void) { printf("Open-Power Flash tool %s\n", version); @@ -494,6 +587,10 @@ 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--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"); + printf("\t\twith the -P flag.\n\n"); printf("\t-h, --help\n"); printf("\t\tThis message.\n\n"); } @@ -508,7 +605,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, detail_id = UINT_MAX; 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; @@ -516,7 +613,7 @@ int main(int argc, char *argv[]) bool show_help = false, show_version = false; bool no_action = false, tune = false; char *write_file = NULL, *read_file = NULL, *part_name = NULL; - bool ffs_toc_seen = false, direct = false; + bool ffs_toc_seen = false, direct = false, print_detail = false; int rc; while(1) { @@ -535,6 +632,7 @@ int main(int argc, char *argv[]) {"force", no_argument, NULL, 'f'}, {"flash-file", required_argument, NULL, 'F'}, {"info", no_argument, NULL, 'i'}, + {"detail", optional_argument, NULL, 'm'}, {"tune", no_argument, NULL, 't'}, {"dummy", no_argument, NULL, 'd'}, {"help", no_argument, NULL, 'h'}, @@ -622,6 +720,11 @@ int main(int argc, char *argv[]) case 'c': do_clear = true; break; + case 'm': + print_detail = true; + if (optarg) + detail_id = strtoul(optarg, NULL, 0); + break; case ':': fprintf(stderr, "Unrecognised option \"%s\" to '%c'\n", optarg, optopt); no_action = true; @@ -651,7 +754,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_detail); /* Nothing to do, if we didn't already, print usage */ if (no_action && !show_version) @@ -684,6 +787,12 @@ int main(int argc, char *argv[]) exit(1); } + if (print_detail && ((detail_id == UINT_MAX && !part_name) + || (detail_id != UINT_MAX && part_name))) { + fprintf(stderr, "--detail requires either a partition id or\n"); + fprintf(stderr, "a partition name with -P\n"); + } + /* part-name and erase-all make no sense together */ if (part_name && erase_all) { fprintf(stderr, "--partition and --erase-all are mutually" @@ -872,6 +981,9 @@ int main(int argc, char *argv[]) print_flash_info(flash_side ? 0 : ffs_toc); } + if (print_detail) + print_partition_detail(flash_side ? 0 : ffs_toc, detail_id, part_name); + /* Unlock flash (PNOR only) */ if ((erase || program || do_clear) && !bmc_flash && !flashfilename) { need_relock = arch_flash_set_wrprotect(bl, false); |