# HG changeset patch # User Michael Spacefalcon # Date 1372375345 0 # Node ID cc1d2413991a02019974c4ca0ed74b9ad485a5c0 # Parent 6fb41cfa773de59aeb44e4141fab66ef49b73833 loadagent: AMD flash write implemented diff -r 6fb41cfa773d -r cc1d2413991a target-utils/libload/Makefile --- a/target-utils/libload/Makefile Thu Jun 27 04:56:17 2013 +0000 +++ b/target-utils/libload/Makefile Thu Jun 27 23:22:25 2013 +0000 @@ -5,7 +5,7 @@ RANLIB= arm-elf-ranlib OBJS= cmd_blankchk.o cmd_crc32.o cmd_memdump_human.o cmd_memdump_machine.o \ - cmd_memload.o hexstrings.o + cmd_memload.o amdflash.o hexstrings.o all: libload.a diff -r 6fb41cfa773d -r cc1d2413991a target-utils/libload/amdflash.c --- /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 -- sets the base address for subsequent AMFW commands + * AMFW -- 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 +#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; + } + } +} diff -r 6fb41cfa773d -r cc1d2413991a target-utils/loadagent/cmdtab.c --- a/target-utils/loadagent/cmdtab.c Thu Jun 27 04:56:17 2013 +0000 +++ b/target-utils/loadagent/cmdtab.c Thu Jun 27 23:22:25 2013 +0000 @@ -1,5 +1,7 @@ #include "cmdtab.h" +extern void cmd_AMFB(); +extern void cmd_AMFW(); extern void cmd_blankchk(); extern void cmd_crc32(); extern void cmd_jump(); @@ -16,6 +18,8 @@ extern void cmd_memload(); const struct cmdtab cmdtab[] = { + {"AMFB", cmd_AMFB}, + {"AMFW", cmd_AMFW}, {"DUMP", cmd_memdump_machine}, {"ML", cmd_memload}, {"baud", cmd_baud_switch},