cpu.c
上传用户:wstnjxml
上传日期:2014-04-03
资源大小:7248k
文件大小:6k
源码类别:

Windows CE

开发平台:

C/C++

  1. /*****************************************************************************
  2.  *
  3.  * This program is free software ; you can redistribute it and/or modify
  4.  * it under the terms of the GNU General Public License as published by
  5.  * the Free Software Foundation; either version 2 of the License, or
  6.  * (at your option) any later version.
  7.  *
  8.  * This program is distributed in the hope that it will be useful,
  9.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11.  * GNU General Public License for more details.
  12.  *
  13.  * You should have received a copy of the GNU General Public License
  14.  * along with this program; if not, write to the Free Software
  15.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  16.  *
  17.  * $Id: cpu.c 585 2006-01-16 09:48:55Z picard $
  18.  *
  19.  * The Core Pocket Media Player
  20.  * Copyright (c) 2004-2005 Gabor Kovacs
  21.  *
  22.  ****************************************************************************/
  23. #include "../common.h"
  24. #include "cpu.h"
  25. #ifdef ARM
  26. extern int STDCALL CheckARM5E();
  27. extern int STDCALL CheckARMXScale();
  28. #endif
  29. #ifndef SH3
  30. extern void STDCALL GetCpuId(int,uint32_t*);
  31. #if defined(TARGET_SYMBIAN) && !defined(ARM)
  32. #define GetCpuId(a,b)
  33. #endif
  34. static NOINLINE void SafeGetCpuId(int Id, uint32_t* p)
  35. {
  36. memset(p,0,4*sizeof(uint32_t));
  37. TRY_BEGIN
  38. {
  39. bool_t Mode = KernelMode(1);
  40. GetCpuId(Id,p); 
  41. KernelMode(Mode);
  42. }
  43. TRY_END
  44. }
  45. #endif
  46. int CPUCaps()
  47. {
  48. cpudetect p;
  49. CPUDetect(&p);
  50. return p.Caps;
  51. }
  52. void CPUDetect(cpudetect* p)
  53. {
  54. int Caps = 0;
  55. uint32_t CpuId[4];
  56. memset(p,0,sizeof(cpudetect));
  57. #ifdef ARM
  58. p->Arch = T("ARM");
  59. SafeGetCpuId(0,CpuId);
  60. if (CpuId[0])
  61. {
  62. p->ICache = 512 << ((CpuId[1] >> 6) & 7);
  63. p->DCache = 512 << ((CpuId[1] >> 18) & 7);
  64. }
  65. else
  66. {
  67. #if !defined(TARGET_PALMOS) && !defined(TARGET_SYMBIAN)
  68. // when need to detect cpu features somehow
  69. // (only works if we can catch cpu exceptions)
  70. TRY_BEGIN
  71. {
  72. if (CheckARM5E())
  73. {
  74. int XScale;
  75. Caps |= CAPS_ARM_5E;
  76. XScale = CheckARMXScale();
  77. if (XScale)
  78. {
  79. p->ICache = p->DCache = 32768;
  80. Caps |= CAPS_ARM_XSCALE;
  81. if (XScale > 1)
  82. Caps |= CAPS_ARM_WMMX;
  83. }
  84. }
  85. }
  86. TRY_END
  87. #endif
  88. }
  89. if ((CpuId[0] & 0xFF000000) == 0x54000000) //TI
  90. {
  91. p->Vendor = T("TI");
  92. Caps |= CAPS_ARM_GENERAL;
  93. switch ((CpuId[0] >> 4) & 0xFFF)
  94. {
  95. case 0x915: p->Model = T("915T"); break;
  96. case 0x925: p->Model = T("925T"); break;
  97. case 0x926: p->Model = T("926T"); Caps |= CAPS_ARM_5E; break;
  98. }
  99. }
  100. else
  101. if ((CpuId[0] & 0xFF000000) == 0x41000000) //arm
  102. {
  103. Caps |= CAPS_ARM_GENERAL;
  104. switch ((CpuId[0] >> 4) & 0xFFF)
  105. {
  106. case 0x920: p->Model = T("920T"); break;
  107. case 0x922: p->Model = T("922T"); break;
  108. case 0x926: p->Model = T("926E"); Caps |= CAPS_ARM_5E; break;
  109. case 0x940: p->Model = T("940T"); break;
  110. case 0x946: p->Model = T("946E"); Caps |= CAPS_ARM_5E; break;
  111. case 0xA22: p->Model = T("1020E"); Caps |= CAPS_ARM_5E; break;
  112. }
  113. }
  114. else
  115. if ((CpuId[0] & 0xFF000000) == 0x69000000) //intel
  116. {
  117. p->Vendor = T("Intel");
  118. if ((CpuId[0] & 0xFF0000) == 0x050000) //intel arm5e
  119. Caps |= CAPS_ARM_5E|CAPS_ARM_XSCALE;
  120. if (((CpuId[0] >> 4) & 0xFFF) == 0xB11)
  121. {
  122. p->Model = T("SA1110");
  123. }
  124. else
  125. {
  126. switch ((CpuId[0] >> 13) & 7)
  127. {
  128. case 0x2: Caps |= CAPS_ARM_WMMX; break;
  129. }
  130. switch ((CpuId[0] >> 4) & 31)
  131. {
  132. case 0x10: 
  133. p->Model = T("PXA25x/26x");
  134. break;
  135. case 0x11: 
  136. p->Model = T("PXA27x");
  137. break;
  138. case 0x12:
  139. p->Model = T("PXA210");
  140. break;
  141. }
  142. }
  143. }
  144. #elif defined(MIPS)
  145. SafeGetCpuId(0,CpuId);
  146. p->Arch = T("MIPS");
  147. if (((CpuId[0] >> 8) & 255) == 0x0c)
  148. {
  149. if ((CpuId[0] & 0xF0) == 0x50)
  150. {
  151. Caps |= CAPS_MIPS_VR4110;
  152. p->Model = T("VR411X");
  153. }
  154. else
  155. {
  156. Caps |= CAPS_MIPS_VR4120;
  157. if ((CpuId[0] & 0xF0) == 0x80)
  158. p->Model = T("VR413X");
  159. else
  160. p->Model = T("VR412X");
  161. }
  162. }
  163. #elif defined(SH3)
  164. CpuId[0] = 0; // avoid warning
  165. Caps = CpuId[0];
  166. p->Arch = T("SH3");
  167. #elif defined(_M_IX86)
  168. p->Arch = T("x86");
  169. SafeGetCpuId(0,CpuId);
  170.     if (CpuId[1] == 0x756e6547 &&
  171.         CpuId[3] == 0x49656e69 &&
  172.         CpuId[2] == 0x6c65746e) 
  173. {
  174. p->Vendor = T("Intel");
  175. Intel:
  176. SafeGetCpuId(1,CpuId);
  177.         if (CpuId[3] & 0x00800000)
  178. {
  179. Caps |= CAPS_X86_MMX;
  180. if (CpuId[3] & 0x02000000) 
  181. Caps |= CAPS_X86_MMX2 | CAPS_X86_SSE;
  182. if (CpuId[3] & 0x04000000) 
  183. Caps |= CAPS_X86_SSE2;
  184. }
  185.     } 
  186. else if (CpuId[1] == 0x68747541 &&
  187.              CpuId[3] == 0x69746e65 &&
  188.              CpuId[2] == 0x444d4163) 
  189. {
  190. p->Vendor = T("AMD");
  191. SafeGetCpuId(0x80000000,CpuId);
  192.         if (CpuId[0] < 0x80000001)
  193.             goto Intel;
  194. SafeGetCpuId(0x80000001,CpuId);
  195.         if (CpuId[3] & 0x00800000)
  196. {
  197. Caps |= CAPS_X86_MMX;
  198. if (CpuId[3] & 0x80000000)
  199. Caps |= CAPS_X86_3DNOW;
  200. if (CpuId[3] & 0x00400000)
  201. Caps |= CAPS_X86_MMX2;
  202. }
  203.     } 
  204. else if (CpuId[1] == 0x746e6543 &&
  205.              CpuId[3] == 0x48727561 &&
  206.              CpuId[2] == 0x736c7561) 
  207. {
  208. p->Vendor = T("VIA C3");
  209. SafeGetCpuId(0x80000000,CpuId);
  210.         if (CpuId[0] < 0x80000001)
  211.             goto Intel;
  212. SafeGetCpuId(0x80000001,CpuId);
  213. if (CpuId[3] & (1<<31))
  214. Caps |= CAPS_X86_3DNOW;
  215. if (CpuId[3] & (1<<23))
  216. Caps |= CAPS_X86_MMX;
  217. if (CpuId[3] & (1<<24))
  218. Caps |= CAPS_X86_MMX2;
  219. }
  220. else if (CpuId[1] == 0x69727943 &&
  221.              CpuId[3] == 0x736e4978 &&
  222.              CpuId[2] == 0x64616574) 
  223. {
  224. p->Vendor = T("Cyrix");
  225.         if (CpuId[0] != 2) 
  226.             goto Intel;
  227. SafeGetCpuId(0x80000001,CpuId);
  228.         if (CpuId[3] & 0x00800000)
  229. {
  230. Caps |= CAPS_X86_MMX;
  231. if (CpuId[3] & 0x01000000)
  232. Caps |= CAPS_X86_MMX2;
  233. }
  234.     }
  235. #endif
  236. p->Caps = Caps;
  237. }