| H. Peter Anvin | 31b54f4 | 2007-07-11 12:18:47 -0700 | [diff] [blame] | 1 | /* -*- linux-c -*- ------------------------------------------------------- * | 
 | 2 |  * | 
 | 3 |  *   Copyright (C) 1991, 1992 Linus Torvalds | 
| H. Peter Anvin | f0be6c6 | 2008-02-04 16:48:00 +0100 | [diff] [blame] | 4 |  *   Copyright 2007-2008 rPath, Inc. - All Rights Reserved | 
| H. Peter Anvin | 31b54f4 | 2007-07-11 12:18:47 -0700 | [diff] [blame] | 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 | /* | 
| H. Peter Anvin | f0be6c6 | 2008-02-04 16:48:00 +0100 | [diff] [blame] | 12 |  * arch/x86/boot/cpu.c | 
| H. Peter Anvin | 31b54f4 | 2007-07-11 12:18:47 -0700 | [diff] [blame] | 13 |  * | 
 | 14 |  * Check for obligatory CPU features and abort if the features are not | 
 | 15 |  * present. | 
 | 16 |  */ | 
 | 17 |  | 
 | 18 | #include "boot.h" | 
| H. Peter Anvin | f0be6c6 | 2008-02-04 16:48:00 +0100 | [diff] [blame] | 19 | #include "cpustr.h" | 
 | 20 |  | 
| H. Peter Anvin | 31b54f4 | 2007-07-11 12:18:47 -0700 | [diff] [blame] | 21 | static char *cpu_name(int level) | 
 | 22 | { | 
 | 23 | 	static char buf[6]; | 
 | 24 |  | 
 | 25 | 	if (level == 64) { | 
 | 26 | 		return "x86-64"; | 
 | 27 | 	} else { | 
| Dave Jones | c7d624d | 2008-05-28 12:57:13 -0400 | [diff] [blame] | 28 | 		if (level == 15) | 
 | 29 | 			level = 6; | 
| H. Peter Anvin | 31b54f4 | 2007-07-11 12:18:47 -0700 | [diff] [blame] | 30 | 		sprintf(buf, "i%d86", level); | 
 | 31 | 		return buf; | 
 | 32 | 	} | 
 | 33 | } | 
 | 34 |  | 
 | 35 | int validate_cpu(void) | 
 | 36 | { | 
 | 37 | 	u32 *err_flags; | 
 | 38 | 	int cpu_level, req_level; | 
| H. Peter Anvin | f0be6c6 | 2008-02-04 16:48:00 +0100 | [diff] [blame] | 39 | 	const unsigned char *msg_strs; | 
| H. Peter Anvin | 31b54f4 | 2007-07-11 12:18:47 -0700 | [diff] [blame] | 40 |  | 
 | 41 | 	check_cpu(&cpu_level, &req_level, &err_flags); | 
 | 42 |  | 
 | 43 | 	if (cpu_level < req_level) { | 
 | 44 | 		printf("This kernel requires an %s CPU, ", | 
 | 45 | 		       cpu_name(req_level)); | 
 | 46 | 		printf("but only detected an %s CPU.\n", | 
 | 47 | 		       cpu_name(cpu_level)); | 
 | 48 | 		return -1; | 
 | 49 | 	} | 
 | 50 |  | 
 | 51 | 	if (err_flags) { | 
 | 52 | 		int i, j; | 
 | 53 | 		puts("This kernel requires the following features " | 
 | 54 | 		     "not present on the CPU:\n"); | 
 | 55 |  | 
| H. Peter Anvin | f0be6c6 | 2008-02-04 16:48:00 +0100 | [diff] [blame] | 56 | 		msg_strs = (const unsigned char *)x86_cap_strs; | 
 | 57 |  | 
| H. Peter Anvin | 31b54f4 | 2007-07-11 12:18:47 -0700 | [diff] [blame] | 58 | 		for (i = 0; i < NCAPINTS; i++) { | 
 | 59 | 			u32 e = err_flags[i]; | 
 | 60 |  | 
 | 61 | 			for (j = 0; j < 32; j++) { | 
| H. Peter Anvin | 97fc055 | 2008-09-16 15:09:26 -0700 | [diff] [blame] | 62 | 				if (msg_strs[0] < i || | 
 | 63 | 				    (msg_strs[0] == i && msg_strs[1] < j)) { | 
| H. Peter Anvin | f0be6c6 | 2008-02-04 16:48:00 +0100 | [diff] [blame] | 64 | 					/* Skip to the next string */ | 
| H. Peter Anvin | 97fc055 | 2008-09-16 15:09:26 -0700 | [diff] [blame] | 65 | 					msg_strs += 2; | 
 | 66 | 					while (*msg_strs++) | 
 | 67 | 						; | 
| H. Peter Anvin | f0be6c6 | 2008-02-04 16:48:00 +0100 | [diff] [blame] | 68 | 				} | 
 | 69 | 				if (e & 1) { | 
| H. Peter Anvin | 97fc055 | 2008-09-16 15:09:26 -0700 | [diff] [blame] | 70 | 					if (msg_strs[0] == i && | 
 | 71 | 					    msg_strs[1] == j && | 
 | 72 | 					    msg_strs[2]) | 
 | 73 | 						printf("%s ", msg_strs+2); | 
| H. Peter Anvin | f0be6c6 | 2008-02-04 16:48:00 +0100 | [diff] [blame] | 74 | 					else | 
 | 75 | 						printf("%d:%d ", i, j); | 
 | 76 | 				} | 
| H. Peter Anvin | 31b54f4 | 2007-07-11 12:18:47 -0700 | [diff] [blame] | 77 | 				e >>= 1; | 
 | 78 | 			} | 
 | 79 | 		} | 
 | 80 | 		putchar('\n'); | 
 | 81 | 		return -1; | 
 | 82 | 	} else { | 
 | 83 | 		return 0; | 
 | 84 | 	} | 
 | 85 | } |