3 * Copyright (C) 2003 Eric Kohl
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 * U32 CpuidSupported(VOID);
31 * 0x00000001: CPU supports the CPUID instruction
32 * 0x00000300: Found 80386 CPU
33 * 0x00000400: Found 80486 CPU without CPUID support
36 EXTERN(CpuidSupported)
39 pushl %ecx /* save ECX */
41 pushfl /* push original EFLAGS */
42 popl %eax /* get original EFLAGS */
43 movl %eax,%ecx /* save original EFLAGS */
44 xorl $0x40000,%eax /* flip AC bit in EFLAGS */
45 pushl %eax /* save new EFLAGS value on stack */
46 popfl /* replace current EFLAGS value */
48 pushfl /* get new EFLAGS */
49 popl %eax /* store new EFLAGS in EAX */
50 xorl %ecx, %eax /* can't toggle AC bit, processor=80386 */
52 movl $0x300,%eax /* return processor id */
53 jz NoCpuid /* jump if 80386 processor */
56 popfl /* restore AC bit in EFLAGS first */
58 movl %ecx,%eax /* get original EFLAGS */
59 xorl $0x200000,%eax /* flip ID bit in EFLAGS */
60 pushl %eax /* save new EFLAGS value on stack */
61 popfl /* replace current EFLAGS value */
62 pushfl /* get new EFLAGS */
63 popl %eax /* store new EFLAGS in EAX */
64 xorl %ecx,%eax /* can't toggle ID bit, */
66 movl $0x400,%eax /* return processor id */
67 je NoCpuid /* processor=80486 */
69 movl $1,%eax /* CPUID supported */
73 popfl /* restore EFLAGS */
74 popl %ecx /* retore ECX */
80 * VOID GetCpuid(U32 Level, U32 *eax, U32 *ebx, U32 *ecx, U32 *edx);