[Skiboot] [PATCH 2/2] external/pflash: Add --clear command
Samuel Mendoza-Jonas
sam.mj at au1.ibm.com
Thu Jun 18 17:21:57 AEST 2015
On 18/06/15 17:08, Cyril Bur wrote:
> The current pflash --erase command simply sets all the bits of the flash
> back to 1 and When hostboot decides to gard everything there isn't a
> useful way to get the machine booting again as even --eraseing the GUARD
> partition won't leave the necessary ECC bits.
>
> The --clear command will erase the specified partition and then fill in the
> ECC bits.
>
> Signed-off-by: Cyril Bur <cyril.bur at au1.ibm.com>
Aside from the little comment below,
Reviewed-by: Samuel Mendoza-Jonas <sam.mj at au1.ibm.com>
> ---
> external/pflash/pflash.c | 52 +++++++++++++++++++++++++++++++++++++++++++-----
> 1 file changed, 47 insertions(+), 5 deletions(-)
>
> diff --git a/external/pflash/pflash.c b/external/pflash/pflash.c
> index 2bea98f..8a86517 100644
> --- a/external/pflash/pflash.c
> +++ b/external/pflash/pflash.c
> @@ -271,6 +271,25 @@ static void erase_range(uint32_t start, uint32_t size, bool will_program)
> }
> }
>
> +static void set_ecc(uint32_t start, uint32_t size)
> +{
> + uint32_t i = start + 8;
> + uint8_t ecc = 0;
> +
> + printf("About to erase and set ECC bits in region 0x%08x to 0x%08x\n", start, start + size);
> + check_confirm();
> + erase_range(start, size, true);
> +
> + printf("Programming ECC bits...\n");
> + progress_init(size);
> + while (i < start + size) {
> + blocklevel_write(bl, i, &ecc, sizeof(ecc));
> + i += 9;
> + progress_tick(i - start);
As discussed, you could overflow in the loop, but that would also mean you have >4GB of flash...
> + }
> + progress_end();
> +}
> +
> static void program_file(const char *file, uint32_t start, uint32_t size)
> {
> int fd, rc;
> @@ -554,6 +573,10 @@ static void print_help(const char *pname)
> printf("\t-t, --tune\n");
> printf("\t\tJust tune the flash controller & access size\n");
> printf("\t\t(Implicit for all other operations)\n\n");
> + printf("\t-c --clear\n");
> + printf("\t\tUsed to ECC clear a partition of the flash\n");
> + printf("\t\tMust be used in conjunction with -P. Will erase the\n");
> + 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-h, --help\n");
> @@ -565,7 +588,7 @@ int main(int argc, char *argv[])
> const char *pname = argv[0];
> uint32_t address = 0, read_size = 0, write_size = 0;
> uint32_t erase_start = 0, erase_size = 0;
> - bool erase = false;
> + bool erase = false, do_clear = false;
> bool program = false, erase_all = false, info = false, do_read = false;
> bool enable_4B = false, disable_4B = false, use_lpc = true;
> bool show_help = false, show_version = false;
> @@ -597,10 +620,11 @@ int main(int argc, char *argv[])
> {"debug", no_argument, NULL, 'g'},
> {"side", required_argument, NULL, 'S'},
> {"toc", required_argument, NULL, 'T'},
> + {"clear", no_argument, NULL, 'c'}
> };
> int c, oidx = 0;
>
> - c = getopt_long(argc, argv, "a:s:P:r:43Eep:fdihlvbtgS:T:",
> + c = getopt_long(argc, argv, "a:s:P:r:43Eep:fdihlvbtgS:T:c",
> long_opts, &oidx);
> if (c == EOF)
> break;
> @@ -669,6 +693,9 @@ int main(int argc, char *argv[])
> ffs_toc_seen = true;
> ffs_toc = strtoul(optarg, NULL, 0);
> break;
> + case 'c':
> + do_clear = true;
> + break;
> default:
> exit(1);
> }
> @@ -678,7 +705,7 @@ int main(int argc, char *argv[])
> * also tune them as a side effect
> */
> no_action = !erase && !program && !info && !do_read &&
> - !enable_4B && !disable_4B && !tune;
> + !enable_4B && !disable_4B && !tune && !do_clear;
>
> /* Nothing to do, if we didn't already, print usage */
> if (no_action && !show_version)
> @@ -736,6 +763,11 @@ int main(int argc, char *argv[])
> exit(1);
> }
>
> + if (do_clear && !part_name) {
> + fprintf(stderr, "--clear only supported on a partition name\n");
> + exit(1);
> + }
> +
> /* Explicitly only support two sides */
> if (flash_side != 0 && flash_side != 1) {
> fprintf(stderr, "Unexpected value for --side '%d'\n", flash_side);
> @@ -799,15 +831,24 @@ int main(int argc, char *argv[])
> /* We have a partition, adjust read/write size if needed */
> if (ffsh && ffs_index >= 0) {
> uint32_t pstart, pmaxsz, pactsize;
> + bool ecc;
> int rc;
>
> rc = ffs_part_info(ffsh, ffs_index, NULL,
> - &pstart, &pmaxsz, &pactsize, NULL);
> + &pstart, &pmaxsz, &pactsize, &ecc);
> if (rc) {
> fprintf(stderr,"Failed to get partition info\n");
> exit(1);
> }
>
> + if (!ecc && do_clear) {
> + fprintf(stderr, "The partition on which to do --clear "
> + "does not have ECC, are you sure?\n");
> + check_confirm();
> + /* Still confirm later on */
> + must_confirm = true;
> + }
> +
> /* Read size is obtained from partition "actual" size */
> if (!read_size)
> read_size = pactsize;
> @@ -873,6 +914,7 @@ int main(int argc, char *argv[])
> erase_range(erase_start, erase_size, program);
> if (program)
> program_file(write_file, address, write_size);
> -
> + if (do_clear)
> + set_ecc(address, write_size);
> return 0;
> }
>
--
-----------
LTC Ozlabs
IBM
More information about the Skiboot
mailing list