platformCPU.cpp
Engine/source/platform/platformCPU.cpp
Public Enumerations
enum
CPUFlags { BIT_FPU = BIT(0) BIT_RDTSC = BIT(4) BIT_MMX = BIT(23) BIT_SSE = BIT(25) BIT_SSE2 = BIT(26) BIT_3DNOW = BIT(31) BIT_SSE3 = BIT(0) BIT_SSE3xt = BIT(9) BIT_SSE4_1 = BIT(19) BIT_SSE4_2 = BIT(20) }
Public Functions
SetProcessorInfo(Platform::SystemInfo_struct::Processor & pInfo, char * vendor, U32 processor, U32 properties, U32 properties2)
Detailed Description
Public Enumerations
CPUFlags
Enumerator
- BIT_FPU = BIT(0)
- BIT_RDTSC = BIT(4)
- BIT_MMX = BIT(23)
- BIT_SSE = BIT(25)
- BIT_SSE2 = BIT(26)
- BIT_3DNOW = BIT(31)
- BIT_SSE3 = BIT(0)
- BIT_SSE3xt = BIT(9)
- BIT_SSE4_1 = BIT(19)
- BIT_SSE4_2 = BIT(20)
Public Functions
SetProcessorInfo(Platform::SystemInfo_struct::Processor & pInfo, char * vendor, U32 processor, U32 properties, U32 properties2)
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#include "platform/platform.h" 25#include "platform/platformCPUCount.h" 26#include "core/strings/stringFunctions.h" 27#include "core/stringTable.h" 28#include "core/util/tSignal.h" 29 30Signal<void(void)> Platform::SystemInfoReady; 31 32enum CPUFlags 33{ 34 // EDX Register flags 35 BIT_FPU = BIT(0), 36 BIT_RDTSC = BIT(4), 37 BIT_MMX = BIT(23), 38 BIT_SSE = BIT(25), 39 BIT_SSE2 = BIT(26), 40 BIT_3DNOW = BIT(31), 41 42 // These use a different value for comparison than the above flags (ECX Register) 43 BIT_SSE3 = BIT(0), 44 BIT_SSE3xt = BIT(9), 45 BIT_SSE4_1 = BIT(19), 46 BIT_SSE4_2 = BIT(20), 47}; 48 49// fill the specified structure with information obtained from asm code 50void SetProcessorInfo(Platform::SystemInfo_struct::Processor& pInfo, 51 char* vendor, U32 processor, U32 properties, U32 properties2) 52{ 53 Platform::SystemInfo.processor.properties |= (properties & BIT_FPU) ? CPU_PROP_FPU : 0; 54 Platform::SystemInfo.processor.properties |= (properties & BIT_RDTSC) ? CPU_PROP_RDTSC : 0; 55 Platform::SystemInfo.processor.properties |= (properties & BIT_MMX) ? CPU_PROP_MMX : 0; 56 57 if (dStricmp(vendor, "GenuineIntel") == 0) 58 { 59 pInfo.properties |= (properties & BIT_SSE) ? CPU_PROP_SSE : 0; 60 pInfo.properties |= (properties & BIT_SSE2) ? CPU_PROP_SSE2 : 0; 61 pInfo.properties |= (properties2 & BIT_SSE3) ? CPU_PROP_SSE3 : 0; 62 pInfo.properties |= (properties2 & BIT_SSE3xt) ? CPU_PROP_SSE3xt : 0; 63 pInfo.properties |= (properties2 & BIT_SSE4_1) ? CPU_PROP_SSE4_1 : 0; 64 pInfo.properties |= (properties2 & BIT_SSE4_2) ? CPU_PROP_SSE4_2 : 0; 65 66 pInfo.type = CPU_Intel_Unknown; 67 // switch on processor family code 68 switch ((processor >> 8) & 0x0f) 69 { 70 case 4: 71 pInfo.type = CPU_Intel_486; 72 pInfo.name = StringTable->insert("Intel 486 class"); 73 break; 74 75 // Pentium Family 76 case 5: 77 // switch on processor model code 78 switch ((processor >> 4) & 0xf) 79 { 80 case 1: 81 case 2: 82 case 3: 83 pInfo.type = CPU_Intel_Pentium; 84 pInfo.name = StringTable->insert("Intel Pentium"); 85 break; 86 case 4: 87 pInfo.type = CPU_Intel_PentiumMMX; 88 pInfo.name = StringTable->insert("Intel Pentium MMX"); 89 break; 90 default: 91 pInfo.type = CPU_Intel_Pentium; 92 pInfo.name = StringTable->insert( "Intel (unknown)" ); 93 break; 94 } 95 break; 96 97 // Pentium Pro/II/II family 98 case 6: 99 { 100 U32 extendedModel = ( processor & 0xf0000 ) >> 16; 101 // switch on processor model code 102 switch ((processor >> 4) & 0xf) 103 { 104 case 1: 105 pInfo.type = CPU_Intel_PentiumPro; 106 pInfo.name = StringTable->insert("Intel Pentium Pro"); 107 break; 108 case 3: 109 case 5: 110 pInfo.type = CPU_Intel_PentiumII; 111 pInfo.name = StringTable->insert("Intel Pentium II"); 112 break; 113 case 6: 114 pInfo.type = CPU_Intel_PentiumCeleron; 115 pInfo.name = StringTable->insert("Intel Pentium Celeron"); 116 break; 117 case 7: 118 case 8: 119 case 11: 120 pInfo.type = CPU_Intel_PentiumIII; 121 pInfo.name = StringTable->insert("Intel Pentium III"); 122 break; 123 case 0xA: 124 if( extendedModel == 1) 125 { 126 pInfo.type = CPU_Intel_Corei7Xeon; 127 pInfo.name = StringTable->insert( "Intel Core i7 / Xeon" ); 128 } 129 else 130 { 131 pInfo.type = CPU_Intel_PentiumIII; 132 pInfo.name = StringTable->insert( "Intel Pentium III Xeon" ); 133 } 134 break; 135 case 0xD: 136 if( extendedModel == 1 ) 137 { 138 pInfo.type = CPU_Intel_Corei7Xeon; 139 pInfo.name = StringTable->insert( "Intel Core i7 / Xeon" ); 140 } 141 else 142 { 143 pInfo.type = CPU_Intel_PentiumM; 144 pInfo.name = StringTable->insert( "Intel Pentium/Celeron M" ); 145 } 146 break; 147 case 0xE: 148 pInfo.type = CPU_Intel_Core; 149 pInfo.name = StringTable->insert( "Intel Core" ); 150 break; 151 case 0xF: 152 pInfo.type = CPU_Intel_Core2; 153 pInfo.name = StringTable->insert( "Intel Core 2" ); 154 break; 155 default: 156 pInfo.type = CPU_Intel_PentiumPro; 157 pInfo.name = StringTable->insert( "Intel (unknown)" ); 158 break; 159 } 160 break; 161 } 162 163 // Pentium4 Family 164 case 0xf: 165 pInfo.type = CPU_Intel_Pentium4; 166 pInfo.name = StringTable->insert( "Intel Pentium 4" ); 167 break; 168 169 default: 170 pInfo.type = CPU_Intel_Unknown; 171 pInfo.name = StringTable->insert( "Intel (unknown)" ); 172 break; 173 } 174 } 175 //-------------------------------------- 176 else 177 if (dStricmp(vendor, "AuthenticAMD") == 0) 178 { 179 // AthlonXP processors support SSE 180 pInfo.properties |= (properties & BIT_SSE) ? CPU_PROP_SSE : 0; 181 pInfo.properties |= ( properties & BIT_SSE2 ) ? CPU_PROP_SSE2 : 0; 182 pInfo.properties |= (properties & BIT_3DNOW) ? CPU_PROP_3DNOW : 0; 183 // Phenom and PhenomII support SSE3, SSE4a 184 pInfo.properties |= ( properties2 & BIT_SSE3 ) ? CPU_PROP_SSE3 : 0; 185 pInfo.properties |= ( properties2 & BIT_SSE4_1 ) ? CPU_PROP_SSE4_1 : 0; 186 // switch on processor family code 187 switch ((processor >> 8) & 0xf) 188 { 189 // K6 Family 190 case 5: 191 // switch on processor model code 192 switch ((processor >> 4) & 0xf) 193 { 194 case 0: 195 case 1: 196 case 2: 197 case 3: 198 pInfo.type = CPU_AMD_K6_3; 199 pInfo.name = StringTable->insert("AMD K5"); 200 break; 201 case 4: 202 case 5: 203 case 6: 204 case 7: 205 pInfo.type = CPU_AMD_K6; 206 pInfo.name = StringTable->insert("AMD K6"); 207 break; 208 case 8: 209 pInfo.type = CPU_AMD_K6_2; 210 pInfo.name = StringTable->insert("AMD K6-2"); 211 break; 212 case 9: 213 case 10: 214 case 11: 215 case 12: 216 case 13: 217 case 14: 218 case 15: 219 pInfo.type = CPU_AMD_K6_3; 220 pInfo.name = StringTable->insert("AMD K6-3"); 221 break; 222 } 223 break; 224 225 // Athlon Family 226 case 6: 227 pInfo.type = CPU_AMD_Athlon; 228 pInfo.name = StringTable->insert("AMD Athlon"); 229 break; 230 231 // Phenom Family 232 case 15: 233 pInfo.type = CPU_AMD_Phenom; 234 pInfo.name = StringTable->insert("AMD Phenom"); 235 break; 236 237 // Phenom II Family 238 case 16: 239 pInfo.type = CPU_AMD_PhenomII; 240 pInfo.name = StringTable->insert("AMD Phenom II"); 241 break; 242 243 // Bulldozer Family 244 case 17: 245 pInfo.type = CPU_AMD_Bulldozer; 246 pInfo.name = StringTable->insert("AMD Bulldozer"); 247 break; 248 249 default: 250 pInfo.type = CPU_AMD_Unknown; 251 pInfo.name = StringTable->insert("AMD (unknown)"); 252 break; 253 } 254 } 255 //-------------------------------------- 256 else 257 if (dStricmp(vendor, "CyrixInstead") == 0) 258 { 259 switch (processor) 260 { 261 case 0x520: 262 pInfo.type = CPU_Cyrix_6x86; 263 pInfo.name = StringTable->insert("Cyrix 6x86"); 264 break; 265 case 0x440: 266 pInfo.type = CPU_Cyrix_MediaGX; 267 pInfo.name = StringTable->insert("Cyrix Media GX"); 268 break; 269 case 0x600: 270 pInfo.type = CPU_Cyrix_6x86MX; 271 pInfo.name = StringTable->insert("Cyrix 6x86mx/MII"); 272 break; 273 case 0x540: 274 pInfo.type = CPU_Cyrix_GXm; 275 pInfo.name = StringTable->insert("Cyrix GXm"); 276 break; 277 default: 278 pInfo.type = CPU_Cyrix_Unknown; 279 pInfo.name = StringTable->insert("Cyrix (unknown)"); 280 break; 281 } 282 } 283 284 // Get multithreading caps. 285 286 CPUInfo::EConfig config = CPUInfo::CPUCount( pInfo.numLogicalProcessors, pInfo.numAvailableCores, pInfo.numPhysicalProcessors ); 287 pInfo.isHyperThreaded = CPUInfo::isHyperThreaded( config ); 288 pInfo.isMultiCore = CPUInfo::isMultiCore( config ); 289 290 // Trigger the signal 291 Platform::SystemInfoReady.trigger(); 292} 293