blob: d08d50cd34d52f6f49becdee0b860b89e954942a [file] [log] [blame]
#include <sys/types.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/syssgi.h>
#include <sys/immu.h>
#include <errno.h>
#include <stdio.h>
/* The following works on SGI Power Challenge systems */
typedef unsigned long iotimer_t;
unsigned int cycleval;
volatile iotimer_t *iotimer_addr, base_counter;
double resolution;
/* address_t is an integer type big enough to hold an address */
typedef unsigned long address_t;
void timer_init()
{
int fd;
char *virt_addr;
address_t phys_addr, page_offset, pagemask, pagebase_addr;
pagemask = getpagesize() - 1;
errno = 0;
phys_addr = syssgi(SGI_QUERY_CYCLECNTR, &cycleval);
if (errno != 0) {
perror("SGI_QUERY_CYCLECNTR");
exit(1);
}
/* rel_addr = page offset of physical address */
page_offset = phys_addr & pagemask;
pagebase_addr = phys_addr - page_offset;
fd = open("/dev/mmem", O_RDONLY);
virt_addr = mmap(0, pagemask, PROT_READ, MAP_PRIVATE, fd, pagebase_addr);
virt_addr = virt_addr + page_offset;
iotimer_addr = (iotimer_t *)virt_addr;
/* cycleval in picoseconds to this gives resolution in seconds */
resolution = 1.0e-12*cycleval;
base_counter = *iotimer_addr;
}
void wtime_(double *time)
{
static int initialized = 0;
volatile iotimer_t counter_value;
if (!initialized) {
timer_init();
initialized = 1;
}
counter_value = *iotimer_addr - base_counter;
*time = (double)counter_value * resolution;
}
void wtime(double *time)
{
static int initialized = 0;
volatile iotimer_t counter_value;
if (!initialized) {
timer_init();
initialized = 1;
}
counter_value = *iotimer_addr - base_counter;
*time = (double)counter_value * resolution;
}