//------------------------------------------------------------------- // timing.c // // This example employs the x86 processor's TimeStamp Counter // to obtain a measurement of the cpu's elapsed clock-cycles. // // NOTE: Written and tested with Linux kernel version 2.6.22.5. // // programmer: ALLAN CRUSE // written on: 05 FEB 2008 //------------------------------------------------------------------- #include // for init_module() #include // for create_proc_info_entry() #include // for pci_get_device() #define VENDOR_ID 0x8086 // Intel Corporation #define DEVICE_ID 0x109A // 82573L controller //#define DEVICE_ID 0x10B9 // 82572EI controller enum { E1000_STATUS = 0x0008, }; char modname[] = "timing"; struct pci_dev *devp; unsigned int mmio_base; unsigned int mmio_size; void *io; unsigned long long stamp1; unsigned long long stamp2; unsigned long long cycles; int my_get_info( char *buf, char **start, off_t off, int count ) { int status, len = 0; // disable interrupts and save TimeStamp Counter's initial value asm(" cli \n rdtsc "); asm(" mov %%eax, stamp1 \n mov %%edx, stamp1+4 " : : : "ax", "dx" ); // perform a NIC register-access status = ioread32( io + E1000_STATUS ); // save TimeStamp Counter's final value and reenable interrupts asm(" rdtsc \n sti "); asm(" mov %%eax, stamp2 \n mov %%edx, stamp2+4 " : : : "ax", "dx" ); // subtract to get the number of elapsed cpu clock-cycles cycles = stamp2 - stamp1; // display the number of elapsed cpu clock-cycles len += sprintf( buf+len, "\n Elapsed cpu-cycles = %llu\n", cycles ); len += sprintf( buf+len, "\n" ); return len; } static int __init timing_init( void ) { printk( "<1>\nInstalling \'%s\' module\n", modname ); devp = pci_get_device( VENDOR_ID, DEVICE_ID, NULL ); if ( !devp ) return -ENODEV; mmio_base = pci_resource_start( devp, 0 ); mmio_size = pci_resource_len( devp, 0 ); io = ioremap_nocache( mmio_base, mmio_size ); if ( !io ) return -ENOSPC; create_proc_info_entry( modname, 0, NULL, my_get_info ); return 0; //SUCCESS } static void __exit timing_exit(void ) { remove_proc_entry( modname, NULL ); iounmap( io ); printk( "<1>Removing \'%s\' module\n", modname ); } module_init( timing_init ); module_exit( timing_exit ); MODULE_LICENSE("GPL");