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