PageRenderTime 24ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/antares/headers/private/shared/cpu_type.h

https://github.com/mmanley/Antares
C Header | 362 lines | 283 code | 44 blank | 35 comment | 39 complexity | b90994e73907f763b3fa2065bba37f1e MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, MPL-2.0-no-copyleft-exception, GPL-3.0, ISC, LGPL-2.0, LGPL-3.0
  1. /*
  2. * Copyright 2004-2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
  3. * Distributed under the terms of the MIT License.
  4. */
  5. /* Taken from the Pulse application, and extended.
  6. * It's used by Pulse, AboutAntares, and sysinfo.
  7. */
  8. #include <stdlib.h>
  9. #include <stdio.h>
  10. #include <OS.h>
  11. #ifdef __cplusplus
  12. extern "C" {
  13. #endif
  14. const char *get_cpu_vendor_string(enum cpu_types type);
  15. const char *get_cpu_model_string(system_info *info);
  16. void get_cpu_type(char *vendorBuffer, size_t vendorSize,
  17. char *modelBuffer, size_t modelSize);
  18. int32 get_rounded_cpu_speed(void);
  19. #ifdef __cplusplus
  20. }
  21. #endif
  22. const char *
  23. get_cpu_vendor_string(enum cpu_types type)
  24. {
  25. #if __POWERPC__
  26. /* We're not that nice here. */
  27. return "IBM/Motorola";
  28. #endif
  29. #if __INTEL__
  30. /* Determine x86 vendor name */
  31. switch (type & B_CPU_x86_VENDOR_MASK) {
  32. case B_CPU_INTEL_x86:
  33. return "Intel";
  34. case B_CPU_AMD_x86:
  35. return "AMD";
  36. case B_CPU_CYRIX_x86:
  37. return "Cyrix";
  38. case B_CPU_IDT_x86:
  39. /* IDT was bought by VIA */
  40. if (((type >> 8) & 0xf) >= 6)
  41. return "VIA";
  42. return "IDT";
  43. case B_CPU_RISE_x86:
  44. return "Rise";
  45. case B_CPU_TRANSMETA_x86:
  46. return "Transmeta";
  47. default:
  48. return NULL;
  49. }
  50. #endif
  51. }
  52. #ifdef __INTEL__
  53. /* Parameter 'name' needs to point to an allocated array of 49 characters. */
  54. void
  55. get_cpuid_model_string(char *name)
  56. {
  57. /* References:
  58. *
  59. * http://grafi.ii.pw.edu.pl/gbm/x86/cpuid.html
  60. * http://www.sandpile.org/ia32/cpuid.htm
  61. * http://www.amd.com/us-en/assets/content_type/
  62. * white_papers_and_tech_docs/TN13.pdf (Duron erratum)
  63. */
  64. cpuid_info baseInfo;
  65. cpuid_info cpuInfo;
  66. int32 maxStandardFunction, maxExtendedFunction = 0;
  67. memset(name, 0, 49 * sizeof(char));
  68. if (get_cpuid(&baseInfo, 0, 0) != B_OK) {
  69. /* This CPU doesn't support cpuid. */
  70. return;
  71. }
  72. maxStandardFunction = baseInfo.eax_0.max_eax;
  73. if (maxStandardFunction >= 500) {
  74. maxStandardFunction = 0;
  75. /* Old Pentium sample chips have the CPU signature here. */
  76. }
  77. /* Extended cpuid */
  78. get_cpuid(&cpuInfo, 0x80000000, 0);
  79. /* hardcoded to CPU 0 */
  80. /* Extended cpuid is only supported if max_eax is greater than the */
  81. /* service id. */
  82. if (cpuInfo.eax_0.max_eax > 0x80000000)
  83. maxExtendedFunction = cpuInfo.eax_0.max_eax & 0xff;
  84. if (maxExtendedFunction >= 4) {
  85. int32 i;
  86. for (i = 0; i < 3; i++) {
  87. cpuid_info nameInfo;
  88. get_cpuid(&nameInfo, 0x80000002 + i, 0);
  89. memcpy(name, &nameInfo.regs.eax, 4);
  90. memcpy(name + 4, &nameInfo.regs.ebx, 4);
  91. memcpy(name + 8, &nameInfo.regs.ecx, 4);
  92. memcpy(name + 12, &nameInfo.regs.edx, 4);
  93. name += 16;
  94. }
  95. }
  96. }
  97. #endif /* __INTEL__ */
  98. const char *
  99. get_cpu_model_string(system_info *info)
  100. {
  101. #if __INTEL__
  102. char cpuidName[49];
  103. /* for use with get_cpuid_model_string() */
  104. #endif /* __INTEL__ */
  105. /* Determine CPU type */
  106. switch (info->cpu_type) {
  107. #if __POWERPC__
  108. case B_CPU_PPC_603:
  109. return "603";
  110. case B_CPU_PPC_603e:
  111. return "603e";
  112. case B_CPU_PPC_750:
  113. return "750";
  114. case B_CPU_PPC_604:
  115. return "604";
  116. case B_CPU_PPC_604e:
  117. return "604e";
  118. #endif /* __POWERPC__ */
  119. #if __INTEL__
  120. case B_CPU_x86:
  121. return "Unknown x86";
  122. /* Intel */
  123. case B_CPU_INTEL_PENTIUM:
  124. case B_CPU_INTEL_PENTIUM75:
  125. return "Pentium";
  126. case B_CPU_INTEL_PENTIUM_486_OVERDRIVE:
  127. case B_CPU_INTEL_PENTIUM75_486_OVERDRIVE:
  128. return "Pentium OD";
  129. case B_CPU_INTEL_PENTIUM_MMX:
  130. case B_CPU_INTEL_PENTIUM_MMX_MODEL_8:
  131. return "Pentium MMX";
  132. case B_CPU_INTEL_PENTIUM_PRO:
  133. return "Pentium Pro";
  134. case B_CPU_INTEL_PENTIUM_II_MODEL_3:
  135. case B_CPU_INTEL_PENTIUM_II_MODEL_5:
  136. return "Pentium II";
  137. case B_CPU_INTEL_CELERON:
  138. case B_CPU_INTEL_CELERON_MODEL_22:
  139. return "Celeron";
  140. case B_CPU_INTEL_PENTIUM_III:
  141. case B_CPU_INTEL_PENTIUM_III_MODEL_8:
  142. case B_CPU_INTEL_PENTIUM_III_MODEL_11:
  143. case B_CPU_INTEL_PENTIUM_III_XEON:
  144. return "Pentium III";
  145. case B_CPU_INTEL_PENTIUM_M:
  146. case B_CPU_INTEL_PENTIUM_M_MODEL_13:
  147. get_cpuid_model_string(cpuidName);
  148. if (strcasestr(cpuidName, "Celeron") != NULL)
  149. return "Pentium M Celeron";
  150. return "Pentium M";
  151. case B_CPU_INTEL_ATOM:
  152. return "Atom";
  153. case B_CPU_INTEL_PENTIUM_CORE:
  154. get_cpuid_model_string(cpuidName);
  155. if (strcasestr(cpuidName, "Celeron") != NULL)
  156. return "Core Celeron";
  157. return "Core";
  158. case B_CPU_INTEL_PENTIUM_CORE_2:
  159. get_cpuid_model_string(cpuidName);
  160. if (strcasestr(cpuidName, "Celeron") != NULL)
  161. return "Core 2 Celeron";
  162. if (strcasestr(cpuidName, "Xeon") != NULL)
  163. return "Core 2 Xeon";
  164. return "Core 2";
  165. case B_CPU_INTEL_PENTIUM_CORE_2_45_NM:
  166. get_cpuid_model_string(cpuidName);
  167. if (strcasestr(cpuidName, "Celeron") != NULL)
  168. return "Core 2 Celeron";
  169. if (strcasestr(cpuidName, "Duo") != NULL
  170. || strcasestr(cpuidName, "Quad") != NULL)
  171. return "Core 2";
  172. if (strcasestr(cpuidName, "Xeon") != NULL)
  173. return "Core 2 Xeon";
  174. return "Core 2 Extreme";
  175. case B_CPU_INTEL_PENTIUM_CORE_I7:
  176. case B_CPU_INTEL_PENTIUM_CORE_I7_Q720:
  177. get_cpuid_model_string(cpuidName);
  178. if (strcasestr(cpuidName, "Xeon") != NULL)
  179. return "Core i7 Xeon";
  180. return "Core i7";
  181. case B_CPU_INTEL_PENTIUM_IV:
  182. case B_CPU_INTEL_PENTIUM_IV_MODEL_1:
  183. case B_CPU_INTEL_PENTIUM_IV_MODEL_2:
  184. case B_CPU_INTEL_PENTIUM_IV_MODEL_3:
  185. case B_CPU_INTEL_PENTIUM_IV_MODEL_4:
  186. get_cpuid_model_string(cpuidName);
  187. if (strcasestr(cpuidName, "Celeron") != NULL)
  188. return "Pentium 4 Celeron";
  189. if (strcasestr(cpuidName, "Xeon") != NULL)
  190. return "Pentium 4 Xeon";
  191. return "Pentium 4";
  192. /* AMD */
  193. case B_CPU_AMD_K5_MODEL_0:
  194. case B_CPU_AMD_K5_MODEL_1:
  195. case B_CPU_AMD_K5_MODEL_2:
  196. case B_CPU_AMD_K5_MODEL_3:
  197. return "K5";
  198. case B_CPU_AMD_K6_MODEL_6:
  199. case B_CPU_AMD_K6_MODEL_7:
  200. return "K6";
  201. case B_CPU_AMD_K6_2:
  202. return "K6-2";
  203. case B_CPU_AMD_K6_III:
  204. case B_CPU_AMD_K6_III_MODEL_13:
  205. return "K6-III";
  206. case B_CPU_AMD_ATHLON_MODEL_1:
  207. case B_CPU_AMD_ATHLON_MODEL_2:
  208. case B_CPU_AMD_ATHLON_THUNDERBIRD:
  209. return "Athlon";
  210. case B_CPU_AMD_ATHLON_XP:
  211. case B_CPU_AMD_ATHLON_XP_MODEL_8:
  212. case B_CPU_AMD_ATHLON_XP_MODEL_10:
  213. return "Athlon XP";
  214. case B_CPU_AMD_DURON:
  215. case B_CPU_AMD_ATHLON_XP_MODEL_7:
  216. return "Duron";
  217. case B_CPU_AMD_ATHLON_64_MODEL_3:
  218. case B_CPU_AMD_ATHLON_64_MODEL_4:
  219. case B_CPU_AMD_ATHLON_64_MODEL_7:
  220. case B_CPU_AMD_ATHLON_64_MODEL_8:
  221. case B_CPU_AMD_ATHLON_64_MODEL_11:
  222. case B_CPU_AMD_ATHLON_64_MODEL_12:
  223. case B_CPU_AMD_ATHLON_64_MODEL_14:
  224. case B_CPU_AMD_ATHLON_64_MODEL_15:
  225. return "Athlon 64";
  226. case B_CPU_AMD_OPTERON:
  227. return "Opteron";
  228. case B_CPU_AMD_PHENOM:
  229. return "Phenom";
  230. case B_CPU_AMD_GEODE_LX:
  231. return "Geode LX";
  232. /* Transmeta */
  233. case B_CPU_TRANSMETA_CRUSOE:
  234. return "Crusoe";
  235. case B_CPU_TRANSMETA_EFFICEON:
  236. case B_CPU_TRANSMETA_EFFICEON_2:
  237. return "Efficeon";
  238. /* IDT/VIA */
  239. case B_CPU_IDT_WINCHIP_C6:
  240. return "WinChip C6";
  241. case B_CPU_IDT_WINCHIP_2:
  242. return "WinChip 2";
  243. case B_CPU_VIA_C3_SAMUEL:
  244. return "C3 Samuel";
  245. case B_CPU_VIA_C3_SAMUEL_2:
  246. /* stepping identified the model */
  247. if ((info->cpu_revision & 0xf) < 8)
  248. return "C3 Eden/Samuel 2";
  249. return "C3 Ezra";
  250. case B_CPU_VIA_C3_EZRA_T:
  251. return "C3 Ezra-T";
  252. case B_CPU_VIA_C3_NEHEMIAH:
  253. /* stepping identified the model */
  254. if ((info->cpu_revision & 0xf) < 8)
  255. return "C3 Nehemiah";
  256. return "C3 Eden-N";
  257. case B_CPU_VIA_C7_ESTHER:
  258. case B_CPU_VIA_C7_ESTHER_2:
  259. return "C7";
  260. case B_CPU_VIA_NANO_ISAIAH:
  261. return "Nano";
  262. /* Cyrix/VIA */
  263. case B_CPU_CYRIX_GXm:
  264. return "GXm";
  265. case B_CPU_CYRIX_6x86MX:
  266. return "6x86MX";
  267. /* Rise */
  268. case B_CPU_RISE_mP6:
  269. return "mP6";
  270. /* National Semiconductor */
  271. case B_CPU_NATIONAL_GEODE_GX1:
  272. return "Geode GX1";
  273. #endif /* __INTEL__ */
  274. default:
  275. return NULL;
  276. }
  277. }
  278. void
  279. get_cpu_type(char *vendorBuffer, size_t vendorSize, char *modelBuffer,
  280. size_t modelSize)
  281. {
  282. const char *vendor, *model;
  283. system_info info;
  284. get_system_info(&info);
  285. vendor = get_cpu_vendor_string(info.cpu_type);
  286. if (vendor == NULL)
  287. vendor = "Unknown";
  288. model = get_cpu_model_string(&info);
  289. if (model == NULL)
  290. model = "Unknown";
  291. #ifdef R5_COMPATIBLE
  292. strncpy(vendorBuffer, vendor, vendorSize - 1);
  293. vendorBuffer[vendorSize - 1] = '\0';
  294. strncpy(modelBuffer, model, modelSize - 1);
  295. modelBuffer[modelSize - 1] = '\0';
  296. #else
  297. strlcpy(vendorBuffer, vendor, vendorSize);
  298. strlcpy(modelBuffer, model, modelSize);
  299. #endif
  300. }
  301. int32
  302. get_rounded_cpu_speed(void)
  303. {
  304. system_info info;
  305. int target, frac, delta;
  306. int freqs[] = { 100, 50, 25, 75, 33, 67, 20, 40, 60, 80, 10, 30, 70, 90 };
  307. uint x;
  308. get_system_info(&info);
  309. target = info.cpu_clock_speed / 1000000;
  310. frac = target % 100;
  311. delta = -frac;
  312. for (x = 0; x < sizeof(freqs) / sizeof(freqs[0]); x++) {
  313. int ndelta = freqs[x] - frac;
  314. if (abs(ndelta) < abs(delta))
  315. delta = ndelta;
  316. }
  317. return target + delta;
  318. }