xref: /minix3/minix/lib/libc/arch/i386/getprocessor.S (revision bad58c9c5145c5fa2a65ce5ca37ceebbbd315e2d)
1/*	getprocessor() - determine processor type	Author: Kees J. Bot */
2/*								26 Jan 1994 */
3#include <machine/asm.h>
4
5/* int getprocessor(void); */
6/*	Return 386, 486, 586, ... */
7ENTRY(getprocessor)
8	push	%ebp
9	movl	%esp, %ebp
10	andl	$0xFFFFFFFC, %esp	/* Align stack to avoid AC fault */
11	movl	$0x00040000, %ecx	/* Try to flip the AC bit introduced on the 486 */
12	call	flip
13	movl	$386, %eax	/* 386 if it didn't react to "flipping" */
14	je	gotprocessor
15	movl	$0x00200000, %ecx	/* Try to flip the ID bit introduced on the 586 */
16	call	flip
17	movl	$486, %eax	/* 486 if it didn't react */
18	je	gotprocessor
19	pushf
20	pusha	/* Save the world */
21	movl	$1, %eax
22.byte	0x0F, 0xA2	/* CPUID instruction tells the processor type */
23	andb	$0x0F, %ah	/* Extract the family (5, 6, ...) */
24	movzbl	%ah, %eax
25	cmpl	$15, %eax	/* 15: extended family */
26	jne	direct
27	movl	$6, %eax	/* Make it 686 */
28direct:
29	imull	$100, %eax	/* 500, 600, ... */
30	addl	$86, %eax	/* 586, 686, ... */
31	movl	%eax, 7*4(%esp)	/* Pass eax through */
32	popa
33	popf
34gotprocessor:
35	leave
36	ret
37
38flip:
39	pushf	/* Push eflags */
40	pop	%eax	/* eax = eflags */
41	movl	%eax, %edx	/* Save original eflags */
42	xorl	%ecx, %eax	/* Flip the bit to test */
43	push	%eax	/* Push modified eflags value */
44	popf	/* Load modified eflags register */
45	pushf
46	pop	%eax	/* Get it again */
47	push	%edx
48	popf	/* Restore original eflags register */
49	xorl	%edx, %eax	/* See if the bit changed */
50	testl	%ecx, %eax
51	ret
52