/*******************************************************************
***
***  JK Microsystems
***  7/12/05
***  Adam Yergovich
***  regedit.c
***  This example program allows for easy command line manipulation of registers.  The -q option
***  sets it into quiet mode wherin it will only print out the register value if read, or the new
***  value if written.
***
*******************************************************************/





#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <asm/io.h>

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


int main(int argc, char *argv[]){
int mem;
char status, yn;
char *mmStatus;
void *statusAdr, *map_base, *virt_addr;
unsigned long writeval, readval;
int quiet=0;
off_t target;

if(argc < 2 || argc > 4){
printf("usage: \n");
printf("%s [-q] <MemoryLocation> [writevalue] \n", argv[0]);
exit(-1);
}


if(argv[1][1]=='q'){
quiet = 1;
}
if(quiet)
target = strtoul(argv[2], 0, 0);
else
target =strtoul(argv[1], 0, 0);

if(!quiet)
printf("Checking %x \n", target);

if((mem = open ("/dev/mem", O_RDWR | O_SYNC))== -1){
  printf("Cannot open /dev/mem! \n");
  exit(-1);
}
map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, mem, target & ~MAP_MASK);
if( map_base == (void *)-1){
printf("mmap error!");
exit(-1);
}
if(!quiet)
printf("Memory mapped at address %p \n", map_base);

virt_addr=map_base + (target & MAP_MASK);

if( ((!quiet)&&(argc==2)) || ((quiet)&&(argc==3))){
readval = *((unsigned long *) virt_addr);
if(!quiet)
printf("Value:");
printf("%x", readval);
if(!quiet)
printf("\n");
}



if(((argc == 3) && quiet) || ((argc == 2) && !quiet)) {

exit(1);
}
else{
if(quiet)
writeval = strtoul(argv[3], 0, 0);
else
writeval = strtoul(argv[2], 0, 0);
*((unsigned long *)virt_addr) = writeval;
if(!quiet)
printf("New Value: %X \n", *((unsigned long *) virt_addr));
}

munmap(map_base, MAP_SIZE);
close(mem);

return 0;


}
