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 23static 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 37static 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 75int 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 { 97 return 0; 98 } 99} 100