made some changes according to the intel programmers guide. Our get_cpuid needs changes

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30259 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
David McPaul 2009-04-19 05:02:42 +00:00
parent 33befb1eff
commit 98b956380c
1 changed files with 108 additions and 15 deletions

View File

@ -66,7 +66,7 @@ struct cache_description {
{0x4C, "L3 cache: 12288 KB, 12-way set associative, 64 bytes/line"},
{0x4D, "L3 cache: 16384 KB, 16-way set associative, 64 bytes/line"},
{0x4E, "L2 cache: 6144 KB, 24-way set associative, 64 bytes/line"},
{0x4F, "Inst TLB, 4K-bytes pages, ???, 32 entries"},
{0x4F, "Inst TLB, 4K-bytes pages, 32 entries"},
{0x50, "Inst TLB: 4K/4M/2M-bytes pages, fully associative, 64 entries"},
{0x51, "Inst TLB: 4K/4M/2M-bytes pages, fully associative, 128 entries"},
{0x52, "Inst TLB: 4K/4M/2M-bytes pages, fully associative, 256 entries"},
@ -139,17 +139,58 @@ struct cache_description {
static void
print_intel_cache_descriptors(enum cpu_types type, cpuid_info *info)
{
int i, j;
int i, j, max_desc;
uint8 cache_descriptors[15]; // Max
max_desc = 0;
i = 0;
// put valid values into array
if ((info->regs.eax & 0x80000000) == 0) {
// eax is valid, include values
cache_descriptors[max_desc++] = info->eax_2.cache_descriptors[i++];
cache_descriptors[max_desc++] = info->eax_2.cache_descriptors[i++];
cache_descriptors[max_desc++] = info->eax_2.cache_descriptors[i++];
} else {
i+=3;
}
if ((info->regs.ebx & 0x80000000) == 0) {
// ebx is valid, include values
cache_descriptors[max_desc++] = info->eax_2.cache_descriptors[i++];
cache_descriptors[max_desc++] = info->eax_2.cache_descriptors[i++];
cache_descriptors[max_desc++] = info->eax_2.cache_descriptors[i++];
cache_descriptors[max_desc++] = info->eax_2.cache_descriptors[i++];
} else {
i+=4;
}
if ((info->regs.edx & 0x80000000) == 0) {
// edx is valid, include values
cache_descriptors[max_desc++] = info->eax_2.cache_descriptors[i++];
cache_descriptors[max_desc++] = info->eax_2.cache_descriptors[i++];
cache_descriptors[max_desc++] = info->eax_2.cache_descriptors[i++];
cache_descriptors[max_desc++] = info->eax_2.cache_descriptors[i++];
} else {
i+=4;
}
if ((info->regs.ecx & 0x80000000) == 0) {
// ecx is valid, include values
cache_descriptors[max_desc++] = info->eax_2.cache_descriptors[i++];
cache_descriptors[max_desc++] = info->eax_2.cache_descriptors[i++];
cache_descriptors[max_desc++] = info->eax_2.cache_descriptors[i++];
cache_descriptors[max_desc++] = info->eax_2.cache_descriptors[i++];
}
putchar('\n');
for (i = 0; i < 15; i++) {
if (info->eax_2.cache_descriptors[i] == 0)
for (i = 0; i < max_desc; i++) {
// ignore NULL descriptors
if (cache_descriptors[i] == 0)
continue;
for (j = 0; sIntelCacheDescriptions[j].code; j++) {
if (info->eax_2.cache_descriptors[i] == sIntelCacheDescriptions[j].code) {
if (info->eax_2.cache_descriptors[i] == 0x40) {
if (cache_descriptors[i] == sIntelCacheDescriptions[j].code) {
if (cache_descriptors[i] == 0x40) {
printf("\tNo integrated L%u cache\n",
type >= B_CPU_INTEL_PENTIUM_IV
&& (type & B_CPU_x86_VENDOR_MASK) == B_CPU_INTEL_x86 ?
@ -159,8 +200,10 @@ print_intel_cache_descriptors(enum cpu_types type, cpuid_info *info)
break;
}
}
// Reached the end without finding a descriptor
if (sIntelCacheDescriptions[j].code == 0)
printf("\tUnknown cache descriptor 0x%02x\n", info->eax_2.cache_descriptors[i]);
printf("\tUnknown cache descriptor 0x%02x\n", cache_descriptors[i]);
}
}
@ -197,7 +240,7 @@ print_level2_cache(uint32 reg, const char *name)
{
uint32 size = (reg >> 16) & 0xffff;
uint32 ways = (reg >> 12) & 0xf;
uint32 lines_per_tag = (reg >> 8) & 0xf;
uint32 lines_per_tag = (reg >> 8) & 0xf; // intel does not define this
uint32 linesize = reg & 0xff;
printf("\t%s: %lu KB, ", name, size);
@ -206,8 +249,7 @@ print_level2_cache(uint32 reg, const char *name)
else if (ways == 0x1)
printf("direct-mapped, ");
else
printf("%lu-way set associative, ", 1UL << (
ways / 2));
printf("%lu-way set associative, ", 1UL << (ways / 2));
printf("%lu lines/tag, %lu bytes/line\n", lines_per_tag, linesize);
}
@ -232,12 +274,13 @@ print_level1_cache(uint32 reg, const char *name)
#ifdef __INTEL__
static void
print_cache_descriptors(int32 cpu)
print_cache_desc(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)
@ -250,6 +293,52 @@ print_cache_descriptors(int32 cpu)
print_level2_cache(info.regs.ecx, "L2 cache");
}
static void
print_intel_cache_desc(int32 cpu)
{
cpuid_info info;
uint32 type;
uint32 level;
bool is_fully_assoc;
uint32 linesize;
uint32 lines_per_tag;
uint32 ways;
uint32 sets;
// A second parameters needs to be passed to CPUID which determines the cache level to query
get_cpuid(&info, 0x00000004, cpu);
putchar('\n');
type = info.regs.eax & 0xf;
level = (info.regs.eax & 0x70) >> 4;
is_fully_assoc = info.regs.eax & 0x100;
linesize = (info.regs.ebx & 0xfff) + 1;
lines_per_tag = ((info.regs.ebx & 0x3ff000) >> 12) + 1;
ways = ((info.regs.ebx & 0xffc00000) >> 22) + 1;
sets = info.regs.ecx;
printf("\tL%ld ",level);
switch (type) {
case 1: printf("Data cache "); break;
case 2: printf("Inst cache "); break;
case 3: printf("Unified cache "); break;
default: break;
}
if (is_fully_assoc)
printf("fully associative, ");
else
printf("%lu-way set associative, ", ways);
printf("%lu lines/tag, %lu bytes/line\n", lines_per_tag, linesize);
get_cpuid(&info, 0x80000006, cpu);
print_level2_cache(info.regs.ecx, "L2 cache");
}
static void
print_transmeta_features(uint32 features)
@ -515,10 +604,14 @@ dump_cpu(system_info *info, int32 cpu)
/* Cache/TLB descriptors */
if (maxExtendedFunction >= 5) {
if (!strncmp(baseInfo.eax_0.vendor_id, "CyrixInstead", 12)) {
get_cpuid(&cpuInfo, 0x80000005, cpu);
get_cpuid(&cpuInfo, 0x00000002, cpu);
print_intel_cache_descriptors(info->cpu_type, &cpuInfo);
} else
print_cache_descriptors(cpu);
} else if ((info->cpu_type & B_CPU_x86_VENDOR_MASK) == B_CPU_INTEL_x86) {
// Intel does not support extended function 5 (but it does 6 hmm)
print_intel_cache_desc(cpu);
} else {
print_cache_desc(cpu);
}
}
if (maxStandardFunction >= 2) {