#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/mman.h>

#define	OPEN_DEVNAME	"/dev/mem"
#define OPEN_FLAGS	O_RDWR
#define	MAP_OFFSET	(off_t) 	(0)
//#define	MAP_OFFSET	(off_t) 	(0xd0000000)
#define	MAP_LENGTH	(size_t) 	(1024 * 1024 * 16)
#define	MAP_PROT	(int) 		(PROT_READ | PROT_WRITE)
#define	MAP_FLAGS	(int) 		(MAP_SHARED)

int main(int argc, char** argv)
{
	int fd;
	char* p;
	int status;
	unsigned long ulAddr;
	unsigned long ulOffset;
	unsigned long ulLen;
	//unsigned long ulValue;
	unsigned long ulMapLen;

	if (argc <= 3)
	{
		fprintf(stderr, "usage: %s <memory physical address> <offset> <len>\n", argv[0]);
		return 0;
	}
	
	if (sscanf(argv[1], "%X",  &ulAddr) != 1)
	{
		fprintf(stderr, "Invalid memory address %s\n", argv[1]);
		fprintf(stderr, "usage: %s <memory physical address> <offset> <len>\n", argv[0]);
		return 0;
	}

	if (sscanf(argv[2], "%X",  &ulOffset) != 1)
	{
		fprintf(stderr, "Invalid memory offset %s\n", argv[2]);
		fprintf(stderr, "usage: %s <memory physical address> <offset> <len>\n", argv[0]);
		return 0;
	}

	if (sscanf(argv[3], "%X",  &ulLen) != 1)
	{
		fprintf(stderr, "Invalid memory length %s\n", argv[3]);
		fprintf(stderr, "usage: %s <memory physical address> <offset> <len>\n", argv[0]);
		return 0;
	}

	fd = open(OPEN_DEVNAME, OPEN_FLAGS);
	if (fd < 0)
	{
		fprintf(stderr, "Fail to open \"%s\"\n", OPEN_DEVNAME);
		return (-1);
	}

	p = (char *) mmap(NULL, MAP_LENGTH, MAP_PROT, MAP_FLAGS, fd, ulAddr);
	fprintf(stderr, "Map 0X%X bytes at offset 0X%08X from \"%s\" to 0X%08X\n", ulLen, ulOffset, OPEN_DEVNAME, p);

	if (p == (char *) (MAP_FAILED))
	{
		fprintf(stderr, "Fail to call mmap()!\n");

		close(fd);
		return (-1);
	}	
	
	{
		int i=0;
		unsigned char c0,c1,c2,c3;

		while( i < ulLen)
		{
			printf("%08X:%08X : ", ulAddr, ulOffset + i);                        
                        c0=p[ulOffset + i];
                        c1=p[ulOffset + i+1];
                        c2=p[ulOffset + i+2];
                        c3=p[ulOffset + i+3];
                        printf("%02X%02X%02X%02X", c3,c2,c1,c0);
                        printf("\n");
                        i+=4;
		}
	}

	if (munmap(p, ulLen))
	{
		fprintf(stderr, "Fail to call munmap()!\n");
	}

	close(fd);

	return 0;
}
