devtime.c revision 1051
1963Ssaidi@eecs.umich.edu/* 2963Ssaidi@eecs.umich.edu * Copyright (c) 2004 The Regents of The University of Michigan 3963Ssaidi@eecs.umich.edu * All rights reserved. 4963Ssaidi@eecs.umich.edu * 5963Ssaidi@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 6963Ssaidi@eecs.umich.edu * modification, are permitted provided that the following conditions are 7963Ssaidi@eecs.umich.edu * met: redistributions of source code must retain the above copyright 8963Ssaidi@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 9963Ssaidi@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 10963Ssaidi@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 11963Ssaidi@eecs.umich.edu * documentation and/or other materials provided with the distribution; 12963Ssaidi@eecs.umich.edu * neither the name of the copyright holders nor the names of its 13963Ssaidi@eecs.umich.edu * contributors may be used to endorse or promote products derived from 14963Ssaidi@eecs.umich.edu * this software without specific prior written permission. 15963Ssaidi@eecs.umich.edu * 16963Ssaidi@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17963Ssaidi@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18963Ssaidi@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19963Ssaidi@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20963Ssaidi@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21963Ssaidi@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22963Ssaidi@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23963Ssaidi@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24963Ssaidi@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25963Ssaidi@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26963Ssaidi@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27963Ssaidi@eecs.umich.edu */ 28963Ssaidi@eecs.umich.edu 29963Ssaidi@eecs.umich.edu#include <linux/module.h> 30963Ssaidi@eecs.umich.edu#include <linux/config.h> 31963Ssaidi@eecs.umich.edu#include <linux/moduleparam.h> 32963Ssaidi@eecs.umich.edu#include <linux/init.h> 33963Ssaidi@eecs.umich.edu#include <linux/fs.h> 34963Ssaidi@eecs.umich.edu#include <asm/uaccess.h> 35963Ssaidi@eecs.umich.edu#include <linux/kernel.h> 36963Ssaidi@eecs.umich.edu#include <asm/io.h> 37964Ssaidi@eecs.umich.edu#include <asm/page.h> 38963Ssaidi@eecs.umich.edu#include <linux/netdevice.h> 39963Ssaidi@eecs.umich.edu 40963Ssaidi@eecs.umich.edu#ifdef __i386__ 41963Ssaidi@eecs.umich.edu#include <asm/processor.h> 42963Ssaidi@eecs.umich.edu#include <asm/msr.h> 43963Ssaidi@eecs.umich.edu#endif 44963Ssaidi@eecs.umich.edu 45963Ssaidi@eecs.umich.edu#define DRIVER_AUTHOR "Ali Saidi" 46963Ssaidi@eecs.umich.edu#define DRIVER_DESC "Interface to time uncacachable read and writes to device registers" 47963Ssaidi@eecs.umich.edu#define DRIVER_VER "0.1" 48963Ssaidi@eecs.umich.edu 49963Ssaidi@eecs.umich.edustatic char *dataAddr = NULL; 50963Ssaidi@eecs.umich.edustatic int count = 0; 51963Ssaidi@eecs.umich.edu 52963Ssaidi@eecs.umich.edustatic inline uint32_t cycleCounter(uint32_t dep); 53963Ssaidi@eecs.umich.edu 54963Ssaidi@eecs.umich.edustatic int __init devtime_start(void) 55963Ssaidi@eecs.umich.edu{ 56963Ssaidi@eecs.umich.edu uint64_t addr; 57963Ssaidi@eecs.umich.edu uint32_t t1, t2; 58963Ssaidi@eecs.umich.edu uint32_t trash; 59963Ssaidi@eecs.umich.edu int x; 601051Ssaidi@eecs.umich.edu uint32_t *times; 611051Ssaidi@eecs.umich.edu uint32_t num = 0; 62963Ssaidi@eecs.umich.edu struct net_device *dev; 63963Ssaidi@eecs.umich.edu 64963Ssaidi@eecs.umich.edu 65963Ssaidi@eecs.umich.edu printk("Devtime Driver Version %s Loaded...\n", DRIVER_VER); 66963Ssaidi@eecs.umich.edu 67963Ssaidi@eecs.umich.edu if ((dataAddr != 0) && (count != 0)) 68963Ssaidi@eecs.umich.edu { 69963Ssaidi@eecs.umich.edu addr = simple_strtoull(dataAddr, NULL, 0); 70963Ssaidi@eecs.umich.edu 71964Ssaidi@eecs.umich.edu addr = ioremap(addr, PAGE_SIZE); 72964Ssaidi@eecs.umich.edu /** 73964Ssaidi@eecs.umich.edu * Make sure that the remapping actually worked. On alpha we have 74964Ssaidi@eecs.umich.edu * linear addressing, so its not a problem. But it can fail in x86 75964Ssaidi@eecs.umich.edu * if physical memory is mapped to this address. 76964Ssaidi@eecs.umich.edu */ 771051Ssaidi@eecs.umich.edu times = kmalloc(sizeof(uint32_t) * count, GFP_USER); 781051Ssaidi@eecs.umich.edu if (!times) 791051Ssaidi@eecs.umich.edu { 801051Ssaidi@eecs.umich.edu printk("Could not allocate memory... Try again later.\n"); 811051Ssaidi@eecs.umich.edu return -1; 821051Ssaidi@eecs.umich.edu } 831051Ssaidi@eecs.umich.edu 84964Ssaidi@eecs.umich.edu if (addr) 85964Ssaidi@eecs.umich.edu { 86964Ssaidi@eecs.umich.edu printk("Preparing to read %#llx %d times.\n", addr, count); 87963Ssaidi@eecs.umich.edu 88964Ssaidi@eecs.umich.edu t1 = cycleCounter(trash); 89964Ssaidi@eecs.umich.edu for (x=0; x < count; x++) 90964Ssaidi@eecs.umich.edu { 91964Ssaidi@eecs.umich.edu trash = readl(addr); 92964Ssaidi@eecs.umich.edu t2 = cycleCounter(trash); 931051Ssaidi@eecs.umich.edu times[num++] = t2 - t1; 94964Ssaidi@eecs.umich.edu t1 = t2; 95964Ssaidi@eecs.umich.edu } 96964Ssaidi@eecs.umich.edu 97964Ssaidi@eecs.umich.edu /** 98964Ssaidi@eecs.umich.edu * Unmap the address. 99964Ssaidi@eecs.umich.edu */ 100964Ssaidi@eecs.umich.edu iounmap(addr); 101964Ssaidi@eecs.umich.edu 1021051Ssaidi@eecs.umich.edu printk("Measurements:\n"); 1031051Ssaidi@eecs.umich.edu for (x = 0; x < count; x++) 1041051Ssaidi@eecs.umich.edu { 1051051Ssaidi@eecs.umich.edu printk("%d ", times[x]); 1061051Ssaidi@eecs.umich.edu if (((x+1) % 10) == 0) 1071051Ssaidi@eecs.umich.edu printk("\n"); 1081051Ssaidi@eecs.umich.edu } 1091051Ssaidi@eecs.umich.edu printk("\nDone.\n"); 1101051Ssaidi@eecs.umich.edu 1111051Ssaidi@eecs.umich.edu 112963Ssaidi@eecs.umich.edu } 113964Ssaidi@eecs.umich.edu else 114964Ssaidi@eecs.umich.edu printk("Unable to remap address. Please try again later.\n"); 115963Ssaidi@eecs.umich.edu } else { 116963Ssaidi@eecs.umich.edu dev = dev_get_by_name("eth0"); 117963Ssaidi@eecs.umich.edu if (dev) 118963Ssaidi@eecs.umich.edu { 119963Ssaidi@eecs.umich.edu printk("Eth0: MemStart: %#lx MemEnd: %#lx I/O Addr: %#lx\n", dev->mem_start, 120963Ssaidi@eecs.umich.edu dev->mem_end, dev->base_addr); 121963Ssaidi@eecs.umich.edu dev_put(dev); 122963Ssaidi@eecs.umich.edu } 123964Ssaidi@eecs.umich.edu dev = 0; 124963Ssaidi@eecs.umich.edu dev = dev_get_by_name("eth1"); 125963Ssaidi@eecs.umich.edu if (dev) 126963Ssaidi@eecs.umich.edu { 127963Ssaidi@eecs.umich.edu printk("Eth1: MemStart: %#lx MemEnd: %#lx I/O Addr: %#lx\n", dev->mem_start, 128963Ssaidi@eecs.umich.edu dev->mem_end, dev->base_addr); 129963Ssaidi@eecs.umich.edu dev_put(dev); 130963Ssaidi@eecs.umich.edu } 131963Ssaidi@eecs.umich.edu 132963Ssaidi@eecs.umich.edu 133963Ssaidi@eecs.umich.edu printk("Required information not supplied.\n"); 134963Ssaidi@eecs.umich.edu } 135963Ssaidi@eecs.umich.edu 136963Ssaidi@eecs.umich.edu return 0; 137963Ssaidi@eecs.umich.edu} 138963Ssaidi@eecs.umich.edu 139963Ssaidi@eecs.umich.edu#ifdef __i386__ 140963Ssaidi@eecs.umich.edu 141963Ssaidi@eecs.umich.edustatic inline uint32_t cycleCounter(uint32_t dep) 142963Ssaidi@eecs.umich.edu{ 143963Ssaidi@eecs.umich.edu uint32_t time; 144963Ssaidi@eecs.umich.edu cpuid_eax(0); 145963Ssaidi@eecs.umich.edu rdtscl(time); 146963Ssaidi@eecs.umich.edu cpuid_eax(0); 147963Ssaidi@eecs.umich.edu return time; 148963Ssaidi@eecs.umich.edu} 149963Ssaidi@eecs.umich.edu 150963Ssaidi@eecs.umich.edu#elif __alpha__ 151963Ssaidi@eecs.umich.edu 152963Ssaidi@eecs.umich.eduinline uint32_t cycleCounter(uint32_t dep) 153963Ssaidi@eecs.umich.edu{ 154963Ssaidi@eecs.umich.edu uint32_t res; 155963Ssaidi@eecs.umich.edu asm volatile ("rpcc %0, %1" : "=r"(res) : "r" (dep) : "memory"); 156963Ssaidi@eecs.umich.edu return res; 157963Ssaidi@eecs.umich.edu} 158963Ssaidi@eecs.umich.edu#else 159963Ssaidi@eecs.umich.edu#error Architecture NOT SUPPORTE 160963Ssaidi@eecs.umich.edu#endif 161963Ssaidi@eecs.umich.edu 162963Ssaidi@eecs.umich.edustatic void __exit devtime_end(void) { 163963Ssaidi@eecs.umich.edu printk("Devtime Driver Version %s Unloaded...\n", DRIVER_VER); 164963Ssaidi@eecs.umich.edu} 165963Ssaidi@eecs.umich.edu 166963Ssaidi@eecs.umich.edu 167963Ssaidi@eecs.umich.edumodule_init(devtime_start); 168963Ssaidi@eecs.umich.edumodule_exit(devtime_end); 169963Ssaidi@eecs.umich.edu 1701051Ssaidi@eecs.umich.eduMODULE_LICENSE("Dual BSD/GPL"); 171963Ssaidi@eecs.umich.eduMODULE_AUTHOR(DRIVER_AUTHOR); 172963Ssaidi@eecs.umich.eduMODULE_DESCRIPTION(DRIVER_DESC); 173963Ssaidi@eecs.umich.edumodule_param(dataAddr, charp, 0); 174963Ssaidi@eecs.umich.edumodule_param(count, int, 0); 175