Messages in this thread Patch in this message | | | Date | Wed, 10 Jun 1998 12:28:18 -0500 (EST) | From | "Rafael R. Reilova" <> | Subject | Cyrix detection PATCH ([2.1.105] Cyrix 6x86 reduced to 486) |
| |
Hi,
Andre Balsa posted a patch against the 2.0.33 that correctly identified the Cyrix cpu's without disturbing those touchy PII-BX boards. This is my 1/2 version of the patch, only the low-level stuff in head.S is changed. If this is correct decoding the step/rev to actual chip names should be almost trivial (the other 1/2). The TSC stuff, that's another story ;)
The patch is almost a complete cut-and-paste of Andre's, with a few changes to make it work on the 2.1.x's. Someone familiar with this code please eyeball it closely (it was really late when I finished, and assembly is not kind to typos). Of course, also please test and confirm this is correct. The patch is against 2.1.105, but should patch to 2.1.10[345]. BTW, who maintains this part of the code?
Cheers,
Rafael
--- /usr/src/linux-2.1.105/arch/i386/kernel/head.S Thu May 28 13:11:51 1998 +++ /usr/src/linux/arch/i386/kernel/head.S Wed Jun 10 12:21:31 1998 @@ -152,29 +152,44 @@ * apply at our cpl of 0 and the stack ought to be aligned already, and * we don't need to preserve eflags. */ + movl $3,X86 # at least 386 + pushfl # push EFLAGS + popl %eax # get EFLAGS + movl %eax,%ecx # save original EFLAGS + xorl $0x40000,%eax # flip AC bit in EFLAGS + pushl %eax # copy to EFLAGS + popfl # set EFLAGS + pushfl # get new EFLAGS + popl %eax # put it in eax + xorl %ecx,%eax # change in flags + andl $0x40000,%eax # check if AC bit changed + je is386 -/* - * Don't do this here. Do it in the CPU init code in C, right now we - * must _not_ play unsafe games with the IO ports. - * - * A PPro and a P-II will also preserve the flags after a division, - * so this "cyrix" test is just completely unsafe. IO port 0x22 is - * some magic ACPI port on non-cyrix chips, so if this trashes that - * we're screwed. - * - * This code belongs in "asm-i386/bugs.h" anyway (at which point we - * _have_ done a CPUID for CPU's that support it directly, so we'll - * be able to tell a intel P-II trivially at that point). - */ -#undef CYRIX_CODE_BREAKAGE -#ifdef CYRIX_CODE_BREAKAGE + movl $4,X86 # at least 486 + movl %ecx,%eax + xorl $0x200000,%eax # check ID flag + pushl %eax + popfl # if we are on a straight 486DX, SX, or + pushfl # 487SX we can't change it + popl %eax # also if we are on a Cyrix 6x86(L) + xorl %ecx,%eax # OTOH 6x86MXs and MIIs check OK + pushl %ecx # restore original EFLAGS + popfl + andl $0x200000,%eax + jne has_cpuid +/* Now we test if we have a Cyrix w/o cpuid. We didn't test before to avoid + * clobbering the new BX chipset used with the Pentium II, which has a register + * at the same addresses as those used to access the Cyrix special configuration + * registers (CCRs). Anything in with BX should have cpuid! + */ /* - * A Cyrix preserves flags in cases where other CPUs change + * A Cyrix/IBM 486 or better 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. (Cyrix chips - * prior to M2 have CPUID disabled by default, the Cx486s - * didn't have it at all.) + * need to enable the CPUID instruction at least. + * We couldn't use this test before since the PPro and PII behave + * like Cyrix chips in this respect. */ xor %ax,%ax sahf @@ -183,7 +198,7 @@ div %bl lahf cmpb $2,%ah - jne ncyrix + jne is486 /* * It behaves like a Cyrix so put "Cyrix" in the vendor id @@ -194,9 +209,9 @@ movl $0x00000078,X86_VENDOR_ID+4 # next 4 chars /* - * 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. + * 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,%al; \ @@ -209,51 +224,35 @@ outb %al,$0x22; \ inb $0x23,%al + getCx86($0xfe) # DIR0 : let's check this is a 6x86(L) + andb $0xf0,%al # should be 3xh + cmpb $0x30,%al + jne cyrix_id # Cx486/586? + + /* The Cyrix 6x86(L) has the cpuid instruction off by default. + * Turn it on and also fix the udelay calculation problem. + */ + getCx86($0xc3) # get CCR3 movb %al,%cl # Save old value movb %al,%bl - andb $0x0f,%bl # Enable all config registers (for CCR4 access) - orb $0x10,%bl + andb $0x0f,%bl # Enable access to all config registers + orb $0x10,%bl # by setting bit 4 setCx86($0xc3,%bl) - getCx86($0xe8) # CCR4 |= CPUID - orb $0x80,%al - movb %al,%bl + getCx86($0xe8) # now we can get CCR4 + orb $0x80,%al # and set bit 7 (CPUIDEN) + movb %al,%bl # to enable CPUID execution setCx86($0xe8,%bl) + getCx86($0xe9) # CCR5 : we reset the SLOP bit + andb $0xfd,%al # so that udelay calculation + movb %al,%bl # is correct on 6x86(L) CPUs + setCx86($0xe9,%bl) setCx86($0xc3,%cl) # Restore old CCR3 -ncyrix: - -#endif - - movl $3,X86 # at least 386 - pushfl # push EFLAGS - popl %eax # get EFLAGS - movl %eax,%ecx # save original EFLAGS - xorl $0x40000,%eax # flip AC bit in EFLAGS - pushl %eax # copy to EFLAGS - popfl # set EFLAGS - pushfl # get new EFLAGS - popl %eax # put it in eax - xorl %ecx,%eax # change in flags - andl $0x40000,%eax # check if AC bit changed - je is386 - - movl $4,X86 # at least 486 - movl %ecx,%eax - xorl $0x200000,%eax # check ID flag - pushl %eax - popfl # if we are on a straight 486DX, SX, or - pushfl # 487SX we can't change it - popl %eax - xorl %ecx,%eax - pushl %ecx # restore original EFLAGS - popfl - andl $0x200000,%eax - je nocpuid - /* get vendor info */ +has_cpuid: xorl %eax,%eax # call CPUID with 0 -> return vendor ID cpuid movl %eax,X86_CPUID # save CPUID level @@ -262,7 +261,7 @@ movl %ecx,X86_VENDOR_ID+8 # last 4 chars orl %eax,%eax # do we have processor info as well? - je nocpuid + je cyrix_id movl $1,%eax # Use the CPUID instruction to get CPU type cpuid @@ -276,15 +275,14 @@ movb %cl,X86_MASK movl %edx,X86_CAPABILITY -nocpuid: - -#ifdef CYRIX_CODE_BREAKAGE +cyrix_id: /* * Even if we had CPUID Cyrix tries to look compatible with * Intel so we have to go elsewhere for the nitty gritty. + * We already tested for cpuid, so non-cyrixes should be safe. */ cmpl $0x69727943,X86_VENDOR_ID # "Cyri[x.*]"? - jne is486 # maybe ... + jne is486 movb $0xfe,X86_MODEL # Generic Cx486? movb $0,X86_MASK @@ -305,14 +303,6 @@ movb %al,X86_MASK getCx86($0xfe) movb %al,X86_MODEL - andb $0xf0,%al # Check for 6x86(L) - cmp $0x30,%al - jnz is486 - getCx86($0xe9) # CCR5: reset SLOP bit, so that the udelay loop - andb $0xfd,%al # works well on 6x86(L) CPU's. - movb %al,%bl - setCx86($0xe9,%bl) -#endif is486: movl %cr0,%eax # 486 or better
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu
| |