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.

cpu.c 2.0KB

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