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