2004. augusztus 9., hétfő

Get INTEL Chip Features using CPUID Call (asm)

Problem/Question/Abstract:

Get the INTEL chip features via the CPUID call. The function can return results both in a string list and a feature SET, or one or the other. The call only works with INTEL chips 486 or greater. Other chips will return [cpuNonIntel] or [cpuNoCPUID].

example on my machine ...

GetCpuFeatures(memo1.Lines);

FEATURES SUPPORTED

CPU Family 6
CPU Model 7
CPU Stepping 3
On-Chip FPU
VirtualMode Extensions
Debugging Extensions
Page Size Extensions
Time Stamp Counter
Model Specific Registers
Physical Address Extensions
Machine Check Extensions
CMPXCHG8B Instruction
Fast System Call
Memory Type Range Registers
Page Global Enable
Machine Check Architecture
Conditional Move Instruction
Page Attribute Table
32 Bit Page Size Extension
Intel MMX Technology
Fast Floating Point Save and Restore
Streaming SIMD Extensions

Amyone have the algorythms for AMD and other chips ?

Answer:

unit Unit2;
interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms;

type
TForm2 = class(TForm)
private
{ Private declarations }
public
{ Public declarations }
end;

TCpuFeature = (cpuNoCPUID, cpuNonIntel, cpuOnChipFPU,
cpuVirtualModeExtensions, cpuDebuggingExtensions,
cpuPageSizeExtensions, cpuTimeStampCounter,
cpuModelSpecificRegisters, cpuPhysicalAddressExtensions,
cpuMachineCheckExtensions, cpuCMPXCHG8B, cpuOnChipAPIC,
cpuFastSystemCall, cpuMemoryRangeRegisters, cpuPageGlobalEnable,
cpuMachineCheckArchitecture, cpuConditionalMoveInstruction,
cpuPageAttributeTable, cpu32bitPageSzExtension,
cpuProcessorSerialNum, cpuMMXTechnology, cpuFastFloatingPoint,
cpuSIMDExtensions);

TCpuFeatures = set of TCpuFeature;

function GetCpuFeatures(FeatureList: TStrings = nil): TCpuFeatures;

var
Form2: TForm2;
implementation
{$R *.DFM}

// ===================================================
// Get INTEL chip features using CPUID call
// ===================================================

function GetCpuFeatures(FeatureList: TStrings = nil): TCpuFeatures;
const
FPU_FLAG = $0001;
VME_FLAG = $0002;
DE_FLAG = $0004;
PSE_FLAG = $0008;
TSC_FLAG = $0010;
MSR_FLAG = $0020;
PAE_FLAG = $0040;
MCE_FLAG = $0080;
CX8_FLAG = $0100;
APIC_FLAG = $0200;
SEP_FLAG = $0800;
MTRR_FLAG = $1000;
PGE_FLAG = $2000;
MCA_FLAG = $4000;
CMOV_FLAG = $8000;
PAT_FLAG = $10000;
PSE36_FLAG = $20000;
PSNUM_FLAG = $40000;
MMX_FLAG = $800000;
FXSR_FLAG = $1000000;
SIMD_FLAG = $2000000;

var
IsIntel: boolean;
VendorID: array[0..12] of char;
IntelID: array[0..12] of char;
FeaturesFlag, CpuSignature: DWord;
Temp: DWord;
RetVar: TCpuFeatures;
CpuType: byte;

// Local routine to add to List and Return SET
procedure CheckFeature(FeatureFlag: DWord;
const Item: string;
cpuFeatureType: TCpuFeature);
begin
if FeaturesFlag and FeatureFlag = FeatureFlag then
begin
if FeatureList <> nil then
FeatureList.Add(Item);
include(RetVar, cpuFeatureType);
end;
end;

begin
RetVar := [];
if FeatureList <> nil then
FeatureList.Clear;
IsIntel := false;
IntelId := 'GenuineIntel'#0;
VendorID := '------------'#0;

try
asm
// Determine Intel CPUID support.

