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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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 }