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