Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

377 lines
6.8 KiB

  1. //===== Copyright � 1996-2005, Valve Corporation, All rights reserved. ======//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //===========================================================================//
  8. #ifndef IA32DETECT_H
  9. #define IA32DETECT_H
  10. #ifdef COMPILER_MSVC64
  11. extern "C" void __cpuid(int* CPUInfo, int InfoType);
  12. #pragma intrinsic (__cpuid)
  13. #endif
  14. /*
  15. This section from http://iss.cs.cornell.edu/ia32.htm
  16. */
  17. typedef unsigned bit;
  18. enum CPUVendor
  19. {
  20. INTEL,
  21. AMD,
  22. UNKNOWN_VENDOR
  23. };
  24. class ia32detect
  25. {
  26. public:
  27. enum type_t
  28. {
  29. type_OEM,
  30. type_OverDrive,
  31. type_Dual,
  32. type_reserved
  33. };
  34. enum brand_t
  35. {
  36. brand_na,
  37. brand_Celeron,
  38. brand_PentiumIII,
  39. brand_PentiumIIIXeon,
  40. brand_reserved1,
  41. brand_reserved2,
  42. brand_PentiumIIIMobile,
  43. brand_reserved3,
  44. brand_Pentium4,
  45. brand_invalid
  46. };
  47. # pragma pack(push, 1)
  48. struct version_t
  49. {
  50. bit Stepping : 4;
  51. bit Model : 4;
  52. bit Family : 4;
  53. bit Type : 2;
  54. bit Reserved1 : 2;
  55. bit XModel : 4;
  56. bit XFamily : 8;
  57. bit Reserved2 : 4;
  58. };
  59. struct misc_t
  60. {
  61. byte Brand;
  62. byte CLFLUSH;
  63. byte Reserved;
  64. byte APICId;
  65. };
  66. struct feature_t
  67. {
  68. bit FPU : 1; // Floating Point Unit On-Chip
  69. bit VME : 1; // Virtual 8086 Mode Enhancements
  70. bit DE : 1; // Debugging Extensions
  71. bit PSE : 1; // Page Size Extensions
  72. bit TSC : 1; // Time Stamp Counter
  73. bit MSR : 1; // Model Specific Registers
  74. bit PAE : 1; // Physical Address Extension
  75. bit MCE : 1; // Machine Check Exception
  76. bit CX8 : 1; // CMPXCHG8 Instruction
  77. bit APIC : 1; // APIC On-Chip
  78. bit Reserved1 : 1;
  79. bit SEP : 1; // SYSENTER and SYSEXIT instructions
  80. bit MTRR : 1; // Memory Type Range Registers
  81. bit PGE : 1; // PTE Global Bit
  82. bit MCA : 1; // Machine Check Architecture
  83. bit CMOV : 1; // Conditional Move Instructions
  84. bit PAT : 1; // Page Attribute Table
  85. bit PSE36 : 1; // 32-bit Page Size Extension
  86. bit PSN : 1; // Processor Serial Number
  87. bit CLFSH : 1; // CLFLUSH Instruction
  88. bit Reserved2 : 1;
  89. bit DS : 1; // Debug Store
  90. bit ACPI : 1; // Thermal Monitor and Software Controlled Clock Facilities
  91. bit MMX : 1; // Intel MMX Technology
  92. bit FXSR : 1; // FXSAVE and FXRSTOR Instructions
  93. bit SSE : 1; // Intel SSE Technology
  94. bit SSE2 : 1; // Intel SSE2 Technology
  95. bit SS : 1; // Self Snoop
  96. bit HTT : 1; // Hyper Threading
  97. bit TM : 1; // Thermal Monitor
  98. bit Reserved3 : 1;
  99. bit PBE : 1; // Pending Brk. EN.
  100. };
  101. # pragma pack(pop)
  102. tstring vendor_name;
  103. CPUVendor vendor;
  104. tstring brand;
  105. version_t version;
  106. misc_t misc;
  107. feature_t feature;
  108. byte *cache;
  109. ia32detect ()
  110. {
  111. cache = 0;
  112. uint32 m = init0();
  113. uint32 *d = new uint32[m * 4];
  114. for (uint32 i = 1; i <= m; i++)
  115. {
  116. #ifdef COMPILER_MSVC64
  117. __cpuid((int *) (d + (i-1) * 4), i);
  118. #else
  119. uint32 *t = d + (i - 1) * 4;
  120. __asm
  121. {
  122. mov eax, i;
  123. mov esi, t;
  124. cpuid;
  125. mov dword ptr [esi + 0x0], eax;
  126. mov dword ptr [esi + 0x4], ebx;
  127. mov dword ptr [esi + 0x8], ecx;
  128. mov dword ptr [esi + 0xC], edx;
  129. }
  130. #endif
  131. }
  132. if (m >= 1)
  133. init1(d);
  134. if (m >= 2)
  135. init2(d[4] & 0xFF);
  136. delete [] d;
  137. init0x80000000();
  138. //-----------------------------------------------------------------------
  139. // Get the vendor of the processor
  140. //-----------------------------------------------------------------------
  141. if (_tcscmp(vendor_name.c_str(), _T("GenuineIntel")) == 0)
  142. {
  143. vendor = INTEL;
  144. }
  145. else if (_tcscmp(vendor_name.c_str(), _T("AuthenticAMD")) == 0)
  146. {
  147. vendor = AMD;
  148. }
  149. else
  150. {
  151. vendor = UNKNOWN_VENDOR;
  152. }
  153. }
  154. const tstring version_text () const
  155. {
  156. tchar b[128];
  157. _stprintf(b, _T("%d.%d.%d %s XVersion(%d.%d)"),
  158. version.Family, version.Model, version.Stepping, type_text(), version.XFamily, version.XModel);
  159. return tstring(b);
  160. }
  161. protected:
  162. const tchar * type_text () const
  163. {
  164. static const tchar *text[] =
  165. {
  166. _T("Intel OEM Processor"),
  167. _T("Intel OverDrive(R) Processor"),
  168. _T("Intel Dual Processor"),
  169. _T("reserved")
  170. };
  171. return text[version.Type];
  172. }
  173. const tstring brand_text () const
  174. {
  175. static const tchar *text[] =
  176. {
  177. _T("n/a"),
  178. _T("Celeron"),
  179. _T("Pentium III"),
  180. _T("Pentium III Xeon"),
  181. _T("reserved (4)"),
  182. _T("reserved (5)"),
  183. _T("Pentium III Mobile"),
  184. _T("reserved (7)"),
  185. _T("Pentium 4")
  186. };
  187. if (misc.Brand < brand_invalid)
  188. return tstring(text[misc.Brand]);
  189. else
  190. {
  191. tchar b[32];
  192. _stprintf(b, _T("Brand %d (Update)"), misc.Brand);
  193. return tstring(b);
  194. }
  195. }
  196. private:
  197. uint32 init0 ()
  198. {
  199. uint32 m;
  200. int data[4 + 1];
  201. tchar * s1;
  202. s1 = (tchar *) &data[1];
  203. __cpuid(data, 0);
  204. data[4] = 0;
  205. // Returns something like this:
  206. // data[0] = 0x0000000b
  207. // data[1] = 0x756e6547 Genu
  208. // data[2] = 0x6c65746e ntel
  209. // data[3] = 0x49656e69 ineI
  210. // data[4] = 0x00000000
  211. m = data[0];
  212. int t = data[2];
  213. data[2] = data[3];
  214. data[3] = t;
  215. vendor_name = s1;
  216. return m;
  217. }
  218. void init1 (uint32 *d)
  219. {
  220. version = *(version_t *)&d[0];
  221. misc = *(misc_t *)&d[1];
  222. feature = *(feature_t *)&d[3];
  223. }
  224. void process2 (uint32 d, bool c[])
  225. {
  226. if ((d & 0x80000000) == 0)
  227. for (int i = 0; i < 32; i += 8)
  228. c[(d >> i) & 0xFF] = true;
  229. }
  230. void init2 (byte count)
  231. {
  232. uint32 d[4];
  233. bool c[256];
  234. for (int ci1 = 0; ci1 < 256; ci1++)
  235. c[ci1] = false;
  236. for (int i = 0; i < count; i++)
  237. {
  238. #ifdef COMPILER_MSVC64
  239. __cpuid((int *) d, 2);
  240. #else
  241. __asm
  242. {
  243. mov eax, 2;
  244. lea esi, d;
  245. cpuid;
  246. mov [esi + 0x0], eax;
  247. mov [esi + 0x4], ebx;
  248. mov [esi + 0x8], ecx;
  249. mov [esi + 0xC], edx;
  250. }
  251. #endif
  252. if (i == 0)
  253. d[0] &= 0xFFFFFF00;
  254. process2(d[0], c);
  255. process2(d[1], c);
  256. process2(d[2], c);
  257. process2(d[3], c);
  258. }
  259. int m = 0;
  260. for (int ci2 = 0; ci2 < 256; ci2++)
  261. if (c[ci2])
  262. m++;
  263. cache = new byte[m];
  264. m = 0;
  265. for (int ci3 = 1; ci3 < 256; ci3++)
  266. if (c[ci3])
  267. cache[m++] = ci3;
  268. cache[m] = 0;
  269. }
  270. void init0x80000000 ()
  271. {
  272. uint32 m;
  273. #ifdef COMPILER_MSVC64
  274. int data[4];
  275. __cpuid(data, 0x80000000);
  276. m = data[0];
  277. #else
  278. __asm
  279. {
  280. mov eax, 0x80000000;
  281. cpuid;
  282. mov m, eax
  283. }
  284. #endif
  285. if ((m & 0x80000000) != 0)
  286. {
  287. uint32 *d = new uint32[(m - 0x80000000) * 4];
  288. for (uint32 i = 0x80000001; i <= m; i++)
  289. {
  290. uint32 *t = d + (i - 0x80000001) * 4;
  291. #ifdef COMPILER_MSVC64
  292. __cpuid((int *) (d + (i - 0x80000001) * 4), i);
  293. #else
  294. __asm
  295. {
  296. mov eax, i;
  297. mov esi, t;
  298. cpuid;
  299. mov dword ptr [esi + 0x0], eax;
  300. mov dword ptr [esi + 0x4], ebx;
  301. mov dword ptr [esi + 0x8], ecx;
  302. mov dword ptr [esi + 0xC], edx;
  303. }
  304. #endif
  305. }
  306. if (m >= 0x80000002)
  307. brand = (tchar *)(d + 4);
  308. // note the assignment to brand above does a copy, we need to delete
  309. delete[] d;
  310. }
  311. }
  312. };
  313. #endif // IA32DETECT_H