/* ** Command & Conquer Renegade(tm) ** Copyright 2025 Electronic Arts Inc. ** ** This program is free software: you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation, either version 3 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program. If not, see . */ /*********************************************************************************************** *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S *** *********************************************************************************************** * * * Project Name : wwlib * * * * $Archive:: /Commando/Code/wwlib/cpudetect.h $* * * * Original Author:: Jani Penttinen * * * * $Author:: Jani_p $* * * * $Modtime:: 3/29/02 4:09p $* * * * $Revision:: 11 $* * * *---------------------------------------------------------------------------------------------* * Functions: * * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #if defined(_MSC_VER) #pragma once #endif #ifndef WWLIB_CPU_DETECT_H__ #define WWLIB_CPU_DETECT_H__ #include "always.h" #include "wwstring.h" class CPUDetectInitClass; class CPUDetectClass { public: typedef enum { MANUFACTURER_UNKNOWN = 0, MANUFACTURER_INTEL, MANUFACTURER_UMC, MANUFACTURER_AMD, MANUFACTURER_CYRIX, MANUFACTURER_NEXTGEN, MANUFACTURER_VIA, MANUFACTURER_RISE, MANUFACTURER_TRANSMETA } ProcessorManufacturerType; typedef enum { INTEL_PROCESSOR_UNKNOWN, INTEL_PROCESSOR_80386, INTEL_PROCESSOR_80486DX, INTEL_PROCESSOR_80486SX, INTEL_PROCESSOR_80486DX2, INTEL_PROCESSOR_80486SL, INTEL_PROCESSOR_80486SX2, INTEL_PROCESSOR_80486DX2_WB, INTEL_PROCESSOR_80486DX4, INTEL_PROCESSOR_80486DX4_WB, INTEL_PROCESSOR_PENTIUM, INTEL_PROCESSOR_PENTIUM_OVERDRIVE, INTEL_PROCESSOR_PENTIUM_MMX, INTEL_PROCESSOR_PENTIUM_PRO_SAMPLE, INTEL_PROCESSOR_PENTIUM_PRO, INTEL_PROCESSOR_PENTIUM_II_OVERDRIVE, INTEL_PROCESSOR_PENTIUM_II_MODEL_3, INTEL_PROCESSOR_PENTIUM_II_MODEL_4, INTEL_PROCESSOR_CELERON_MODEL_5, INTEL_PROCESSOR_PENTIUM_II_MODEL_5, INTEL_PROCESSOR_PENTIUM_II_XEON_MODEL_5, INTEL_PROCESSOR_CELERON_MODEL_6, INTEL_PROCESSOR_PENTIUM_III_MODEL_7, INTEL_PROCESSOR_PENTIUM_III_XEON_MODEL_7, INTEL_PROCESSOR_CELERON_MODEL_8, INTEL_PROCESSOR_PENTIUM_III_MODEL_8, INTEL_PROCESSOR_PENTIUM_III_XEON_MODEL_8, INTEL_PROCESSOR_PENTIUM_III_XEON_MODEL_A, INTEL_PROCESSOR_PENTIUM_III_MODEL_B, INTEL_PROCESSOR_PENTIUM4 } IntelProcessorType; typedef enum { AMD_PROCESSOR_UNKNOWN, AMD_PROCESSOR_486DX2, AMD_PROCESSOR_486DX4, AMD_PROCESSOR_5x86, AMD_PROCESSOR_486, AMD_PROCESSOR_K5_MODEL0, AMD_PROCESSOR_K5_MODEL1, AMD_PROCESSOR_K5_MODEL2, AMD_PROCESSOR_K5_MODEL3, AMD_PROCESSOR_K6_MODEL6, AMD_PROCESSOR_K6_MODEL7, AMD_PROCESSOR_K6_2_3DNOW_MODEL8, AMD_PROCESSOR_K6_3_3DNOW_MODEL9, AMD_PROCESSOR_K6_3_PLUS, AMD_PROCESSOR_K6, AMD_PROCESSOR_ATHLON_025, AMD_PROCESSOR_ATHLON_018, AMD_PROCESSOR_DURON, AMD_PROCESSOR_ATHLON_018_IL2, AMD_PROCESSOR_ATHLON } AMDProcessorType; typedef enum { VIA_PROCESSOR_UNKNOWN, VIA_PROCESSOR_IDT_C6_WINCHIP, VIA_PROCESSOR_IDT_C6_WINCHIP2, VIA_PROCESSOR_IDT_C6_WINCHIP3, VIA_PROCESSOR_CYRIX_III_SAMUEL } VIAProcessorType; typedef enum { RISE_PROCESSOR_UNKNOWN, RISE_PROCESSOR_DRAGON_025, RISE_PROCESSOR_DRAGON_018, RISE_PROCESSOR_DRAGON2_025, RISE_PROCESSOR_DRAGON2_018 } RiseProcessorType; inline static ProcessorManufacturerType Get_Processor_Manufacturer() {return ProcessorManufacturer;} static const char* Get_Processor_Manufacturer_Name(); inline static bool Has_CPUID_Instruction() { return HasCPUIDInstruction; } inline static bool Has_RDTSC_Instruction() { return HasRDTSCInstruction; } inline static bool Has_CMOV_Instruction() { return HasCMOVSupport; } inline static bool Has_MMX_Instruction_Set() { return HasMMXSupport; } inline static bool Has_SSE_Instruction_Set() { return HasSSESupport; } inline static bool Has_SSE2_Instruction_Set() { return HasSSE2Support; } inline static bool Has_3DNow_Instruction_Set() { return Has3DNowSupport; } inline static bool Has_Extended_3DNow_Instruction_Set() { return HasExtended3DNowSupport; } // Call these functions after determining the manufacturer to find out which of the manufacturers processors // the system has. inline static IntelProcessorType Get_Intel_Processor() { return IntelProcessor; } inline static AMDProcessorType Get_AMD_Processor() { return AMDProcessor; } inline static VIAProcessorType Get_VIA_Processor() { return VIAProcessor; } inline static RiseProcessorType Get_Rise_Processor() { return RiseProcessor; } // Note that processor speed is only calculated at start and could change during execution, so // this number is not to be relied on! inline static int Get_Processor_Speed() { return ProcessorSpeed; } inline static __int64 Get_Processor_Ticks_Per_Second() { return ProcessorTicksPerSecond; } // Ticks per second inline static double Get_Inv_Processor_Ticks_Per_Second() { return InvProcessorTicksPerSecond; } // 1.0 / Ticks per second static unsigned Get_Feature_Bits() { return FeatureBits; } static unsigned Get_Extended_Feature_Bits() { return ExtendedFeatureBits; } // L2 cache static unsigned Get_L2_Cache_Size() { return L2CacheSize; } static unsigned Get_L2_Cache_Line_Size() { return L2CacheLineSize; } static unsigned Get_L2_Cache_Set_Associative() { return L2CacheSetAssociative; } // L1 data cache static unsigned Get_L1_Data_Cache_Size() { return L1DataCacheSize; } static unsigned Get_L1_Data_Cache_Line_Size() { return L1DataCacheLineSize; } static unsigned Get_L1_Data_Cache_Set_Associative() { return L1DataCacheSetAssociative; } // L1 instruction cache static unsigned Get_L1_Instruction_Cache_Size() { return L1InstructionCacheSize; } static unsigned Get_L1_Instruction_Cache_Line_Size() { return L1InstructionCacheLineSize; } static unsigned Get_L1_Instruction_Cache_Set_Associative() { return L1InstructionCacheSetAssociative; } // L1 instruction trace cache static unsigned Get_L1_Instruction_Trace_Cache_Size() { return L1InstructionTraceCacheSize; } static unsigned Get_L1_Instruction_Trace_Cache_Set_Associative() { return L1InstructionTraceCacheSetAssociative; } // System memory static unsigned Get_Total_Physical_Memory() { return TotalPhysicalMemory; } static unsigned Get_Available_Physical_Memory() { return AvailablePhysicalMemory; } static unsigned Get_Total_Page_File_Size() { return TotalPageMemory; } static unsigned Get_Available_Page_File_Size() { return AvailablePageMemory; } static unsigned Get_Total_Virtual_Memory() { return TotalVirtualMemory; } static unsigned Get_Available_Virtual_Memory() { return AvailableVirtualMemory; } static unsigned Get_Processor_Type() { return ProcessorType; } inline static const char* Get_Processor_String() { return ProcessorString; } inline static const StringClass& Get_Processor_Log() { return ProcessorLog; } inline static const StringClass& Get_Compact_Log() { return CompactLog; } static bool CPUID( unsigned& u_eax_, unsigned& u_ebx_, unsigned& u_ecx_, unsigned& u_edx_, unsigned cpuid_type); private: // static void Detect_CPU_Type(); static void Init_CPUID_Instruction(); static void Init_Processor_Speed(); static void Init_Processor_String(); static void Init_Processor_Manufacturer(); static void Init_Processor_Family(); static void Init_Processor_Features(); static void Init_Memory(); static void Init_OS(); static void Init_Intel_Processor_Type(); static void Init_AMD_Processor_Type(); static void Init_VIA_Processor_Type(); static void Init_Rise_Processor_Type(); static void Init_Cache(); static void Init_Processor_Log(); static void Init_Compact_Log(); static void Process_Cache_Info(unsigned value); static void Process_Extended_Cache_Info(); friend class CPUDetectInitClass; static StringClass ProcessorLog; static StringClass CompactLog; static int ProcessorType; static int ProcessorFamily; static int ProcessorModel; static int ProcessorRevision; static int ProcessorSpeed; static __int64 ProcessorTicksPerSecond; // Ticks per second static double InvProcessorTicksPerSecond; // 1.0 / Ticks per second static ProcessorManufacturerType ProcessorManufacturer; static IntelProcessorType IntelProcessor; static AMDProcessorType AMDProcessor; static VIAProcessorType VIAProcessor; static RiseProcessorType RiseProcessor; static unsigned FeatureBits; static unsigned ExtendedFeatureBits; // L2 cache information static unsigned L2CacheSize; static unsigned L2CacheLineSize; static unsigned L2CacheSetAssociative; // L1 data cache information static unsigned L1DataCacheSize; static unsigned L1DataCacheLineSize; static unsigned L1DataCacheSetAssociative; // L1 instruction cache information static unsigned L1InstructionCacheSize; static unsigned L1InstructionCacheLineSize; static unsigned L1InstructionCacheSetAssociative; // L1 instruction trace cache information static unsigned L1InstructionTraceCacheSize; static unsigned L1InstructionTraceCacheSetAssociative; static unsigned TotalPhysicalMemory; static unsigned AvailablePhysicalMemory; static unsigned TotalPageMemory; static unsigned AvailablePageMemory; static unsigned TotalVirtualMemory; static unsigned AvailableVirtualMemory; static unsigned OSVersionNumberMajor; static unsigned OSVersionNumberMinor; static unsigned OSVersionBuildNumber; static unsigned OSVersionPlatformId; static StringClass OSVersionExtraInfo; static bool HasCPUIDInstruction; static bool HasRDTSCInstruction; static bool HasSSESupport; static bool HasSSE2Support; static bool HasCMOVSupport; static bool HasMMXSupport; static bool Has3DNowSupport; static bool HasExtended3DNowSupport; static char VendorID[20]; static char ProcessorString[48]; }; struct CPUIDStruct { unsigned Eax; unsigned Ebx; unsigned Ecx; unsigned Edx; CPUIDStruct(unsigned cpuid_type) { if (!CPUDetectClass::Has_CPUID_Instruction()) { Eax=Ebx=Ecx=Edx=0; return; } CPUDetectClass::CPUID(Eax,Ebx,Ecx,Edx,cpuid_type); } }; #endif // WWLIB_CPU_DETECT_H__