//------------------------------------------------------------------- // mmiodiff.cpp // // This user-space application uses the 'read()' and 'llseek()' // functions provided within our '82573.c' device-driver module // to investigate a claim that Intel's Pro1000 gigabit ethernet // controller implements the same i/o-memory register-values at // two different locations (although this fact is not disclosed // in the official Intel programming reference manual); namely, // the 128-byte i/o-memory range 0x05400-0x0547F which is named // the 'Receive-address Array' in Intel's manual can apparently // be accessed at the alternate i/o-memory range 0x00040-000BF. // // compile using: $ g++ mmiodiff.cpp -o mmiodiff // execute using: $ ./mmiodiff // // NOTE: This application requires our '82573.c' device-driver. // // ------------------------------------------------------------ // REVISED to examine the following four i/o-memory ranges: // // 0x6000-0x63FF, 0x6400-0x67FF, 0x6800-0x6BFF, 0x6C00-0x6FFF // // and to count any "mismatches" among corresponding registers. // ------------------------------------------------------------ // // programmer: ALLAN CRUSE // written on: 19 FEB 2008 // revised on: 20 FEB 2008 -- for Question V on Midterm Exam I //------------------------------------------------------------------- #include // for printf(), perror() #include // for open() #include // for exit() #include // for lseek(), read() #define RANGE_SIZE 0x400 // 1024-byte i/o address-range <--- #define NUM_REGS (RANGE_SIZE >> 2) // number of 32-bit registers char devname[] = "/dev/82573"; // our device-file's pathname int main( int argc, char **argv ) { // open the device-file for reading int fd = open( devname, O_RDONLY ); if ( fd < 0 ) { perror( devname ); exit(1); } // read register-range 0x06000-0x063FF into a local array unsigned int range1[ NUM_REGS ]; lseek( fd, 0x06000, SEEK_SET ); for (int i = 0; i < NUM_REGS; i++) read( fd, &range1[i], 4 ); // read register-range 0x06400-0x067FF into a local array unsigned int range2[ NUM_REGS ]; lseek( fd, 0x06400, SEEK_SET ); for (int i = 0; i < NUM_REGS; i++) read( fd, &range2[i], 4 ); // read register-range 0x06800-0x06BFF into a local array unsigned int range3[ NUM_REGS ]; lseek( fd, 0x06800, SEEK_SET ); for (int i = 0; i < NUM_REGS; i++) read( fd, &range3[i], 4 ); // read register-range 0x06C00-0x06FFF into a local array unsigned int range4[ NUM_REGS ]; lseek( fd, 0x06C00, SEEK_SET ); for (int i = 0; i < NUM_REGS; i++) read( fd, &range4[i], 4 ); // count the number of occurrences of any 'mismatch' among // any set of four corresponding register-entries (if any) int mismatch = 0; for (int i = 0; i < NUM_REGS; i++) { printf( "\n 0x%04X: ", 4*i ); printf( " %08X ", range1[ i ] ); printf( " %08X ", range2[ i ] ); printf( " %08X ", range3[ i ] ); printf( " %08X ", range4[ i ] ); if ( !( ( range1[ i ] == range2[ i ] ) ||( range2[ i ] == range3[ i ] ) ||( range3[ i ] == range4[ i ] ) ) ) ++mismatch; } printf( "\n\n Number of mismatched entries: %d \n\n", mismatch ); }