cpu.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. /* -*- linux-c -*- ------------------------------------------------------- *
  2. *
  3. * Copyright (C) 1991, 1992 Linus Torvalds
  4. * Copyright 2007-2008 rPath, Inc. - All Rights Reserved
  5. *
  6. * This file is part of the Linux kernel, and is made available under
  7. * the terms of the GNU General Public License version 2.
  8. *
  9. * ----------------------------------------------------------------------- */
  10. /*
  11. * arch/x86/boot/cpu.c
  12. *
  13. * Check for obligatory CPU features and abort if the features are not
  14. * present.
  15. */
  16. #include "boot.h"
  17. #ifdef CONFIG_X86_FEATURE_NAMES
  18. #include "cpustr.h"
  19. #endif
  20. static char *cpu_name(int level)
  21. {
  22. static char buf[6];
  23. if (level == 64) {
  24. return "x86-64";
  25. } else {
  26. if (level == 15)
  27. level = 6;
  28. sprintf(buf, "i%d86", level);
  29. return buf;
  30. }
  31. }
  32. static void show_cap_strs(u32 *err_flags)
  33. {
  34. int i, j;
  35. #ifdef CONFIG_X86_FEATURE_NAMES
  36. const unsigned char *msg_strs = (const unsigned char *)x86_cap_strs;
  37. for (i = 0; i < NCAPINTS; i++) {
  38. u32 e = err_flags[i];
  39. for (j = 0; j < 32; j++) {
  40. if (msg_strs[0] < i ||
  41. (msg_strs[0] == i && msg_strs[1] < j)) {
  42. /* Skip to the next string */
  43. msg_strs += 2;
  44. while (*msg_strs++)
  45. ;
  46. }
  47. if (e & 1) {
  48. if (msg_strs[0] == i &&
  49. msg_strs[1] == j &&
  50. msg_strs[2])
  51. printf("%s ", msg_strs+2);
  52. else
  53. printf("%d:%d ", i, j);
  54. }
  55. e >>= 1;
  56. }
  57. }
  58. #else
  59. for (i = 0; i < NCAPINTS; i++) {
  60. u32 e = err_flags[i];
  61. for (j = 0; j < 32; j++) {
  62. if (e & 1)
  63. printf("%d:%d ", i, j);
  64. e >>= 1;
  65. }
  66. }
  67. #endif
  68. }
  69. int validate_cpu(void)
  70. {
  71. u32 *err_flags;
  72. int cpu_level, req_level;
  73. check_cpu(&cpu_level, &req_level, &err_flags);
  74. if (cpu_level < req_level) {
  75. printf("This kernel requires an %s CPU, ",
  76. cpu_name(req_level));
  77. printf("but only detected an %s CPU.\n",
  78. cpu_name(cpu_level));
  79. return -1;
  80. }
  81. if (err_flags) {
  82. puts("This kernel requires the following features "
  83. "not present on the CPU:\n");
  84. show_cap_strs(err_flags);
  85. putchar('\n');
  86. return -1;
  87. } else {
  88. return 0;
  89. }
  90. }