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