FreeCalypso > hg > freecalypso-sw
annotate target-utils/libload/amdflash.c @ 400:f027c6fbe37e
fc-loadtool flash: first round of refactoring for CFI
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Sun, 15 Jun 2014 20:05:54 +0000 |
parents | cc1d2413991a |
children |
rev | line source |
---|---|
63
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
1 /* |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
2 * This module implements the AMFB and AMFW commands for programming |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
3 * AMD-style flash memories. Syntax: |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
4 * |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
5 * AMFB <baseaddr> -- sets the base address for subsequent AMFW commands |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
6 * AMFW <offset> <hexstring> -- the actual flash write operation |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
7 * |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
8 * The flash memory is assumed to be 16 bits wide. The hex string |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
9 * argument to the AMFW command is just data, with no header, address, |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
10 * length, checksum or other additions. The number of hex digits in the |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
11 * string must be a multiple of 4, and the byte order is the same as |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
12 * that of TI's *.m0 files: we interpret the string as consisting of |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
13 * 16-bit words rather than bytes. |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
14 * |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
15 * The address to which each flash write is directed is the sum of the |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
16 * base given to AMFB and the offset given to AMFW. The fixed offsets |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
17 * of 0xAAA and 0x554 (0x555 and 0x2AA in words) prescribed for the flash |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
18 * programming command sequence are also made from the base set with AMFB. |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
19 */ |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
20 |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
21 #include <sys/types.h> |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
22 #include "types.h" |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
23 |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
24 static u32 base_addr; |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
25 |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
26 void |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
27 cmd_AMFB(argbulk) |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
28 char *argbulk; |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
29 { |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
30 char *argv[2]; |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
31 u_long addr; |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
32 |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
33 if (parse_args(argbulk, 1, 1, argv, 0) < 0) |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
34 return; |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
35 if (parse_hexarg(argv[0], 8, &addr) < 0) { |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
36 printf("ERROR: argument must be a valid 32-bit hex address\n"); |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
37 return; |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
38 } |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
39 if (addr & 1) { |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
40 printf("ERROR: odd address\n"); |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
41 return; |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
42 } |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
43 base_addr = addr; |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
44 } |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
45 |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
46 void |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
47 cmd_AMFW(argbulk) |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
48 char *argbulk; |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
49 { |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
50 char *argv[3], *s; |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
51 u_long offset; |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
52 volatile u16 *flashptr; |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
53 u32 datum; /* needs to be u32 for decode_hex_digits() */ |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
54 int i; |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
55 |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
56 if (parse_args(argbulk, 2, 2, argv, 0) < 0) |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
57 return; |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
58 if (parse_hexarg(argv[0], 8, &offset) < 0) { |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
59 printf("ERROR: offset argument must a valid 32-bit hex value\n"); |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
60 return; |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
61 } |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
62 if (offset & 1) { |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
63 printf("ERROR: odd offset argument\n"); |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
64 return; |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
65 } |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
66 flashptr = (volatile u16 *)(base_addr + offset); |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
67 for (s = argv[1]; *s; flashptr++, s += 4) { |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
68 if (decode_hex_digits(s, 4, &datum) < 0) { |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
69 printf("ERROR: bad AMFW hex string argument\n"); |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
70 return; |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
71 } |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
72 if (*flashptr != 0xFFFF) { |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
73 printf("ERROR: flash not blank at %08X\n", |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
74 (u_long) flashptr); |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
75 return; |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
76 } |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
77 *(volatile u16 *)(base_addr + 0xAAA) = 0xAA; |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
78 *(volatile u16 *)(base_addr + 0x554) = 0x55; |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
79 *(volatile u16 *)(base_addr + 0xAAA) = 0xA0; |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
80 *flashptr = datum; |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
81 for (i = 10000; i; i--) |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
82 if (*flashptr == datum) |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
83 break; |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
84 if (!i) { |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
85 printf("ERROR: flash write timeout at %08X\n", |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
86 (u_long) flashptr); |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
87 return; |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
88 } |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
89 } |
cc1d2413991a
loadagent: AMD flash write implemented
Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
parents:
diff
changeset
|
90 } |