summaryrefslogtreecommitdiffstats
path: root/arch/i386/boot/cpu.c
diff options
context:
space:
mode:
authorH. Peter Anvin2007-07-11 21:18:47 +0200
committerLinus Torvalds2007-07-12 19:55:55 +0200
commit31b54f40e12e4d04941762be6615edaf3c6ed811 (patch)
tree137c160c216f35a589b4c2fabe255a14a1343d91 /arch/i386/boot/cpu.c
parentVersion string for the new x86 setup code (diff)
downloadkernel-qcow2-linux-31b54f40e12e4d04941762be6615edaf3c6ed811.tar.gz
kernel-qcow2-linux-31b54f40e12e4d04941762be6615edaf3c6ed811.tar.xz
kernel-qcow2-linux-31b54f40e12e4d04941762be6615edaf3c6ed811.zip
CPU features verification for the new x86 setup code
Verify that the CPU has enough features to run the kernel. This may entail enabling features on some CPUs. By doing this in the setup code we can be guaranteed to still be able to write to the console through the BIOS. Signed-off-by: H. Peter Anvin <hpa@zytor.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/i386/boot/cpu.c')
-rw-r--r--arch/i386/boot/cpu.c69
1 files changed, 69 insertions, 0 deletions
diff --git a/arch/i386/boot/cpu.c b/arch/i386/boot/cpu.c
new file mode 100644
index 000000000000..2a5c32da5852
--- /dev/null
+++ b/arch/i386/boot/cpu.c
@@ -0,0 +1,69 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ * Copyright 2007 rPath, Inc. - All Rights Reserved
+ *
+ * This file is part of the Linux kernel, and is made available under
+ * the terms of the GNU General Public License version 2.
+ *
+ * ----------------------------------------------------------------------- */
+
+/*
+ * arch/i386/boot/cpu.c
+ *
+ * Check for obligatory CPU features and abort if the features are not
+ * present.
+ */
+
+#include "boot.h"
+#include "bitops.h"
+#include <asm/cpufeature.h>
+
+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;
+
+ 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");
+
+ for (i = 0; i < NCAPINTS; i++) {
+ u32 e = err_flags[i];
+
+ for (j = 0; j < 32; j++) {
+ if (e & 1)
+ printf("%d:%d ", i, j);
+
+ e >>= 1;
+ }
+ }
+ putchar('\n');
+ return -1;
+ } else {
+ return 0;
+ }
+}