*** c3mul.c.orig Mon Oct 1 21:23:26 2001 --- c3mul.c Thu Dec 25 21:22:48 2003 *************** *** 18,23 **** --- 18,25 ---- #define SAMUEL1 0x01 #define SAMUEL2 0x02 #define EZRA 0x03 + #define EZRA_T 0x04 + #define NEHEMIAH 0x05 extern int detect_cyrix3(void); *************** *** 241,246 **** --- 243,299 ---- __asm__ __volatile__ ("sti"); } + static void set_powersaver(int bit_pattern) + { + DWORD _edx, _eax; + int d0; + + __asm__ __volatile__ ("cli"); + + readmsr( 0x110a, &_edx, &_eax); + + _eax = bset(_eax, 4); /* [7:4](RevisionKey) = 3 */ + _eax = bset(_eax, 5); + _eax = bclr(_eax, 6); + _eax = bclr(_eax, 7); + _eax = bset(_eax, 8); /* enable software clock multiplier */ + d0 = 16; + while(d0 <= 19){ + if( (bit_pattern & 0x01) == 1 ){ + _eax = bset(_eax, d0); + }else{ + _eax = bclr(_eax, d0); + } + bit_pattern = bit_pattern >> 1; + d0 += 1; + } + if( (bit_pattern & 0x01) == 1 ){ + _eax = bset(_eax, 14); + }else{ + _eax = bclr(_eax, 14); + } + writemsr(0x110a, _edx, _eax); + + __asm__ __volatile__ ("sti"); + } + + static void disable_powersaver_clock_multiplier(void) + { + DWORD _edx, _eax; + + __asm__ __volatile__ ("cli"); + + readmsr( 0x110a, &_edx, &_eax); + _eax = bset(_eax, 4); /* [7:4](RevisionKey) = 3 */ + _eax = bset(_eax, 5); + _eax = bclr(_eax, 6); + _eax = bclr(_eax, 7); + _eax = bclr(_eax, 8); + writemsr(0x110a, _edx, _eax); + + __asm__ __volatile__ ("sti"); + } + static void usage(void) *************** *** 269,274 **** --- 322,360 ---- if( strcmp(mulstr, "1110b") == 0 ) return 0xE; if( strcmp(mulstr, "1111b") == 0 ) return 0xF; + if( strcmp(mulstr, "00000b") == 0 ) return 0x00; + if( strcmp(mulstr, "00001b") == 0 ) return 0x01; + if( strcmp(mulstr, "00010b") == 0 ) return 0x02; + if( strcmp(mulstr, "00011b") == 0 ) return 0x03; + if( strcmp(mulstr, "00100b") == 0 ) return 0x04; + if( strcmp(mulstr, "00101b") == 0 ) return 0x05; + if( strcmp(mulstr, "00110b") == 0 ) return 0x06; + if( strcmp(mulstr, "00111b") == 0 ) return 0x07; + if( strcmp(mulstr, "01000b") == 0 ) return 0x08; + if( strcmp(mulstr, "01001b") == 0 ) return 0x09; + if( strcmp(mulstr, "01010b") == 0 ) return 0x0A; + if( strcmp(mulstr, "01011b") == 0 ) return 0x0B; + if( strcmp(mulstr, "01100b") == 0 ) return 0x0C; + if( strcmp(mulstr, "01101b") == 0 ) return 0x0D; + if( strcmp(mulstr, "01110b") == 0 ) return 0x0E; + if( strcmp(mulstr, "01111b") == 0 ) return 0x0F; + if( strcmp(mulstr, "10000b") == 0 ) return 0x10; + if( strcmp(mulstr, "10001b") == 0 ) return 0x11; + if( strcmp(mulstr, "10010b") == 0 ) return 0x12; + if( strcmp(mulstr, "10011b") == 0 ) return 0x13; + if( strcmp(mulstr, "10100b") == 0 ) return 0x14; + if( strcmp(mulstr, "10101b") == 0 ) return 0x15; + if( strcmp(mulstr, "10110b") == 0 ) return 0x16; + if( strcmp(mulstr, "10111b") == 0 ) return 0x17; + if( strcmp(mulstr, "11000b") == 0 ) return 0x18; + if( strcmp(mulstr, "11001b") == 0 ) return 0x19; + if( strcmp(mulstr, "11010b") == 0 ) return 0x1A; + if( strcmp(mulstr, "11011b") == 0 ) return 0x1B; + if( strcmp(mulstr, "11100b") == 0 ) return 0x1C; + if( strcmp(mulstr, "11101b") == 0 ) return 0x1D; + if( strcmp(mulstr, "11110b") == 0 ) return 0x1E; + if( strcmp(mulstr, "11111b") == 0 ) return 0x1F; + if(cpu_type == SAMUEL1){ if( strcmp(mulstr, "3" ) == 0 ) return 0x0; if( strcmp(mulstr, "3.0") == 0 ) return 0x1; *************** *** 331,336 **** --- 417,496 ---- if( strcmp(mulstr, "10.0") == 0 ) return 0x0; if( strcmp(mulstr, "12" ) == 0 ) return 0xF; if( strcmp(mulstr, "12.0") == 0 ) return 0xF; + }else if(cpu_type == EZRA_T){ + if( strcmp(mulstr, "3" ) == 0 ) return 0x01; + if( strcmp(mulstr, "3.0" ) == 0 ) return 0x01; + if( strcmp(mulstr, "3.5" ) == 0 ) return 0x05; + if( strcmp(mulstr, "4" ) == 0 ) return 0x02; + if( strcmp(mulstr, "4.0" ) == 0 ) return 0x02; + if( strcmp(mulstr, "4.5" ) == 0 ) return 0x06; + if( strcmp(mulstr, "5" ) == 0 ) return 0x0B; + if( strcmp(mulstr, "5.0" ) == 0 ) return 0x0B; + if( strcmp(mulstr, "5.5" ) == 0 ) return 0x07; + if( strcmp(mulstr, "6" ) == 0 ) return 0x08; + if( strcmp(mulstr, "6.0" ) == 0 ) return 0x08; + if( strcmp(mulstr, "6.5" ) == 0 ) return 0x0C; + if( strcmp(mulstr, "7" ) == 0 ) return 0x09; + if( strcmp(mulstr, "7.0" ) == 0 ) return 0x09; + if( strcmp(mulstr, "7.5" ) == 0 ) return 0x0D; + if( strcmp(mulstr, "8" ) == 0 ) return 0x0A; + if( strcmp(mulstr, "8.0" ) == 0 ) return 0x0A; + if( strcmp(mulstr, "8.5" ) == 0 ) return 0x0E; + if( strcmp(mulstr, "9" ) == 0 ) return 0x03; + if( strcmp(mulstr, "9.0" ) == 0 ) return 0x03; + if( strcmp(mulstr, "9.5" ) == 0 ) return 0x04; + if( strcmp(mulstr, "10" ) == 0 ) return 0x00; + if( strcmp(mulstr, "10.0") == 0 ) return 0x00; + if( strcmp(mulstr, "11" ) == 0 ) return 0x11; + if( strcmp(mulstr, "11.0") == 0 ) return 0x11; + if( strcmp(mulstr, "12" ) == 0 ) return 0x0F; + if( strcmp(mulstr, "12.0") == 0 ) return 0x0F; + if( strcmp(mulstr, "12.5") == 0 ) return 0x16; + if( strcmp(mulstr, "13" ) == 0 ) return 0x1B; + if( strcmp(mulstr, "13.0") == 0 ) return 0x1B; + if( strcmp(mulstr, "13.5") == 0 ) return 0x17; + if( strcmp(mulstr, "14" ) == 0 ) return 0x18; + if( strcmp(mulstr, "14.0") == 0 ) return 0x18; + if( strcmp(mulstr, "14.5") == 0 ) return 0x1C; + if( strcmp(mulstr, "15" ) == 0 ) return 0x19; + if( strcmp(mulstr, "15.0") == 0 ) return 0x19; + if( strcmp(mulstr, "15.5") == 0 ) return 0x1D; + if( strcmp(mulstr, "16" ) == 0 ) return 0x1A; + if( strcmp(mulstr, "16.0") == 0 ) return 0x1A; + }else if(cpu_type == NEHEMIAH){ + if( strcmp(mulstr, "5" ) == 0 ) return 0x0B; + if( strcmp(mulstr, "5.0" ) == 0 ) return 0x0B; + if( strcmp(mulstr, "5.5" ) == 0 ) return 0x07; + if( strcmp(mulstr, "6" ) == 0 ) return 0x08; + if( strcmp(mulstr, "6.0" ) == 0 ) return 0x08; + if( strcmp(mulstr, "6.5" ) == 0 ) return 0x0C; + if( strcmp(mulstr, "7" ) == 0 ) return 0x09; + if( strcmp(mulstr, "7.0" ) == 0 ) return 0x09; + if( strcmp(mulstr, "7.5" ) == 0 ) return 0x0D; + if( strcmp(mulstr, "8" ) == 0 ) return 0x0A; + if( strcmp(mulstr, "8.0" ) == 0 ) return 0x0A; + if( strcmp(mulstr, "8.5" ) == 0 ) return 0x0E; + if( strcmp(mulstr, "9" ) == 0 ) return 0x03; + if( strcmp(mulstr, "9.0" ) == 0 ) return 0x03; + if( strcmp(mulstr, "9.5" ) == 0 ) return 0x04; + if( strcmp(mulstr, "10" ) == 0 ) return 0x00; + if( strcmp(mulstr, "10.0") == 0 ) return 0x00; + if( strcmp(mulstr, "11" ) == 0 ) return 0x11; + if( strcmp(mulstr, "11.0") == 0 ) return 0x11; + if( strcmp(mulstr, "12" ) == 0 ) return 0x0F; + if( strcmp(mulstr, "12.0") == 0 ) return 0x0F; + if( strcmp(mulstr, "12.5") == 0 ) return 0x16; + if( strcmp(mulstr, "13" ) == 0 ) return 0x1B; + if( strcmp(mulstr, "13.0") == 0 ) return 0x1B; + if( strcmp(mulstr, "13.5") == 0 ) return 0x17; + if( strcmp(mulstr, "14" ) == 0 ) return 0x18; + if( strcmp(mulstr, "14.0") == 0 ) return 0x18; + if( strcmp(mulstr, "14.5") == 0 ) return 0x1C; + if( strcmp(mulstr, "15" ) == 0 ) return 0x19; + if( strcmp(mulstr, "15.0") == 0 ) return 0x19; + if( strcmp(mulstr, "15.5") == 0 ) return 0x1D; + if( strcmp(mulstr, "16" ) == 0 ) return 0x1A; + if( strcmp(mulstr, "16.0") == 0 ) return 0x1A; } return -1; *************** *** 358,363 **** --- 518,527 ---- }else{ cpu_type = SAMUEL2; } + }else if( (id & 0x00003FF0) == 0x00000680 ){ + cpu_type = EZRA_T; + }else if( (id & 0x00003FF0) == 0x00000690 ){ + cpu_type = NEHEMIAH; } switch(cpu_type){ case SAMUEL1: *************** *** 369,374 **** --- 533,544 ---- case EZRA: printf("Ezra found\n"); break; + case EZRA_T: + printf("Ezra-T found\n"); + break; + case NEHEMIAH: + printf("Nehemiah found\n"); + break; default: printf("Unknown Centaur CPU found\n"); printf("exit.\n"); *************** *** 389,395 **** } printf("Multiplier "); ! for(d0 = 3; d0 >= 0; d0 -= 1){ if(multiplier_bit_pattern & (1 << d0)){ printf("1"); }else{ --- 559,565 ---- } printf("Multiplier "); ! for(d0 = 4; d0 >= 0; d0 -= 1){ if(multiplier_bit_pattern & (1 << d0)){ printf("1"); }else{ *************** *** 413,419 **** unmask_irq(0); /* unmask timer IRQ */ /* set CyrixIII internal clock multiplier */ ! set_bcr2(multiplier_bit_pattern); tick = 0; while(1){ --- 583,597 ---- unmask_irq(0); /* unmask timer IRQ */ /* set CyrixIII internal clock multiplier */ ! switch(cpu_type){ ! case EZRA_T: ! case NEHEMIAH: ! set_powersaver(multiplier_bit_pattern); ! break; ! default: ! set_bcr2(multiplier_bit_pattern); ! break; ! } tick = 0; while(1){ *************** *** 425,431 **** /* CPU wake up by timer interrupt */ ! disable_software_clock_multiplier(); restore_irq_handler(); load_irq_mask(); --- 603,617 ---- /* CPU wake up by timer interrupt */ ! switch(cpu_type){ ! case EZRA_T: ! case NEHEMIAH: ! disable_powersaver_clock_multiplier(); ! break; ! default: ! disable_software_clock_multiplier(); ! break; ! } restore_irq_handler(); load_irq_mask();