diff options
| author | Keith Packard <keithp@keithp.com> | 2013-11-28 09:46:13 -0800 | 
|---|---|---|
| committer | Keith Packard <keithp@keithp.com> | 2013-11-28 09:46:13 -0800 | 
| commit | d93a65a90f19e4816231e03b1f399af6e3742aee (patch) | |
| tree | f4c2d026846a0c282bebdc13c00f5ba2147a7170 /ao-tools/lib | |
| parent | 14204e3d147ad99cc249ad8de254809180fe5c38 (diff) | |
ao-tools: Move ao-selfload into library
This needs to be shared between ao-stmload and ao-usbload
Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'ao-tools/lib')
| -rw-r--r-- | ao-tools/lib/Makefile.am | 2 | ||||
| -rw-r--r-- | ao-tools/lib/ao-selfload.c | 124 | ||||
| -rw-r--r-- | ao-tools/lib/ao-verbose.h | 1 | 
3 files changed, 127 insertions, 0 deletions
diff --git a/ao-tools/lib/Makefile.am b/ao-tools/lib/Makefile.am index ca32e121..5f47c089 100644 --- a/ao-tools/lib/Makefile.am +++ b/ao-tools/lib/Makefile.am @@ -44,5 +44,7 @@ libao_tools_a_SOURCES = \  	ao-hex.h \  	ao-elf.c \  	ao-elf.h \ +	ao-selfload.c \ +	ao-selfload.h \  	ao-verbose.c \  	ao-verbose.h diff --git a/ao-tools/lib/ao-selfload.c b/ao-tools/lib/ao-selfload.c new file mode 100644 index 00000000..bf036f33 --- /dev/null +++ b/ao-tools/lib/ao-selfload.c @@ -0,0 +1,124 @@ +/* + * Copyright © 2013 Keith Packard <keithp@keithp.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + */ + +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <sysexits.h> +#include <unistd.h> +#include <string.h> +#include "ao-hex.h" +#include "ao-selfload.h" +#include "ao-verbose.h" + +#define TRACE(...) ao_printf(AO_VERBOSE_SELF, __VA_ARGS__) + +static void +ao_self_block_read(struct cc_usb *cc, uint32_t address, uint8_t block[256]) +{ +	int			byte; +	cc_usb_sync(cc); +	cc_usb_printf(cc, "R %x\n", address); +	for (byte = 0; byte < 0x100; byte++) { +		block[byte] = cc_usb_getchar(cc); +	} +	TRACE ("\nread %08x\n", address); +	for (byte = 0; byte < 0x100; byte++) { +		TRACE (" %02x", block[byte]); +		if ((byte & 0xf) == 0xf) +			TRACE ("\n"); +	} +} + +static void +ao_self_block_write(struct cc_usb *cc, uint32_t address, uint8_t block[256]) +{ +	int			byte; +	cc_usb_sync(cc); +	cc_usb_printf(cc, "W %x\n", address); +	TRACE ("write %08x\n", address); +	for (byte = 0; byte < 0x100; byte++) { +		TRACE (" %02x", block[byte]); +		if ((byte & 0xf) == 0xf) +			TRACE ("\n"); +	} +	for (byte = 0; byte < 0x100; byte++) { +		cc_usb_printf(cc, "%c", block[byte]); +	} +} + +struct ao_hex_image * +ao_self_read(struct cc_usb *cc, uint32_t address, uint32_t length) +{ +	struct ao_hex_image	*image; +	int			pages; +	int			page; +	uint32_t		base = address & ~0xff; +	uint32_t		bound = (address + length + 0xff) & ~0xff; + +	image = calloc(sizeof (struct ao_hex_image) + (bound - base), 1); +	image->address = base; +	image->length = bound - base; +	pages = image->length / 0x100; +	for (page = 0; page < pages; page++) +		ao_self_block_read(cc, image->address + page * 0x100, image->data + page * 0x100); +	return image; +} + +bool +ao_self_write(struct cc_usb *cc, struct ao_hex_image *image) +{ +	uint8_t		block[256]; +	uint8_t		check[256]; +	uint32_t	base, bound, length, address; +	uint32_t	pages; +	uint32_t	page; + +	base = image->address & ~0xff; +	bound = (image->address + image->length + 0xff) & ~0xff; + +	address = base; +	length = bound - base; + +	pages = length / 0x100; +	printf ("Write %08x %d pages: ", address, length/0x100); fflush(stdout); +	for (page = 0; page < pages; page++) { +		uint32_t	start, stop; +		address = base + page * 0x100; + +		if (address < image->address || address + 0x100 > image->address + image->length) { +			ao_self_block_read(cc, address, block); +		} +		start = address; +		stop = address + 0x100; +		if (start < image->address) +			start = image->address; +		if (stop > image->address + image->length) +			stop = image->address + image->length; +		memcpy(block + start - address, image->data + start - image->address, stop - start); +		ao_self_block_write(cc, address, block); +		ao_self_block_read(cc, address, check); +		if (memcmp(block, check, 0x100) != 0) { +			fprintf(stderr, "Block at 0x%08x doesn't match\n", address); +			return 0; +		} +		putchar('.'); fflush(stdout); +	} +	printf("done\n"); +	cc_usb_printf(cc,"a\n"); +	return 1; +} diff --git a/ao-tools/lib/ao-verbose.h b/ao-tools/lib/ao-verbose.h index 45a0559c..26c2fe41 100644 --- a/ao-tools/lib/ao-verbose.h +++ b/ao-tools/lib/ao-verbose.h @@ -24,6 +24,7 @@  uint32_t	ao_verbose;  #define AO_VERBOSE_EXE	1 +#define AO_VERBOSE_SELF	2  void  ao_printf(uint32_t verbose, const char *format, ...);  | 
