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 }