push ebx
push esi
push edi
mov  eax,0                     // Set up for CPUID instruction
db 00fh                        // CPUID - Get Vendor and check INTEL
db 0a2h
mov dword ptr VendorId,ebx
mov dword ptr VendorId[+4],edx
mov dword ptr VendorId[+8],ecx
cmp dword ptr IntelId,ebx      // Check if it is INTEL
jne @@EndCPUID
cmp dword ptr IntelId[+4],edx
jne @@EndCPUID
cmp dword ptr IntelId[+8],ecx
jne @@EndCPUID                 // Not an Intel processor

mov byte ptr IsIntel,1         // Set IsIntel to true
cmp eax,1                      // Ensure 1 is valid input for CPUID
jl  @@EndCPUID                 // Else jump to end

mov eax,1
db 00fh                        // CPUID -  Get features,family etc.
db 0a2h
mov CpuSignature,eax
mov FeaturesFlag,edx
shr eax,8                      // Isolate family
and eax,0fh
mov byte ptr CpuType,al        // Set cputype with family

@@EndCPUID :

pop edi                        // Restore registers
pop esi
pop ebx
end;

// Check Features Mask if Intel
if IsIntel then
begin
if FeatureList <> nil then
begin
FeatureList.Add('CPU Family ' + IntToStr(CpuType));
Temp := (CpuSignature shr 4) and $0F;
FeatureList.Add('CPU Model ' + IntToStr(Temp));
Temp := CpuSignature and $0F;
FeatureList.Add('CPU Stepping ' + IntToStr(Temp));
end;

CheckFeature(FPU_FLAG, 'On-Chip FPU', cpuOnChipFPU);
CheckFeature(VME_FLAG,
'VirtualMode Extensions', cpuVirtualModeExtensions);
CheckFeature(DE_FLAG, 'Debugging Extensions', cpuDebuggingExtensions);
CheckFeature(PSE_FLAG, 'Page Size Extensions', cpuPageSizeExtensions);
CheckFeature(TSC_FLAG, 'Time Stamp Counter', cpuTimeStampCounter);
CheckFeature(MSR_FLAG,
'Model Specific Registers', cpuModelSpecificRegisters);
CheckFeature(PAE_FLAG,
'Physical Address Extensions',
cpuPhysicalAddressExtensions);
CheckFeature(MCE_FLAG,
'Machine Check Extensions', cpuMachineCheckExtensions);
CheckFeature(CX8_FLAG, 'CMPXCHG8B Instruction', cpuCMPXCHG8B);
CheckFeature(APIC_FLAG, 'On Chip APIC', cpuOnChipAPIC);
CheckFeature(SEP_FLAG, 'Fast System Call', cpuFastSystemCall);
CheckFeature(MTRR_FLAG,
'Memory Type Range Registers', cpuMemoryRangeRegisters);
CheckFeature(PGE_FLAG, 'Page Global Enable', cpuPageGlobalEnable);
CheckFeature(MCA_FLAG,
'Machine Check Architecture', cpuMachineCheckArchitecture);
CheckFeature(CMOV_FLAG,
'Conditional Move Instruction',
cpuConditionalMoveInstruction);
CheckFeature(PAT_FLAG, 'Page Attribute Table', cpuPageAttributeTable);
CheckFeature(PSE36_FLAG,
'32 Bit Page Size Extension', cpu32BitPageSzExtension);
CheckFeature(PSNUM_FLAG,
'Processor Serial Number', cpuProcessorSerialNum);
CheckFeature(MMX_FLAG, 'Intel MMX Technology', cpuMMXTechnology);
CheckFeature(FXSR_FLAG,
'Fast Floating Point Save and Restore',
cpuFastFloatingPoint);
CheckFeature(SIMD_FLAG, 'Streaming SIMD Extensions', cpuSIMDExtensions);
end
else
begin
if FeatureList <> nil then
FeatureList.Add('Non-Intel or >486 Chip - Features Unknown');
include(RetVar, cpuNonIntel);
end;
except
if FeatureList <> nil then
FeatureList.Add('No CPUID Support');
include(RetVar, cpuNoCPUID);
end;

Result := RetVar;
end;

end.

Nincsenek megjegyzések:

Megjegyzés küldése