/* Most of this code is from FreeBSD. */ /* * Copyright (c) 1990 The Regents of the University of California. * All rights reserved. * * This code is derived from software contributed to Berkeley by * William Jolitz. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #define ASSEMBLER #include "cpus.h" #include "i386-asm.h" #include "i386-syms.h" #include "i386-flags.h" .text /* Identify the type of CPU we are running on, possibly initialize special features. First argument is pointer to host_info_processor. */ ENTRY(identify_cpu) movl 4(%esp), %edi movl $0, HIP_CPU_TYPE(%edi) /* Try to toggle alignment check flag; does not exist on 386. */ pushfl popl %eax movl %eax,%ecx orl $EFL_AC,%eax pushl %eax popfl pushfl popl %eax xorl %ecx,%eax andl $EFL_AC,%eax pushl %ecx popfl testl %eax,%eax jnz try486 /* NexGen CPU does not have aligment check flag. */ pushfl movl $0x5555, %eax xorl %edx, %edx movl $2, %ecx clc divl %ecx jz trynexgen popfl movl $3, HIP_CPU_SUBTYPE(%edi) jmp 3f trynexgen: popfl movl $5, HIP_CPU_SUBTYPE(%edi) #if 0 movl $0x4778654e,EXT(cpu_vendor) # store vendor string movl $0x72446e65,EXT(cpu_vendor)+4 movl $0x6e657669,EXT(cpu_vendor)+8 movl $0,EXT(cpu_vendor)+12 #endif jmp 3f try486: /* Try to toggle identification flag; does not exist on early 486s. */ pushfl popl %eax movl %eax,%ecx xorl $EFL_ID,%eax pushl %eax popfl pushfl popl %eax xorl %ecx,%eax andl $EFL_ID,%eax pushl %ecx popfl testl %eax,%eax jnz trycpuid movl $4,HIP_CPU_SUBTYPE(%edi) /* * Check Cyrix CPU * Cyrix CPUs do not change the undefined flags following * execution of the divide instruction which divides 5 by 2. * * Note: CPUID is enabled on M2, so it passes another way. */ pushfl movl $0x5555, %eax xorl %edx, %edx movl $2, %ecx clc divl %ecx jnc trycyrix popfl jmp 3f /* You may use Intel CPU. */ trycyrix: popfl /* * IBM Bluelighting CPU also doesn't change the undefined flags. * Because IBM doesn't disclose the information for Bluelighting * CPU, we couldn't distinguish it from Cyrix's (including IBM * brand of Cyrix CPUs). */ #if 0 movl $0x69727943,EXT(cpu_vendor) # store vendor string movl $0x736e4978,EXT(cpu_vendor)+4 movl $0x64616574,EXT(cpu_vendor)+8 movl $0,EXT(cpu_vendor)+12 #endif movb $0xc3,%al outb %al,$0x22 inb $0x23,%al movb %al,%ah xorb $0x80,%al outb %al,$0x23 inb $0x23,%al xchgb %al,%ah outb %al,$0x23 cmpb %al,%ah jz 1f movb $0xff,%al outb %al,$0x22 inb $0x23,%al movb %al,%ah movb $0xfe,%al outb %al,$0x22 inb $0x23,%al jmp 2f 1: movb $0xc2,%al outb %al,$0x22 inb $0x23,%al movb %al,%ah xorb $4,%al outb %al,$0x23 inb $0x23,%al xchgb %al,%ah outb %al,$0x23 cmpb %al,%ah jnz 1f movw $0xff,%ax jmp 2f 1: movw $0x10,%ax 2: /* Write the vendor-specific data for the CPU. */ /* movw %ax,EXT(cpu_vspec) */ jmp 3f trycpuid: /* Use the `cpuid' instruction. */ xorl %eax,%eax .byte 0x0f,0xa2 # cpuid 0 #if 0 movl %eax,EXT(cpu_high) # highest capability movl %ebx,EXT(cpu_vendor) # store vendor string movl %edx,EXT(cpu_vendor)+4 movl %ecx,EXT(cpu_vendor)+8 movl $0,EXT(cpu_vendor)+12 #endif movl $1,%eax .byte 0x0f,0xa2 # cpuid 1 #if 0 movl %eax,EXT(cpu_id) # store cpu_id movl %edx,EXT(cpu_feature) # store cpu_feature #endif rorl $8,%eax # extract family type andl $15,%eax cmpl $5,%eax jae 1f /* less than Pentium; must be 486 */ movl $4,HIP_CPU_SUBTYPE(%edi) jmp 3f 1: /* a Pentium? */ cmpl $5,%eax jne 2f movl $5,HIP_CPU_SUBTYPE(%edi) jmp 3f 2: /* Greater than Pentium...call it a Pentium Pro */ movl $6,HIP_CPU_SUBTYPE(%edi) 3: ret