# HG changeset patch # User Mychaela Falconia # Date 1701505320 0 # Node ID 0407d14fb85432481012d1d7194a60417bb95bc5 # Parent 1c5b485f10ba39257efb6fe77b99628bca9c7ced PL-J flash PPB ops: rework for full verification of lock state diff -r 1c5b485f10ba -r 0407d14fb854 loadtools/flamdsec.c --- a/loadtools/flamdsec.c Sat Dec 02 06:04:37 2023 +0000 +++ b/loadtools/flamdsec.c Sat Dec 02 08:22:00 2023 +0000 @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include #include "flash.h" @@ -181,6 +183,52 @@ } /* + * Here comes a version of the above lock-state checking code, + * modified for use from within ppb-program-all and ppb-erase-all + * functions for chips that don't do this work internally. + */ + +static +int_lock_state_check(bi, sought_state) + struct flash_bank_info *bi; +{ + struct amd_lock_info *li = bi->amd_lock; + struct lock_group_desc *grp; + uint32_t offset, part_addr; + uint16_t word; + unsigned ng, nb; + int lock_state; + + offset = 0; + for (ng = 0; ng < li->ngroups; ng++) { + grp = li->groups + ng; + if (grp->part_begin) { + part_addr = bi->base_addr + offset; + if (issue_read_id(part_addr) < 0) + return(-1); + } + for (nb = 0; nb < grp->nblocks; nb++) { + if (do_r16(bi->base_addr + offset + 4, &word) < 0) + return(-1); + lock_state = word & 1; + if (lock_state != sought_state) + break; + offset += grp->block_size; + } + if (lock_state != sought_state) { + if (issue_reset_cmd(part_addr) < 0) + return(-1); + return(0); + } + if (grp->part_end) { + if (issue_reset_cmd(part_addr) < 0) + return(-1); + } + } + return(1); +} + +/* * Spansion PL-J PPB write functions, referenced from lock_info structures * in fldevs.c device descriptions. */ @@ -228,14 +276,14 @@ pulsecnt, pulsecnt > 1 ? "s" : ""); return amd_reset_cmd(bi); } - printf("PPB 0x%X programming FAILED, tried %u pulses\n", sector_addr, - pulsecnt); + fprintf(stderr, "PPB 0x%X programming FAILED, tried %u pulses\n", + sector_addr, pulsecnt); return(-1); } -plj_ppb_program_all_single(bank) +plj_ppb_program_all(bi) + struct flash_bank_info *bi; { - struct flash_bank_info *bi = flash_bank_info + bank; struct amd_lock_info *li = bi->amd_lock; struct lock_group_desc *grp; uint32_t offset; @@ -252,35 +300,20 @@ offset += grp->block_size; } } - return(0); -} - -plj_ppb_program_all_dualbank(reqbank) -{ - int altbank = !reqbank; - int rc; - - if (flash_detect(altbank, 0) < 0) - return(-1); - if (flash_bank_info[0].device != flash_bank_info[1].device) { - fprintf(stderr, "error: mismatch between two flash banks\n"); - return(-1); - } - printf("Programming all PPBs in flash bank 0\n"); - rc = plj_ppb_program_all_single(0); + printf("Verifying PPB programming\n"); + rc = int_lock_state_check(bi, 1); if (rc < 0) - return(-1); - printf("Programming all PPBs in flash bank 1\n"); - rc = plj_ppb_program_all_single(1); - if (rc < 0) - return(-1); - return(0); + return(rc); + if (rc) + return(0); + fprintf(stderr, "flash error: one or more PPBs failed to program\n"); + return(-1); } static -plj_ppb_erase_cycle(bank) +plj_ppb_erase_cycle(bi) + struct flash_bank_info *bi; { - struct flash_bank_info *bi = flash_bank_info + bank; uint16_t stat; unsigned pulsecnt; int rc; @@ -297,29 +330,107 @@ pulsecnt, pulsecnt > 1 ? "s" : ""); return amd_reset_cmd(bi); } - printf("PPB erase cycle FAILED, tried %u pulses\n", pulsecnt); + fprintf(stderr, "PPB erase cycle FAILED, tried %u pulses\n", pulsecnt); return(-1); } -plj_ppb_erase_all_single(bank) +plj_ppb_erase_all_single(bank, raw_mode) { + struct flash_bank_info *bi = flash_bank_info + bank; + unsigned pulsecnt; + uint16_t stat; int rc; + if (raw_mode) + return plj_ppb_erase_cycle(bi); printf("Programming all PPBs before erase cycle\n"); - rc = plj_ppb_program_all_single(bank); + rc = plj_ppb_program_all(bi); if (rc < 0) return(-1); - return plj_ppb_erase_cycle(bank); + printf("Entering PPB erase and verify loop\n"); + for (pulsecnt = 0; ; ) { + if (pulsecnt >= 1000) { + fprintf(stderr, + "flash error: unable to complete PPB erase after %u pulses\n", + pulsecnt); + return(-1); + } + rc = plj_ppb_write_op(bi->base_addr, 1, &stat); + if (rc < 0) + return(rc); + pulsecnt++; + if (stat & 1) + continue; + putchar('.'); + fflush(stdout); + rc = amd_reset_cmd(bi); + if (rc < 0) + return(rc); + rc = int_lock_state_check(bi, 0); + if (rc < 0) + return(rc); + if (rc) + break; + } + printf("\nPPB erase complete, total pulses: %u\n", pulsecnt); + return(0); } -plj_ppb_erase_all_dualbank(reqbank) +plj_ppb_erase_all_dualbank(reqbank, raw_mode) { + int altbank = !reqbank; + unsigned pulsecnt; + uint16_t stat; int rc; - rc = plj_ppb_program_all_dualbank(reqbank); + if (flash_detect(altbank, 0) < 0) + return(-1); + if (flash_bank_info[0].device != flash_bank_info[1].device) { + fprintf(stderr, "error: mismatch between two flash banks\n"); + return(-1); + } + if (raw_mode) + return plj_ppb_erase_cycle(flash_bank_info + reqbank); + printf("Programming all PPBs in flash bank 0\n"); + rc = plj_ppb_program_all(&flash_bank_info[0]); + if (rc < 0) + return(-1); + printf("Programming all PPBs in flash bank 1\n"); + rc = plj_ppb_program_all(&flash_bank_info[1]); if (rc < 0) return(-1); - return plj_ppb_erase_cycle(reqbank); + printf("Entering PPB erase and verify loop\n"); + for (pulsecnt = 0; ; ) { + if (pulsecnt >= 1000) { + fprintf(stderr, + "flash error: unable to complete PPB erase after %u pulses\n", + pulsecnt); + return(-1); + } + rc = plj_ppb_write_op(flash_bank_info[0].base_addr, 1, &stat); + if (rc < 0) + return(rc); + pulsecnt++; + if (stat & 1) + continue; + putchar('.'); + fflush(stdout); + rc = amd_reset_cmd(&flash_bank_info[0]); + if (rc < 0) + return(rc); + rc = int_lock_state_check(&flash_bank_info[0], 0); + if (rc < 0) + return(rc); + if (!rc) + continue; + rc = int_lock_state_check(&flash_bank_info[1], 0); + if (rc < 0) + return(rc); + if (rc) + break; + } + printf("\nPPB erase complete, total pulses: %u\n", pulsecnt); + return(0); } /* @@ -390,7 +501,7 @@ "Operation not supported for this flash chip type\n"); return(-1); } - return li->ppb_program_all(bank); + return li->ppb_program_all(bi); } flashcmd_ppb_erase_all(argc, argv, bank) @@ -398,9 +509,20 @@ { struct flash_bank_info *bi; struct amd_lock_info *li; + int raw_mode; - if (argc > 2) { - fprintf(stderr, "error: too many arguments\n"); + switch (argc) { + case 2: + raw_mode = 0; + break; + case 3: + if (!strcmp(argv[2], "raw")) { + raw_mode = 1; + break; + } + /* FALL THRU */ + default: + fprintf(stderr, "usage: %s %s [raw]\n", argv[0], argv[1]); return(-1); } if (flash_detect(bank, 0) < 0) @@ -412,5 +534,5 @@ "Operation not supported for this flash chip type\n"); return(-1); } - return li->ppb_erase_all(bank); + return li->ppb_erase_all(bank, raw_mode); } diff -r 1c5b485f10ba -r 0407d14fb854 loadtools/fldevs.c --- a/loadtools/fldevs.c Sat Dec 02 06:04:37 2023 +0000 +++ b/loadtools/fldevs.c Sat Dec 02 08:22:00 2023 +0000 @@ -10,8 +10,7 @@ extern struct flash_cmdset flash_cmdset_intel_w30; extern int plj_ppb_program_one(); -extern int plj_ppb_program_all_single(); -extern int plj_ppb_program_all_dualbank(); +extern int plj_ppb_program_all(); extern int plj_ppb_erase_all_single(); extern int plj_ppb_erase_all_dualbank(); @@ -441,7 +440,7 @@ .have_status_word_3 = 1, .have_mode_lock_bits = 1, .ppb_program_one = plj_ppb_program_one, - .ppb_program_all = plj_ppb_program_all_single, + .ppb_program_all = plj_ppb_program_all, .ppb_erase_all = plj_ppb_erase_all_single, }; @@ -494,7 +493,7 @@ .have_status_word_3 = 1, .have_mode_lock_bits = 1, .ppb_program_one = plj_ppb_program_one, - .ppb_program_all = plj_ppb_program_all_dualbank, + .ppb_program_all = plj_ppb_program_all, .ppb_erase_all = plj_ppb_erase_all_dualbank, }; @@ -507,7 +506,7 @@ {0x2000, 8, 0, 0, 1}}, .have_status_word_3 = 1, .ppb_program_one = plj_ppb_program_one, - .ppb_program_all = plj_ppb_program_all_dualbank, + .ppb_program_all = plj_ppb_program_all, .ppb_erase_all = plj_ppb_erase_all_dualbank, }; @@ -701,7 +700,7 @@ .have_status_word_7 = 1, .have_mode_lock_bits = 1, .ppb_program_one = plj_ppb_program_one, - .ppb_program_all = plj_ppb_program_all_dualbank, + .ppb_program_all = plj_ppb_program_all, .ppb_erase_all = plj_ppb_erase_all_dualbank, }; @@ -715,7 +714,7 @@ .have_status_word_3 = 1, .have_status_word_7 = 1, .ppb_program_one = plj_ppb_program_one, - .ppb_program_all = plj_ppb_program_all_dualbank, + .ppb_program_all = plj_ppb_program_all, .ppb_erase_all = plj_ppb_erase_all_dualbank, };