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 /* 12 * arch/x86/boot/cpu.c 13 * 14 * Check for obligatory CPU features and abort if the features are not 15 * present. 16 */ 17 18 #include "boot.h" 19 #ifdef CONFIG_X86_FEATURE_NAMES 20 #include "cpustr.h" 21 #endif 22 23 static char *cpu_name(int level) 24 { 25 static char buf[6]; 26 27 if (level == 64) { 28 return "x86-64"; 29 } else { 30 if (level == 15) 31 level = 6; 32 sprintf(buf, "i%d86", level); 33 return buf; 34 } 35 } 36 37 static void show_cap_strs(u32 *err_flags) 38 { 39 int i, j; 40 #ifdef CONFIG_X86_FEATURE_NAMES 41 const unsigned char *msg_strs = (const unsigned char *)x86_cap_strs; 42 for (i = 0; i < NCAPINTS; i++) { 43 u32 e = err_flags[i]; 44 for (j = 0; j < 32; j++) { 45 if (msg_strs[0] < i || 46 (msg_strs[0] == i && msg_strs[1] < j)) { 47 /* Skip to the next string */ 48 msg_strs += 2; 49 while (*msg_strs++) 50 ; 51 } 52 if (e & 1) { 53 if (msg_strs[0] == i && 54 msg_strs[1] == j && 55 msg_strs[2]) 56 printf("%s ", msg_strs+2); 57 else 58 printf("%d:%d ", i, j); 59 } 60 e >>= 1; 61 } 62 } 63 #else 64 for (i = 0; i < NCAPINTS; i++) { 65 u32 e = err_flags[i]; 66 for (j = 0; j < 32; j++) { 67 if (e & 1) 68 printf("%d:%d ", i, j); 69 e >>= 1; 70 } 71 } 72 #endif 73 } 74 75 int validate_cpu(void) 76 { 77 u32 *err_flags; 78 int cpu_level, req_level; 79 80 check_cpu(&cpu_level, &req_level, &err_flags); 81 82 if (cpu_level < req_level) { 83 printf("This kernel requires an %s CPU, ", 84 cpu_name(req_level)); 85 printf("but only detected an %s CPU.\n", 86 cpu_name(cpu_level)); 87 return -1; 88 } 89 90 if (err_flags) { 91 puts("This kernel requires the following features " 92 "not present on the CPU:\n"); 93 show_cap_strs(err_flags); 94 putchar('\n'); 95 return -1; 96 } else if (check_knl_erratum()) { 97 return -1; 98 } else { 99 return 0; 100 } 101 } 102