| 
									
										
										
										
											2007-07-11 12:18:47 -07:00
										 |  |  | /* -*- linux-c -*- ------------------------------------------------------- *
 | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *   Copyright (C) 1991, 1992 Linus Torvalds | 
					
						
							| 
									
										
										
										
											2008-02-04 16:48:00 +01:00
										 |  |  |  *   Copyright 2007-2008 rPath, Inc. - All Rights Reserved | 
					
						
							| 
									
										
										
										
											2007-07-11 12:18:47 -07:00
										 |  |  |  * | 
					
						
							|  |  |  |  *   This file is part of the Linux kernel, and is made available under | 
					
						
							|  |  |  |  *   the terms of the GNU General Public License version 2. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ----------------------------------------------------------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2008-02-04 16:48:00 +01:00
										 |  |  |  * arch/x86/boot/cpu.c | 
					
						
							| 
									
										
										
										
											2007-07-11 12:18:47 -07:00
										 |  |  |  * | 
					
						
							|  |  |  |  * Check for obligatory CPU features and abort if the features are not | 
					
						
							|  |  |  |  * present. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "boot.h"
 | 
					
						
							|  |  |  | #include "bitops.h"
 | 
					
						
							|  |  |  | #include <asm/cpufeature.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 16:48:00 +01:00
										 |  |  | #include "cpustr.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-07-11 12:18:47 -07:00
										 |  |  | static char *cpu_name(int level) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	static char buf[6]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (level == 64) { | 
					
						
							|  |  |  | 		return "x86-64"; | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		sprintf(buf, "i%d86", level); | 
					
						
							|  |  |  | 		return buf; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int validate_cpu(void) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	u32 *err_flags; | 
					
						
							|  |  |  | 	int cpu_level, req_level; | 
					
						
							| 
									
										
										
										
											2008-02-04 16:48:00 +01:00
										 |  |  | 	const unsigned char *msg_strs; | 
					
						
							| 
									
										
										
										
											2007-07-11 12:18:47 -07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	check_cpu(&cpu_level, &req_level, &err_flags); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (cpu_level < req_level) { | 
					
						
							|  |  |  | 		printf("This kernel requires an %s CPU, ", | 
					
						
							|  |  |  | 		       cpu_name(req_level)); | 
					
						
							|  |  |  | 		printf("but only detected an %s CPU.\n", | 
					
						
							|  |  |  | 		       cpu_name(cpu_level)); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (err_flags) { | 
					
						
							|  |  |  | 		int i, j; | 
					
						
							|  |  |  | 		puts("This kernel requires the following features " | 
					
						
							|  |  |  | 		     "not present on the CPU:\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-02-04 16:48:00 +01:00
										 |  |  | 		msg_strs = (const unsigned char *)x86_cap_strs; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-07-11 12:18:47 -07:00
										 |  |  | 		for (i = 0; i < NCAPINTS; i++) { | 
					
						
							|  |  |  | 			u32 e = err_flags[i]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			for (j = 0; j < 32; j++) { | 
					
						
							| 
									
										
										
										
											2008-02-04 16:48:00 +01:00
										 |  |  | 				int n = (i << 5)+j; | 
					
						
							|  |  |  | 				if (*msg_strs < n) { | 
					
						
							|  |  |  | 					/* Skip to the next string */ | 
					
						
							|  |  |  | 					do { | 
					
						
							|  |  |  | 						msg_strs++; | 
					
						
							|  |  |  | 					} while (*msg_strs); | 
					
						
							|  |  |  | 					msg_strs++; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				if (e & 1) { | 
					
						
							|  |  |  | 					if (*msg_strs == n && msg_strs[1]) | 
					
						
							|  |  |  | 						printf("%s ", msg_strs+1); | 
					
						
							|  |  |  | 					else | 
					
						
							|  |  |  | 						printf("%d:%d ", i, j); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2007-07-11 12:18:47 -07:00
										 |  |  | 				e >>= 1; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		putchar('\n'); | 
					
						
							|  |  |  | 		return -1; | 
					
						
							|  |  |  | 	} else { | 
					
						
							|  |  |  | 		return 0; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } |