Re: 6x86 recognition

Kurt Garloff (garloff@kg1.ping.de)
Thu, 6 Aug 1998 15:40:54 +0200


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

On Thu, Aug 06, 1998 at 01:14:02AM +0200, Kurt Garloff wrote:
> Have a look at the appended patch; it works for me. It does three additional
> things:

Hi,

here's an updated version od the 6c86 detection patch.

It fixes problems in setup.c:
* amd_model() was not called
* amd capabilities were taken from cpuid 1 instead 80000001
* capabilities name fixup depended on whether mask was set (and not
capability)
* added syscr capability name for AMD K6

Fixes for head.S (compared with patch posted yesterday):
* Name of Cyrix CPUs is CyrixInstead and not Cyrix
* K6: Enable WriteAlloc if the BIOS forgot ...

Enjoy.

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

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

--- linux/arch/i386/kernel/head.S.21114 Thu Jul 16 01:24:26 1998 +++ linux/arch/i386/kernel/head.S Thu Aug 6 14:33:16 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,93 @@ 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 $0x736e4978,X86_VENDOR_ID+4 # next 4 chars "xIns" + movl $0x64616574,X86_VENDOR_ID+8 # last 4 chars "tead" + +#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($0xe9) # CCR5 |= WT_ALLOC + orb $0x01,%ax # Enable L1 cache alloc on Write miss + movb %ax,%bx + setCx86($0xe9,%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 @@ -196,6 +281,21 @@ andb $0x0f,%cl # mask mask revision movb %cl,X86_MASK movl %edx,X86_CAPABILITY + + cmpl $0x68747541, X86_VENDOR_ID # Auth[enticAMD] + jne is486 + cmpl $6,X86_MODEL # K6 or higher + jc is486 + + movl $0xc0000082,%ecx + rdmsr + orl %eax,%eax # Accept BIOS settings if any + jne is486 + cli + wbinvd + movb $0xff,%al # Setup WriteAlloc for 508MB (incl. 15--16MB) + wrmsr + sti is486: movl %cr0,%eax # 486 or better --- linux/arch/i386/kernel/setup.c.21114 Sat Jul 18 22:43:05 1998 +++ linux/arch/i386/kernel/setup.c Thu Aug 6 15:31:38 1998 @@ -247,6 +247,7 @@ cpuid(0x80000000, &n, &dummy, &dummy, &dummy); if (n < 4) return 0; + cpuid(0x80000001, &dummy, &dummy, &dummy, &(c->x86_capability)); v = (unsigned int *) c->x86_model_id; cpuid(0x80000002, &v[0], &v[1], &v[2], &v[3]); cpuid(0x80000003, &v[4], &v[5], &v[6], &v[7]); @@ -480,6 +481,9 @@ return; } + if (c->x86_vendor == X86_VENDOR_AMD && amd_model(c)) + return; + if (c->x86_model < 16) for (i=0; i<sizeof(cpu_models)/sizeof(struct cpu_model_info); i++) if (cpu_models[i].vendor == c->x86_vendor && @@ -492,9 +496,6 @@ return; } - if (c->x86_vendor == X86_VENDOR_AMD && amd_model(c)) - return; - sprintf(c->x86_model_id, "%02x/%02x", c->x86_vendor, c->x86_model); } @@ -537,7 +538,7 @@ int sep_bug; static char *x86_cap_flags[] = { "fpu", "vme", "de", "pse", "tsc", "msr", "6", "mce", - "cx8", "9", "10", "sep", "12", "pge", "14", "cmov", + "cx8", "9", "10", "11", "12", "pge", "14", "cmov", "16", "17", "18", "19", "20", "21", "22", "mmx", "24", "25", "26", "27", "28", "29", "30", "31" }; @@ -563,18 +564,21 @@ else p += sprintf(p, "stepping\t: %d\n", c->x86_mask); } else - p += sprintf(p, "stepping\t: unknown\n"); + p += sprintf(p, "stepping\t: unknown or 0\n"); /* Modify the capabilities according to chip type */ - if (c->x86_mask) { + if (c->x86_capability) { if (c->x86_vendor == X86_VENDOR_CYRIX) { x86_cap_flags[24] = "cxmmx"; } else if (c->x86_vendor == X86_VENDOR_AMD) { + if (c->x86 < 6) x86_cap_flags[9] = "gpe"; + x86_cap_flags[11] = "syscr"; x86_cap_flags[16] = "fcmov"; x86_cap_flags[31] = "amd3d"; } else if (c->x86_vendor == X86_VENDOR_INTEL) { x86_cap_flags[6] = "pae"; x86_cap_flags[9] = "apic"; + x86_cap_flags[11] = "sep"; x86_cap_flags[12] = "mtrr"; x86_cap_flags[14] = "mca"; x86_cap_flags[16] = "pat";

--pf9I7BMVVzbSWLtt--

- 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