mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-18 17:54:13 +08:00
9def39be4e
The table mapping CPUID bits to human-readable strings takes up a non-trivial amount of space, and only exists to support /proc/cpuinfo and a couple of kernel messages. Since programs depend on the format of /proc/cpuinfo, force inclusion of the table when building with /proc support; otherwise, support omitting that table to save space, in which case the kernel messages will print features numerically instead. In addition to saving 1408 bytes out of vmlinux, this also saves 1373 bytes out of the uncompressed setup code, which contributes directly to the size of bzImage. Signed-off-by: Josh Triplett <josh@joshtriplett.org>
100 lines
2.0 KiB
C
100 lines
2.0 KiB
C
/* -*- linux-c -*- ------------------------------------------------------- *
|
|
*
|
|
* Copyright (C) 1991, 1992 Linus Torvalds
|
|
* Copyright 2007-2008 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/x86/boot/cpu.c
|
|
*
|
|
* Check for obligatory CPU features and abort if the features are not
|
|
* present.
|
|
*/
|
|
|
|
#include "boot.h"
|
|
#ifdef CONFIG_X86_FEATURE_NAMES
|
|
#include "cpustr.h"
|
|
#endif
|
|
|
|
static char *cpu_name(int level)
|
|
{
|
|
static char buf[6];
|
|
|
|
if (level == 64) {
|
|
return "x86-64";
|
|
} else {
|
|
if (level == 15)
|
|
level = 6;
|
|
sprintf(buf, "i%d86", level);
|
|
return buf;
|
|
}
|
|
}
|
|
|
|
static void show_cap_strs(u32 *err_flags)
|
|
{
|
|
int i, j;
|
|
#ifdef CONFIG_X86_FEATURE_NAMES
|
|
const unsigned char *msg_strs = (const unsigned char *)x86_cap_strs;
|
|
for (i = 0; i < NCAPINTS; i++) {
|
|
u32 e = err_flags[i];
|
|
for (j = 0; j < 32; j++) {
|
|
if (msg_strs[0] < i ||
|
|
(msg_strs[0] == i && msg_strs[1] < j)) {
|
|
/* Skip to the next string */
|
|
msg_strs += 2;
|
|
while (*msg_strs++)
|
|
;
|
|
}
|
|
if (e & 1) {
|
|
if (msg_strs[0] == i &&
|
|
msg_strs[1] == j &&
|
|
msg_strs[2])
|
|
printf("%s ", msg_strs+2);
|
|
else
|
|
printf("%d:%d ", i, j);
|
|
}
|
|
e >>= 1;
|
|
}
|
|
}
|
|
#else
|
|
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;
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
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) {
|
|
puts("This kernel requires the following features "
|
|
"not present on the CPU:\n");
|
|
show_cap_strs(err_flags);
|
|
putchar('\n');
|
|
return -1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|