Messages in this thread Patch in this message | | | Date | Tue, 7 Oct 1997 19:14:49 +0200 | Subject | Re: cyrix patch: where??? | From | Thorsten Kalkbrenner <> |
| |
In article <343A3A7A.BB52D90D@livenet.net> you wrote: : I am looking for the cyrix patch for 2.0.29. The only one I can find : for 2.0.x is for .31-pre_something. Thanks for the assistance. The : cyrix page posted a few days ago was fabulous, I love set6x86. My : machine runs so much cooler!! However it had a patch for pre.
hi it is called: 20-cyrix-2.patch
sorry, not more time :)
Thorsten
--- linux/Documentation/Configure.help.noCyrix Mon Jun 16 09:39:26 1997 +++ linux/Documentation/Configure.help Tue Jun 17 22:06:26 1997 @@ -690,18 +690,112 @@ later load the module when you install the JDK or find an interesting Java program that you can't live without. -Processor type +Processor family CONFIG_M386 This is the processor type of your CPU. It is used for optimizing - purposes. In order to compile a kernel that can run on all CPU types - (albeit not optimally fast), you can specify "386" here. If you - specify "486" or "Pentium" or "PPro", then the kernel will run on - 486 and Pentium (=586) and Pentium Pro (=686) CPUs. In rare cases, - it can make sense to specify "Pentium" even if running a 486: the - kernel will be smaller but slower. On the other hand, if you use a - compiler before gcc 2.7 (say "gcc -v" to find out), then you have to - say "386" or "486" here even if running on a Pentium or PPro + purposes. In order to compile a kernel that can run on all ix86 CPU + types (albeit not optimally fast), you can specify "386" here. If + you specify "486" or "Pentium" or "PPro", then the kernel will run + on 486 and Pentium (=586) and Pentium Pro (=686) CPUs. In rare + cases, it can make sense to specify "Pentium" even if running a 486: + the kernel will be smaller but slower. On the other hand, if you use + a compiler before gcc 2.7 (say "gcc -v" to find out), then you have + to say "386" or "486" here even if running on a Pentium or PPro machine. If you don't know what to do, say "386". + +Support for Cyrix processors +CONFIG_CYRIX + This enables recognition of Cyrix processors. Without it + /proc/cpuinfo will list your processor as an unknown model + of Cyrix. With it it will list the correct details. It should + be safe to say Y here regardless of what processor you are + actually using. If this option is not enabled none of the + Cyrix feature options are available. + +Enable suspend on halt power saving feature +CONFIG_CYRIX_SUSP_HLT + Suspend on halt causes the processor to enter a low power state + when the "hlt" instruction is executed. This is disabled at + power up and many BIOSs leave it that way. You probably want it + enabled since it dramatically reduces the operating temperature + of the processor. In a few rare cases there may be problems + with some bus master DMA cards if this is enabled. + +No I/O recovery delays +CONFIG_CYRIX_FAST_IO + Historically programmers used "jmp $+2" instructions to create + delays between I/O instructions. The branch prediction of 5x86 + and higher processors renders this ineffective and so a selectable + delay is implemented for I/O instructions in the processor. Linux + uses dummy I/O instructions where necessary rather than jumps + and so the extra processor imposed delay should not be necessary. + Enabling this option removes this delay. + +5x86 performance features +CONFIG_CYRIX_5X86 + The Cyrix 5x86 has several performance feature which are enabled + using on-chip registers. This code attempts to ensure that the + useful features are set to suit Linux. Read Documentation/Cyrix + before enabling this. + WARNING: If this is enabled you may find that the only way to + reboot is to power cycle the machine. Even a hard reboot seems + to fail on some systems. + +6x86 performance features +CONFIG_CYRIX_6X86 + The Cyrix 6x86 has several performance feature which are enabled + using on-chip registers. Most are normally enabled by the BIOS + however this code ensures that all the useful ones are set to + suit Linux. Read Documentation/Cyrix before enabling this. + +Avoid unnecessary locked cycles +CONFIG_CYRIX_6X86_NOLOCK + Enabling this option causes the 6x86 not to use locked bus cycles + except for page table access and interrupt acknowledge cycles. + This allows the data used by descriptor tables, xchg instructions + and instructions preceeded by the LOCK prefix to be cached leading + to improved performance. Enabling this option has no effect if + an SMP kernel is being built - SMP requires locked cycles to + guarantee processor synchronization. + +Allocate L1 cache lines on write misses +CONFIG_CYRIX_6X86_WTALLOC + If this is enabled L1 cache write misses will cause a cache line + to be allocated. This may result in increased performance. On the + other hand it may cause excessive trashing of the L1 cache when + copying or zeroing pages. + +Branch Target Buffer features +CONFIG_CYRIX_6X86_BTB + The Cyrix 6x86 has branch prediction logic. + Enabling this option resets BTB configuration to reasonable values. + +BTB risky features +CONFIG_CYRIX_6X86_BTB_RISKY + Sets Bit 4 of BTB register 5. This results in better performance + (context switching) but sometimes causes problems, e.g. when + running X. + +Variable sized paging mechanism (VSPM) +CONFIG_CYRIX_6X86_VSPM + Variable sized paging mechanism (VSPM) is a feature of the Cyrix + 6x86 family of processors that allows large regions of memory + to be mapped in one go, significantly reducing the amount of work + the MMU has to do compared with traditional paging. However VSPM + is known to be buggy in many 6x86 chip revisions. Please read + Documentation/Cyrix before enabling this. + WARNING: If this is enabled you may find that the only way to + reboot is to power cycle the machine. Even a hard reboot seems + to fail on some systems. + +VSPM No traditional pages +CONFIG_CYRIX_6X86_VSPM_NOTRADPAGE + When you enable VSPM, normally traditional page table entries are + created (but not used by the 6x86). These PTEs enable the kernel + to unset VSPM (on 1rev7 or better) before rebooting, thus enabling + other Protected Mode OSes to be warm booted. + Enabling this option disables the creation of traditional page + table entries and thus unsetting of VSPM on (warm) reboot. Compile the kernel into the ELF object format CONFIG_ELF_KERNEL --- /dev/null Mon Aug 26 02:21:17 1996 +++ linux/Documentation/Cyrix Tue Jun 17 22:37:38 1997 @@ -0,0 +1,189 @@ + Cyrix Processor Support + ----------------------- + +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 Cyrix processor recognition kernel build option compiles +in code that enables the CPUID instruction on Cyrix processors +and that uses the Cyrix specific DEVID feature to identify the +particular type of Cyrix chip present. + + The M2 and later processors have CPUID enabled by default +however special handling is still required to read the specific +processor type using DEVID since the CPUID information gives +family 6, model 0 - i.e. an A step PPro. + + The combination of CPUID and DEVID allows all current Cyrix +processors to be recognised and listed correctly in /proc/cpuinfo. +This includes Cx486, 5x86, 6x86, Gx86 (aka MediaGx) and M2. + + Processor recognition is required for all other Cyrix specific +options. + + +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 an disabled +through their configuration registers. The default state on reset +is disabled and many (most?) BIOSs leave it disabled hence a +kernel configuration option is provided that adds code to explicitly +enabled suspend on halt when Linux boots. + + However there appear to be a few rare cases in which the +combination of suspend on halt and some bus master DMA cards can +cause the system to lock up. If this appears to happen you may +need to leave suspend on halt in its default state. (Note that +an option to _disable_ suspend on halt is not provided. If your +BIOS enables it you have to live with it) + + +5x86 Performance Features +------------------------- + +The 5x86 contains a performance control register that allows +several performance enhancing features to be turned on. Unfortunately +many of these features do not appear to work correctly. The 5x86 +performance features kernel build option will attempt to set +the performance control register appropriately but it is +impossible to guarantee that even these conservative settings +will work on all chips. + + WARNING: If this is enabled you may find that the only way to +reboot is to power cycle the machine. Even a hard reboot seems +to fail on some systems. + + +6x86 Performance Features +------------------------- + +Like the 5x86 the 6x86 has several Cyrix specific performance +features. Normally a 6x86 aware BIOS will set these to reasonable, +if not fully optimal, settings. The 6x86 performance features +kernel build option mostly just fine tunes them. + + +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. + + Unfortunately Cyrix offer no documentation on how to configure +branch prediction and IBM have only partial documentation available. +Further detail and speculation is available from the 6x86opt package +by Mikael Johansson <Mikael.Johansson@helsinki.fi>. + + The initial power up state of the 6x86 configures the branch +prediction logic to handle short branches. The 6x86 branch target +buffer features kernel build option enables code that sets the +BTB configuration to reasonable values, if BIOS or power on state +are not satisfactory. +There is also a risky option, which sets an additional BTB config +bit. It's risky, because it can cause system hangs, esp. when +running X, but you gain some speed (context switching). + + +6x86 Variable Sized Paging Mechanism +------------------------------------ + +The variable sized paging mechanism (VSPM) is a feature of the Cyrix +6x86 family of 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 Linux. + + The Cyrix documenation offers only a brief paragraph of explanation. +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! Work arounds are in place for the known bugs in step 1, +revisions 4, 5 and 6 chips. Revision 7 is also believed to work. + + 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. In order to optimize, 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 Pentium Compiler Group homepage (http://www.goof.com/pcg) +and by following the links found in the docs. --- linux/arch/i386/config.in.noCyrix Mon Jun 16 09:40:34 1997 +++ linux/arch/i386/config.in Tue Jun 17 21:59:59 1997 @@ -37,13 +37,42 @@ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then tristate 'Kernel support for JAVA binaries' CONFIG_BINFMT_JAVA fi + bool 'Compile kernel as ELF - if your GCC is ELF-GCC' CONFIG_KERNEL_ELF -choice 'Processor type' \ +choice 'Processor family' \ "386 CONFIG_M386 \ 486 CONFIG_M486 \ Pentium CONFIG_M586 \ PPro CONFIG_M686" Pentium +endmenu + +mainmenu_option next_comment +comment 'Processor features' + +comment 'Some or all of the following may cause problems' +comment 'with some drivers or hardware. Please read the' +comment 'help text and Documentation/Cyrix before enabling' +comment 'any of these options.' +bool 'Cyrix processor recognition' CONFIG_CYRIX +if [ "$CONFIG_CYRIX" = "y" ]; then + bool 'Enable suspend on halt power saving' CONFIG_CYRIX_SUSP_HLT + bool 'No I/O recovery delays' CONFIG_CYRIX_FAST_IO + bool '5x86 performance features' CONFIG_CYRIX_5X86 + bool '6x86 performance features' CONFIG_CYRIX_6X86 + if [ "$CONFIG_CYRIX_6X86" = "y" ]; then + bool ' Avoid unnecessary locked cycles' CONFIG_CYRIX_6X86_NOLOCK + bool ' Allocate L1 cache lines on write misses' CONFIG_CYRIX_6X86_WTALLOC + bool ' Branch Target Buffer features' CONFIG_CYRIX_6X86_BTB + if [ "$CONFIG_CYRIX_6X86_BTB" = "y" ]; then + bool ' BTB risky features' CONFIG_CYRIX_6X86_BTB_RISKY + fi + bool ' Variable sized paging mechanism (VSPM)' CONFIG_CYRIX_6X86_VSPM + if [ "$CONFIG_CYRIX_6X86_VSPM" = "y" ]; then + bool ' VSPM disable traditional pages' CONFIG_CYRIX_6X86_VSPM_NOTRADPAGE + fi + fi +fi endmenu source drivers/block/Config.in --- linux/arch/i386/defconfig.noCyrix Mon Jun 16 09:45:16 1997 +++ linux/arch/i386/defconfig Tue Jun 17 22:00:15 1997 @@ -27,8 +27,19 @@ CONFIG_KERNEL_ELF=y # CONFIG_M386 is not set # CONFIG_M486 is not set -CONFIG_M586=y -# CONFIG_M686 is not set +# CONFIG_M586 is not set +CONFIG_M686=y +CONFIG_CYRIX=y +CONFIG_CYRIX_SUSP_HLT=y +# CONFIG_CYRIX_FAST_IO is not set +# CONFIG_CYRIX_5X86 is not set +# CONFIG_CYRIX_6X86 is not set +# CONFIG_CYRIX_6X86_NOLOCK is not set +# CONFIG_CYRIX_6X86_WTALLOC is not set +# CONFIG_CYRIX_6X86_BTB is not set +# CONFIG_CYRIX_6X86_BTB_RISKY is not set +# CONFIG_CYRIX_6X86_VSPM is not set +# CONFIG_CYRIX_6X86_VSPM_NOTRADPAGE is not set # # Floppy, IDE, and other block devices --- linux/include/asm-i386/processor.h.noCyrix Mon Jan 20 14:45:06 1997 +++ linux/include/asm-i386/processor.h Tue Jun 17 00:19:47 1997 @@ -16,7 +16,7 @@ */ extern char hard_math; -extern char x86; /* lower 4 bits */ +extern char x86; /* upper 4 bits=vendor, lower 4 bits=family */ extern char x86_vendor_id[13]; extern char x86_model; /* lower 4 bits */ extern char x86_mask; /* lower 4 bits */ @@ -148,6 +148,22 @@ extern inline unsigned long thread_saved_pc(struct thread_struct *t) { return ((unsigned long *)t->esp)[3]; +} + +extern inline void cpuid(int op, int *eax, int *ebx, int *ecx, int *edx) +{ + __asm__("movl %4,%%eax\n\t" + ".byte 0x0f, 0xa2\n\t" + "movl %%eax,%0\n\t" + "movl %%ebx,%1\n\t" + "movl %%ecx,%2\n\t" + "movl %%edx,%3\n\t" + : "=m" (*eax), + "=m" (*ebx), + "=m" (*ecx), + "=m" (*edx) + : "g" (op) + : "eax", "ebx", "ecx", "edx", "cc"); } #endif /* __ASM_I386_PROCESSOR_H */ --- linux/include/asm-i386/bugs.h.noCyrix Mon Jun 16 23:22:16 1997 +++ linux/include/asm-i386/bugs.h Tue Jun 17 15:44:06 1997 @@ -130,5 +130,5 @@ check_tlb(); check_fpu(); check_hlt(); - system_utsname.machine[1] = '0' + x86; + system_utsname.machine[1] = '0' + (x86 & 0x0f); } --- linux/arch/i386/kernel/head.S.noCyrix Mon Jun 23 15:13:14 1997 +++ linux/arch/i386/kernel/head.S Mon Jun 23 15:23:12 1997 @@ -103,13 +103,80 @@ checkCPUtype: #endif + movl $-1,SYMBOL_NAME(have_cpuid) # -1 for no CPUID initially + /* check if it is 486 or 386. */ /* * XXX - this does a lot of unnecessary setup. Alignment checks don't * 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 preserves flags in cases where other CPUs change + * them in undefined ways. We need to know this since we may + * need to enable the CPUID instruction at least. (Cyrix chips + * prior to M2 have CPUID disabled by default, the Cx486s + * didn't have it at all.) + */ + xor %ax,%ax + sahf + movb $5,%ax + movb $2,%bx + div %bl + lahf + cmpb $2,%ah + jne ncyrix + + /* + * It behaves like a Cyrix 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 + +#ifdef CONFIG_CYRIX + /* + * N.B. The pattern of accesses to 0x22 and 0x23 is *important* + * so do not try and "optimise" it! For the same reason we + * do all this with interrupts off just to be sure. + */ +#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 all config registers (for CCR4 access) + orb $0x10,%bx + setCx86($0xc3,%bx) + +#ifdef CONFIG_CYRIX_SUSP_HLT + getCx86($0xc2) # CCR2 |= SUSP_HLT + orb $8,%ax + movb %ax,%bx + setCx86($0xc2,%bx) +#endif + + getCx86($0xe8) # CCR4 |= CPUID | DTE_EN + orb $0x90,%ax + movb %ax,%bx + setCx86($0xe8,%bx) + + setCx86($0xc3,%cx) # Restore old CCR3 + sti +#endif /* CONFIG_CYRIX */ + +ncyrix: movl $3, SYMBOL_NAME(x86)# at least 386 pushfl # push EFLAGS popl %eax # get EFLAGS movl %eax,%ecx # save original EFLAGS @@ -121,6 +188,7 @@ xorl %ecx,%eax # change in flags andl $0x40000,%eax # check if AC bit changed je is386 + movl $4,SYMBOL_NAME(x86) movl %ecx,%eax xorl $0x200000,%eax # check ID flag @@ -129,11 +197,22 @@ pushfl # 487SX we can't change it popl %eax xorl %ecx,%eax - andl $0x200000,%eax - je is486 -isnew: pushl %ecx # restore original EFLAGS + pushl %ecx # restore original EFLAGS popfl - incl SYMBOL_NAME(have_cpuid) # we have CPUID + andl $0x200000,%eax + je nocpuid + + /* get vendor info */ + xorl %eax, %eax # call CPUID with 0 -> return vendor ID + .byte 0x0f, 0xa2 # CPUID + movl %eax,SYMBOL_NAME(have_cpuid) # save CPUID level + movl %ebx,SYMBOL_NAME(x86_vendor_id) # lo 4 chars + movl %edx,SYMBOL_NAME(x86_vendor_id)+4 # next 4 chars + movl %ecx,SYMBOL_NAME(x86_vendor_id)+8 # last 4 chars + + cmpl $0,%eax # do we have processor info as well? + je nocpuid + /* get processor type */ movl $1, %eax # Use the CPUID instruction to .byte 0x0f, 0xa2 # check the processor type @@ -146,20 +225,159 @@ andb $0x0f, %cl # mask mask revision movb %cl,SYMBOL_NAME(x86_mask) movl %edx,SYMBOL_NAME(x86_capability) - /* get vendor info */ - 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 - movl %ecx,SYMBOL_NAME(x86_vendor_id)+8 # last 4 chars - movl %cr0,%eax # 486+ - andl $0x80000011,%eax # Save PG,PE,ET - orl $0x50022,%eax # set AM, WP, NE and MP - jmp 2f -is486: pushl %ecx # restore original EFLAGS - popfl - movl %cr0,%eax # 486 + cmpl $0x444d4163,SYMBOL_NAME(x86_vendor_id)+8 # "[Authenti]cAMD"? + jne nocpuid + + orb $0x20,SYMBOL_NAME(x86) # Flag as AMD + cmpb $0x25,SYMBOL_NAME(x86) # K5 model 0 has swapped + jne is486 # feature flags + andl $0x00000200,%edx # move bit 9 to bit 13 + roll $4,%edx # and clear bit 9 + orl %edx,SYMBOL_NAME(x86_capability) + andl $0xfffffdff,SYMBOL_NAME(x86_capability) + jmp is486 + +nocpuid: + /* + * Even if we had CPUID Cyrix tries to look compatible with + * Intel so we have to go elsewhere for the nitty gritty. + */ + cmpl $0x69727943,SYMBOL_NAME(x86_vendor_id) # "Cyri[x.*]"? + jne is486 # maybe ... + +chkdevid: + orb $0x10,SYMBOL_NAME(x86) # Flag as Cyrix + movb $0xfe,SYMBOL_NAME(x86_model) # Generic Cx486? + movb $0,SYMBOL_NAME(x86_mask) + +#ifdef CONFIG_CYRIX + cli # Test for DEVID + getCx86($0xc3) # by writing CCR3 + movb %ax,%cx + movb %ax,%bx + orb $0x80,%bx + setCx86($0xc3,%bx) + getCx86($0xc0) # dummy to change bus + getCx86($0xc3) + sti + cmp %ax,%cx + je is486 # not writable == no DEVID + + cli + setCx86($0xc3,%cx) # restore CCR3 + + getCx86($0xff) # get DEVID in preference to any CPUID + movb %al,SYMBOL_NAME(x86_mask) + getCx86($0xfe) + movb %al,SYMBOL_NAME(x86_model) + sti + +#if defined(CONFIG_CYRIX_5X86) || defined(CONFIG_CYRIX_6X86) + andb $0xf0,%al +#ifdef CONFIG_CYRIX_6X86 + cmpb $0x30,%al + je is6x86 +#endif +#ifdef CONFIG_CYRIX_5X86 + cmpb $0x20,%al + je is5x86 +#endif + /* Cx486 or something beyond a 6x86 (M2 or better). Note that + * the Cx486 also have performance features we could tweak + * but given the problems with [56]x86, the number of Cx486 + * variants, the fact that the Cx486 is pretty well dead + * now and the fact that I have no Cx486 myself I haven't + * risked it. Nor have I looked at the M2 in any detail yet. + */ + jmp is486 +#endif + +#ifdef CONFIG_CYRIX_5X86 + /* Special set up for 5x86 */ +is5x86: + cli + movb %cx,%bx + andb $0x0f,%bx # Enable all config registers + orb $0x10,%bx + setCx86($0xc3,%bx) + + getCx86($0x20) # PCR0 |= LSSER | BTB_EN + orb $0x82,%ax # LOOP_EN is broken, RSTK_EN shows no benefi + + movb %ax,%bx # and LSSER=0 could break memory mapped + setCx86($0x20,%bx) # devices - we have no way of knowing) + +#ifdef CONFIG_CYRIX_FAST_IO + getCx86($0xe8) # CCR4: IORT=0 (nodelay) + andb $0xf1,%ax + movb %ax,%bx + setCx86($0xe8,%bx) +#endif + + setCx86($0xc3,%cx) # restore CCR3 + sti + jmp is486 +#endif + +#if defined(CONFIG_CYRIX_6X86) || defined(CONFIG_CYRIX_FAST_IO) + /* Special set up for 6x86 */ +is6x86: + cli + movb %cx,%bx + andb $0x0f,%bx # Enable all config registers + orb $0x10,%bx + setCx86($0xc3,%bx) + +#if !defined(__SMP__) && defined(CONFIG_CYRIX_6X86_NOLOCK) + getCx86($0xc1) # CCR1 |= NO_LOCK + orb $0x10,%ax + movb %ax,%bx + setCx86($0xe8,%bx) +#endif + +#ifdef CONFIG_CYRIX_FAST_IO + getCx86($0xe8) # CCR4: IORT=7 (nodelay) + orb $0x97,%ax + movb %ax,%bx + setCx86($0xe8,%bx) +#endif + + getCx86($0xe9) # CCR5 &= ~SLOP + andb $0xfd,%ax +#ifdef CONFIG_CYRIX_6X86_WTALLOC + orb $0x01,%ax # CCR5 |= WT_ALLOC +#endif + movb %ax,%bx + setCx86($0xe9,%bx) + +#ifdef CONFIG_CYRIX_6X86_BTB # IBM documentation, no Cyrix docs + getCx86($0x30) + orb $020,%ax # Enable data bypassing/forwarding + movb %ax,%dx + orb $0x40,%ax # Enable test register opcodes + movb %ax,%bx + setCx86($0x30,%bx) + mov $0x28,%ebx # BTB index 5 + .byte 0x0f,0x26,0xcb # mov %ebx,%tr1 + .byte 0x0f,0x24,0xd0 # mov %tr2,%eax + + and $0xffffffe2,%eax # FAR COF doesn't make any diff + +#ifdef CONFIG_CYRIX_6X86_BTB_RISKY # Bit 4 is somewhat risky + or $0x00000010,%eax # but accelerates context switching +#endif + .byte 0x0f,0x26,0xd0 # mov %eax,%tr2 + + setCx86($0x30,%dx) # Disable test register opcodes +#endif /* CONFIG_CYRIX_6X86_BTB */ + + setCx86($0xc3,%cx) # restore CCR3 + sti +#endif /* CONFIG_CYRIX_6X86 */ +#endif /* CONFIG_CYRIX */ + +is486: movl %cr0,%eax # 486 or better andl $0x80000011,%eax # Save PG,PE,ET orl $0x50022,%eax # set AM, WP, NE and MP jmp 2f --- linux/arch/i386/kernel/setup.c.noCyrix Tue Jun 17 22:42:48 1997 +++ linux/arch/i386/kernel/setup.c Tue Jun 17 16:03:01 1997 @@ -42,8 +42,8 @@ char x86_mask = 0; /* set by kernel/head.S */ int x86_capability = 0; /* set by kernel/head.S */ int fdiv_bug = 0; /* set if Pentium(TM) with FP bug */ -int have_cpuid = 0; /* set if CPUID instruction works */ - +int have_cpuid = -1; /* CPUID level (-1 if no CPUID) */ + char x86_vendor_id[13] = "unknown"; char ignore_irq13 = 0; /* set if exception 16 works */ @@ -235,11 +235,86 @@ return NULL; } +static const char * cyrixmodel(unsigned int nr) +{ + static char nbuf[32]; + + + /* Note that some of the possibilities this decoding allows + * have never actually been manufactured - but those that + * do actually exist are correctly decoded. + */ + if (nr < 0x20) { + strcpy(nbuf, "Cx486"); + if (!(nr & 0x10)) { + sprintf(nbuf+5, "%c%s%c", + (nr & 0x01) ? 'D' : 'S', + (nr & 0x04) ? "Rx" : "LC", + (nr & 0x02) ? '2' : '\000'); + } else if (!(nr & 0x08)) { + sprintf(nbuf+5, "S%s%c", + (nr & 0x01) ? "2" : "", + (nr & 0x02) ? 'e' : '\000'); + } else { + sprintf(nbuf+5, "DX%c", + nr == 0x1b ? '2' + : (nr == 0x1f ? '4' : '\000')); + } + return nbuf; + } else if (nr >= 0x20 && nr <= 0x4f) { /* 5x86, 6x86 or Gx86 */ + sprintf(nbuf, "%cx86 %cx Core/Bus Clock", + "??56G"[nr>>4], + "12??43"[nr & 0x05]); + return nbuf; + } else if (nr >= 0x50 && nr <= 0x5f) { /* Cyrix M2 */ + sprintf(nbuf, "M2 %c%sx Core/Bus Clock", + "12233445"[nr & 0x07], + (nr && !(nr&1)) ? ".5" : ""); + return nbuf; + } + + /* Probably 0xfd (Cx486[SD]LC with no ID register) + * or 0xfe (Cx486 A step with no ID register). + */ + return "Cx486"; +} + static const char * getmodel(int x86, int model) { - const char *p = NULL; - static char nbuf[12]; - switch (x86) { + const char *p = NULL; + static char nbuf[49]; + + if ((x86 & 0xf0) == 0x10) { /* Cyrix */ + p = cyrixmodel(model); + } else if ((x86 & 0xf0) == 0x20) { /* AMD */ + /* Actually we must have cpuid or we could never have + * figured out that this was AMD from the vendor info :-). + */ + if (have_cpuid < 0) + p = "Am486"; + else { + int n, dummy; + cpuid(0x80000000, &n, &dummy, &dummy, &dummy); + if (!n) { + if ((x86 & 0x0f) == 4) + p = i486model(model); + else if ((x86 & 0x0f) == 5) + p = "AMD-K5 (Model 0)"; + else if ((x86 & 0x0f) == 6) + p = "AMD-K6"; + } else { + int *v = (int *)nbuf; + cpuid(0x80000002, &v[0], &v[1], &v[2], &v[3]); + cpuid(0x80000003, &v[4], &v[5], &v[6], &v[7]); + cpuid(0x80000004, &v[8], &v[9], &v[10], &v[11]); + nbuf[48] = '\0'; + p = nbuf; + } + } + } else switch (x86) { /* Intel */ + case 0: + p = "unknown"; + break; case 4: p = i486model(model); break; @@ -250,8 +325,8 @@ p = i686model(model); break; } - if (p) - return p; + if (p) + return p; sprintf(nbuf, "%d", model); return nbuf; @@ -260,6 +335,7 @@ int get_cpuinfo(char * buffer) { int i, len = 0; + int sep_bug; static const char *x86_cap_flags[] = { "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce", "cx8", "apic", "10", "11", "mtrr", "pge", "mca", "cmov", @@ -284,39 +360,51 @@ #define CPUN 0 #endif - len += sprintf(buffer+len,"processor\t: %d\n" - "cpu\t\t: %c86\n" - "model\t\t: %s\n" - "vendor_id\t: %s\n", - CPUN, - CD(x86)+'0', - CD(have_cpuid) ? - getmodel(CD(x86), CD(x86_model)) : - "unknown", - CD(x86_vendor_id)); + len += sprintf(buffer+len,"processor\t: %d\n" + "cpu family\t: %c\n" + "model\t\t: %s\n" + "vendor_id\t: %s\n", + CPUN, + (CD(x86) & 0x0f)+'0', + getmodel(CD(x86), CD(x86_model)), + CD(x86_vendor_id)); - if (CD(x86_mask)) - len += sprintf(buffer+len, - "stepping\t: %d\n", - CD(x86_mask)); - else + if (CD(x86_mask)) { + if ((CD(x86) & 0xf0) == 0x10) + len += sprintf(buffer+len, + "stepping\t: %d rev %d\n", + CD(x86_mask) >> 4, + CD(x86_mask) & 0x0f); + else + len += sprintf(buffer+len, + "stepping\t: %d\n", + CD(x86_mask)); + } else len += sprintf(buffer+len, "stepping\t: unknown\n"); - len += sprintf(buffer+len, + sep_bug = CD(x86) == 0x06 && /* Intel family 6 */ + CD(have_cpuid) >= 0 && + (CD(x86_capability) & 0x800) && + CD(x86_model) < 3 && + CD(x86_mask) < 3; + + len += sprintf(buffer+len, "fdiv_bug\t: %s\n" "hlt_bug\t\t: %s\n" + "sep_bug\t\t: %s\n" "fpu\t\t: %s\n" "fpu_exception\t: %s\n" - "cpuid\t\t: %s\n" + "cpuid level\t: %d\n" "wp\t\t: %s\n" "flags\t\t:", CD(fdiv_bug) ? "yes" : "no", CD(hlt_works_ok) ? "no" : "yes", + CD(sep_bug) ? "yes" : "no", CD(hard_math) ? "yes" : "no", (CD(hard_math) && ignore_irq13) ? "yes" : "no", - CD(have_cpuid) ? "yes" : "no", + CD(have_cpuid), CD(wp_works_ok) ? "yes" : "no"); for ( i = 0 ; i < 32 ; i++ ) { --- linux/arch/i386/kernel/process.c.noCyrix Wed Oct 30 15:31:46 1996 +++ linux/arch/i386/kernel/process.c Tue Jun 17 16:02:45 1997 @@ -30,6 +30,7 @@ #include <asm/segment.h> #include <asm/pgtable.h> #include <asm/system.h> +#include <asm/processor.h> #include <asm/io.h> #include <linux/smp.h> @@ -278,7 +279,28 @@ void hard_reset_now (void) { - +#if defined(CONFIG_CYRIX) && defined(CONFIG_CYRIX_6X86_VSPM) && !defined(__SMP__) && !defined(CONFIG_CYRIX_6X86_VSPM_NOTRADPAGE) + /* disable VSPM in order to make it possible to boot other OS */ + /* check for stepping, only >= 1rev7 allows disabling of VSPM */ + if ((x86 & 0xf0) == 0x10 && (x86_model & 0xf0) == 0x30 + && ((x86_mask & 0x0f) > 6 || (x86_mask >> 4) > 1)) { + int vspm_idx; + for (vspm_idx = 3; vspm_idx >=0; vspm_idx--) { + asm( "movl %0,%%eax\n" + "movl %%eax,%%tr7\n" + "movl $0x00000004,%%eax\n" + "movl %%eax,%%tr6\n" + "movl %0,%%eax\n" + "movl %%eax,%%tr7\n" + "movl $0x000004ce,%%eax\n" + "movl %%eax,%%tr6\n" + : /* no outputs */ + : "g" (vspm_idx << 7) + : "eax", "cc" + ); + } + } +#endif if(!reboot_thru_bios) { sti(); /* rebooting needs to touch the page at absolute addr 0 */ --- linux/arch/i386/mm/init.c.noCyrix Mon Jun 16 21:41:27 1997 +++ linux/arch/i386/mm/init.c Tue Jun 17 11:32:57 1997 @@ -119,6 +119,82 @@ unsigned long tmp; unsigned long address; +#ifdef TEST_VERIFY_AREA + wp_works_ok = 0; +#endif + +#if defined(CONFIG_CYRIX) && defined(CONFIG_CYRIX_6X86_VSPM) && !defined(__SMP__) + unsigned long vspm_max = 0; + + /* If this is a Cyrix 6x86 we use the variable size paging + * mechanism (VSPM) to map physical memory at 0xc0000000. + * Note that VSPM pages are stored on the CPU only so this + * needs to be done for each processor in a multi-processor + * system. If we have a mixture of processors we would also + * need to set up the traditional page tables for them. + * Note also that VSPM pages will be global to all memory + * spaces since they are not stored in the normal page + * directories. + * + * By experiment: + * VSPM pages must be power of two sizes. A single 24MB + * page fails. + * Documentation suggests there are 8 VSPM slots (3 bit + * index) but tests show the upper four slots mirror the + * lower four. + * 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 VSPM and use + * traditional paging for the rest. + * VSPM pages override traditional pages so we cannot + * overlap the start of the vmalloc region. + * Do not try and create a mapping with dirty and accessed + * flags clear - a step 1 rev 5 chip will crash and burn. + */ + if ((x86 & 0xf0) == 0x10 || (x86_model & 0xf0) == 0x30) { + int vspm_index = 0; + int max_vspm_pages = 1; + if ((x86_mask & 0x0f) > 6 || (x86_mask >> 4) > 1) max_vspm_pages = 4; + + do { + unsigned long mem_size; + + mem_size = 4096; + while (vspm_max+mem_size < end_mem) + mem_size <<= 1; + if (vspm_max+mem_size > end_mem) + if ((mem_size >>= 1) < 4096) + break; + + asm( "movl %0,%%eax\n" + "movl %%eax,%%tr7\n" + "movl $0x00000004,%%eax\n" + "movl %%eax,%%tr6\n" + "movl %1,%%eax\n" + "movl %%eax,%%tr7\n" + "movl %2,%%eax\n" + "movl %%eax,%%tr6\n" + : /* no outputs */ + : "g" ((((mem_size-1) & 0xfffff000)) | (vspm_index<<7)), + "g" ((vspm_max & 0xfffff000) | (vspm_index<<7)), + "g" (vspm_max | 0xc0000cd6) + : "eax", "cc" + ); + + vspm_max += mem_size; + + } while (vspm_max < end_mem && vspm_index++ < max_vspm_pages); + + /* Write protect does work correctly but the test + * will fail because we can't map just page 0 read + * only from under the VSPM big page. If we didn't + * know before we do now. + */ + wp_works_ok = 1; + } +#endif + /* * Physical page 0 is special; it's not touched by Linux since BIOS * and SMM (for laptops with [34]86/SL chips) may need it. It is read @@ -147,9 +223,6 @@ */ /* smp_alloc_memory(8192); */ #endif -#ifdef TEST_VERIFY_AREA - wp_works_ok = 0; -#endif start_mem = PAGE_ALIGN(start_mem); address = 0; pg_dir = swapper_pg_dir; @@ -181,6 +254,16 @@ continue; } #endif +#if defined(CONFIG_CYRIX) && defined(CONFIG_CYRIX_6X86_VSPM) && !defined(__SMP__) && defined(CONFIG_CYRIX_6X86_VSPM_NOTRADPAGE) + if ((x86 & 0xf0) == 0x10 /* Cyrix */ + && (x86_model & 0xf0) == 0x30 /* 6x86 */ + && (address + PAGE_SIZE*PTRS_PER_PTE) < vspm_max) { /* within VSPM mappings */ + pg_dir++; + address += PAGE_SIZE * PTRS_PER_PTE; + continue; + } +#endif + /* map the memory at virtual addr 0xC0000000 */ pg_table = (pte_t *) (PAGE_MASK & pgd_val(pg_dir[768])); if (!pg_table) { @@ -192,11 +275,17 @@ pgd_val(pg_dir[0]) = _PAGE_TABLE | (unsigned long) pg_table; pgd_val(pg_dir[768]) = _PAGE_TABLE | (unsigned long) pg_table; pg_dir++; + for (tmp = 0 ; tmp < PTRS_PER_PTE ; tmp++,pg_table++) { - if (address < end_mem) - set_pte(pg_table, mk_pte(address, PAGE_SHARED)); - else +#if defined(CONFIG_CYRIX) && defined(CONFIG_CYRIX_6X86_VSPM) && !defined(__SMP__) && defined(CONFIG_CYRIX_6X86_VSPM_NOTRADPAGE) + if (address < vspm_max || address >= end_mem) + pte_clear(pg_table); +#else + if (address >= end_mem) pte_clear(pg_table); +#endif + else + set_pte(pg_table, mk_pte(address, PAGE_SHARED)); address += PAGE_SIZE; } } -- cu,
Thorsten
___ | h o r s t e n K a l k b r e n n e r tk@wh36-b404.stud.uni-karlsruhe.de
| |