選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

cpu.c 2.0KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. #ifdef CONFIG_X86_64
  2. #include "stdint.h"
  3. #include "string.h"
  4. #include "bits/cpu.h"
  5. /* Standard macro to see if a specific flag is changeable */
  6. static inline int flag_is_changeable_p(uint32_t flag)
  7. {
  8. uint32_t f1, f2;
  9. asm("pushfl\n\t"
  10. "pushfl\n\t"
  11. "popl %0\n\t"
  12. "movl %0,%1\n\t"
  13. "xorl %2,%0\n\t"
  14. "pushl %0\n\t"
  15. "popfl\n\t"
  16. "pushfl\n\t"
  17. "popl %0\n\t"
  18. "popfl\n\t"
  19. : "=&r" (f1), "=&r" (f2)
  20. : "ir" (flag));
  21. return ((f1^f2) & flag) != 0;
  22. }
  23. /* Probe for the CPUID instruction */
  24. static inline int have_cpuid_p(void)
  25. {
  26. return flag_is_changeable_p(X86_EFLAGS_ID);
  27. }
  28. static void identify_cpu(struct cpuinfo_x86 *c)
  29. {
  30. unsigned xlvl;
  31. c->cpuid_level = -1; /* CPUID not detected */
  32. c->x86_model = c->x86_mask = 0; /* So far unknown... */
  33. c->x86_vendor_id[0] = '\0'; /* Unset */
  34. memset(&c->x86_capability, 0, sizeof c->x86_capability);
  35. if (!have_cpuid_p()) {
  36. /* CPU doesn'thave CPUID */
  37. /* If there are any capabilities, they'r vendor-specific */
  38. /* enable_cpuid() would have set c->x86 for us. */
  39. }
  40. else {
  41. /* CPU does have CPUID */
  42. /* Get vendor name */
  43. cpuid(0x00000000, &c->cpuid_level,
  44. (int *)&c->x86_vendor_id[0],
  45. (int *)&c->x86_vendor_id[8],
  46. (int *)&c->x86_vendor_id[4]);
  47. /* Initialize the standard set of capabilities */
  48. /* Note that the vendor-specific code below might override */
  49. /* Intel-defined flags: level 0x00000001 */
  50. if ( c->cpuid_level >= 0x00000001 ) {
  51. unsigned tfms, junk;
  52. cpuid(0x00000001, &tfms, &junk, &junk,
  53. &c->x86_capability[0]);
  54. c->x86 = (tfms >> 8) & 15;
  55. c->x86_model = (tfms >> 4) & 15;
  56. c->x86_mask = tfms & 15;
  57. }
  58. /* AMD-defined flags: level 0x80000001 */
  59. xlvl = cpuid_eax(0x80000000);
  60. if ( (xlvl & 0xffff0000) == 0x80000000 ) {
  61. if ( xlvl >= 0x80000001 )
  62. c->x86_capability[1] = cpuid_edx(0x80000001);
  63. }
  64. }
  65. }
  66. struct cpuinfo_x86 cpu_info;
  67. void cpu_setup(void)
  68. {
  69. identify_cpu(&cpu_info);
  70. }
  71. #endif /* CONFIG_X86_64 */