281 lines
7.3 KiB
NASM
281 lines
7.3 KiB
NASM
|
;//==========================================================================
|
||
|
;//
|
||
|
;// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
|
||
|
;// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
||
|
;// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
|
||
|
;// PURPOSE.
|
||
|
;//
|
||
|
;// Copyright (c) 1999 - 2001 On2 Technologies Inc. All Rights Reserved.
|
||
|
;//
|
||
|
;//--------------------------------------------------------------------------
|
||
|
|
||
|
|
||
|
;
|
||
|
; **-getCPUType
|
||
|
;
|
||
|
; This function will return a code indicating the type of the processor
|
||
|
; that is in the system. If the processor type is unknown the generic
|
||
|
; x86 (Intel 486) type is returned
|
||
|
;
|
||
|
; parts taken from intel's AP-485
|
||
|
;
|
||
|
;put checks for cmov and mmx support ????
|
||
|
;
|
||
|
; Assumptions:
|
||
|
; None
|
||
|
;
|
||
|
; Input:
|
||
|
; None
|
||
|
;
|
||
|
; Output:
|
||
|
; Code for CPU type returned. See cpuidlib.h for the supported
|
||
|
; types.
|
||
|
;
|
||
|
|
||
|
|
||
|
|
||
|
.586
|
||
|
.MODEL flat, SYSCALL, os_dos
|
||
|
.DATA
|
||
|
|
||
|
NAME x86cpuid
|
||
|
|
||
|
PUBLIC getCPUType_
|
||
|
PUBLIC _getCPUType
|
||
|
|
||
|
CPU_ID MACRO
|
||
|
db 0fh ; Hardcoded CPUID instruction
|
||
|
db 0a2h
|
||
|
ENDM
|
||
|
|
||
|
;see cpuidlib.h
|
||
|
X86 EQU 0 ; /* 486, Pentium plain, or any other x86 compatible */
|
||
|
PMMX EQU 1 ; /* Pentium with MMX */
|
||
|
PPRO EQU 2 ; /* Pentium Pro */
|
||
|
PII EQU 3 ; /* Pentium II */
|
||
|
C6X86 EQU 4
|
||
|
C6X86MX EQU 5
|
||
|
AMDK63D EQU 6
|
||
|
AMDK6 EQU 7
|
||
|
AMDK5 EQU 8
|
||
|
XMM EQU 11
|
||
|
WMT EQU 12 ;/* Willamette */
|
||
|
|
||
|
|
||
|
_486 EQU 4h
|
||
|
PENT EQU 50h
|
||
|
PENTMMX EQU 54h
|
||
|
PENTPRO EQU 61h
|
||
|
PENTII EQU 63h
|
||
|
SIMD EQU 25
|
||
|
|
||
|
AMD_K63D EQU 58h
|
||
|
AMD_K6 EQU 56h
|
||
|
AMD_K5 EQU 50h ; K5 has models 0 - 6
|
||
|
|
||
|
_6X86 EQU 52h
|
||
|
_6X86MX EQU 60h
|
||
|
|
||
|
|
||
|
_vendor_id db "------------"
|
||
|
intel_id db "GenuineIntel"
|
||
|
amd_id db "AuthenticAMD"
|
||
|
cyrix_id db "CyrixInstead"
|
||
|
|
||
|
.CODE
|
||
|
|
||
|
getCPUType_:
|
||
|
_getCPUType:
|
||
|
push esi ;safety sh*&
|
||
|
push edi
|
||
|
push ebp
|
||
|
push ebx
|
||
|
push ecx
|
||
|
push edx
|
||
|
|
||
|
;------------------------------------------------
|
||
|
; Intel486 processor check
|
||
|
; Checking for ability to set/clear ID flag (Bit 21) in EFLAGS
|
||
|
; which indicates the presence of a processor with the CPUID
|
||
|
; instruction.
|
||
|
;------------------------------------------------
|
||
|
check_80486:
|
||
|
pushfd ; push original EFLAGS
|
||
|
pop eax ; get original EFLAGS
|
||
|
mov ebp,X86 ; rv
|
||
|
mov ecx, eax ; save original EFLAGS
|
||
|
xor eax, 200000h ; flip ID bit in EFLAGS
|
||
|
push eax ; save new EFLAGS value on stack
|
||
|
popfd ; replace current EFLAGS value
|
||
|
pushfd ; get new EFLAGS
|
||
|
pop eax ; store new EFLAGS in EAX
|
||
|
xor eax, ecx ; can not toggle ID bit,
|
||
|
je end_cpu_type486 ; processor=80486
|
||
|
|
||
|
;------------------------------------------------
|
||
|
; Execute CPUID instruction to not determine vendor, family,
|
||
|
; model, stepping and features. For the purpose of this
|
||
|
; code, only the initial set of CPUID information is saved.
|
||
|
;------------------------------------------------
|
||
|
; push ebx ; save registers
|
||
|
; push esi
|
||
|
; push edi
|
||
|
; push edx
|
||
|
; push ecx
|
||
|
|
||
|
; mov ebp,X86 ; rv
|
||
|
|
||
|
mov eax, 0 ; set up for CPUID instruction
|
||
|
CPU_ID ; get and save vendor ID
|
||
|
|
||
|
mov DWORD PTR _vendor_id, ebx
|
||
|
mov DWORD PTR _vendor_id[+4], edx
|
||
|
mov DWORD PTR _vendor_id[+8], ecx
|
||
|
|
||
|
cmp DWORD PTR intel_id, ebx
|
||
|
jne IsProc_AMD
|
||
|
cmp DWORD PTR intel_id[+4], edx
|
||
|
jne end_cpuid_type
|
||
|
cmp DWORD PTR intel_id[+8], ecx
|
||
|
jne end_cpuid_type ; if not equal, not an Intel processor
|
||
|
|
||
|
cmp eax, 1 ; make sure 1 is valid input for CPUID
|
||
|
jl end_cpuid_type ; if not, jump to end
|
||
|
|
||
|
mov eax, 1
|
||
|
CPU_ID ; get family/model/stepping/features
|
||
|
|
||
|
mov ebp,XMM ; assume PIII
|
||
|
|
||
|
bt edx,SIMD ; check for SIMD support
|
||
|
jnae end_cpuid_type
|
||
|
|
||
|
SIMDContinue:
|
||
|
shr eax, 4 ; isolate family and model
|
||
|
mov ebp,PII ; assume PII
|
||
|
|
||
|
and eax,0ffh ;mask out type and reserved
|
||
|
nop
|
||
|
|
||
|
cmp eax,PENTII
|
||
|
jge end_cpuid_type
|
||
|
|
||
|
mov ebp,PPRO
|
||
|
|
||
|
cmp eax,PENTPRO
|
||
|
je end_cpuid_type
|
||
|
|
||
|
mov ebp,PMMX
|
||
|
|
||
|
cmp eax,PENTMMX
|
||
|
je end_cpuid_type
|
||
|
|
||
|
mov ebp,X86
|
||
|
|
||
|
cmp eax,PENT
|
||
|
jge end_cpuid_type
|
||
|
|
||
|
; mov ebp,X86
|
||
|
|
||
|
end_cpuid_type:
|
||
|
mov eax,ebp
|
||
|
|
||
|
;remove these pops ???
|
||
|
|
||
|
; pop edi ; restore registers
|
||
|
; pop esi
|
||
|
; pop ebx
|
||
|
; pop edx
|
||
|
; pop ecx
|
||
|
|
||
|
end_cpu_type:
|
||
|
pop edx ;safety sh*&
|
||
|
pop ecx
|
||
|
pop ebx
|
||
|
pop ebp
|
||
|
pop edi
|
||
|
pop esi
|
||
|
ret
|
||
|
|
||
|
end_cpu_type486:
|
||
|
mov eax,ebp
|
||
|
pop edx ;safety sh*&
|
||
|
pop ecx
|
||
|
pop ebx
|
||
|
pop ebp
|
||
|
pop edi
|
||
|
pop esi
|
||
|
ret
|
||
|
|
||
|
;------------------------------------------------
|
||
|
IsProc_AMD:
|
||
|
cmp DWORD PTR amd_id, ebx
|
||
|
jne IsProc_CYRIX
|
||
|
|
||
|
cmp DWORD PTR amd_id[+4], edx
|
||
|
jne end_cpuid_type
|
||
|
|
||
|
cmp DWORD PTR amd_id[+8], ecx
|
||
|
jne end_cpuid_type ; if not equal, not an AMD processor
|
||
|
|
||
|
cmp eax, 1 ; make sure 1 is valid input for CPUID
|
||
|
jl end_cpuid_type ; if not, jump to end
|
||
|
|
||
|
mov eax, 1
|
||
|
CPU_ID ; get family/model/stepping/features
|
||
|
|
||
|
shr eax, 4 ; isolate family and model
|
||
|
mov ebp,AMDK63D
|
||
|
|
||
|
and eax,0ffh ;mask out type and reserved
|
||
|
nop
|
||
|
|
||
|
cmp eax,AMD_K63D
|
||
|
jge end_cpuid_type
|
||
|
|
||
|
mov ebp,AMDK6
|
||
|
nop
|
||
|
|
||
|
cmp eax,AMD_K6
|
||
|
jge end_cpuid_type
|
||
|
|
||
|
mov ebp,X86
|
||
|
nop
|
||
|
|
||
|
cmp eax,AMD_K5
|
||
|
jge end_cpuid_type
|
||
|
|
||
|
mov ebp,X86
|
||
|
jmp end_cpuid_type
|
||
|
|
||
|
;------------------------------------------------
|
||
|
IsProc_CYRIX:
|
||
|
cmp DWORD PTR cyrix_id, ebx
|
||
|
jne end_cpuid_type
|
||
|
|
||
|
cmp DWORD PTR cyrix_id[+4], edx
|
||
|
jne end_cpuid_type
|
||
|
|
||
|
cmp DWORD PTR cyrix_id[+8], ecx
|
||
|
jne end_cpuid_type ; if not equal, not an CYRIX processor
|
||
|
|
||
|
cmp eax, 1 ; make sure 1 is valid input for CPUID
|
||
|
jl end_cpuid_type ; if not, jump to end
|
||
|
|
||
|
mov eax, 1
|
||
|
CPU_ID ; get family/model/stepping/features
|
||
|
|
||
|
shr eax, 4 ; isolate family and model
|
||
|
mov ebp,C6X86MX
|
||
|
|
||
|
and eax,0ffh ;mask out type and reserved
|
||
|
nop
|
||
|
|
||
|
cmp eax,_6X86MX
|
||
|
je end_cpuid_type
|
||
|
|
||
|
mov ebp,X86
|
||
|
jmp end_cpuid_type
|
||
|
;************************************************
|
||
|
END
|