winCPUInfo.cpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "platform/platform.h"
  23. #include "platformWin32/platformWin32.h"
  24. #include "console/console.h"
  25. #include "core/stringTable.h"
  26. #include <math.h>
  27. Platform::SystemInfo_struct Platform::SystemInfo;
  28. extern void PlatformBlitInit();
  29. extern void SetProcessorInfo(Platform::SystemInfo_struct::Processor& pInfo,
  30. char* vendor, U32 processor, U32 properties, U32 properties2); // platform/platformCPU.cc
  31. #if defined(TORQUE_SUPPORTS_NASM)
  32. // asm cpu detection routine from platform code
  33. extern "C"
  34. {
  35. void detectX86CPUInfo(char *vendor, U32 *processor, U32 *properties);
  36. }
  37. #endif
  38. void Processor::init()
  39. {
  40. // Reference:
  41. // www.cyrix.com
  42. // www.amd.com
  43. // www.intel.com
  44. // http://developer.intel.com/design/PentiumII/manuals/24512701.pdf
  45. Con::printf("Processor Init:");
  46. Platform::SystemInfo.processor.type = CPU_X86Compatible;
  47. Platform::SystemInfo.processor.name = StringTable->insert("Unknown x86 Compatible");
  48. Platform::SystemInfo.processor.mhz = 0;
  49. Platform::SystemInfo.processor.properties = CPU_PROP_C | CPU_PROP_LE;
  50. char vendor[13] = {0,};
  51. U32 properties = 0;
  52. U32 processor = 0;
  53. U32 properties2 = 0;
  54. #if defined(TORQUE_SUPPORTS_VC_INLINE_X86_ASM)
  55. __asm
  56. {
  57. //--------------------------------------
  58. // is CPUID supported
  59. push ebx
  60. push edx
  61. push ecx
  62. pushfd
  63. pushfd // save EFLAGS to stack
  64. pop eax // move EFLAGS into EAX
  65. mov ebx, eax
  66. xor eax, 0x200000 // flip bit 21
  67. push eax
  68. popfd // restore EFLAGS
  69. pushfd
  70. pop eax
  71. cmp eax, ebx
  72. jz EXIT // doesn't support CPUID instruction
  73. //--------------------------------------
  74. // Get Vendor Informaion using CPUID eax==0
  75. xor eax, eax
  76. cpuid
  77. mov DWORD PTR vendor, ebx
  78. mov DWORD PTR vendor+4, edx
  79. mov DWORD PTR vendor+8, ecx
  80. // get Generic Extended CPUID info
  81. mov eax, 1
  82. cpuid // eax=1, so cpuid queries feature information
  83. and eax, 0x0fff3fff
  84. mov processor, eax // just store the model bits
  85. mov properties, edx
  86. mov properties2, ecx
  87. // Want to check for 3DNow(tm). Need to see if extended cpuid functions present.
  88. mov eax, 0x80000000
  89. cpuid
  90. cmp eax, 0x80000000
  91. jbe MAYBE_3DLATER
  92. mov eax, 0x80000001
  93. cpuid
  94. and edx, 0x80000000 // 3DNow if bit 31 set -> put bit in our properties
  95. or properties, edx
  96. MAYBE_3DLATER:
  97. EXIT:
  98. popfd
  99. pop ecx
  100. pop edx
  101. pop ebx
  102. }
  103. #elif defined(TORQUE_SUPPORTS_NASM)
  104. detectX86CPUInfo(vendor, &processor, &properties);
  105. #endif
  106. SetProcessorInfo(Platform::SystemInfo.processor, vendor, processor, properties, properties2);
  107. // now calculate speed of processor...
  108. U32 nearmhz = 0; // nearest rounded mhz
  109. U32 mhz = 0; // calculated value.
  110. LONG result;
  111. DWORD data = 0;
  112. DWORD dataSize = 4;
  113. HKEY hKey;
  114. result = ::RegOpenKeyExA (HKEY_LOCAL_MACHINE,"Hardware\\Description\\System\\CentralProcessor\\0", 0, KEY_QUERY_VALUE, &hKey);
  115. if (result == ERROR_SUCCESS)
  116. {
  117. result = ::RegQueryValueExA (hKey, "~MHz",NULL, NULL,(LPBYTE)&data, &dataSize);
  118. if (result == ERROR_SUCCESS)
  119. nearmhz = mhz = data;
  120. ::RegCloseKey(hKey);
  121. }
  122. Platform::SystemInfo.processor.mhz = mhz;
  123. if (mhz==0)
  124. {
  125. Con::printf(" %s, (Unknown) Mhz", Platform::SystemInfo.processor.name);
  126. // stick SOMETHING in so it isn't ZERO.
  127. Platform::SystemInfo.processor.mhz = 200; // seems a decent value.
  128. }
  129. else
  130. {
  131. if (nearmhz >= 1000)
  132. Con::printf(" %s, ~%.2f Ghz", Platform::SystemInfo.processor.name, ((float)nearmhz)/1000.0f);
  133. else
  134. Con::printf(" %s, ~%d Mhz", Platform::SystemInfo.processor.name, nearmhz);
  135. if (nearmhz != mhz)
  136. {
  137. if (mhz >= 1000)
  138. Con::printf(" (timed at roughly %.2f Ghz)", ((float)mhz)/1000.0f);
  139. else
  140. Con::printf(" (timed at roughly %d Mhz)", mhz);
  141. }
  142. }
  143. if( Platform::SystemInfo.processor.numAvailableCores > 0
  144. || Platform::SystemInfo.processor.numPhysicalProcessors > 0
  145. || Platform::SystemInfo.processor.isHyperThreaded )
  146. Platform::SystemInfo.processor.properties |= CPU_PROP_MP;
  147. if (Platform::SystemInfo.processor.properties & CPU_PROP_FPU)
  148. Con::printf( " FPU detected" );
  149. if (Platform::SystemInfo.processor.properties & CPU_PROP_MMX)
  150. Con::printf( " MMX detected" );
  151. if (Platform::SystemInfo.processor.properties & CPU_PROP_3DNOW)
  152. Con::printf( " 3DNow detected" );
  153. if (Platform::SystemInfo.processor.properties & CPU_PROP_SSE)
  154. Con::printf( " SSE detected" );
  155. if( Platform::SystemInfo.processor.properties & CPU_PROP_SSE2 )
  156. Con::printf( " SSE2 detected" );
  157. if( Platform::SystemInfo.processor.isHyperThreaded )
  158. Con::printf( " HT detected" );
  159. if( Platform::SystemInfo.processor.properties & CPU_PROP_MP )
  160. Con::printf( " MP detected [%i cores, %i logical, %i physical]",
  161. Platform::SystemInfo.processor.numAvailableCores,
  162. Platform::SystemInfo.processor.numLogicalProcessors,
  163. Platform::SystemInfo.processor.numPhysicalProcessors );
  164. Con::printf(" ");
  165. PlatformBlitInit();
  166. }