/******************************************************************************
*                                                                             *
*   Copyright 2005 University of Cambridge Computer Laboratory.               *
*                                                                             *
*   This file is part of Nprobe.                                              *
*                                                                             *
*   Nprobe 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.                                       *
*                                                                             *
*   Nprobe 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 Nprobe; 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 <stdarg.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/errno.h>
#include <fcntl.h>
#include <string.h>

#include <unistd.h>



#define KERNEL_VA   (0xC0000000UL) 

#define MEM_SIZE (64 << 20UL)       // Total memory

#define MFN "/dev/mem"
// #define MFN "/dev/mem"


#define PROC_FILE "/proc/nprobe"

int main(int argc,char **argv)
{
    int pfd,kfd; 
    char buf[256], buf1[256];
    unsigned long np_off;
    int maxdev, fifosize;
    char *km = NULL; 
    int rc, i;

    if( (pfd = open(PROC_FILE, O_RDONLY)) < 0) {
        perror("failed to open proc file");
        exit(errno);
    } else fprintf(stderr, "Opened %s (fd = %d)\n", PROC_FILE, pfd); 

    if( (rc = read( pfd, buf, 255 )) < 0 ) {
	perror("read error on proc file");
	exit(errno);
    } 
    
    buf[(rc>255)?255:rc] = 0; // just in case...

    printf("Read %d bytes --- %s\n", rc, buf );

    buf1[0]=0;

    rc = sscanf(buf,"%s %p %d %d", buf1, &np_off, &maxdev, &fifosize);

    printf("rc = %d, %s ptr = %lx maxdev = %d fifosize = %d\n",
	   rc, buf1, np_off, maxdev, fifosize );
	

    /* final read to collect the EOF */

    if( (rc = read( pfd, buf, 255 )) < 0 ) {
	perror("read error on proc file");
	exit(errno);
    } 

    if (rc>0) 
	printf("Expected to read 0 bytes got %d --- %s\n", rc, buf );

    
    np_off &=0xfffffff ;
    
    
    if( (kfd = open(MFN, O_RDWR)) < 0) {
        perror("failed to open /dev/[k]mem");
        exit(errno);
    } else fprintf(stderr, "Opened /dev/[k]mem (fd = %d)\n", kfd); 

#if 0
    if(lseek(kfd, /*KERNEL_VA +*/ 0x24b8000 , SEEK_SET) == -1) {
        perror("failed to seek /dev/[k]mem");
        exit(errno);
    } else fprintf(stderr, "Seeked to %lx\n", KERNEL_VA); 

    read(kfd, &i, 4);
      printf("YY=%lx\n",i);
      exit(0);
#endif

    km = mmap(NULL, MEM_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE, kfd, 0 );
//    km = mmap(NULL, MEM_SIZE-0x100000, PROT_READ, MAP_PRIVATE, kfd, 0x100000 );
//    km = mmap(NULL, 0x8000, PROT_READ, MAP_PRIVATE, kfd, 0x2f90000 );

close(kfd);

    if(km == MAP_FAILED) {
        perror("failed to map /dev/[k]mem"); 
        exit(errno); 
    }

// exit(-1);

//    printf("ZZ=%lx\n",*((unsigned long *)km));

//      printf("ZZ=%lx\n",*((unsigned long *)(0x2874000-0x100000+km)));



#define MAGIC np_off
      printf("ZZ=%lx\n",*((unsigned long *)(MAGIC+km)));
      
*((unsigned long *)(MAGIC+km)) = 0x1234567;

printf("ZZ=%lx\n",*((unsigned long *)(MAGIC+km)));


exit(-1);

#if 0
{
int rc;
rc = munmap(km, MEM_SIZE );
    if(km == MAP_FAILED) {
        perror("failed to unmap ");
        exit(errno);
    }else printf("success unmap\n");

}


#endif

while(1)sleep(10000);



//while(1);
#if 0
    {
      //      unsigned long foo = strtol(argv[1],NULL,16);
unsigned long foo = 0xc24b8000;
      printf("%s = 0x%lx\n",argv[1],foo);

foo=foo-KERNEL_VA;
      printf("%lx\n",foo);

      printf("XX=%lx\n",*((unsigned long *)(foo+km)));
    }
#endif

}
