Fixed some minor bugs that made it into the last version; for example
the 0x80000001 generation/model/stepping was displayed incorrectly.
Only the new features in cpuid 0x80000001 are printed, added support for
No-Execute ("NX") and Long Mode ("64").
Improved non-Intel TLB display, added page sizes, 2nd level cache is now
also displayed correctly (unlike the BeOS version which has a wrong
associativity).
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@10330 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+61
-43
@@ -110,19 +110,22 @@ print_intel_cache_descriptors(cpuid_info *info)
|
|||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_TLB(uint32 reg)
|
print_TLB(uint32 reg, const char *pages)
|
||||||
{
|
{
|
||||||
int num;
|
int num;
|
||||||
int entries[2];
|
int entries[2];
|
||||||
int ways[2];
|
int ways[2];
|
||||||
char *name[2] = { "Inst TLB:\t", "Data TLB:\t" };
|
char *name[2] = { "Inst TLB", "Data TLB" };
|
||||||
|
|
||||||
entries[0] = (reg & 0xff);
|
entries[0] = (reg & 0xff);
|
||||||
ways[0] = ((reg >> 8) & 0xff);
|
ways[0] = ((reg >> 8) & 0xff);
|
||||||
entries[1] = ((reg >> 16) & 0xff);
|
entries[1] = ((reg >> 16) & 0xff);
|
||||||
ways[1] = ((reg >> 24) & 0xff);
|
ways[1] = ((reg >> 24) & 0xff);
|
||||||
for (num=0; num < 2; num++) {
|
|
||||||
printf("\t%s %u entries, ", name[num], entries[num]);
|
for (num = 0; num < 2; num++) {
|
||||||
|
printf("\t%s: %s%s%u entries, ", name[num],
|
||||||
|
pages ? pages : "", pages ? " pages, " : "", entries[num]);
|
||||||
|
|
||||||
if (ways[num] == 0xff)
|
if (ways[num] == 0xff)
|
||||||
printf("fully associative\n");
|
printf("fully associative\n");
|
||||||
else
|
else
|
||||||
@@ -132,39 +135,59 @@ print_TLB(uint32 reg)
|
|||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_cache(uint32 reg, int code)
|
print_level2_cache(uint32 reg, const char *name)
|
||||||
{
|
{
|
||||||
int size;
|
uint32 size = (reg >> 16) & 0xffff;
|
||||||
int ways;
|
uint32 ways = (reg >> 12) & 0xf;
|
||||||
int lines_per_tag;
|
uint32 lines_per_tag = (reg >> 8) & 0xf;
|
||||||
int linesize;
|
uint32 linesize = reg & 0xff;
|
||||||
char *name[2] = { "L1 inst cache:", "L1 data cache:" };
|
|
||||||
|
|
||||||
size = ((reg >> 24) & 0xff);
|
printf("\t%s: %lu KB, ", name, size);
|
||||||
ways = ((reg >> 16) & 0xff);
|
if (ways == 0xf)
|
||||||
lines_per_tag = ((reg >> 8) & 0xff);
|
|
||||||
linesize = (reg & 0xff);
|
|
||||||
printf("\t%s %u KB,", name[code?1:0], size);
|
|
||||||
if (ways == 0xff)
|
|
||||||
printf("fully associative, ");
|
printf("fully associative, ");
|
||||||
|
else if (ways == 0x1)
|
||||||
|
printf("direct-mapped, ");
|
||||||
else
|
else
|
||||||
printf("%u-way set associative, ", ways);
|
printf("%lu-way set associative, ", 1UL << (
|
||||||
printf("%u lines/tag, %u bytes/line\n", lines_per_tag, linesize);
|
ways / 2));
|
||||||
|
printf("%lu lines/tag, %lu bytes/line\n", lines_per_tag, linesize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
print_cache_descriptors(cpuid_info *info)
|
print_level1_cache(uint32 reg, const char *name)
|
||||||
{
|
{
|
||||||
putchar('\n');
|
uint32 size = (reg >> 24) & 0xff;
|
||||||
if (info->regs.eax)
|
uint32 ways = (reg >> 16) & 0xff;
|
||||||
print_TLB(info->regs.eax);
|
uint32 lines_per_tag = (reg >> 8) & 0xff;
|
||||||
if (info->regs.ebx)
|
uint32 linesize = reg & 0xff;
|
||||||
print_TLB(info->regs.ebx);
|
|
||||||
if (info->regs.eax || info->regs.ebx)
|
|
||||||
|
|
||||||
print_cache(info->regs.ecx, 0);
|
printf("\t%s: %lu KB, ", name, size);
|
||||||
print_cache(info->regs.edx, 1);
|
if (ways == 0xff)
|
||||||
|
printf("fully associative, ");
|
||||||
|
else
|
||||||
|
printf("%lu-way set associative, ", ways);
|
||||||
|
printf("%lu lines/tag, %lu bytes/line\n", lines_per_tag, linesize);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_cache_descriptors(int32 cpu)
|
||||||
|
{
|
||||||
|
cpuid_info info;
|
||||||
|
get_cpuid(&info, 0x80000005, cpu);
|
||||||
|
|
||||||
|
putchar('\n');
|
||||||
|
if (info.regs.eax)
|
||||||
|
print_TLB(info.regs.eax, info.regs.ebx ? "2M/4M-byte" : NULL);
|
||||||
|
if (info.regs.ebx)
|
||||||
|
print_TLB(info.regs.ebx, info.regs.eax ? "4K-byte" : NULL);
|
||||||
|
|
||||||
|
print_level1_cache(info.regs.ecx, "L1 inst cache");
|
||||||
|
print_level2_cache(info.regs.edx, "L1 data cache");
|
||||||
|
|
||||||
|
get_cpuid(&info, 0x80000006, cpu);
|
||||||
|
print_level2_cache(info.regs.ecx, "L2 cache");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -172,14 +195,10 @@ static void
|
|||||||
print_amd_features(uint32 features)
|
print_amd_features(uint32 features)
|
||||||
{
|
{
|
||||||
static const char *kFeatures[32] = {
|
static const char *kFeatures[32] = {
|
||||||
"FPU", "VME", "DE", "PSE",
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||||
"TSC", "MSR", "PAE", "MCE",
|
NULL, NULL, NULL, "SCE", NULL, NULL, NULL, NULL,
|
||||||
"CX8", "APIC", NULL, "SCE",
|
NULL, NULL, NULL, NULL, "NX", NULL, "AMD-MMX", NULL,
|
||||||
"MTRR", "PGE", "MCA", "CMOV",
|
NULL, "FFXSTR", NULL, NULL, NULL, "64", "3DNow+", "3DNow!"
|
||||||
"PAT", "PSE36", NULL, NULL,
|
|
||||||
NULL, NULL, "AMD-MMX", "MMX",
|
|
||||||
"FXSR", NULL, NULL, NULL,
|
|
||||||
NULL, NULL, "3DNow+", "3DNow!"
|
|
||||||
};
|
};
|
||||||
int32 found = 0;
|
int32 found = 0;
|
||||||
int32 i;
|
int32 i;
|
||||||
@@ -208,9 +227,9 @@ print_features(uint32 features)
|
|||||||
"TSC", "MSR", "PAE", "MCE",
|
"TSC", "MSR", "PAE", "MCE",
|
||||||
"CX8", "APIC", NULL, "SEP",
|
"CX8", "APIC", NULL, "SEP",
|
||||||
"MTRR", "PGE", "MCA", "CMOV",
|
"MTRR", "PGE", "MCA", "CMOV",
|
||||||
"PAT", "PSE36", "PSN", "CFLSH",
|
"PAT", "PSE36", "PSN", "CFLUSH",
|
||||||
NULL, "DS", "ACPI", "MMX",
|
NULL, "DS", "ACPI", "MMX",
|
||||||
"FXSR", "SSE", "SSE2", "SS",
|
"FXSTR", "SSE", "SSE2", "SS",
|
||||||
NULL, "TM", NULL, NULL,
|
NULL, "TM", NULL, NULL,
|
||||||
};
|
};
|
||||||
int32 found = 0;
|
int32 found = 0;
|
||||||
@@ -315,19 +334,18 @@ dump_cpu(system_info *info, int32 cpu)
|
|||||||
if (max_extended_eax >= 1 && (info->cpu_type & B_CPU_x86_VENDOR_MASK) == B_CPU_AMD_x86) {
|
if (max_extended_eax >= 1 && (info->cpu_type & B_CPU_x86_VENDOR_MASK) == B_CPU_AMD_x86) {
|
||||||
get_cpuid(&cpuInfo, 0x80000001, cpu);
|
get_cpuid(&cpuInfo, 0x80000001, cpu);
|
||||||
printf("\textended: generation %lu, model %lu, stepping %lu, features 0x%08lx\n",
|
printf("\textended: generation %lu, model %lu, stepping %lu, features 0x%08lx\n",
|
||||||
(cpuInfo.regs.eax >> 8) & 0xff, (cpuInfo.regs.eax >> 4) & 0xff,
|
(cpuInfo.regs.eax >> 8) & 0xf, (cpuInfo.regs.eax >> 4) & 0xf,
|
||||||
cpuInfo.regs.eax & 0xff, cpuInfo.regs.edx);
|
cpuInfo.regs.eax & 0xf, cpuInfo.regs.edx);
|
||||||
print_amd_features(cpuInfo.regs.edx);
|
print_amd_features(cpuInfo.regs.edx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Cache/TLB descriptors */
|
/* Cache/TLB descriptors */
|
||||||
if (max_extended_eax >= 5) {
|
if (max_extended_eax >= 5) {
|
||||||
|
if (!strncmp(baseInfo.eax_0.vendor_id, "CyrixInstead", 12)) {
|
||||||
get_cpuid(&cpuInfo, 0x80000005, cpu);
|
get_cpuid(&cpuInfo, 0x80000005, cpu);
|
||||||
|
|
||||||
if (!strncmp(baseInfo.eax_0.vendor_id, "CyrixInstead", 12))
|
|
||||||
print_intel_cache_descriptors(&cpuInfo);
|
print_intel_cache_descriptors(&cpuInfo);
|
||||||
else
|
} else
|
||||||
print_cache_descriptors(&cpuInfo);
|
print_cache_descriptors(cpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (max_eax >= 2) {
|
if (max_eax >= 2) {
|
||||||
|
|||||||
Reference in New Issue
Block a user