OpenCores
URL https://opencores.org/ocsvn/eus100lx/eus100lx/trunk

Subversion Repositories eus100lx

[/] [eus100lx/] [trunk/] [tools/] [cris-bus/] [bus.c] - Rev 3

Go to most recent revision | Compare with Previous | Blame | View Log

/* $Id: bus.c,v 1.1.1.1 2006-02-04 03:35:01 freza Exp $ */
 
#include <sys/mman.h>
 
#include <errno.h>
#include <fcntl.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
 
#include <asm/page.h>
 
 
typedef int 			bus_space_tag_t;
typedef u_char 			*bus_space_handle_t;
 
#define bus_space_read_4(t, h, addr) \
	*((volatile u_int32_t *) ((h) + (addr)))
 
#define bus_space_write_4(t, h, addr, val) \
	(*((volatile u_int32_t *) ((h) + (addr))) = (u_int32_t)(val))
 
#define bus_space_read_2(t, h, addr) \
	*((volatile u_int16_t *) ((h) + (u_int16_t)(addr)))
 
#define bus_space_write_2(t, h, addr, val) \
	(*((volatile u_int16_t *) ((h) + (addr))) = (u_int16_t)(val))
 
#define bus_space_read_1(t, h, addr) \
	*((volatile u_int8_t *) ((h) + (addr)))
 
#define bus_space_write_1(t, h, addr, val) \
	(*((volatile u_int8_t *) ((h) + (addr))) = (u_int8_t)(val))
 
#define VERBOSE(arg) 	if (verbose) warnx arg
 
static int 		verbose = 0;
 
 
void
warnx(char *fmt, ...)
{
	va_list 		ap;
 
	fprintf(stderr, "bus: ");
	va_start(ap, fmt);
	vfprintf(stderr, fmt, ap);
	va_end(ap);
	fprintf(stderr, "\n");
}
 
void
errx(int ret, char *fmt, ...)
{
	va_list 		ap;
 
	fprintf(stderr, "bus: ");
	va_start(ap, fmt);
	vfprintf(stderr, fmt, ap);
	va_end(ap);
	fprintf(stderr, "\n");
 
	exit(ret);
}
 
void
err(int ret, char *fmt, ...)
{
	va_list 		ap;
 
	fprintf(stderr, "bus: ");
	va_start(ap, fmt);
	vfprintf(stderr, fmt, ap);
	va_end(ap);
	fprintf(stderr, ": %s\n", strerror(errno));
 
	exit(ret);
}
 
 
#include <stdlib.h>
#include <errno.h>
 
int
xstrtou(char *str, u_long *val)
{
	char                    *end;
	int 			base = 10;
 
	if (str[0] == '0')
		switch (str[1]) {
		case 'x':
			base = 16;
			str += 2;
			break;
		case 'd':
			base = 10;
			str += 2;
			break;
		case 'o':
			base = 8;
			str += 2;
			break;
		case 'b':
			base = 2;
			str += 2;
			break;
		default:
			return EINVAL;
		}
 
	*val = (u_long) strtoul(str, &end, base);
	if (*end != '\0' || str[0] == '\0')
		return EINVAL;
 
	return 0;
}
 
int
bus_space_tag(bus_space_tag_t *t)
{
	*t = open("/dev/mem", O_RDWR | O_SYNC, 0);
	if (*t == -1)
		return (errno);
	return 0;
}
 
#ifndef PAGE_ALIGN
#define PAGE_ALIGN(val) 	(((val) + PAGE_SIZE - 1) & PAGE_MASK)
#endif
 
int
bus_space_map(bus_space_tag_t t, u_int32_t base, u_int32_t size, int flags,
    bus_space_handle_t *h)
{
	off_t 			real;
 
	real = base & PAGE_MASK;
	size = PAGE_ALIGN(size);
 
	VERBOSE(("fd %d, mapping %dB at 0x%08x with offs 0x%08x",
	    t, size, real, base % PAGE_SIZE));
 
	*h = mmap(0, size, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED, t, real);
	if (*h == MAP_FAILED)
		return (errno);
	*h += base % PAGE_SIZE;
 
	return (0);
}
 
/*
 * Main and stuff.
 */
#define ARGUMENTS 	"a:b:c:f:hvw:"
 
