comparison loadtools/flamdsec.c @ 981:f21798eb13cf

fc-loadtool: implement flash ppb-* commands
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 02 Dec 2023 05:46:00 +0000
parents c5133c3c11b1
children 1c5b485f10ba
comparison
equal deleted inserted replaced
980:0a4d19aab608 981:f21798eb13cf
11 #include <unistd.h> 11 #include <unistd.h>
12 #include "flash.h" 12 #include "flash.h"
13 13
14 extern struct flash_bank_info flash_bank_info[2]; 14 extern struct flash_bank_info flash_bank_info[2];
15 15
16 /*
17 * Some common functions for Spansion PL-N flash: common between
18 * flash lock-state retrieval and active PPB programming.
19 */
20
21 static
22 pln_special_mode_entry(base_addr, mode_opc)
23 uint32_t base_addr;
24 uint16_t mode_opc;
25 {
26 if (do_w16(base_addr + 0xAAA, 0xAA)) {
27 bad_w16: fprintf(stderr,
28 "unexpected response to w16 in PL-N special mode entry sequence - aborting\n");
29 return(-1);
30 }
31 if (do_w16(base_addr + 0x554, 0x55))
32 goto bad_w16;
33 if (do_w16(base_addr + 0xAAA, mode_opc))
34 goto bad_w16;
35 return(0);
36 }
37
38 static
39 pln_special_mode_exit(base_addr)
40 uint32_t base_addr;
41 {
42 if (do_w16(base_addr, 0x90)) {
43 bad_w16: fprintf(stderr,
44 "unexpected response to w16 in PL-N special mode exit sequence - aborting\n");
45 return(-1);
46 }
47 if (do_w16(base_addr, 0x00))
48 goto bad_w16;
49 return(0);
50 }
51
52 /*
53 * flash lock-state implementation with its helper functions.
54 */
55
16 static 56 static
17 issue_read_id(base_addr) 57 issue_read_id(base_addr)
18 uint32_t base_addr; 58 uint32_t base_addr;
19 { 59 {
20 if (do_w16(base_addr + 0xAAA, 0xAA)) { 60 if (do_w16(base_addr + 0xAAA, 0xAA)) {
57 goto bad_w16; 97 goto bad_w16;
58 if (do_w16(base_addr + word_offset, 0x48)) 98 if (do_w16(base_addr + word_offset, 0x48))
59 goto bad_w16; 99 goto bad_w16;
60 if (do_r16(base_addr + word_offset, retp) < 0) 100 if (do_r16(base_addr + word_offset, retp) < 0)
61 return(-1); 101 return(-1);
62 return(0);
63 }
64
65 static
66 pln_special_mode_entry(base_addr, mode_opc)
67 uint32_t base_addr;
68 uint16_t mode_opc;
69 {
70 if (do_w16(base_addr + 0xAAA, 0xAA)) {
71 bad_w16: fprintf(stderr,
72 "unexpected response to w16 in PL-N special mode entry sequence - aborting\n");
73 return(-1);
74 }
75 if (do_w16(base_addr + 0x554, 0x55))
76 goto bad_w16;
77 if (do_w16(base_addr + 0xAAA, mode_opc))
78 goto bad_w16;
79 return(0);
80 }
81
82 static
83 pln_special_mode_exit(base_addr)
84 uint32_t base_addr;
85 {
86 if (do_w16(base_addr, 0x90)) {
87 bad_w16: fprintf(stderr,
88 "unexpected response to w16 in PL-N special mode exit sequence - aborting\n");
89 return(-1);
90 }
91 if (do_w16(base_addr, 0x00))
92 goto bad_w16;
93 return(0); 102 return(0);
94 } 103 }
95 104
96 flashcmd_lock_state(argc, argv, bank) 105 flashcmd_lock_state(argc, argv, bank)
97 char **argv; 106 char **argv;
168 if (pln_special_mode_exit(bi->base_addr) < 0) 177 if (pln_special_mode_exit(bi->base_addr) < 0)
169 return(-1); 178 return(-1);
170 } 179 }
171 return(0); 180 return(0);
172 } 181 }
182
183 /*
184 * Spansion PL-J PPB write functions, referenced from lock_info structures
185 * in fldevs.c device descriptions.
186 */
173 187
174 static 188 static
175 plj_ppb_write_op(base_addr, is_erase, retp) 189 plj_ppb_write_op(base_addr, is_erase, retp)
176 uint32_t base_addr; 190 uint32_t base_addr;
177 uint16_t *retp; 191 uint16_t *retp;
305 rc = plj_ppb_program_all_dualbank(reqbank); 319 rc = plj_ppb_program_all_dualbank(reqbank);
306 if (rc < 0) 320 if (rc < 0)
307 return(-1); 321 return(-1);
308 return plj_ppb_erase_cycle(reqbank); 322 return plj_ppb_erase_cycle(reqbank);
309 } 323 }
324
325 /*
326 * Front end functions for PPB operation commands.
327 */
328
329 flashcmd_ppb_program(argc, argv, bank)
330 char **argv;
331 {
332 struct flash_bank_info *bi;
333 struct amd_lock_info *li;
334 u_long offset_arg;
335 struct sector_info *sp;
336 char *strtoul_endp;
337
338 if (argc != 3) {
339 inv: fprintf(stderr, "usage: %s %s sector-offset\n",
340 argv[0], argv[1]);
341 return(-1);
342 }
343 offset_arg = strtoul(argv[2], &strtoul_endp, 16);
344 if (*strtoul_endp)
345 goto inv;
346 if (flash_detect(bank, 0) < 0)
347 return(-1);
348 bi = flash_bank_info + bank;
349 li = bi->amd_lock;
350 if (!li || !li->ppb_program_one) {
351 fprintf(stderr,
352 "Operation not supported for this flash chip type\n");
353 return(-1);
354 }
355 if (offset_arg >= bi->geom->total_size) {
356 fprintf(stderr,
357 "error: specified offset exceeds flash bank size (0x%lx)\n",
358 (u_long) bi->geom->total_size);
359 return(-1);
360 }
361 if (get_flash_sector_table(bi) < 0)
362 return(-1);
363 for (sp = bi->sectors; sp->size; sp++)
364 if (sp->start == offset_arg)
365 break;
366 if (!sp->size) {
367 fprintf(stderr,
368 "error: specified offset not aligned to a flash sector boundary\n");
369 return(-1);
370 }
371 return li->ppb_program_one(bi, sp->start);
372 }
373
374 flashcmd_ppb_program_all(argc, argv, bank)
375 char **argv;
376 {
377 struct flash_bank_info *bi;
378 struct amd_lock_info *li;
379
380 if (argc > 2) {
381 fprintf(stderr, "error: too many arguments\n");
382 return(-1);
383 }
384 if (flash_detect(bank, 0) < 0)
385 return(-1);
386 bi = flash_bank_info + bank;
387 li = bi->amd_lock;
388 if (!li || !li->ppb_program_all) {
389 fprintf(stderr,
390 "Operation not supported for this flash chip type\n");
391 return(-1);
392 }
393 return li->ppb_program_all(bank);
394 }
395
396 flashcmd_ppb_erase_all(argc, argv, bank)
397 char **argv;
398 {
399 struct flash_bank_info *bi;
400 struct amd_lock_info *li;
401
402 if (argc > 2) {
403 fprintf(stderr, "error: too many arguments\n");
404 return(-1);
405 }
406 if (flash_detect(bank, 0) < 0)
407 return(-1);
408 bi = flash_bank_info + bank;
409 li = bi->amd_lock;
410 if (!li || !li->ppb_erase_all) {
411 fprintf(stderr,
412 "Operation not supported for this flash chip type\n");
413 return(-1);
414 }
415 return li->ppb_erase_all(bank);
416 }