6x86 recognition

Kurt Garloff (garloff@kg1.ping.de)
Thu, 6 Aug 1998 01:14:02 +0200


--EVF5PPMfhYS0aIcm
Content-Type: text/plain; charset=us-ascii

Hi everybody,

with 2.1.114, 6x86 isn't recognized by the kernel.
There has been code to detect Cyrix CPUs in the kernel, but it conflicted
with BX boards registers. (6x86 uses ports 0x22/3 for configuration, so do
BX boards.)
This can be solved by testing for 6x86 only when cpuid is not supported,
which cannot happen in a BX board (unless you are an electrical engineer and
manage to do very strange things).

Have a look at the appended patch; it works for me. It does three additional
things:
* enable SUSP_HLT (reduce power; improves stability on most boards; use
boot option no_hlt on others)
* enable NO_LOCK (workaround for a famous Cyrix bug; problems with X
reported were caused by other things)
* enable CPUID to allow normal detection.

I know that there have been discussions about whether the kernel should do
CPU intialization even if it can be done later in userspace. And I learned,
that in most cases it's better to do things in userspace. So feel free to
remove SUSP_HLT and NO_LOCK from the patch. I think, that it also depends on
the size. Things that require four lines in kernel and do not cause harm to
anybody and everybody wants to use them which could be done in userspace
using a program consisting of a few hundred lines are IMHO better done in
kernel land.
I already dropped the BTB and VSPM and FAST_IO and ... from the patch, so I
think it's a sort of compromise.

Could people having different CPUs (Cyrix 486, 5x86, 6x86MX) then me (6x86)
please try the patch. I know it won't turn on the features described above
on 6x86MX because it supports cpuid. Blame the intel developers for creating
the BX boards. Any solution to this tends to get complicated and won't be
accepted by the kernel gods.

May the SOURCE be with you!

-- 
Kurt Garloff, Dortmund 
<K.Garloff@ping.de>
PGP key on http://student.physik.uni-dortmund.de/homepages/garloff

--EVF5PPMfhYS0aIcm Content-Type: text/plain; charset=us-ascii Content-Description: cyrix6x86.patch Content-Disposition: attachment; filename="cryix6x86.patch"

--- linux/arch/i386/kernel/head.S.21114 Thu Jul 16 01:24:26 1998 +++ linux/arch/i386/kernel/head.S Wed Aug 5 23:19:13 1998 @@ -172,7 +172,7 @@ pushl %ecx # restore original EFLAGS popfl andl $0x200000,%eax - je is486 + je is486orcyrix /* get vendor info */ xorl %eax,%eax # call CPUID with 0 -> return vendor ID @@ -183,8 +183,87 @@ movl %ecx,X86_VENDOR_ID+8 # last 4 chars orl %eax,%eax # do we have processor info as well? + jne hascpuid + +is486orcyrix: + xor %ax,%ax # if no cpuid: 486 or cyrix + sahf # Check for Cyrix by dividing 5/2 + movb $5,%ax # Cyrixes will preserve flags + movb $2,%bx + div %bl + lahf + cmpb $2,%ah + jne is486 + + movl $0x69727943,X86_VENDOR_ID # low 4 chars "Cyri" + movl $0x00000078,X86_VENDOR_ID+4 # next 4 chars "x" + +#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) + + getCx86($0xc2) # CCR2 |= SUSP_HLT + orb $8,%ax # Power saving like other CPUs do by default + movb %ax,%bx + setCx86($0xc2,%bx) + + getCx86($0xe8) # CCR4 |= CPUID | DTE_EN + orb $0x90,%ax # Enable cpuid and DTE cache + movb %ax,%bx + setCx86($0xe8,%bx) + + getCx86($0xc1) # CCR1 |= NO_LOCK + orb $0x10,%ax # Workaround for Coma bug + movb %ax,%bx + setCx86($0xc1,%bx) + + getCx86($0xc3) # by writing CCR3 + movb %ax,%bx + orb $0x80,%bx + setCx86($0xc3,%bx) + getCx86($0xc0) # dummy to change bus + getCx86($0xc3) + sti + cmp %ax,%bx + je is486 # not writable == no DEVID + + cli + setCx86($0xc3,%cx) # restore CCR3 + + getCx86($0xff) # get DEVID in preference to any CPUID + movb %al,X86_MASK + getCx86($0xfe) + movb %al,X86_MODEL + sti + andb $0xf0,%al + cmpb $0x30,%al # DevID below 0x30 means 486 or 5x86 => no cpuid + jc is486 + + xor %eax, %eax + cpuid # Try cpuid again + movl %eax,X86_CPUID # save CPUID level + orl %eax,%eax # do we have processor info as well? je is486 + movl %ebx,X86_VENDOR_ID # lo 4 chars + movl %edx,X86_VENDOR_ID+4 # next 4 chars + movl %ecx,X86_VENDOR_ID+8 # last 4 chars +hascpuid: movl $1,%eax # Use the CPUID instruction to get CPU type cpuid movb %al,%cl # save reg for future use

--EVF5PPMfhYS0aIcm--

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.altern.org/andrebalsa/doc/lkml-faq.html