/*
 * pcimem.c: Simple program to read/write from/to a pci device from userspace.
 *
 *  Copyright (C) 2010, Bill Farrow (bfarrow@beyondelectronics.us)
 *
 *  Based on the devmem2.c code
 *  Copyright (C) 2000, Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl)
 *
 * 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; either version 2 of the License, or
 * (at your option) any later version.
 *
 * 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 <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include <ctype.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/mman.h>

#define PRINT_ERROR \
	do { \
		fprintf(stderr, "Error at line %d, file %s (%d) [%s]\n", \
		__LINE__, __FILE__, errno, strerror(errno)); exit(1); \
	} while(0)

#define MAP_SIZE 4096UL
#define MAP_MASK (MAP_SIZE - 1)

void dump_page(uint32_t *vaddr, uint32_t *vbase, uint32_t *pbase)
{
	int i = 0;
	uint32_t *end = vaddr + (MAP_SIZE >> 6);
	uint32_t *start = vaddr;

	while(start  < end) {
		printf("%p:%08x %08x %08x %08x\n",
			start - vbase + pbase, start[0], start[1] , start[2], start[3]);
		start+=4;
	}
}

void reg_mod_bits(uint32_t *virt_addr, int data, int start_bit, int data_len)
{
	int mask = 0;
	int value;
	int i;

	if ((start_bit < 0) || (start_bit > 31) ||
	    (data_len < 1) || (data_len > 32) ||
	    (start_bit + data_len > 32)) {
		fprintf(stderr,
			"Startbit range[0~31], and DataLen range[1~32], and Startbit + DataLen <= 32\n");
		exit(1);
	}

	for (i = 0; i < data_len; i++) {
		if (start_bit + i > 31)
			break;

		mask |= 1 << (start_bit + i);
	}

	value = *((volatile uint32_t *) virt_addr);
	value &= ~mask;
	value |= (data << start_bit) & mask;;

	*((uint32_t *) virt_addr) = value;

	printf("Modify 0x%X[%d:%d]; ", data, start_bit + data_len - 1, start_bit);
}

void print_binary(uint32_t data)
{
	if (data > 1)
		print_binary(data >> 1);

	printf("%x", data % 2);
}

void reg_read_bits(uint32_t *virt_addr, uint32_t *virt_base, uint32_t *phy_base,
		   int start_bit, int data_len)
{
	uint32_t mask = 0;
	uint32_t value;
	int i;

	if ((start_bit < 0) || (start_bit > 31) ||
	    (data_len < 1) || (data_len > 32) ||
	    (start_bit + data_len > 32)) {
		fprintf(stderr,
			"Startbit range[0~31], and DataLen range[1~32], and Startbit + DataLen <= 32\n");
		exit(1);
	}

	for (i = 0; i < data_len; i++) {
		if (start_bit + i > 31)
			break;

		mask |= 1 << (start_bit + i);
	}

	value = *((uint32_t *)virt_addr);
	value &= mask;

	if (start_bit == 0 && data_len == 32)
		printf("%p: %08x\n",
		       virt_addr - virt_base + phy_base, value);
	else {
		printf("%p[%2d:%2d] = %x (hex)\n",
		       virt_addr - virt_base + phy_base,
		       start_bit + data_len - 1, start_bit,
		       value >> start_bit);
		printf("%17s = %d (dec)\n", "", value >> start_bit);
		printf("%17s = ", "");
		print_binary(value >> start_bit);
		printf(" (bin)\n");
	}
}

void usage(void)
{
	fprintf(stderr,
		"\nUsage:\tregs [Type] [ Offset:Hex ] [ Data:Hex ] [StartBit:Dec] [DataLen:Dec]\n"
		"\tType    : access operation type : [m]odify, [w]wite, [d]ump\n"
		"\tOffset  : offset into memory region to act upon\n"
		"\tData    : data to be written\n"
		"\tStartbit: Startbit of Addr that want to be modified. Range[0~31]\n"
		"\tDataLen : Data length of Data. Range[1~32], and Startbit + DataLen <= 32\n\n"
		"Example:\tRead/Write/Modify register\n"
		"\tDump    : regs d 0x1b100000           //dump 0x1b100000~0x1b1000f0\n"
		"\tRead    : regs r 0x1b100000           //read 0x1b100000\n"
		"\tRead    : regs r 0x1b100000 29 3      //read 0x1b100000[29:31]\n"
		"\tWrite   : regs w 0x1b100000 0x1234    //write 0x1b100000=0x1234\n"
		"\tModify  : regs m 0x1b100000 0x0 29 3  //modify 0x1b100000[29:31]=0\n");
	exit(1);
}

int main(int argc, char **argv)
{
	int fd;
	void *map_base = NULL;
	void *virt_addr = NULL;
	uint32_t read_result =0;
	uint32_t writeval = 0;
	uint32_t startbit = 0;
	uint32_t datalen = 0;
	char *filename = NULL;
	off_t offset = 0;
	int access_type = 0;

	if(argc < 3) {
		usage();
		exit(1);
	}

	access_type = tolower(argv[1][0]);
	if ((access_type == 'w' && argc < 4) || (access_type == 'm' && argc < 6)) {
		usage();
		exit(1);
	}

	filename = "/dev/mem";
	if((fd = open(filename, O_RDWR | O_SYNC)) == -1)
		PRINT_ERROR;

	/* Map one page */
	offset = strtoul(argv[2], NULL, 16);
	if (offset > 0xFFFFFFFFFFFF)
		PRINT_ERROR;

	map_base = mmap(0, 2 * MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED,
			fd, offset & ~MAP_MASK);
	if(map_base == (void *) -1)
		PRINT_ERROR;

	virt_addr = map_base + (offset & MAP_MASK);
	read_result = *((volatile uint32_t *) virt_addr);
	printf("Value at 0x%llX (%p): 0x%X\n",
	       (unsigned long long)offset, virt_addr, read_result);

	switch(access_type) {
		case 'm':
			writeval = strtoul(argv[3], 0, 16);
			if (writeval > UINT_MAX)
				PRINT_ERROR;
			startbit = strtoul(argv[4], 0, 10);
			if (startbit > 32)
				PRINT_ERROR;
			datalen  = strtoul(argv[5], 0, 10);
			if (datalen > 32)
				PRINT_ERROR;
			reg_mod_bits((uint32_t *)virt_addr, writeval, startbit, datalen);
			break;
		case 'w':
			writeval = strtoul(argv[3], 0, 16);
			if (writeval > UINT_MAX)
				PRINT_ERROR;
			*((uint32_t *) virt_addr) = writeval;
			printf("Written 0x%X; ", writeval);
			break;
		case 'd':
			dump_page((uint32_t *)virt_addr, (uint32_t *)map_base,
				  (uint32_t *)(offset & ~MAP_MASK));
			goto out;
		case 'r':
			if (argc == 3)
				reg_read_bits((uint32_t *)virt_addr,
					      (uint32_t *)map_base,
					      (uint32_t *)(offset & ~MAP_MASK),
					      0, 32);
			else {
				startbit = strtoul(argv[3], 0, 10);
				if (startbit > 32)
					PRINT_ERROR;
				datalen = strtoul(argv[4], 0, 10);
				if (datalen > 32)
					PRINT_ERROR;
				reg_read_bits((uint32_t *)virt_addr,
					      (uint32_t *)map_base,
					      (uint32_t *)(offset & ~MAP_MASK),
					      startbit, datalen);
			}
			goto out;
		default:
			printf("Illegal data type '%c'.\n", access_type);
			goto out;
	}

	read_result = *((volatile uint32_t *) virt_addr);
	printf("Readback 0x%X\n", read_result);

out:
	if(munmap(map_base, MAP_SIZE) == -1)
		PRINT_ERROR;

	close(fd);
	return 0;
}
