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