linux/arch/x86/boot/cpu.c
<<
>>
Prefs
   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#ifdef CONFIG_X86_FEATURE_NAMES
  18#include "cpustr.h"
  19#endif
  20
  21static char *cpu_name(int level)
  22{
  23        static char buf[6];
  24
  25        if (level == 64) {
  26                return "x86-64";
  27        } else {
  28                if (level == 15)
  29                        level = 6;
  30                sprintf(buf, "i%d86", level);
  31                return buf;
  32        }
  33}
  34
  35static void show_cap_strs(u32 *err_flags)
  36{
  37        int i, j;
  38#ifdef CONFIG_X86_FEATURE_NAMES
  39        const unsigned char *msg_strs = (const unsigned char *)x86_cap_strs;
  40        for (i = 0; i < NCAPINTS; i++) {
  41                u32 e = err_flags[i];
  42                for (j = 0; j < 32; j++) {
  43                        if (msg_strs[0] < i ||
  44                            (msg_strs[0] == i && msg_strs[1] < j)) {
  45                                /* Skip to the next string */
  46                                msg_strs += 2;
  47                                while (*msg_strs++)
  48                                        ;
  49                        }
  50                        if (e & 1) {
  51                                if (msg_strs[0] == i &&
  52                                    msg_strs[1] == j &&
  53                                    msg_strs[2])
  54                                        printf("%s ", msg_strs+2);
  55                                else
  56                                        printf("%d:%d ", i, j);
  57                        }
  58                        e >>= 1;
  59                }
  60        }
  61#else
  62        for (i = 0; i < NCAPINTS; i++) {
  63                u32 e = err_flags[i];
  64                for (j = 0; j < 32; j++) {
  65                        if (e & 1)
  66                                printf("%d:%d ", i, j);
  67                        e >>= 1;
  68                }
  69        }
  70#endif
  71}
  72
  73int validate_cpu(void)
  74{
  75        u32 *err_flags;
  76        int cpu_level, req_level;
  77
  78        check_cpu(&cpu_level, &req_level, &err_flags);
  79
  80        if (cpu_level < req_level) {
  81                printf("This kernel requires an %s CPU, ",
  82                       cpu_name(req_level));
  83                printf("but only detected an %s CPU.\n",
  84                       cpu_name(cpu_level));
  85                return -1;
  86        }
  87
  88        if (err_flags) {
  89                puts("This kernel requires the following features "
  90                     "not present on the CPU:\n");
  91                show_cap_strs(err_flags);
  92                putchar('\n');
  93                return -1;
  94        } else if (check_knl_erratum()) {
  95                return -1;
  96        } else {
  97                return 0;
  98        }
  99}
 100