FreeCalypso > hg > freecalypso-tools
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 } |