FreeCalypso > hg > freecalypso-sw
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/target-utils/libload/amdflash.c Thu Jun 27 23:22:25 2013 +0000 @@ -0,0 +1,90 @@ +/* + * This module implements the AMFB and AMFW commands for programming + * AMD-style flash memories. Syntax: + * + * AMFB <baseaddr> -- sets the base address for subsequent AMFW commands + * AMFW <offset> <hexstring> -- the actual flash write operation + * + * The flash memory is assumed to be 16 bits wide. The hex string + * argument to the AMFW command is just data, with no header, address, + * length, checksum or other additions. The number of hex digits in the + * string must be a multiple of 4, and the byte order is the same as + * that of TI's *.m0 files: we interpret the string as consisting of + * 16-bit words rather than bytes. + * + * The address to which each flash write is directed is the sum of the + * base given to AMFB and the offset given to AMFW. The fixed offsets + * of 0xAAA and 0x554 (0x555 and 0x2AA in words) prescribed for the flash + * programming command sequence are also made from the base set with AMFB. + */ + +#include <sys/types.h> +#include "types.h" + +static u32 base_addr; + +void +cmd_AMFB(argbulk) + char *argbulk; +{ + char *argv[2]; + u_long addr; + + if (parse_args(argbulk, 1, 1, argv, 0) < 0) + return; + if (parse_hexarg(argv[0], 8, &addr) < 0) { + printf("ERROR: argument must be a valid 32-bit hex address\n"); + return; + } + if (addr & 1) { + printf("ERROR: odd address\n"); + return; + } + base_addr = addr; +} + +void +cmd_AMFW(argbulk) + char *argbulk; +{ + char *argv[3], *s; + u_long offset; + volatile u16 *flashptr; + u32 datum; /* needs to be u32 for decode_hex_digits() */ + int i; + + if (parse_args(argbulk, 2, 2, argv, 0) < 0) + return; + if (parse_hexarg(argv[0], 8, &offset) < 0) { + printf("ERROR: offset argument must a valid 32-bit hex value\n"); + return; + } + if (offset & 1) { + printf("ERROR: odd offset argument\n"); + return; + } + flashptr = (volatile u16 *)(base_addr + offset); + for (s = argv[1]; *s; flashptr++, s += 4) { + if (decode_hex_digits(s, 4, &datum) < 0) { + printf("ERROR: bad AMFW hex string argument\n"); + return; + } + if (*flashptr != 0xFFFF) { + printf("ERROR: flash not blank at %08X\n", + (u_long) flashptr); + return; + } + *(volatile u16 *)(base_addr + 0xAAA) = 0xAA; + *(volatile u16 *)(base_addr + 0x554) = 0x55; + *(volatile u16 *)(base_addr + 0xAAA) = 0xA0; + *flashptr = datum; + for (i = 10000; i; i--) + if (*flashptr == datum) + break; + if (!i) { + printf("ERROR: flash write timeout at %08X\n", + (u_long) flashptr); + return; + } + } +}