예제 #1
0
type xstrto(_range_sfx)(const char *numstr, int base,
		type lower,
		type upper,
		const struct suffix_mult *suffixes)
{
	unsigned type u = XSTR_TYPE_MAX;
	type r;
	const char *p = numstr;

	if (p[0] == '-') {
		++p;
		++u;	/* two's complement */
	}

	r = xstrtou(_range_sfx)(p, base, 0, u, suffixes);

	if (*numstr == '-') {
		r = -r;
	}

	if (r < lower || r > upper) {
		bb_error_msg_and_die("number %s is not in %lld..%lld range",
				numstr, (long long)lower, (long long)upper);
	}

	return r;
}
예제 #2
0
unsigned type FAST_FUNC xatou(_range_sfx)(const char *numstr,
		unsigned type lower,
		unsigned type upper,
		const struct suffix_mult *suffixes)
{
	return xstrtou(_range_sfx)(numstr, 10, lower, upper, suffixes);
}
예제 #3
0
type FAST_FUNC xstrto(_range_sfx)(const char *numstr, int base,
		type lower,
		type upper,
		const struct suffix_mult *suffixes)
{
	unsigned type u = XSTR_TYPE_MAX;
	type r;
	const char *p = numstr;

	/* NB: if you'll decide to disallow '+':
	 * at least renice applet needs to allow it */
	if (p[0] == '+' || p[0] == '-') {
		++p;
		if (p[0] == '-')
			++u; /* = <type>_MIN (01111... + 1 == 10000...) */
	}

	r = xstrtou(_range_sfx)(p, base, 0, u, suffixes);

	if (*numstr == '-') {
		r = -r;
	}

	if (r < lower || r > upper) {
		bb_error_msg_and_die("number %s is not in %lld..%lld range",
				numstr, (long long)lower, (long long)upper);
	}

	return r;
}
예제 #4
0
static void parse_map_file(const char *filename)
{
	parser_t *parser;
	char *tokens[6];

	parser = config_open2(filename, fopen_for_read);

	if (parser) {
		while (config_read(parser, tokens, 6, 6, "# \t", PARSE_NORMAL)) {
			evt_tab = xrealloc_vector(evt_tab, 1, n_evt);
			evt_tab[n_evt].s_type = xstrdup(tokens[0]);
			evt_tab[n_evt].n_type = xstrtou(tokens[1], 16);
			evt_tab[n_evt].s_code = xstrdup(tokens[2]);
			evt_tab[n_evt].n_code = xatou16(tokens[3]);
			evt_tab[n_evt].value = xatoi_positive(tokens[4]);
			evt_tab[n_evt].desc = xstrdup(tokens[5]);
			n_evt++;
		}
		config_close(parser);
	} else {
		evt_tab = (void*)f_evt_tab;
		n_evt = ARRAY_SIZE(f_evt_tab);
	}
}
예제 #5
0
unsigned type FAST_FUNC xstrtou()(const char *numstr, int base)
{
	return xstrtou(_range_sfx)(numstr, base, 0, XSTR_UTYPE_MAX, NULL);
}
예제 #6
0
unsigned type FAST_FUNC xstrtou(_sfx)(const char *numstr, int base,
		const struct suffix_mult *suffixes)
{
	return xstrtou(_range_sfx)(numstr, base, 0, XSTR_UTYPE_MAX, suffixes);
}
예제 #7
0
unsigned type FAST_FUNC xstrtou(_range)(const char *numstr, int base,
		unsigned type lower,
		unsigned type upper)
{
	return xstrtou(_range_sfx)(numstr, base, lower, upper, NULL);
}
예제 #8
0
int nandwrite_main(int argc UNUSED_PARAM, char **argv)
{
	/* Buffer for OOB data */
	unsigned char *oobbuf;
	unsigned opts;
	int fd;
	ssize_t cnt;
	unsigned mtdoffset, meminfo_writesize, blockstart, limit;
	unsigned end_addr = ~0;
	struct mtd_info_user meminfo;
	struct mtd_oob_buf oob;
	unsigned char *filebuf;
	const char *opt_s = "0", *opt_f = "-", *opt_l;

	if (IS_NANDDUMP) {
		opt_complementary = "=1";
		opts = getopt32(argv, "os:bf:l:", &opt_s, &opt_f, &opt_l);
	} else { /* nandwrite */
		opt_complementary = "-1:?2";
		opts = getopt32(argv, "ps:", &opt_s);
	}
	argv += optind;

	if (IS_NANDWRITE && argv[1])
		opt_f = argv[1];
	if (!LONE_DASH(opt_f)) {
		int tmp_fd = xopen(opt_f,
			IS_NANDDUMP ? O_WRONLY | O_TRUNC | O_CREAT : O_RDONLY
		);
		xmove_fd(tmp_fd, IS_NANDDUMP ? STDOUT_FILENO : STDIN_FILENO);
	}

	fd = xopen(argv[0], O_RDWR);
	xioctl(fd, MEMGETINFO, &meminfo);

	mtdoffset = xstrtou(opt_s, 0);
	if (IS_NANDDUMP && (opts & OPT_l)) {
		unsigned length = xstrtou(opt_l, 0);
		if (length < meminfo.size - mtdoffset)
			end_addr = mtdoffset + length;
	}

	/* Pull it into a CPU register (hopefully) - smaller code that way */
	meminfo_writesize = meminfo.writesize;

	if (mtdoffset & (meminfo_writesize - 1))
		bb_error_msg_and_die("start address is not page aligned");

	filebuf = xmalloc(meminfo_writesize);
	oobbuf = xmalloc(meminfo.oobsize);

	oob.start  = 0;
	oob.length = meminfo.oobsize;
	oob.ptr    = oobbuf;

	blockstart = mtdoffset & ~(meminfo.erasesize - 1);
	if (blockstart != mtdoffset) {
		unsigned tmp;
		/* mtdoffset is in the middle of an erase block, verify that
		 * this block is OK. Advance mtdoffset only if this block is
		 * bad.
		 */
		tmp = next_good_eraseblock(fd, &meminfo, blockstart);
		if (tmp != blockstart) {
			/* bad block(s), advance mtdoffset */
			if (IS_NANDDUMP & !(opts & OPT_b)) {
				int bad_len = MIN(tmp, end_addr) - mtdoffset;
				dump_bad(&meminfo, bad_len, !(opts & OPT_o));
			}
			mtdoffset = tmp;
		}
	}

	cnt = -1;
	limit = MIN(meminfo.size, end_addr);
	while (mtdoffset < limit) {
		int input_fd = IS_NANDWRITE ? STDIN_FILENO : fd;
		int output_fd = IS_NANDWRITE ? fd : STDOUT_FILENO;

		blockstart = mtdoffset & ~(meminfo.erasesize - 1);
		if (blockstart == mtdoffset) {
			/* starting a new eraseblock */
			mtdoffset = next_good_eraseblock(fd, &meminfo, blockstart);
			if (IS_NANDWRITE)
				printf("Writing at 0x%08x\n", mtdoffset);
			else if (mtdoffset > blockstart) {
				int bad_len = MIN(mtdoffset, limit) - blockstart;
				dump_bad(&meminfo, bad_len, !(opts & OPT_o));
			}
			if (mtdoffset >= limit)
				break;
		}
		xlseek(fd, mtdoffset, SEEK_SET);

		/* get some more data from input */
		cnt = full_read(input_fd, filebuf, meminfo_writesize);
		if (cnt == 0) {
			/* even with -p, we do not pad past the end of input
			 * (-p only zero-pads last incomplete page)
			 */
			break;
		}
		if (cnt < meminfo_writesize) {
			if (IS_NANDDUMP)
				bb_error_msg_and_die("short read");
			if (!(opts & OPT_p))
				bb_error_msg_and_die("input size is not rounded up to page size, "
						"use -p to zero pad");
			/* zero pad to end of write block */
			memset(filebuf + cnt, 0, meminfo_writesize - cnt);
		}
		xwrite(output_fd, filebuf, meminfo_writesize);

		if (IS_NANDDUMP && !(opts & OPT_o)) {
			/* Dump OOB data */
			oob.start = mtdoffset;
			xioctl(fd, MEMREADOOB, &oob);
			xwrite(output_fd, oobbuf, meminfo.oobsize);
		}

		mtdoffset += meminfo_writesize;
		if (cnt < meminfo_writesize)
			break;
	}

	if (IS_NANDWRITE && cnt != 0) {
		/* We filled entire MTD, but did we reach EOF on input? */
		if (full_read(STDIN_FILENO, filebuf, meminfo_writesize) != 0) {
			/* no */
			bb_error_msg_and_die("not enough space in MTD device");
		}
	}

	if (ENABLE_FEATURE_CLEAN_UP) {
		free(filebuf);
		close(fd);
	}

	return EXIT_SUCCESS;
}
예제 #9
0
파일: bus.c 프로젝트: freecores/eus100lx
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);
}
예제 #10
0
unsigned type xatou(_sfx)(const char *numstr,
		const struct suffix_mult *suffixes)
{
	return xstrtou(_range_sfx)(numstr, 10, 0, XSTR_UTYPE_MAX, suffixes);
}
예제 #11
0
unsigned type xatou(_range)(const char *numstr,
		unsigned type lower,
		unsigned type upper)
{
	return xstrtou(_range_sfx)(numstr, 10, lower, upper, NULL);
}