# HG changeset patch # User Mychaela Falconia # Date 1701495960 0 # Node ID f21798eb13cfe492b84815721e6df3b930dc4007 # Parent 0a4d19aab608cea9015cc3e268b922602e5d3544 fc-loadtool: implement flash ppb-* commands diff -r 0a4d19aab608 -r f21798eb13cf loadtools/flamdsec.c --- a/loadtools/flamdsec.c Sat Dec 02 04:31:58 2023 +0000 +++ b/loadtools/flamdsec.c Sat Dec 02 05:46:00 2023 +0000 @@ -13,6 +13,46 @@ extern struct flash_bank_info flash_bank_info[2]; +/* + * Some common functions for Spansion PL-N flash: common between + * flash lock-state retrieval and active PPB programming. + */ + +static +pln_special_mode_entry(base_addr, mode_opc) + uint32_t base_addr; + uint16_t mode_opc; +{ + if (do_w16(base_addr + 0xAAA, 0xAA)) { +bad_w16: fprintf(stderr, +"unexpected response to w16 in PL-N special mode entry sequence - aborting\n"); + return(-1); + } + if (do_w16(base_addr + 0x554, 0x55)) + goto bad_w16; + if (do_w16(base_addr + 0xAAA, mode_opc)) + goto bad_w16; + return(0); +} + +static +pln_special_mode_exit(base_addr) + uint32_t base_addr; +{ + if (do_w16(base_addr, 0x90)) { +bad_w16: fprintf(stderr, +"unexpected response to w16 in PL-N special mode exit sequence - aborting\n"); + return(-1); + } + if (do_w16(base_addr, 0x00)) + goto bad_w16; + return(0); +} + +/* + * flash lock-state implementation with its helper functions. + */ + static issue_read_id(base_addr) uint32_t base_addr; @@ -62,37 +102,6 @@ return(0); } -static -pln_special_mode_entry(base_addr, mode_opc) - uint32_t base_addr; - uint16_t mode_opc; -{ - if (do_w16(base_addr + 0xAAA, 0xAA)) { -bad_w16: fprintf(stderr, -"unexpected response to w16 in PL-N special mode entry sequence - aborting\n"); - return(-1); - } - if (do_w16(base_addr + 0x554, 0x55)) - goto bad_w16; - if (do_w16(base_addr + 0xAAA, mode_opc)) - goto bad_w16; - return(0); -} - -static -pln_special_mode_exit(base_addr) - uint32_t base_addr; -{ - if (do_w16(base_addr, 0x90)) { -bad_w16: fprintf(stderr, -"unexpected response to w16 in PL-N special mode exit sequence - aborting\n"); - return(-1); - } - if (do_w16(base_addr, 0x00)) - goto bad_w16; - return(0); -} - flashcmd_lock_state(argc, argv, bank) char **argv; { @@ -171,6 +180,11 @@ return(0); } +/* + * Spansion PL-J PPB write functions, referenced from lock_info structures + * in fldevs.c device descriptions. + */ + static plj_ppb_write_op(base_addr, is_erase, retp) uint32_t base_addr; @@ -307,3 +321,96 @@ return(-1); return plj_ppb_erase_cycle(reqbank); } + +/* + * Front end functions for PPB operation commands. + */ + +flashcmd_ppb_program(argc, argv, bank) + char **argv; +{ + struct flash_bank_info *bi; + struct amd_lock_info *li; + u_long offset_arg; + struct sector_info *sp; + char *strtoul_endp; + + if (argc != 3) { +inv: fprintf(stderr, "usage: %s %s sector-offset\n", + argv[0], argv[1]); + return(-1); + } + offset_arg = strtoul(argv[2], &strtoul_endp, 16); + if (*strtoul_endp) + goto inv; + if (flash_detect(bank, 0) < 0) + return(-1); + bi = flash_bank_info + bank; + li = bi->amd_lock; + if (!li || !li->ppb_program_one) { + fprintf(stderr, + "Operation not supported for this flash chip type\n"); + return(-1); + } + if (offset_arg >= bi->geom->total_size) { + fprintf(stderr, + "error: specified offset exceeds flash bank size (0x%lx)\n", + (u_long) bi->geom->total_size); + return(-1); + } + if (get_flash_sector_table(bi) < 0) + return(-1); + for (sp = bi->sectors; sp->size; sp++) + if (sp->start == offset_arg) + break; + if (!sp->size) { + fprintf(stderr, + "error: specified offset not aligned to a flash sector boundary\n"); + return(-1); + } + return li->ppb_program_one(bi, sp->start); +} + +flashcmd_ppb_program_all(argc, argv, bank) + char **argv; +{ + struct flash_bank_info *bi; + struct amd_lock_info *li; + + if (argc > 2) { + fprintf(stderr, "error: too many arguments\n"); + return(-1); + } + if (flash_detect(bank, 0) < 0) + return(-1); + bi = flash_bank_info + bank; + li = bi->amd_lock; + if (!li || !li->ppb_program_all) { + fprintf(stderr, + "Operation not supported for this flash chip type\n"); + return(-1); + } + return li->ppb_program_all(bank); +} + +flashcmd_ppb_erase_all(argc, argv, bank) + char **argv; +{ + struct flash_bank_info *bi; + struct amd_lock_info *li; + + if (argc > 2) { + fprintf(stderr, "error: too many arguments\n"); + return(-1); + } + if (flash_detect(bank, 0) < 0) + return(-1); + bi = flash_bank_info + bank; + li = bi->amd_lock; + if (!li || !li->ppb_erase_all) { + fprintf(stderr, + "Operation not supported for this flash chip type\n"); + return(-1); + } + return li->ppb_erase_all(bank); +} diff -r 0a4d19aab608 -r f21798eb13cf loadtools/flmain.c --- a/loadtools/flmain.c Sat Dec 02 04:31:58 2023 +0000 +++ b/loadtools/flmain.c Sat Dec 02 05:46:00 2023 +0000 @@ -97,6 +97,9 @@ extern int flashcmd_erase(); extern int flashcmd_erase_program_boot(); extern int flashcmd_lock_state(); +extern int flashcmd_ppb_program(); +extern int flashcmd_ppb_program_all(); +extern int flashcmd_ppb_erase_all(); extern int flashcmd_progbin_wrap(); extern int flashcmd_program_m0(); extern int flashcmd_program_srec(); @@ -125,6 +128,9 @@ {"id", flashcmd_id}, {"info", flashcmd_info}, {"lock-state", flashcmd_lock_state}, + {"ppb-program", flashcmd_ppb_program}, + {"ppb-program-all", flashcmd_ppb_program_all}, + {"ppb-erase-all", flashcmd_ppb_erase_all}, {"program-bin", flashcmd_progbin_wrap}, {"program-m0", flashcmd_program_m0}, {"program-srec", flashcmd_program_srec},