lkml.org 
[lkml]   [1997]   [Oct]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
SubjectRe: cyrix patch: where???
From
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

\
 
 \ /
  Last update: 2005-03-22 13:40    [W:0.050 / U:0.600 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site