I ran scanmsr.c on the PII I have. You can't use the PIII with scanmsr as
the PIII has a stupid bug: if you read an invalid MSR, it won't give you a
GPF. Intel's fix for this is (I quote): "Don't read invalid MSRs". So, on
the PIII, you can't tell if you have invalid MSRs. Score one for AMD!
First, on PII, MSRs repeat every 0x4000, so PII doesn't even really decode
the address space. The K7 fully decodes them. Score one for AMD!
But on PII there is nothing of interest in that high-number space where
the K7 has a bunch of stuff: 0xcxxxxxxx. So it would seem that the K7 MSRs
are really those high-order ones.
OK, so now we know all the K7 MSRs. We have that list. So next step is to
compare what they are set to with linuxbios and what they are set to with
standard bios.
We don't need to probe the 32-bit space with linuxbios. We can just probe
the list we found. You just have to fix scanmsr to only scan those
addresses I posted, instead of scanning the whole space. That's good
because right now linuxbios on K7 is *really* *slow*.
Note once again: those addresses were found by exhaustively running Dave
Jone's scanmsr.c (attached).
So does somebody out there with a K7/m810LMR want to do this, and post the
two MSR sets to this list? In other words, run scanmsr on a linuxbios box.
It will run slow, of course, but that's what we need to fix.
ron
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
int msr(int cpu, unsigned int index, unsigned long *lo, unsigned long *hi)
{
char cpuname[16];
unsigned char buffer[8];
int fh;
sprintf (cpuname, "/dev/cpu/%d/msr", cpu);
fh = open (cpuname, O_RDONLY);
if (fh==-1)
return (0);
lseek (fh, index, SEEK_CUR);
if (fh != -1) {
if (read (fh, &buffer[0], 8) != 8) {
close (fh);
return (0);
}
*lo = (*(unsigned long *)buffer);
*hi = (*(unsigned long *)(buffer+4));
}
close (fh);
return (1);
}
int main (void)
{
unsigned long lo=0, hi=0;
unsigned int index;
for (index=0x00000000; index<0xFFFFFFFF; index++) {
if ((index % 0x10000) == 0)
//printf("%#08x\b\b\b\b\b\b\b\b\r", index);
printf("%#08x\n", index);
if (msr(0, index, &lo, &hi) == 1)
printf ("MSR: %lx, %08lx %08lx\n", index, lo, hi);
}
return (0);
}