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