set6x86-1.5/ 40755 0 144 0 6445076062 11030 5ustar rootusersset6x86-1.5/set6x86.c100644 0 144 14734 6235222720 12540 0ustar rootusers/* get/set6x86: a tool for changing Cyrix 6x86 configuration registers * * Copyright (C) 1996 Koen Gadeyne * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /*** *** This is just a hacking tool! Use at your own risk. It was NOT intended to be *** idiot proof! If you don't understand all this, then don't bother trying to use it. *** ***/ #include #include #include #include #include #include #ifndef DOS # include #else # ifdef DJGPP # include # define outb(data,port) outportb(port,data) # define outw(data,port) outportw(port,data) # define inb(port) inportb(port) # define inw(port) inportw(port) # else /* Borland C */ # define outb(data,port) outp(port,data) # define outw(data,port) outpw(port,data) # define inb(port) inp(port) # define inw(port) inpw(port) # endif # define ioperm(x,y,z) (0) #endif typedef int bool; #ifndef TRUE # define TRUE (1) #endif #ifndef FALSE # define FALSE (0) #endif char *CommandName; void get_IO_range(int start, int len) { if (ioperm(start, len, 1) != 0) { perror("I/O Permissions"); fprintf(stderr,"Cannot get I/O permissions for hardware address range 0x%x-0x%x.\n\ You must be superuser, or the program must be setuid root!\n", start, start+len-1); exit(1); } } void check_int_range(int cvalue, int lmin, int lmax, char* descstr) { if (cvaluelmax) { fprintf(stderr,"%s = %d (0x%x) out of range [%d..%d]!\n", descstr, cvalue, cvalue, lmin, lmax); exit(1); } } int getint(char* instring, char* descrstring, int lmin, int lmax) /* convert the int in 'instring' into an integer. Must be within specified limits 'lmin' and 'lmax' */ /* 'descrstring' contains a description of the number to be parsed, used in error message */ { char** errstr=NULL; int readint; readint = strtol(instring,errstr,0); if (errstr) { fprintf(stderr,"Illegal character '%s' in %s: '%s'\n", *errstr, descrstring, instring); exit(1); } check_int_range(readint, lmin, lmax, descrstring); return(readint); } char* int_to_bin(int num, int bits) { static char binstr[sizeof(long int)+1]; int i; for (i=0; i> i) & 0x00000001); return(binstr); } void usage(int setreg) { printf("%s %s (c) 1996 Koen Gadeyne.\n" "\n" " Usage: %s [options] register_index %s\n\n" " Options: -h print usage information\n" "%s"\ "\n" " register_index: An index to the specified Cyrix 6x86 config register,\n" " In decimal (e.g. '24'), hex ('0x18') or octal ('030').\n" "\n" "%s\n", CommandName, VERSION, CommandName, (setreg) ? "data" : "", (setreg) ? \ " -p silent mode: don't spread the news (no output)\n" " -s `data' is a bitmask for setting bits in the register\n"\ " -c `data' is a bitmask for clearing bits in the register\n"\ : \ " -p pipeable output: only hex register contents are printed\n",\ (setreg) ? \ " data: the data to program into the specified register (dec|hex|oct).\n"\ " (or the bitmask for the -s' (set) or -c' (clear) options)\n"\ : \ ""); } /***********************************************************************************************************/ int main (int argc, char* argv[]) { int c; int tmpbyte=0; int regnum=0; bool setreg = FALSE; bool silent = FALSE; bool arg_is_setmask=FALSE; bool arg_is_clearmask=FALSE; char* commandfilename; int data=0; /* * See what action is required: read or write */ CommandName = argv[0]; commandfilename = strrchr(CommandName, '/'); if (commandfilename) commandfilename++; else commandfilename = CommandName; setreg = (!strncasecmp(commandfilename,"set",3)); /* * command-line argument parsing */ while ((c = getopt (argc, argv, "hpsc")) != EOF) switch (c) { case 'h': usage(setreg); exit(0); break; case 'p': silent=TRUE; break; case 's': arg_is_setmask=TRUE; break; case 'c': arg_is_clearmask=TRUE; break; case '?': usage(setreg); printf("Bad option '-%c'\n",(char)optopt); exit(1); break; default: fprintf(stderr,"getopt returned unknown token '%c'.\n",c); exit(1); } /* get register set from commandline */ if (argcoptind) fprintf(stderr,"Extra parameters (starting with '%s') ignored\n", argv[optind]); /* * start doing something useful */ get_IO_range(0x22, 2); if (setreg) { if (arg_is_clearmask || arg_is_setmask) { outb(regnum, 0x22); tmpbyte = inb(0x23); /* read original data */ if (arg_is_clearmask) data = tmpbyte & ~data; if (arg_is_setmask) data = tmpbyte | data; } outb(regnum, 0x22); outb(data, 0x23); /* write data */ } outb(regnum, 0x22); tmpbyte = inb(0x23); /* read back data */ if (!silent) { printf("Cyrix 6x86 config register, index %d (=0x%x) contains %d (=0x%02x =b%s)\n", regnum, regnum, tmpbyte, tmpbyte, int_to_bin(tmpbyte,8)); } else if (!setreg) /* "getreg" needs to output _something_ */ { printf("0x%x\n", tmpbyte); } return(0); } set6x86-1.5/Makefile100644 0 144 772 6444751734 12560 0ustar rootusers# Makefile for set6x86, a program to get/set Cyrix 6x86 CPU config settings # from GNU/Linux CFLAGS = -O2 -Wall VERSION=1.5 ############################################################################# _VERSION = -DVERSION=\"$(VERSION)\" get6x86: set6x86 ln -sf set6x86 get6x86 set6x86: set6x86.c $(CC) $(CFLAGS) $(_VERSION) -o set6x86 set6x86.c 6x86_reg: 6x86_reg.c $(CC) $(CFLAGS) $(_VERSION) -o 6x86_reg 6x86_reg.c all: set6x86 get6x86 6x86_reg clean: rm -f get6x86 set6x86 6x86_reg *.o set6x86-1.5/README100644 0 17 30240 6445002205 11401 0ustar rootman set6x86 / get6x86 / 6x86_reg ---------------------------- Please read through this file before attempting to use the programs in this package. It might save you a few crashes. Description ----------- Set6x86 and get6x86 are two programs that allow you to poke and peek into the Cyrix/IBM/SGS-Thomson 6x86 CPU's configuration registers. 6x86_reg will display register contents in human-readable format. The short source test_bug is a demo program for the 6x86 "coma" bug. Cyrix CPUs ---------- Cyrix 6x86 CPU's are Intel Pentium-like performance CPUs, but at a lower cost than their Intel parts. Cyrix has adopted a CPU rating that refers to "equivalent Pentium performance in Windows applications" for their CPUs. A Cyrix-6x86 P133+ for example is clocked at only 110 MHz, although it performs as good as a Pentium 133 (hence the "P133+" rating). The "+" is a marketing gadget: it is supposed to point out that it's even a little better than a P133 on the Winstone benchmark. 6x86 CPUs come at a significantly lower price than their equivalent Intel cousins. The only downsides are: - a lack of support from several motherboard vendors and software vendors (most CPU identification programs, Linux 2.0's /proc/cpuinfo included, report a 486 CPU instead of a Cyrix 6x86). A short patch is available from http://www.tux.org/~balsa/linux/cyrix that solves this kernel shortcoming. - Floating point performance is not as good as a Pentium. Depending on the benchmark, 15 to 50% lower FPU performance can be expected. - This baby needs HUGE amounts of power. People used to make fun of the newest Digital chip, the Alpha, a few years ago, because it needed over 20 Watts of power. Well, this one too. Depending on the clock speed, up to 24 Watts of power is dissipated from the package! Anyone familiar with hardware design can tell you that keeping that under control is not a simple task. That is also the main reason why so many people flush newsgroups with messages that the 6x86 CPU's are bad, don't run Win95, crash all the time,... Do you really think those companies would even _risk_ making a CPU that is not as compatible as possible? The only thing they didn't replicate was the ominous Pentium FPU bug ;-) On the other hand Cyrix 6x86 CPUs suffer from another bug, called the 6x86 "coma" bug. The short program test_bug is an example of how this bug affects 6x86 CPUs. The _real_ reason for crashes and system hangs in most cases is either a temperature problem, or a digital timing problem (the latter being caused by the former in many cases). Poorly cooled CPU's tend to go beyond their specified ratings. Most CPUs are only guaranteed to work up to 70 degrees Celsius, and with 24 Watts to sweat out from such a small surface, that's _very_ easily exceeded. Why this program? ----------------- For fun, mostly. But also for some pretty darn good reasons. Most motherboards (mine, a Chaintech board based on the Intel Triton II chipset) support 6x86 CPUs, but not as well-tested and well-set-up as Pentium CPUs. The 6x86 has a set of configuration registers that allows one to do a lot of things, like specifying non-cacheable memory areas (important for e.g. graphics cards), I/O delays, cache write policy (WB/WT), and also to enable an automatic standby mode where a CPU "halt" instruction cuts down power by a factor of 70 (from 5.8 Amps to 83 milli-Amps for the P133+). Since most computers do nothing most of the time, this would be useful to enable. Linux uses the halt instruction when it has nothing better to do, so enabling this feature will _not_ hurt performance: the CPU controls the powering-down of specific internal parts by hardware-control, so there's no software intervention needed for explicitly re-enabling a powered-down part. However, some Linux users have reported that their systems would hang if this feature was enabled and some bus-mastering Ethernet cards were used, in some specific circumstances and only with some motherboards/chipset/BIOS combinations! So even this seemingly inocuous feature should be tested on individual systems. Benefits? --------- Apart from the obvious environmental reasons, there's also the temperature problem that is reduced substantially. If you're on a P133+ and programming like hell, or reading mail, or most of the other things you do in Linux (or any other OS for that matter), the CPU is doing nothing 99% of the time (just take an occasional look at the system load meter). When not set for automatic power-down, the CPU will _always_ draw its full 24 Watts of power. With this feature enabled, power consumption drops to near-zero most of the time. While I'm typing this doc, my CPU is (again) 99% idle, so now the CPU uses only 0.3 Watts instead. That's one _hundreth_ of its full juice. No need to say that most thermal problems are history. In fact, I had _lots_ of spurious core dumps and "signal 11" messages from GCC on my system, and I always suspected temperature problems. With auto-suspend mode on, I haven't had a single core dump since (but I haven't done a lot of testing either). This convinced me that I will have to provide better cooling for the CPU. DANGER!!! --------- Of course, you're fiddling with the guts of your CPU, while it's running. So don't blame me if you accidently set the wrong register and your machine hangs. In other words, let's use the Paul Gortmaker (?) disclaimer: "If it breaks, you get to keep the pieces" LITERATURE ---------- This package is completely useless without the proper docs from Cyrix and/or IBM. I explicitly didn't include any description of the 6x86 config registers because I didn't want to risk distributing faulty information. Cyrix's WWW site (www.cyrix.com) and their FTP site (ftp.cyrix.com) contain all the stuff you need. For ftp, all the files are in the "6x86" directory. You need _at least_ 6X-ABDB.PDF (361748 bytes) which is the abbreviated data book, and contains a description of all the registers you can tamper with (starting at page 18). The full data book is 6X-DBOOK.PDF (2039298 bytes) For the 5x86, the Cyrix FTP/WWW site may contain equivalent doumentation (not checked). Here's a list of WWW sites known to carry information on 6x86 CPUs: http://www.cyrix.com http://www.chips.ibm.com/products/x86/ http://www.tux.org/~balsa/linux/cyrix/index.html http://www.alternativecpu.com EXAMPLE: -------- The power-saving option described above is controlled by register 0xC2, bit 3 of the configuration registers. Thus, get6x86 0xC2 will display (on my system -- "your mileage may vary"): Cyrix 6x86 config register, index 194 (=0xc2) contains 128 (=0x80 =b10000000) Note that bit 3 is set to zero, so the suspend-on-halt mode is disabled. Typing set6x86 0xC2 0x88 will set bit #3 of that register, thus enabling the auto-suspend mode. Simpler is to use the "-s" or "-c" options. These use the data byte on the command line as a set/clear mask instead of raw data to program into the register. So the above can be made much more simple by just typing set6x86 0xC2 -s 0x08 This will read register 0xC2, and "set" bits using the mask given (0x08). The "-s" does a logical "OR" of the original register data and the mask data, and programs it back into the register, whilst the "-c" option will do a logical "AND" with the inverse of the mask (0xF7 in this case). The included rc.cyrix file enables a few performance-related thingies on the Cyrix 6x86 CPU. Copy it to the /etc/rc.d directory, and call it from e.g. rc.local (also included is a new rc.6x86MX for 6x86MX owners). It is a good example of the use of set6x86 to set various different Cyrix 6x86 registers. It does a bit of everything. 6x86_reg -------- This little tool dumps most relevant 6x86 registers in human-readable format. It will also correctly identify the 6x86 model and revision, report bogoMIPS ratings, and dump the more complex ARRs (Address Region Registers). These are the registers where the different memory regions are set up and how they are handled (e.g. if they're cached or if any other special function is enabled for them). Running it may reveal something like the output below: * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 6x86 (Classic/L/MX) Register Dump utility 6x86 DIR0: 0x52 2.5X core/bus clock ratio DIR1: 0x4 6x86MX Rev. 1.4 Wait a moment... Calculated BogoMIPS: 185.12 Kernel BogoMIPS: 186.78 6x86 CCR0: 0x2 NC1 set (address region 640Kb-1Mb non-cacheable) CCR1: 0x92 NO_LOCK set CCR2: 0x88 SUSP_HLT set (low power suspend mode enabled) CCR3: 0x10 CCR4: 0x87 no I/O recovery time CCR5: 0x21 allocate cache lines on write misses 6x86 Address Region Register dump: ARR0: address = 0xA0000 , size = 128 KB RCR = 0x9 : not cached, write gathering ARR1: address = 0xC0000 , size = 256 KB RCR = 0x1 : not cached ARR2: disabled ARR3: address = 0xA8000 , size = 32 KB RCR = 0x9 : not cached, write gathering ARR4: disabled ARR5: disabled ARR6: address = 0xE0000000 , size = 4 MB RCR = 0x9 : not cached, write gathering ARR7: address = 0x0 , size = 32 MB RCR = 0x9 : cached, write gathering * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * This saves you a lot of fingering through the 6x86 data book :-) BogoMIPS -------- First of all you must understand that bogoMIPS are _not_ meant as a measure of performance, but rather as an indicator that the 6x86 registers and the BIOS settings for the chipset on your motherboard are correctly set. That said, we can look at the three possible outcomes of running 6x86_reg: 1) The calculated bogoMIPS and the kernel bogoMIPS reading from /proc/cpuinfo are approx. equal (+/- 1 bogoMIPS). This is the normal case on a "quiet" system. Note that on 6x86 family CPUs, bogoMIPS are approximately equal to the CPU core clock rate. For example: - a 6x86 PR166 should have a bogoMIPS rating of approx. 133, since its core will run at 133MHz (2 x 66.66MHz). - a 6x86MX PR233 at 187.5MHz (2.5 x 75MHz) should have a bogoMIPS rating of approx. 187.5. 2) The calculated bogoMIPS is much higher (> 10-15%) than the kernel bogoMIPS. This indicates that your BIOS is not setting the 6x86 registers or the chipset parameters for the L2 cache correctly, and that set6x86 has remedied to this. Adjust your BIOS CMOS settings and/or upgrade the BIOS flash EEPROM. 3) The calculated bogoMIPS is lower than the /proc/cpuinfo kernel reading: your system load is impairing the bogoMIPS calculation done by 6x86_reg. Fun? ---- You might even be able to _hear_ the difference! Most computer power supplies only compensate higher power demands on the +5V rail, resulting in an increase on the +12V rail when +5V power demand goes up. The CPU draws from the +5V rail, but the CPU fan uses +12V, so when the CPU draws more power (due to CPU load), the CPU cooling fan will run a little faster with higher supply voltages. The significant power consumption drop when the CPU goes into power-suspend mode might cause a noticeable change in the pitch of the buzzing fan sound! On my system, I can now HEAR how busy it is... The 6x86 Coma bug ----------------- Compile and run the short bug demo program as a "normal" user (but unmount all file systems before running it). Type Control-C to try and regain control: nothing happens, right? Your 6x86 CPU is in "coma" mode. :-( The 6x86 CPU effectively gets locked in an infinite loop, executing back-to-back locked cycles and consequently unable to service any interrupts, including attempts by root to kill the process. This is by all means a serious security flaw in a multiuser OS like Linux. This bug affects all 6x86 family CPUs. Solution: enable the NO_LOCK bit with set6x86. Support ------- None. Your own intelligence and common sense should be enough. You may want to take a look at the 6x86/Linux mini-HOWTO site for further info/updates: http://www.tux.org/~balsa/linux/cyrix DOS --- DOS support was removed starting at version 1.4. Author ------ Koen Gadeyne, koen.gadeyne@barco.com (please contact the maintainer below first) New maintainer -------------- Thanks Koen! I'll do my best with this "hot potato" :-) Andrew D. Balsa, andrewbalsa@usa.netset6x86-1.5/6x86_reg100755 0 0 20176 6445075701 12221 0ustar rootrootELF44 (444ԀԀ   Xttt/lib/ld-linux.so.1     ("tȄ""T.؄"5  ?EFQ"X  `"hTv"|(" 8&"H84Xh>x:xlibc.so.5printf_DYNAMICfscanf_IO_stderr_perror__environ_init__libc_initiopermenvironfprintf__fpu_controlfopenfclose_finisprintfatexit_GLOBAL_OFFSET_TABLE_exit__setfpucwclock_etext_edata__bss_start_endT @DHLP T X \`dhlp+ 58%<%@h%Dh%Hh%Lh%Ph %Th(%Xh0%\h8p%`h@`%dhHP%hhP@%lhX0%ph` YЃ1UUUPSQ̀D$ TPhgPd[t&&̀&S0=0t Ѓ;u[Í6ÐUVS]u jVS t)hDPShhjve[^ÐUWVS}u 19}6ƁX0A9|ƆX19}vY)؉X9|Xe[^_ÐUE= Ph v= Ph 6Phh]!]Í6UWVShhuĎtȎxl66ShՎI ̎ uٍPhՎhthՎ ^[^_ÍvUWVSjj"Eh؎ "#ɉM"M#"#ɉMQhUpPuAMtwtnttahRh.JhHBh`:Mtrt"t(vhzhhHhh"#҉URhM$                         h~hˏvhُnhfh^h V1 M<41d1S 1Qh? C6hh+!WÉHyJ)ډӃcsuhth_chY "#Sht@thh&"#Sh t h6h"#Sht h%6hT"#Sh"#ShEtt hvhjكwn$d6hё6h.h&h3hThvhhh"#ShϒEtt hvht h vh0hW1EE"#E"#% ÊE"#ȉ% ÃVh{M*Mu h6ShMMu h@vPPh "#ShtÓt6tÓQhē~Ett h͓ft hTt hBt h0 t hhEF"E#1e[^_ÐS$=$t Ѓ;u[Í6Ð I/O PermissionsCannot get I/O permissions for hardware address range 0x%x-0x%x. You must be superuser, or the program must be setuid root! %d KB%d MB%d GBr/proc/cpuinfounknownbogomips%s 6x86 (Classic/L/MX) Register Dump utility 6x86 DIR0: 0x%x 2X core/bus clock ratio2.5X core/bus clock ratio3X core/bus clock ratio3.5X core/bus clock ratio1X core/bus clock ratio4X core/bus clock ratio DIR1: 0x%x 6x86 Rev. 2.46x86 Rev. 2.56x86 Rev. 2.66x86 Rev. 2.7 or 3.76x86L Rev. 4.26x86MX Rev. 1.36x86MX Rev. 1.4 Wait a moment... Calculated BogoMIPS: %lu.%02lu Kernel BogoMIPS: %s 6x86 CCR0: 0x%x NC1 set (address region 640Kb-1Mb non-cacheable) NC1 reset (address region 640Kb-1Mb cacheable) CCR1: 0x%x NO_LOCK set NO_LOCK reset CCR2: 0x%x SUSP_HLT set (low power suspend mode enabled) SUSP_HLT reset (low power suspend mode disabled) CCR3: 0x%x CCR4: 0x%x DTE cache enabled, DTE cache disabled, 1 clock cycle I/O recovery time2 clock cycles I/O recovery time4 clock cycles I/O recovery time8 clock cycles I/O recovery time16 clock cycles I/O recovery time32 clock cycles I/O recovery time64 clock cycles I/O recovery timeno I/O recovery time CCR5: 0x%x slow LOOP enabled, slow LOOP disabled, allocate cache lines on write misses default cache line allocation policy 6x86 Address Region Register dump: ARR%d: disabled address = 0x%X , size = %s RCR = 0x%X : not %scached, weak write ordering, weak locking, write gathering, write through, no LBA#t΄ބ.>N^n~  < 4h0 GCC: (GNU) 2.7.2.l.3GCC: (GNU) 2.7.2.1GCC: (GNU) 2.7.2.l.301.0101.0101.01.symtab.strtab.shstrtab.interp.hash.dynsym.dynstr.rel.bss.rel.plt.init.plt.text.fini.rodata.data.ctors.dtors.got.dynamic.bss.comment.noteԀ#) 1<<9   B 00hKQVd\bj  p$$w,,~44@tt|@@<<x+       Ѝ Ѝ 1( > I$ W0dk   p ,0 I$ $  4 X]t("t4K Ȅ"T؄"W   $*F6؆F ?"F  N"VTd k z  "؇ (" 8&"H8t4xXh>x:crtstuff.cgcc2_compiled.__do_global_ctors_aux__CTOR_END__init_dummyforce_to_data__DTOR_END__crt0.Sdone__do_global_dtors_aux__DTOR_LIST__fini_dummy__CTOR_LIST__6x86_reg.cbinstr.102size.105infoprintf_DYNAMICget_IO_range_etextfscanf_IO_stderr_perrorint_to_bin__environ_init__libc_initsize_striopermenvironfprintf__fpu_control_start___crt_dummy__read_cpuinfofopen__bss_startmainfclose_finisprintfatexitCommandName_edata_GLOBAL_OFFSET_TABLE__endexit__setfpucwclockset6x86-1.5/rc.cyrix100755 0 144 2174 6235223504 12610 0ustar rootusers#!/bin/sh # # This script, when installed in your /etc/rc.d directory, # and when called from e.g. rc.local or rc.M will enable # various performance and power-saving features on your # Cyrix CPU. # # set6x86 version 1.2 or newer required BINPATH=/usr/sbin echo -n "Cyrix 6x86: Suspend-on-Halt, " $BINPATH/set6x86 -p 0xC2 -s 0x08 echo -n "Fast ADS, " $BINPATH/set6x86 -p 0xC2 -c 0x02 # MAPEN (access to CCR4/5 enabled -- needed for settings below) $BINPATH/set6x86 -p 0xC3 -s 0x10 echo -n "Fast IORT, " $BINPATH/set6x86 -p 0xE8 -s 0x07 echo -n "Enable DTE, " $BINPATH/set6x86 -p 0xE8 -s 0x10 echo -n "Fast LOOP, " $BINPATH/set6x86 -p 0xE9 -c 0x02 # This enables some performance features for the linear memory mapped # VGA memory buffer, assuming it's on address 0xE0000000. # # On my system, memory bandwidth goes from 44 MB/sec to 78 MB/sec. # # It is disabled here, because this is very system-dependent. # #echo -n "Fast Lin. VidMem." #$BINPATH/set6x86 -p 0xD6 0xE0 #$BINPATH/set6x86 -p 0xD7 0x00 #$BINPATH/set6x86 -p 0xD8 0x0A #$BINPATH/set6x86 -p 0xE2 0x09 # MAPEN (disable access to CCR4/5) $BINPATH/set6x86 -p 0xC3 -c 0x10 echo set6x86-1.5/set6x86100755 0 0 15543 6441517215 12077 0ustar rootrootELF44 (444ԀԀDHHH/lib/ld-linux.so.1    ("H-ПT9"@ JVЄ\(Fh8pH"w X"$(h,@ x8, >4ПП<libc.so.5printf_DYNAMIC__strtol_internal_IO_stderr_perror__environstrncasecmp_init__libc_initstrrchriopermenvironfprintf__fpu_controloptindgetopt_finiatexitoptopt_GLOBAL_OFFSET_TABLE_exit__setfpucw_etext_edata__bss_start_endП$(, $( , 0 4 8<@D;5%%h%h% h%$h%(h %,h(%0h0%4h8p%8h@`%<hHP%@hP@%DhX0YЃ1UUUPSQ̀D$$P1h@wPt[t&&̀&S=t Ѓ;u[Í6ÐUVS]u jVS t)hHDPShXhПjve[^ÐUEM U9|9~ RQPPuhhПjvÍ6UWVS] ujjjuǃSVuWe[^_UWVS}u 19}6Ɓ00A9|Ɔ019}vY)؉09|0e[^_ÐUUt-PtPtȌP8Ph͌Phь;ÐUWVS] EEEE8j/PQƒtB8jh؍R 6h܍SuFƒ ht ?tHct7aptstTVj+vE뫍vE럍vE듍vV,PhLjRhhПj(B9E}hhПjhjh?4ǃtQ(E@((E9E}hNhП-jV6hjhe4E((9U~4hshП jj"t9}u}t$"#ڃ}t E!؉E}t ]"E#"#ڃ}ujS6PSSWWhu Sh1e[^_ÐS=t Ѓ;u[Í6ÐI/O PermissionsCannot get I/O permissions for hardware address range 0x%x-0x%x. You must be superuser, or the program must be setuid root! %s = %d (0x%x) out of range [%d..%d]! Illegal character '%s' in %s: '%s' data: the data to program into the specified register (dec|hex|oct). (or the bitmask for the -s' (set) or -c' (clear) options) -p silent mode: don't spread the news (no output) -s `data' is a bitmask for setting bits in the register -c `data' is a bitmask for clearing bits in the register -p pipeable output: only hex register contents are printed data1.4%s %s (c) 1996 Koen Gadeyne. Usage: %s [options] register_index %s Options: -h print usage information %s register_index: An index to the specified Cyrix 6x86 config register, In decimal (e.g. '24'), hex ('0x18') or octal ('030'). %s sethpscBad option '-%c' getopt returned unknown token '%c'. Missing register index on commandline register indexMissing register data register dataExtra parameters (starting with '%s') ignored Cyrix 6x86 config register, index %d (=0x%x) contains %d (=0x%02x =b%s) 0x%x H.>N^n~ Є @P  `lL GCC: (GNU) 2.7.2.l.3GCC: (GNU) 2.7.2.1GCC: (GNU) 2.7.2.l.301.0101.0101.01.symtab.strtab.shstrtab.interp.hash.dynsym.dynstr.rel.bss.rel.plt.init.plt.text.fini.rodata.data.ctors.dtors.got.dynamic.bss.comment.noteԀ#) 1PP9 LL B ll`KЄQ؄V\@@ bHH jpw~  <HHПl@@<L* T        1 >0 I Wdk   0 p0 P I   T 0("HTK 4dK ПT " W ؆4 # -9Є?(FK8SH"Z bX"j$x(  Пh,Q @ x8,8П <6 >crtstuff.cgcc2_compiled.__do_global_ctors_aux__CTOR_END__init_dummyforce_to_data__DTOR_END__crt0.Sdone__do_global_dtors_aux__DTOR_LIST__fini_dummy__CTOR_LIST__set6x86.cbinstr.106printf_DYNAMICget_IO_range_etext__strtol_internalusage_IO_stderr_perrorint_to_bingetint__environstrncasecmp_init__libc_initstrrchriopermenvironfprintf__fpu_controloptind_start___crt_dummy____bss_startgetoptmain_finiatexitoptoptCommandName_edata_GLOBAL_OFFSET_TABLE__endexitcheck_int_range__setfpucwset6x86-1.5/get6x86120777 0 0 0 6444735304 13125 2set6x86ustar rootrootset6x86-1.5/rc.6x86MX100755 0 0 2276 6441471413 12211 0ustar rootroot#!/bin/sh # # This script, when installed in your /etc/rc.d directory, # and when called from e.g. rc.local or rc.M will enable # various performance and power-saving features on your # Cyrix 6x86MX CPU. # # set6x86 version 1.2 or newer required BINPATH=/usr/sbin echo -n "Cyrix 6x86MX: Suspend-on-Halt, " $BINPATH/set6x86 -p 0xC2 -s 0x08 # Enable protection against the Cyrix Coma bug echo -n "NO_LOCK, " $BINPATH/set6x86 -p 0xC1 -s 0x10 # MAPEN (access to CCR4/5 enabled -- needed for settings below) $BINPATH/set6x86 -p 0xC3 -s 0x10 echo -n "Fast IORT, " $BINPATH/set6x86 -p 0xE8 -s 0x07 echo -n "Enable WT_ALLOC, " $BINPATH/set6x86 -p 0xE9 -s 0x01 # This enables some performance features for the memory mapped LVFB - # Linear Video Frame Buffer, assuming it's on address 0xE0000000 and its size # is 4Mb. (check /proc/pci for your system LVFB address) # # Also assumed a power-of-two amount of main memory. # # Improves CPU/video memory bandwidth by anything from 20 to 50%. # echo -n "Fast Lin. VidMem." $BINPATH/set6x86 -p 0xD6 0xE0 $BINPATH/set6x86 -p 0xD7 0x00 $BINPATH/set6x86 -p 0xD8 0x0B $BINPATH/set6x86 -p 0xE2 0x09 # MAPEN (disable access to CCR4/5) $BINPATH/set6x86 -p 0xC3 -c 0x10 echo set6x86-1.5/kernel-patches/ 40755 0 0 0 6445074146 13507 5ustar rootrootset6x86-1.5/kernel-patches/README.patches100644 0 0 1566 6445074142 16116 0ustar rootrootcyrix_patch is my short patch for all 2.0.x kernels and most 2.1.x kernels up to 2.1.64. cyrix_65_patch is a version of the above short patch for kernels 2.1.65-2.1.70, kindly contributed by Stphane Casset. Kernels 2.1.71 and above need an updated version version of my patch, not available yet. I would me most thankful if somebody could contribute it, since I am not using kernels 2.1.x yet on my 6x86/Linux boxes. What these patches do --------------------- 1) Correctly identify the Cyrix CPUs in /proc/cpuinfo. 2) Only for 6x86(L) CPUs, reset the SLOP bit for correct bogoMIPS readings. 3) Only for 6x86MX CPUs, fix a small kernel bug in /arch/i386/kernel/time.c. What these patches will not do ------------------------------ Anything else ;-). And I don't intend to change this, so don't ask for more features: use your good sense and set6x86 instead :-) Andrew D. Balsaset6x86-1.5/kernel-patches/cyrix_65_patch100644 0 0 25106 6435277517 16410 0ustar rootrootdiff -u -r linux-2.1.65/arch/i386/kernel/head.S linux/arch/i386/kernel/head.S --- linux-2.1.65/arch/i386/kernel/head.S Sat Nov 15 01:52:12 1997 +++ linux/arch/i386/kernel/head.S Thu Nov 20 16:58:32 1997 @@ -141,7 +141,72 @@ * apply at our cpl of 0 and the stack ought to be aligned already, and * we don't need to preserve eflags. */ - movl $3, SYMBOL_NAME(x86) + /* + * A Cyrix/IBM 6x86(L) preserves flags after dividing 5 by 2 + * (and it _must_ be 5 divided by 2) while other CPUs change + * them in undefined ways. We need to know this since we may + * need to enable the CPUID instruction at least. + */ + xor %ax,%ax + sahf + movb $5,%ax + movb $2,%bx + div %bl + lahf + cmpb $2,%ah + jne ncyrix + + /* + * It behaves like a Cyrix/IBM 6x86(L) so put "Cyrix" in the + * vendor id field. It may be overwritten later with the + * real thing if CPUID works. + */ + movl $0x69727943,SYMBOL_NAME(x86_vendor_id) # low 4 chars + movl $0x00000078,SYMBOL_NAME(x86_vendor_id)+4 # next 4 chars + + /* + * N.B. The pattern of accesses to 0x22 and 0x23 is *essential* + * so do not try to "optimize" it! For the same reason we + * do all this with interrupts off. + */ +#define setCx86(reg, val) \ + movb reg,%ax; \ + outb %ax,$0x22; \ + movb val,%ax; \ + outb %ax,$0x23 + +#define getCx86(reg) \ + movb reg,%ax; \ + outb %ax,$0x22; \ + inb $0x23,%ax + + cli + getCx86($0xc3) # get CCR3 + movb %ax,%cx # Save old value + movb %ax,%bx + andb $0x0f,%bx # Enable access to all config registers + orb $0x10,%bx # by setting bit 4 + setCx86($0xc3,%bx) + + getCx86($0xe8) # now we can get CCR4 + orb $0x80,%ax # and set bit 7 (CPUIDEN) + movb %ax,%bx # to enable CPUID execution + setCx86($0xe8,%bx) + + getCx86($0xfe) # DIR0 : let's check this is a 6x86(L) + andb $0xf0,%ax # should be 3xh + cmpb $0x30,%ax # + jne n6x86 + getCx86($0xe9) # CCR5 : we reset the SLOP bit + andb $0xfd,%ax # so that udelay calculation + movb %ax,%bx # is correct on 6x86(L) CPUs + setCx86($0xe9,%bx) + +n6x86: setCx86($0xc3,%cx) # Restore old CCR3 + sti + +ncyrix: movl $3, SYMBOL_NAME(x86) + pushfl # push EFLAGS popl %eax # get EFLAGS movl %eax,%ecx # save original EFLAGS @@ -180,8 +245,20 @@ andb $0x0f, %cl # mask mask revision movb %cl,SYMBOL_NAME(x86_mask) movl %edx,SYMBOL_NAME(x86_capability) + + xor %ax,%ax # test again for Cyrix CPU + sahf + movb $5,%ax + movb $2,%bx + div %bl + lahf + cmpb $2,%ah + jne ncyrx2 # skip if not Cyrix CPU + getCx86($0xff) # DIR1 : let's check the stepping + movb %al,SYMBOL_NAME(x86_mask) + /* get vendor info */ - xorl %eax, %eax # call CPUID with 0 -> return vendor ID +ncyrx2: xorl %eax, %eax # call CPUID with 0 -> return vendor ID .byte 0x0f, 0xa2 # CPUID movl %ebx,SYMBOL_NAME(x86_vendor_id) # lo 4 chars movl %edx,SYMBOL_NAME(x86_vendor_id)+4 # next 4 chars diff -u -r linux-2.1.65/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c --- linux-2.1.65/arch/i386/kernel/setup.c Sat Nov 15 02:54:43 1997 +++ linux/arch/i386/kernel/setup.c Thu Nov 20 17:47:52 1997 @@ -47,6 +47,11 @@ char x86_vendor_id[13] = "unknown"; +unsigned char Cx86_step = 0; +static const char *Cx86_type[] = { + "unknown", "1.3", "1.4", "2.4", "2.5", "2.6", "2.7 or 3.7", "4.2" + }; + char ignore_irq13 = 0; /* set if exception 16 works */ char wp_works_ok = -1; /* set if paging hardware honours WP */ char hlt_works_ok = 1; /* set if the "hlt" instruction works */ @@ -266,6 +271,50 @@ return NULL; } +static const char * Cx86model(void) +{ + unsigned char nr6x86 = 0; + static const char *model[] = { + "unknown", "6x86", "6x86L", "6x86MX", "6x86MXi" + }; + switch (x86) { + case 5: + nr6x86 = ((x86_capability & (1 << 8)) ? 2 : 1); /* cx8 flag only on 6x86L */ + break; + case 6: + nr6x86 = 3; + break; + default: + nr6x86 = 0; + } + switch (x86_mask) { + case 0x03: + Cx86_step = 1; /* 6x86MX Rev 1.3 */ + break; + case 0x04: + Cx86_step = 2; /* 6x86MX Rev 1.4 */ + break; + case 0x14: + Cx86_step = 3; /* 6x86 Rev 2.4 */ + break; + case 0x15: + Cx86_step = 4; /* 6x86 Rev 2.5 */ + break; + case 0x16: + Cx86_step = 5; /* 6x86 Rev 2.6 */ + break; + case 0x17: + Cx86_step = 6; /* 6x86 Rev 2.7 or 3.7 */ + break; + case 0x22: + Cx86_step = 7; /* 6x86L Rev 4.2 */ + break; + default: + Cx86_step = 0; + } + return model[nr6x86]; +} + static const char * i686model(unsigned int nr) { static const char *model[] = { @@ -280,20 +329,24 @@ { const char *p = NULL; static char nbuf[12]; - switch (x86) { - case 4: - p = i486model(model); - break; - case 5: - if(strcmp(x86_vendor_id, "AuthenticAMD") == 0){ - p = k5model(model); - } else { - p = i586model(model); - } - break; - case 6: - p = i686model(model); - break; + if (strncmp(x86_vendor_id, "Cyrix", 5) == 0) + p = Cx86model(); + else { + switch (x86) { + case 4: + p = i486model(model); + break; + case 5: + if(strcmp(x86_vendor_id, "AuthenticAMD") == 0){ + p = k5model(model); + } else { + p = i586model(model); + } + break; + case 6: + p = i686model(model); + break; + } } if (p) return p; @@ -342,9 +395,16 @@ CD(x86_vendor_id)); if (CD(x86_mask)) - len += sprintf(buffer+len, - "stepping\t: %d\n", - CD(x86_mask)); + if (strncmp(x86_vendor_id, "Cyrix", 5) != 0) { + len += sprintf(buffer+len, + "stepping\t: %d\n", + CD(x86_mask)); + } + else { /* we have a Cyrix */ + len += sprintf(buffer+len, + "stepping\t: %s\n", + Cx86_type[Cx86_step]); + } else len += sprintf(buffer+len, "stepping\t: unknown\n"); diff -u -r linux-2.1.65/arch/i386/kernel/time.c linux/arch/i386/kernel/time.c --- linux-2.1.65/arch/i386/kernel/time.c Mon Jun 16 23:35:53 1997 +++ linux/arch/i386/kernel/time.c Thu Nov 20 17:09:13 1997 @@ -528,30 +528,31 @@ /* Don't use them if a suspend/resume could corrupt the timer value. This problem needs more debugging. */ - if (x86_capability & 16) { - do_gettimeoffset = do_fast_gettimeoffset; + if (x86_capability & 16) + if (strncmp(x86_vendor_id, "Cyrix", 5) != 0) { + do_gettimeoffset = do_fast_gettimeoffset; do_get_fast_time = do_x86_get_fast_time; - if( strcmp( x86_vendor_id, "AuthenticAMD" ) == 0 ) { - if( x86 == 5 ) { - if( x86_model == 0 ) { - /* turn on cycle counters during power down */ - __asm__ __volatile__ (" movl $0x83, %%ecx \n \ - .byte 0x0f,0x32 \n \ - orl $1,%%eax \n \ - .byte 0x0f,0x30 \n " - : : : "ax", "cx", "dx" ); - udelay(500); + if( strcmp( x86_vendor_id, "AuthenticAMD" ) == 0 ) { + if( x86 == 5 ) { + if( x86_model == 0 ) { + /* turn on cycle counters duringpower down */ + __asm__ __volatile__ (" movl $0x83, %%ecx \n \ + .byte 0x0f,0x32 \n \ + orl $1,%%eax \n \ + .byte 0x0f,0x30 \n " + : : : "ax", "cx", "dx" ); + udelay(500); + } } - } - } + } - /* read Pentium cycle counter */ - __asm__(".byte 0x0f,0x31" - :"=a" (init_timer_cc.low), - "=d" (init_timer_cc.high)); - irq0.handler = pentium_timer_interrupt; - } + /* read Pentium cycle counter */ + __asm__(".byte 0x0f,0x31" + :"=a" (init_timer_cc.low), + "=d" (init_timer_cc.high)); + irq0.handler = pentium_timer_interrupt; + } #endif setup_x86_irq(0, &irq0); } set6x86-1.5/kernel-patches/cyrix_patch100644 0 0 17560 6433757260 16077 0ustar rootrootdiff -u -r linux.orig/arch/i386/kernel/head.S linux/arch/i386/kernel/head.S --- linux.orig/arch/i386/kernel/head.S Mon Mar 18 12:15:00 1996 +++ linux/arch/i386/kernel/head.S Mon Nov 17 05:40:07 1997 @@ -109,7 +109,71 @@ * apply at our cpl of 0 and the stack ought to be aligned already, and * we don't need to preserve eflags. */ - movl $3, SYMBOL_NAME(x86) + /* + * A Cyrix/IBM 6x86(L) preserves flags after dividing 5 by 2 + * (and it _must_ be 5 divided by 2) while other CPUs change + * them in undefined ways. We need to know this since we may + * need to enable the CPUID instruction at least. + */ + xor %ax,%ax + sahf + movb $5,%ax + movb $2,%bx + div %bl + lahf + cmpb $2,%ah + jne ncyrix + + /* + * It behaves like a Cyrix/IBM 6x86(L) so put "Cyrix" in the + * vendor id field. It may be overwritten later with the + * real thing if CPUID works. + */ + movl $0x69727943,SYMBOL_NAME(x86_vendor_id) # low 4 chars + movl $0x00000078,SYMBOL_NAME(x86_vendor_id)+4 # next 4 chars + + /* + * N.B. The pattern of accesses to 0x22 and 0x23 is *essential* + * so do not try to "optimize" it! For the same reason we + * do all this with interrupts off. + */ +#define setCx86(reg, val) \ + movb reg,%ax; \ + outb %ax,$0x22; \ + movb val,%ax; \ + outb %ax,$0x23 + +#define getCx86(reg) \ + movb reg,%ax; \ + outb %ax,$0x22; \ + inb $0x23,%ax + + cli + getCx86($0xc3) # get CCR3 + movb %ax,%cx # Save old value + movb %ax,%bx + andb $0x0f,%bx # Enable access to all config registers + orb $0x10,%bx # by setting bit 4 + setCx86($0xc3,%bx) + + getCx86($0xe8) # now we can get CCR4 + orb $0x80,%ax # and set bit 7 (CPUIDEN) + movb %ax,%bx # to enable CPUID execution + setCx86($0xe8,%bx) + + getCx86($0xfe) # DIR0 : let's check this is a 6x86(L) + andb $0xf0,%ax # should be 3xh + cmpb $0x30,%ax # + jne n6x86 + getCx86($0xe9) # CCR5 : we reset the SLOP bit + andb $0xfd,%ax # so that udelay calculation + movb %ax,%bx # is correct on 6x86(L) CPUs + setCx86($0xe9,%bx) + +n6x86: setCx86($0xc3,%cx) # Restore old CCR3 + sti + +ncyrix: movl $3, SYMBOL_NAME(x86) pushfl # push EFLAGS popl %eax # get EFLAGS movl %eax,%ecx # save original EFLAGS @@ -146,8 +210,20 @@ andb $0x0f, %cl # mask mask revision movb %cl,SYMBOL_NAME(x86_mask) movl %edx,SYMBOL_NAME(x86_capability) + + xor %ax,%ax # test again for Cyrix CPU + sahf + movb $5,%ax + movb $2,%bx + div %bl + lahf + cmpb $2,%ah + jne ncyrx2 # skip if not Cyrix CPU + getCx86($0xff) # DIR1 : let's check the stepping + movb %al,SYMBOL_NAME(x86_mask) + /* get vendor info */ - xorl %eax, %eax # call CPUID with 0 -> return vendor ID +ncyrx2: xorl %eax, %eax # call CPUID with 0 -> return vendor ID .byte 0x0f, 0xa2 # CPUID movl %ebx,SYMBOL_NAME(x86_vendor_id) # lo 4 chars movl %edx,SYMBOL_NAME(x86_vendor_id)+4 # next 4 chars diff -u -r linux.orig/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c --- linux.orig/arch/i386/kernel/setup.c Fri Sep 20 16:00:34 1996 +++ linux/arch/i386/kernel/setup.c Mon Nov 17 06:31:55 1997 @@ -46,6 +46,11 @@ char x86_vendor_id[13] = "unknown"; +unsigned char Cx86_step = 0; +static const char *Cx86_type[] = { + "unknown", "1.3", "1.4", "2.4", "2.5", "2.6", "2.7 or 3.7", "4.2" + }; + char ignore_irq13 = 0; /* set if exception 16 works */ char wp_works_ok = -1; /* set if paging hardware honours WP */ char hlt_works_ok = 1; /* set if the "hlt" instruction works */ @@ -225,6 +230,50 @@ return NULL; } +static const char * Cx86model(void) +{ + unsigned char nr6x86 = 0; + static const char *model[] = { + "unknown", "6x86", "6x86L", "6x86MX", "6x86MXi" + }; + switch (x86) { + case 5: + nr6x86 = ((x86_capability & (1 << 8)) ? 2 : 1); /* cx8 flag only on 6x86L */ + break; + case 6: + nr6x86 = 3; + break; + default: + nr6x86 = 0; + } + switch (x86_mask) { + case 0x03: + Cx86_step = 1; /* 6x86MX Rev 1.3 */ + break; + case 0x04: + Cx86_step = 2; /* 6x86MX Rev 1.4 */ + break; + case 0x14: + Cx86_step = 3; /* 6x86 Rev 2.4 */ + break; + case 0x15: + Cx86_step = 4; /* 6x86 Rev 2.5 */ + break; + case 0x16: + Cx86_step = 5; /* 6x86 Rev 2.6 */ + break; + case 0x17: + Cx86_step = 6; /* 6x86 Rev 2.7 or 3.7 */ + break; + case 0x22: + Cx86_step = 7; /* 6x86L Rev 4.2 */ + break; + default: + Cx86_step = 0; + } + return model[nr6x86]; +} + static const char * i686model(unsigned int nr) { static const char *model[] = { @@ -239,16 +288,20 @@ { const char *p = NULL; static char nbuf[12]; - switch (x86) { - case 4: - p = i486model(model); - break; - case 5: - p = i586model(model); - break; - case 6: - p = i686model(model); - break; + if (strncmp(x86_vendor_id, "Cyrix", 5) == 0) + p = Cx86model(); + else { + switch (x86) { + case 4: + p = i486model(model); + break; + case 5: + p = i586model(model); + break; + case 6: + p = i686model(model); + break; + } } if (p) return p; @@ -296,9 +349,16 @@ CD(x86_vendor_id)); if (CD(x86_mask)) - len += sprintf(buffer+len, - "stepping\t: %d\n", - CD(x86_mask)); + if (strncmp(x86_vendor_id, "Cyrix", 5) != 0) { + len += sprintf(buffer+len, + "stepping\t: %d\n", + CD(x86_mask)); + } + else { /* we have a Cyrix */ + len += sprintf(buffer+len, + "stepping\t: %s\n", + Cx86_type[Cx86_step]); + } else len += sprintf(buffer+len, "stepping\t: unknown\n"); diff -u -r linux.orig/arch/i386/kernel/time.c linux/arch/i386/kernel/time.c --- linux.orig/arch/i386/kernel/time.c Sun Nov 10 18:40:53 1996 +++ linux/arch/i386/kernel/time.c Tue Nov 4 15:45:43 1997 @@ -463,29 +463,30 @@ /* Don't use them if a suspend/resume could corrupt the timer value. This problem needs more debugging. */ - if (x86_capability & 16) { - do_gettimeoffset = do_fast_gettimeoffset; + if (x86_capability & 16) + if (strncmp(x86_vendor_id, "Cyrix", 5) != 0) { + do_gettimeoffset = do_fast_gettimeoffset; - if( strcmp( x86_vendor_id, "AuthenticAMD" ) == 0 ) { - if( x86 == 5 ) { - if( x86_model == 0 ) { - /* turn on cycle counters during power down */ - __asm__ __volatile__ (" movl $0x83, %%ecx \n \ - .byte 0x0f,0x32 \n \ - orl $1,%%eax \n \ - .byte 0x0f,0x30 \n " - : : : "ax", "cx", "dx" ); - udelay(500); + if( strcmp( x86_vendor_id, "AuthenticAMD" ) == 0 ) { + if( x86 == 5 ) { + if( x86_model == 0 ) { + /* turn on cycle counters during power down */ + __asm__ __volatile__ (" movl $0x83, %%ecx \n \ + .byte 0x0f,0x32 \n \ + orl $1,%%eax \n \ + .byte 0x0f,0x30 \n " + : : : "ax", "cx", "dx" ); + udelay(500); + } } - } - } + } - /* read Pentium cycle counter */ - __asm__(".byte 0x0f,0x31" - :"=a" (init_timer_cc.low), - "=d" (init_timer_cc.high)); - irq0.handler = pentium_timer_interrupt; - } + /* read Pentium cycle counter */ + __asm__(".byte 0x0f,0x31" + :"=a" (init_timer_cc.low), + "=d" (init_timer_cc.high)); + irq0.handler = pentium_timer_interrupt; + } #endif setup_x86_irq(0, &irq0); } set6x86-1.5/6x86_reg.c100644 0 144 23543 6445075662 12675 0ustar rootusers/* 6x86_reg: a tool for displaying Cyrix 6x86 configuration registers * and ARRs in human-readable format. * * Copyright (C) 1996, 1997 Koen Gadeyne * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * Updated 12/97 by Andrew D. Balsa * (see http://www.tux.org/~balsa/linux/cyrix) * ****************************************************************************** * * Usage: no parameters! Just typing 6x86_reg at the prompt will dump all 6x86(L) * documented registers to the console. Now of course if you run it on another * processor model don't expect any meaningful results... */ #include #include #include #include #include #include #include #include typedef int bool; #ifndef TRUE # define TRUE (1) #endif #ifndef FALSE # define FALSE (0) #endif char *CommandName; char info[256]; void get_IO_range(int start, int len) { if (ioperm(start, len, 1) != 0) { perror("I/O Permissions"); fprintf(stderr,"Cannot get I/O permissions for hardware address range 0x%x-0x%x.\n\ You must be superuser, or the program must be setuid root!\n", start, start+len-1); exit(1); } } char* int_to_bin(int num, int bits) { static char binstr[sizeof(long int)+1]; int i; for (i=0; i> i) & 0x00000001); return(binstr); } char *size_str(int kb) { static char size[20]; if (kb < 1024) sprintf(size, "%d KB", kb); else if (kb < 1024*1024) sprintf(size, "%d MB", kb >> 10); else sprintf(size, "%d GB", kb >> 20); return size; } /* the original bogomips code from the Linux kernel */ static __inline__ void delay(int loops) { __asm__(".align 2,0x90\n1:\tdecl %0\n\tjns 1b": :"a" (loops):"ax"); } /* a short routine to read /proc/cpuinfo */ void read_cpuinfo(void) { FILE *in; char things[256]; extern char info[256]; if ((in=fopen("/proc/cpuinfo","r"))==NULL) strcpy(info,"unknown"); else { while (strcmp(things,"bogomips")) fscanf(in, "%s", things); /* skip to the bogomips line */ fscanf(in, "%s", things); /* skip the ":" */ fscanf(in, "%s", info); /* now this should be the bogomips */ fclose(in); } return; } /* Register index defines */ #define ARR_BASE 0xC4 #define RCR_BASE 0xDC #define CCR0 0xC0 #define CCR1 0xC1 #define CCR2 0xC2 #define CCR3 0xC3 #define CCR4 0xE8 #define CCR5 0xE9 #define DIR0 0xFE #define DIR1 0xFF /*****************************************************************************/ /* This was a nice short routine before I began messing with it * It still has a very linear structure, but the registers on the 6x86 line * of CPUs are so irregular that the program got a little bit messy. * - Andrew */ /*****************************************************************************/ int main (int argc, char* argv[]) { int i; unsigned int addr, size, rcr, ccr, dir; int mapen; unsigned long loops_per_sec = 1; unsigned long ticks; /* * start doing something useful */ get_IO_range(0x22, 2); printf("\n6x86 (Classic/L/MX) Register Dump utility\n\n"); /* MAPEN **************************************************************/ outb(0xC3, 0x22); mapen = inb(0x23); outb(0xC3, 0x22); outb(mapen | 0x10, 0x23); /* DIR0 ***************************************************************/ outb(DIR0, 0x22); dir = inb(0x23); printf("6x86 DIR0: 0x%x\t", dir); /* core/bus clock ratio analysis **************************************/ if ((dir & 0x70) == 0x50) /* 6x86MX */ switch (dir & 0x07) { case 0x01: { printf("2X core/bus clock ratio"); break; } case 0x02: { printf("2.5X core/bus clock ratio"); break; } case 0x03: { printf("3X core/bus clock ratio"); break; } case 0x04: { printf("3.5X core/bus clock ratio"); break; } } else /* 6x86(L) */ switch (dir & 0x05) { case 0x00: { printf("1X core/bus clock ratio"); break; } case 0x01: /* practically the only one used */ { printf("2X core/bus clock ratio"); break; } case 0x05: { printf("3X core/bus clock ratio"); break; } case 0x04: { printf("4X core/bus clock ratio"); break; } } printf("\n"); /* DIR1 ***************************************************************/ outb(DIR1, 0x22); dir = inb(0x23); printf(" DIR1: 0x%x\t", dir); /* Processor identification *******************************************/ switch (dir) { case 0x14: { printf("6x86 Rev. 2.4"); break; } case 0x15: { printf("6x86 Rev. 2.5"); break; } case 0x16: { printf("6x86 Rev. 2.6"); break; } case 0x17: { printf("6x86 Rev. 2.7 or 3.7"); break; } case 0x22: { printf("6x86L Rev. 4.2"); break; } case 0x03: { printf("6x86MX Rev. 1.3"); break; } case 0x04: { printf("6x86MX Rev. 1.4"); break; } } /* BogoMIPS calculation ***********************************************/ printf("\n\nWait a moment...\n"); /* Now let's take a look at the two bogomips readings */ /* First we calculate the bogoMIPS reading using exactly * the same code as the Linux kernel */ while ((loops_per_sec <<= 1)) { ticks = clock(); delay(loops_per_sec); ticks = clock() - ticks; if (ticks >= CLOCKS_PER_SEC) { loops_per_sec = (loops_per_sec / ticks) * CLOCKS_PER_SEC; printf("Calculated BogoMIPS:\t%lu.%02lu\n", loops_per_sec/500000, (loops_per_sec/5000) % 100 ); break; } } /* and now the kernel bogoMIPS, calculated at boot time and * reported by /proc/cpuinfo. */ read_cpuinfo(); printf("Kernel BogoMIPS:\t%s\n", info); printf("\n"); /* CCR ****************************************************************/ outb(CCR0, 0x22); ccr = inb(0x23); printf("6x86 CCR0: 0x%x\t", ccr); if (ccr & 0x02) printf("NC1 set (address region 640Kb-1Mb non-cacheable)\n"); else printf("NC1 reset (address region 640Kb-1Mb cacheable)\n"); outb(CCR1, 0x22); ccr = inb(0x23); printf(" CCR1: 0x%x\t", ccr); if (ccr & 0x10) printf("NO_LOCK set\n"); else printf("NO_LOCK reset\n"); outb(CCR2, 0x22); ccr = inb(0x23); printf(" CCR2: 0x%x\t", ccr); if (ccr & 0x08) printf("SUSP_HLT set (low power suspend mode enabled)\n"); else printf("SUSP_HLT reset (low power suspend mode disabled)\n"); outb(CCR3, 0x22); ccr = inb(0x23); printf(" CCR3: 0x%x\n", ccr); outb(CCR4, 0x22); ccr = inb(0x23); printf(" CCR4: 0x%x\t", ccr); if (dir & 0xf0) /* if this is a 6x86 or 6x86L */ if (ccr & 0x10) printf("DTE cache enabled, "); else printf("DTE cache disabled, "); switch (ccr & 0x07) { case 0x00: { printf("1 clock cycle I/O recovery time"); break; } case 0x01: { printf("2 clock cycles I/O recovery time"); break; } case 0x02: { printf("4 clock cycles I/O recovery time"); break; } case 0x03: { printf("8 clock cycles I/O recovery time"); break; } case 0x04: { printf("16 clock cycles I/O recovery time"); break; } case 0x05: { printf("32 clock cycles I/O recovery time"); break; } case 0x06: { printf("64 clock cycles I/O recovery time"); break; } case 0x07: { printf("no I/O recovery time"); break; } } printf("\n"); outb(CCR5, 0x22); ccr = inb(0x23); printf(" CCR5: 0x%x\t", ccr); if (dir & 0xf0) /* if this is a 6x86 or 6x86L */ if (ccr & 0x02) printf("slow LOOP enabled, "); else printf("slow LOOP disabled, "); if (ccr & 0x01) printf("allocate cache lines on write misses\n\n"); else printf("default cache line allocation policy\n\n"); /* ARR ****************************************************************/ printf("6x86 Address Region Register dump:\n"); for (i=0; i<8; i++) { outb(ARR_BASE + i*3, 0x22); addr = inb(0x23) << 24; outb(ARR_BASE + i*3 + 1, 0x22); addr |= inb(0x23) << 16; outb(ARR_BASE + i*3 + 2, 0x22); size = inb(0x23); addr |= (size & 0xF0) << 8; size &= 0x0F; printf(" ARR%d: ", i); if (size == 0) { printf("disabled\n"); continue; } else printf("address = 0x%X , size = ", addr); if (i<7) { if (size == 15) printf("%s\n", size_str(4*1024*1024)); else printf("%s\n", size_str(2 << size)); } else { printf("%s\n", size_str(128 << size)); } /* RCR **************************************************************/ outb(RCR_BASE + i, 0x22); rcr = inb(0x23); printf(" RCR = 0x%X : ", rcr); if (i != 7) printf("%scached", (rcr & 0x01) ? "not " : ""); else printf("%scached", (rcr & 0x01) ? "" : "not "); if (dir & 0xf0) /* if this is a 6x86 or 6x86L */ if (rcr & 0x2) printf(", weak write ordering"); if (rcr & 0x4) printf(", weak locking"); if (rcr & 0x8) printf(", write gathering"); if (rcr & 0x10) printf(", write through"); if (rcr & 0x20) printf(", no LBA#"); printf("\n"); } /* Disable MAPEN ******************************************************/ outb(0xC3, 0x22); outb(mapen, 0x23); return(0); } set6x86-1.5/test_bug.c100644 0 0 450 6444743234 12636 0ustar rootroot/* This program is DANGEROUS: it will lock (freeze) your system */ /* Read all the available documentation before executing it */ static unsigned char c[4] = {0x36, 0x78, 0x38, 0x36}; main() { asm ("movl $c, %ebx\n\t" "again: xchgl (%ebx), %eax\n\t" "movl %eax, %edx\n\t" "jmp again\n\t"); } set6x86-1.5/Doc-6x86.txt100644 0 0 16046 6445073630 12702 0ustar rootroot Cyrix Processor Support ----------------------- By Mike Jagdis, updated by Andrew Balsa. Processor Recognition --------------------- Cyrix processors prior to the M2 power up in a default mode which is designed to avoid compatibility problems with software that makes assumptions about processor capabilities based solely on the apparent family of processor. Unless special handling is provided Cyrix chips will be identified as some unknown model of 486. The included Cyrix patch compiles in code that enables the CPUID instruction on Cyrix 6x86 processors. The M2 and later processors have CPUID enabled by default however special handling is still required to read the specific processor type since the CPUID information gives family 6, model 0 - i.e. an A step PPro. The patch allows all current Cyrix 6x86 family processors to be recognised and listed correctly in /proc/cpuinfo. This includes the classic 6x86, the 6x86L and the 6x86MX. Suspend on Halt Power Saving ---------------------------- The suspend on halt power saving feature allows the processor to enter a low power mode when the "hlt" instruction is executed. This results in dramatically reduced operating temperatures if you do not spend long periods of time running processor intensive tasks. Cyrix processors allow this feature to be enabled and disabled through their configuration registers. The default state on reset is disabled and most BIOSes leave it disabled. However there appear to be a few rare cases in which the combination of suspend on halt and some bus master DMA Ethernet cards can cause the system to lock up. In these cases setting SUSP_HALT with a specific set6x86 line in your rc.cyrix file should be avoided. 6x86 Performance Features ------------------------- The 6x86 has several Cyrix specific performance features. Normally a 6x86 aware BIOS will set these to reasonable, if not fully optimal, settings. Benchmarking has shown that this fine-tuning is not needed for normal Linux operation, bringing little or no performance improvements. 6x86 Branch Prediction ---------------------- The 6x86 uses speculative execution coupled with several levels of branch prediction to maximise processing speed. While the default power up state is reasonable the branch prediction logic is configurable and there may be some benefit in fine tuning it. However benchmarking has shown that even through extensive tweaking performance gains are marginal (< 0.5 %). Unfortunately Cyrix offers no documentation on how to configure branch prediction and IBM has only partial documentation available. Further detail and speculation is available from the 6x86opt package by Mikael Johansson . The initial power up state of the 6x86 configures the branch prediction logic to handle short branches. 6x86 Variable Sized Paging Mechanism ------------------------------------ The variable sized paging mechanism (VSPM) is a feature of the Cyrix 6x86 (Classic and L) processors that allows large regions of memory to be mapped using a single MMU entry rather than many individual page sized entries. This significantly reduces the overhead in accessing such regions. It is also ideally suited to use for the linear mapping of physical memory to kernel memory used by the Linux kernel, which has a fixed mapping in memory after boot time. Again, extensive benchmarking has shown that turning on this feature brings no measurable performance improvement in normal use, since the 6x86(L) also has sophisticated caching for the standard fixed-size 4Kb paging mechanism. Perhaps for this reason and also because OS designers didn't seem interested by this specific feature, Cyrix has dropped VSPM on its new 6x86MX processors. The IBM/Cyrix 6x86 and 6x86L Data Books offer only a brief paragraph of explanation about VSPM. Unfortunately the observed behaviour of VSPM suggests that even this little information is not entirely correct. Worse still, no one at Cyrix is able to answer questions concerning VSPM. Given that every revision of 6x86 has *different* VSPM bugs this is not entirely surprising! Since VSPM is not available on 6x86MX processors and Cyrix has dropped all support for this feature, VSPM can be considered as a nice experimental feature, but not as an option for "production" kernels. WARNING: There appears to be no way to disable a VSPM entry once it has been created short of a hard reset (which may mean a power cycle). Failure to clear the VSPM entries means that programs that use virtual memory layouts different from Linux will crash unexpectedly after Linux has been running. This includes Windows NT/95, programs that use DOS extenders etc. By experiment: * VSPM pages must be power of two sizes. A single 24MB page fails. This is not entirely surprising but the documentation could give the impression that VSPM supports arbitrary sizes. * Documentation suggests there are 8 VSPM slots (3 bit index) but tests show the upper four slots mirror the lower four. * VSPM entries appear to override traditional page table entries so we must not overlap the start of the vmalloc region. The following only apply to 6x86 1 rev 6 or lower, 1 rev 7 and up seem not to have these restrictions. * With a 16MB page followed by an 8MB page I always get a write fault on the last 4k of the 8MB page. With 8MB plus 4MB I can't even boot. If we have such a memory size we map the first power of two with a VSPM entry and use traditional paging for the rest. * Do not try and create a mapping with dirty and accessed flags clear - a step 1 rev 5 chip will crash. * The valid bit in a VSPM entry is non-functional. There is no way to invalidate a VSPM entry once it has been written * Attempting to replace a VSPM entry with one that maps a zero sized region from 0 to 0 crashes the CPU. What more could be done ----------------------- The 6x86 allows Address Regions to be set up and en/disabling certain features for these regions. We could analyse the setup done (or not done) by the BIOS and optimize it. * Setting up regions fo the main memory: RCE, WWO, WL(?), WG * Setting up VGA text (0x000a0000) and graphics memory (PCI: e.g. 0xe0000000) to RCD, WG * Setting up BIOS regions to RCD or RCE, WT * Not touching SMM space (ARR3) * Disabling WG for Memory Mapped IO (RCE/D = Region cache enable/disable, WWO = Weak Write Ordering, WL = Weak Locking, WG = Write Gathering, WT = Write Through.) Where to get information ------------------------ There is a databook in PDF format (6X-DBOOK.PDF), which can be down- loaded from Cyrix' WWW server, which contains a description of the Configuration Registers CCR0 - CCR5, the Device Identification Registers DIR0 DIR1 and the Address Region ARRx and Region Control RCRx registers and an incomplete description of the VSPM mechanism. More about CPU detection, VSPM and more undocumented features can be found on the Linux 6x86 mini-HOWTO site (http://www.tux.org/~balsa/linux/cyrix) and by following the links found in the docs. set6x86-1.5/CHANGES100644 0 144 3211 6444777750 12130 0ustar rootusers14DEC97 -- version 1.5 - 6x86_reg now also displays two bogoMIPS readings: the kernel-calculated bogomips from/proc/cpuinfo, and an independently-calculated bogomips reading. - Note that bogoMIPS are *NOT* a benchmark or a test for CPU performance; they are just a very good indicator of whether the BIOS has correctly configured the 6x86 registers and the L2 cache/chipset timing parameters. 03DEC97 -- version 1.4 - 6x86_reg replacement for 6x86_arr (now dumps relevant 6x86 registers in human-readable format). - DOS support was dropped. - A short, simple kernel patch is included. - With Mike Jagdis' permission, a new documentation file Doc-6x86.txt was included with this release of set6x86. It does not replace the relevant Cyrix and IBM Application Notes and Data Books, which one should read anyway to get a better understanding of the 6x86 family of CPUs. - New maintainer: Andrew D. Balsa . 14SEP97 -- version 1.3 - 6x86_arr added (dumps Address Region Registers in human-readable format) 29OCT96 -- version 1.2 - "-c" and "-s" options for bit-setting and bit-masking. - silent mode changed so that get6x86reg outputs HEX-only (otherwise it's pretty useless). - silent mode renamed to "-p" (pipeable output) for compatibility with "setVGAreg". - fatal command line parameter errors now exit instead of dumping core... - DOS version now uses the DOS cross-compiler from DJGPP. 10OCT96 -- version 1.1 - some documentation updates. - DOS version added (DJGPP compiled) + docs - silent mode (no output). 05AUG96 -- version 1.0 - initial release. Hacked up from "setVGAreg", which is part of SVGATextMode. set6x86-1.5/sample_6x86MX100644 0 0 1653 6444774105 13151 0ustar rootroot 6x86 (Classic/L/MX) Register Dump utility 6x86 DIR0: 0x52 2.5X core/bus clock ratio DIR1: 0x4 6x86MX Rev. 1.4 Wait a moment... Calculated BogoMIPS: 185.12 Kernel BogoMIPS: 186.78 6x86 CCR0: 0x2 NC1 set (address region 640Kb-1Mb non-cacheable) CCR1: 0x92 NO_LOCK set CCR2: 0x88 SUSP_HLT set (low power suspend mode enabled) CCR3: 0x10 CCR4: 0x87 no I/O recovery time CCR5: 0x21 allocate cache lines on write misses 6x86 Address Region Register dump: ARR0: address = 0xA0000 , size = 128 KB RCR = 0x9 : not cached, write gathering ARR1: address = 0xC0000 , size = 256 KB RCR = 0x1 : not cached ARR2: disabled ARR3: address = 0xA8000 , size = 32 KB RCR = 0x9 : not cached, write gathering ARR4: disabled ARR5: disabled ARR6: address = 0xE0000000 , size = 4 MB RCR = 0x9 : not cached, write gathering ARR7: address = 0x0 , size = 32 MB RCR = 0x9 : cached, write gathering set6x86-1.5/set6x86-1.5.lsm100644 0 17 2031 6445076060 12755 0ustar rootmanBegin3 Title: Cyrix/IBM 6x86 CPU configuration tool Version: 1.5 Entered-date: 14DEC97 Description: Allows one to modify the internal configuration registers in the 6x86 (Classic, L, MX) CPUs. These include special memory areas (important for e.g. graphics cards), I/O delays, cache write policy (WB/WT), write-gathering, and an automatic power-down mode when a HALT instruction is executed. A utility to display 6x86 registers and model/revision is included, as well as a short kernel patch that correctly identifies Cyrix 6x86 CPUs in /proc/cpuinfo. Keywords: Cyrix IBM SGS-Thomson 6x86 CPU cooling performance Author: koen.gadeyne@barco.com (Koen Gadeyne) Maintained-by: andrewbalsa@usa.net (Andrew Balsa) Primary-site: sunsite.unc.edu /pub/Linux/system/Misc 27Kb set6x86-1.5.tar.gz 1Kb set6x86-1.5.lsm Alternate-site: Original-site: www.tux.org/~balsa/linux/cyrix Platforms: Linux 2.x with 6x86 CPUs. Copying-policy: GPL End