a73b93157f
It encourages users from writing to the FSF without giving an address. Linux also prefers to drop that and their checkpatch.pl (that we imported) looks out for that. This is the result of util/scripts/no-fsf-addresses.sh with no further editing. Change-Id: Ie96faea295fe001911d77dbc51e9a6789558fbd6 Signed-off-by: Patrick Georgi <pgeorgi@chromium.org> Reviewed-on: http://review.coreboot.org/11888 Tested-by: build bot (Jenkins) Reviewed-by: Alexandru Gagniuc <mr.nuke.me@gmail.com> Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
275 lines
6.7 KiB
C
275 lines
6.7 KiB
C
/*
|
|
* This file is part of the coreinfo project.
|
|
*
|
|
* It is derived from the x86info project, which is GPLv2-licensed.
|
|
*
|
|
* Copyright (C) 2001-2007 Dave Jones <davej@codemonkey.org.uk>
|
|
* Copyright (C) 2008 Advanced Micro Devices, Inc.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; version 2 of the License.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*/
|
|
|
|
#include "coreinfo.h"
|
|
|
|
#if IS_ENABLED(CONFIG_MODULE_CPUINFO)
|
|
#include <arch/rdtsc.h>
|
|
|
|
#define VENDOR_INTEL 0x756e6547
|
|
#define VENDOR_AMD 0x68747541
|
|
#define VENDOR_CYRIX 0x69727943
|
|
#define VENDOR_IDT 0x746e6543
|
|
#define VENDOR_GEODE 0x646f6547
|
|
#define VENDOR_RISE 0x52697365
|
|
#define VENDOR_RISE2 0x65736952
|
|
#define VENDOR_SIS 0x20536953
|
|
|
|
/* CPUID 0x00000001 EDX flags */
|
|
static const char *generic_cap_flags[] = {
|
|
"fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
|
|
"cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
|
|
"pat", "pse36", "psn", "clflsh", NULL, "ds", "acpi", "mmx",
|
|
"fxsr", "sse", "sse2", "ss", "ht", "tm", NULL, "pbe"
|
|
};
|
|
|
|
/* CPUID 0x00000001 ECX flags */
|
|
static const char *intel_cap_generic_ecx_flags[] = {
|
|
"sse3", NULL, NULL, "monitor", "ds-cpl", "vmx", NULL, "est",
|
|
"tm2", "ssse3", "cntx-id", NULL, NULL, "cx16", "xTPR", NULL,
|
|
NULL, NULL, "dca", NULL, NULL, NULL, NULL, NULL,
|
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
|
|
};
|
|
|
|
/* CPUID 0x80000001 EDX flags */
|
|
static const char *intel_cap_extended_edx_flags[] = {
|
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
NULL, NULL, NULL, "SYSCALL", NULL, NULL, NULL, NULL,
|
|
NULL, NULL, NULL, NULL, "xd", NULL, NULL, NULL,
|
|
NULL, NULL, NULL, NULL, NULL, "em64t", NULL, NULL,
|
|
};
|
|
|
|
/* CPUID 0x80000001 ECX flags */
|
|
static const char *intel_cap_extended_ecx_flags[] = {
|
|
"lahf_lm", NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
};
|
|
|
|
static const char *amd_cap_generic_ecx_flags[] = {
|
|
"sse3", NULL, NULL, "mwait", NULL, NULL, NULL, NULL,
|
|
NULL, NULL, NULL, NULL, NULL, "cmpxchg16b", NULL, NULL,
|
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, "popcnt",
|
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
|
|
};
|
|
|
|
static const char *amd_cap_extended_edx_flags[] = {
|
|
"fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce",
|
|
"cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov",
|
|
"pat", "pse36", NULL, "mp", "nx", NULL, "mmxext", "mmx",
|
|
"fxsr", "ffxsr", "page1gb", "rdtscp",
|
|
NULL, "lm", "3dnowext", "3dnow"
|
|
}; /* "mp" defined for CPUs prior to AMD family 0xf */
|
|
|
|
static const char *amd_cap_extended_ecx_flags[] = {
|
|
"lahf/sahf", "CmpLegacy", "svm", "ExtApicSpace",
|
|
"LockMovCr0", "abm", "sse4a", "misalignsse",
|
|
"3dnowPref", "osvw", "ibs", NULL, "skinit", "wdt", NULL, NULL,
|
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
|
|
};
|
|
|
|
static unsigned long vendor;
|
|
static unsigned int cpu_khz;
|
|
|
|
static void decode_flags(WINDOW *win, unsigned long reg, const char **flags,
|
|
int *row)
|
|
{
|
|
int i;
|
|
int lrow = *row;
|
|
|
|
wmove(win, lrow, 2);
|
|
|
|
for (i = 0; i < 32; i++) {
|
|
if (flags[i] == NULL)
|
|
continue;
|
|
|
|
if (reg & (1 << i))
|
|
wprintw(win, "%s ", flags[i]);
|
|
|
|
if (i && (i % 16) == 0) {
|
|
lrow++;
|
|
wmove(win, lrow, 2);
|
|
}
|
|
}
|
|
|
|
*row = lrow;
|
|
}
|
|
|
|
static void get_features(WINDOW *win, int *row)
|
|
{
|
|
unsigned long eax, ebx, ecx, edx;
|
|
int lrow = *row;
|
|
|
|
wmove(win, lrow++, 1);
|
|
wprintw(win, "Features: ");
|
|
|
|
docpuid(0x00000001, &eax, &ebx, &ecx, &edx);
|
|
decode_flags(win, edx, generic_cap_flags, &lrow);
|
|
|
|
lrow++;
|
|
|
|
switch (vendor) {
|
|
case VENDOR_AMD:
|
|
wmove(win, lrow++, 1);
|
|
wprintw(win, "AMD Extended Flags: ");
|
|
decode_flags(win, ecx, amd_cap_generic_ecx_flags, &lrow);
|
|
docpuid(0x80000001, &eax, &ebx, &ecx, &edx);
|
|
decode_flags(win, edx, amd_cap_extended_edx_flags, &lrow);
|
|
decode_flags(win, ecx, amd_cap_extended_ecx_flags, &lrow);
|
|
break;
|
|
case VENDOR_INTEL:
|
|
wmove(win, lrow++, 1);
|
|
wprintw(win, "Intel Extended Flags: ");
|
|
decode_flags(win, ecx, intel_cap_generic_ecx_flags, &lrow);
|
|
docpuid(0x80000001, &eax, &ebx, &ecx, &edx);
|
|
decode_flags(win, edx, intel_cap_extended_edx_flags, &lrow);
|
|
decode_flags(win, ecx, intel_cap_extended_ecx_flags, &lrow);
|
|
break;
|
|
}
|
|
|
|
*row = lrow;
|
|
}
|
|
|
|
static void do_name(WINDOW *win, int row)
|
|
{
|
|
char name[49], *p;
|
|
unsigned long eax, ebx, ecx, edx;
|
|
int i, t;
|
|
|
|
p = name;
|
|
|
|
for (i = 0x80000002; i <= 0x80000004; i++) {
|
|
docpuid(i, &eax, &ebx, &ecx, &edx);
|
|
|
|
if (eax == 0)
|
|
break;
|
|
|
|
for (t = 0; t < 4; t++)
|
|
*p++ = eax >> (8 * t);
|
|
for (t = 0; t < 4; t++)
|
|
*p++ = ebx >> (8 * t);
|
|
for (t = 0; t < 4; t++)
|
|
*p++ = ecx >> (8 * t);
|
|
for (t = 0; t < 4; t++)
|
|
*p++ = edx >> (8 * t);
|
|
}
|
|
|
|
mvwprintw(win, row, 1, "Processor: %s", name);
|
|
}
|
|
|
|
static int cpuinfo_module_redraw(WINDOW *win)
|
|
{
|
|
unsigned long eax, ebx, ecx, edx;
|
|
unsigned int brand;
|
|
char *vstr;
|
|
int row = 2;
|
|
|
|
print_module_title(win, "CPU Information");
|
|
|
|
docpuid(0, NULL, &vendor, NULL, NULL);
|
|
|
|
switch (vendor) {
|
|
case VENDOR_INTEL:
|
|
vstr = "Intel";
|
|
break;
|
|
case VENDOR_AMD:
|
|
vstr = "AMD";
|
|
break;
|
|
case VENDOR_CYRIX:
|
|
vstr = "Cyrix";
|
|
break;
|
|
case VENDOR_IDT:
|
|
vstr = "IDT";
|
|
break;
|
|
case VENDOR_GEODE:
|
|
vstr = "NatSemi Geode";
|
|
break;
|
|
case VENDOR_RISE:
|
|
case VENDOR_RISE2:
|
|
vstr = "RISE";
|
|
break;
|
|
case VENDOR_SIS:
|
|
vstr = "SiS";
|
|
break;
|
|
default:
|
|
vstr = "Unknown";
|
|
break;
|
|
}
|
|
|
|
mvwprintw(win, row++, 1, "Vendor: %s", vstr);
|
|
|
|
do_name(win, row++);
|
|
|
|
docpuid(0x00000001, &eax, &ebx, &ecx, &edx);
|
|
|
|
mvwprintw(win, row++, 1, "Family: %X", (eax >> 8) & 0x0f);
|
|
mvwprintw(win, row++, 1, "Model: %X",
|
|
((eax >> 4) & 0xf) | ((eax >> 16) & 0xf) << 4);
|
|
|
|
mvwprintw(win, row++, 1, "Stepping: %X", eax & 0xf);
|
|
|
|
if (vendor == VENDOR_AMD) {
|
|
docpuid(0x80000001, &eax, &ebx, &ecx, &edx);
|
|
brand = ((ebx >> 9) & 0x1f);
|
|
|
|
mvwprintw(win, row++, 1, "Brand: %X", brand);
|
|
}
|
|
|
|
if (cpu_khz != 0)
|
|
mvwprintw(win, row++, 1, "CPU Speed: %d Mhz", cpu_khz / 1000);
|
|
else
|
|
mvwprintw(win, row++, 1, "CPU Speed: Error");
|
|
|
|
row++;
|
|
get_features(win, &row);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static unsigned int getticks(void)
|
|
{
|
|
unsigned long long start, end;
|
|
|
|
/* Read the number of ticks during the period. */
|
|
start = rdtsc();
|
|
mdelay(100);
|
|
end = rdtsc();
|
|
|
|
return (unsigned int)((end - start) / 100);
|
|
}
|
|
|
|
static int cpuinfo_module_init(void)
|
|
{
|
|
cpu_khz = getticks();
|
|
return 0;
|
|
}
|
|
|
|
struct coreinfo_module cpuinfo_module = {
|
|
.name = "CPU Info",
|
|
.init = cpuinfo_module_init,
|
|
.redraw = cpuinfo_module_redraw,
|
|
};
|
|
|
|
#else
|
|
|
|
struct coreinfo_module cpuinfo_module = {
|
|
};
|
|
|
|
#endif
|