void
usage()
{
	printf("Version: $Freza: bus.c,v 1.6 2005/11/22 12:57:25 jh Exp $\n");
	printf("Usage: bus [opts]\n");
	printf("-a x   Set bus address\n");
	printf("-b n   Set bus access width, one of 1, 2, 4 [4]\n");
	printf("-c n   How many values to process\n");
	printf("-f s   Copy data FROM hexa text file TO memory\n");
	printf("-h     Print this help\n");
	printf("-v     Verbose operation\n");
	printf("-w x   Write value x\n");
}
 
int
main(int argc, char *argv[])
{
	FILE 			*data;
	bus_space_handle_t 	ioh;
	bus_space_tag_t 	tag;
	u_int32_t 		addr;
	u_int32_t 		value;
	int 			do_write, has_addr;
	int 			count;
	int 			width;
	int 			i, c, ret;
 
	do_write 	= 0;
	has_addr 	= 0;
	count 		= -1;
	width 		= 4;
	data 		= NULL;
 
	while((c = getopt(argc, argv, ARGUMENTS)) != -1) {
		switch (c) {
		case 'a': 		/* Set address 		*/
			if (xstrtou(optarg, (u_long *) &addr) != 0)
				errx(1, "not a number: %s", optarg);
			has_addr = 1;
			break;
 
		case 'b': 		/* Set access width 	*/
			if (xstrtou(optarg, (u_long *) &width) != 0)
				errx(1, "not a number: %s", optarg);
			switch (width) {
				case 1:
				case 2:
				case 4:
					break;
				default:
					errx(1, "bad width: %d", width);
			}
			break;
 
		case 'c': 		/* Set value count 	*/
			if (xstrtou(optarg, (u_long *) &count) != 0)
				errx(1, "not a number: %s", optarg);
			break;
 
		case 'f': 		/* File to read from/write to */
			do_write = 1;
			if ((data = fopen(optarg, "r")) == NULL)
				err(1, "could not open %s", optarg);
 
			break;
 
		case 'h': 		/* Show help 		*/
			usage();
			return 0;
 
		case 'v': 		/* Verbose operation 	*/
			verbose = 1;
			break;
 
		case 'w': 		/* Value to write 	*/
			if (xstrtou(optarg, (u_long *) &value) != 0)
				errx(1, "not a number: %s", optarg);
			do_write = 1;
			break;
 
		default:
			errx(1, "unknown argument -%c", optopt);
		}
	}
 
	argc -= optind;
	argv += optind;
 
	/* Validate user isn't insane. */
	if (argc > 0)
		errx(1, "stray arguments");
 
	if (! has_addr)
		errx(1, "address is mandatory");
 
	/* Grab bus space. */
	if ((ret = bus_space_tag(&tag)) != 0)
		err(1, "could not access physical memory, error %d", ret);
 
	if (count == -1) {
		if (data != NULL)
			count = PAGE_SIZE / width;
		else
			count = 1;
	}
 
	if ((ret = bus_space_map(tag, addr, count * width, 0, &ioh)) != 0)
		err(1, "could not map bus space, error %d", ret);
 
	if (do_write) {
		for (i = 0; i < count; i++) {
			if (data != NULL) {
				if (fscanf(data, "%x", &value) != 1) {
					if (feof(data))
						break;
					else
					if (ferror(data))
						err(1, "file read error");
					else
						err(1, "invalid input");
				}
			}
			VERBOSE(("[%03d] 0x%08x <- 0x%08x", i,
			    addr + i * width, value));
 
			switch (width) {
			case 1:
				bus_space_write_1(tag, ioh, i * width, value);
				break;
			case 2:
				bus_space_write_2(tag, ioh, i * width, value);
				break;
			case 4:
				bus_space_write_4(tag, ioh, i * width, value);
				break;
			}
		}
	} else {
		for (i = 0; i < count; i++) {
			switch (width) {
			case 1:
				value = bus_space_read_1(tag, ioh, i * width);
				printf("%02x\n", value);
				break;
			case 2:
				value = bus_space_read_2(tag, ioh, i * width);
				printf("%04x\n", value);
				break;
			case 4:
				value = bus_space_read_4(tag, ioh, i * width);
				printf("%08x\n", value);
				break;
			}
		}
	}
 
	return (0);
}
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.