#include <stdio.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>


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

#define FUNC_SET 0
#define FUNC_GET 1
#define FUNC_CMP 2

int main(int argc, char *argv[]){
	off_t mfpTarget = 0x40E10000;
	void *mfp_map_base, *mfp_virt_base;
	int fd,func;
	unsigned long *buff;
	int i;
	FILE *dumpFile;
	
	if(argc < 2){ printf("Usage: %s set/get/cmp file\n",argv[0]); return 0; }

	if(!strcmp(argv[1],"set"))func = FUNC_SET;
	else if(!strcmp(argv[1],"cmp"))func = FUNC_CMP;
	else func = FUNC_GET;

	if(func == FUNC_GET)
		dumpFile = fopen(argv[2],"wb");
	else // FUNC_SET or FUNC_CMP
		dumpFile = fopen(argv[2],"rb");
	
	if(!dumpFile){ printf("'%s' open failed.\n",argv[2]); return 0; }

	fd = open("/dev/mem", O_RDWR | O_SYNC);
	if(!fd){ printf("/dev/mem open failed.\n"); return 0; }

	mfp_map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, mfpTarget & ~MAP_MASK);
	if(mfp_map_base == (void *) -1){
		printf("mmap fail\n");
		return 0;
	}
		
	printf("MFP Memory mapped at address %p.\n", mfp_map_base); 
	
	mfp_virt_base = mfp_map_base + (mfpTarget & MAP_MASK);

	printf("Init, mfp virtual base at %p (phys=0x%X)\n", mfp_virt_base, mfpTarget); 


	if(func == FUNC_SET)
		fread(mfp_virt_base, MAP_SIZE, 1, dumpFile);
	else if(func == FUNC_GET)
		fwrite(mfp_virt_base, MAP_SIZE, 1, dumpFile);
	else{ // FUNC_CMP
		buff = (unsigned long *)malloc(MAP_SIZE);
		if(!buff){ printf("alloc fail\n"); return 0; }
	
		fread(buff, MAP_SIZE, 1, dumpFile);

		printf("num\taddr\tfile\tMFP\n");
		for(i=0;i<(MAP_SIZE/4);i++)
			if( *(buff+i) != *(((unsigned long *)mfp_virt_base)+i) )
				printf("%i:\t%04x\t%08x\t%08x\n",i,i*4,*(buff+i),*(((unsigned long *)mfp_virt_base)+i) );

		free(buff);
	}

	fclose(dumpFile);
		
	munmap(mfp_map_base, MAP_SIZE);	
}

