From: jim mckie jmk@plan9.bell-labs.com
Subject: [9fans] AMD cpu detection
Date: Tue, 28 Apr 1998 22:56:14 -0400 [thread overview]
Message-ID: <19980429025614.Wh-YfF9UyqmZFkdXAfhur0-MG48a4L31OG6oFtnKGEk@z> (raw)
I looked on the AMD web site and the following instructions are a stab
at detecting the AMD chips. I can't try this myself (no AMD chips, no easy
way to make a Plan 9 kernel) and there are no instruction timings available
so I'd appreciate it if anyone who has an AMD chip could try this and
report back. Once the chnages are installed the aalcycles table entries
(commented with /* guesswork */) should be altered until the value printed
by printcpufreq approximates the MHz of the processor.
Thanks, Jim.
1) fns.h
change
int x86cpuid(int*, int*);
to
void cpuid(char*, int*, int*);
2) l.s
replace x86cpuid by
/*
* Try to determine the CPU type which requires fiddling with EFLAGS.
* If the Id bit can be toggled then the CPUID instruciton can be used
* to determine CPU identity and features. First have to check if it's
* a 386 (Ac bit can't be set). If it's not a 386 and the Id bit can't be
* toggled then it's an older 486 of some kind.
*
* cpuid(id[], &ax, &dx);
*/
TEXT cpuid(SB), $0
MOVL $0x240000, AX
PUSHL AX
POPFL /* set Id|Ac */
PUSHFL
POPL BX /* retrieve value */
MOVL $0, AX
PUSHL AX
POPFL /* clear Id|Ac, EFLAGS initialised */
PUSHFL
POPL AX /* retrieve value */
XORL BX, AX
TESTL $0x040000, AX /* Ac */
JZ _cpu386 /* can't set this bit on 386 */
TESTL $0x200000, AX /* Id */
JZ _cpu486 /* can't toggle this bit on some 486 */
MOVL $0, AX
CPUID
MOVL id+0(FP), BP
MOVL BX, 0(BP) /* "Genu" "Auth" "Cyri" */
MOVL DX, 4(BP) /* "ineI" "enti" "xIns" */
MOVL CX, 8(BP) /* "ntel" "cAMD" "tead" */
MOVL $1, AX
CPUID
JMP _cpuid
_cpu486:
MOVL $0x400, AX
MOVL $0, DX
JMP _cpuid
_cpu386:
MOVL $0x300, AX
MOVL $0, DX
_cpuid:
MOVL ax+4(FP), BP
MOVL AX, 0(BP)
MOVL dx+8(FP), BP
MOVL DX, 0(BP)
RET
3) clock.c
a) add
static char cpuidid[16];
after
static int loopconst = 100;
b) replace the x86type array with
static X86type x86intel[] =
{
{ 4, 0, 22, "486DX", }, /* known chips */
{ 4, 1, 22, "486DX50", },
{ 4, 2, 22, "486SX", },
{ 4, 3, 22, "486DX2", },
{ 4, 4, 22, "486SL", },
{ 4, 5, 22, "486SX2", },
{ 4, 7, 22, "DX2WB", }, /* P24D */
{ 4, 8, 22, "DX4", }, /* P24C */
{ 4, 9, 22, "DX4WB", }, /* P24CT */
{ 5, 0, 23, "P5", },
{ 5, 1, 23, "P5", },
{ 5, 2, 23, "P54C", },
{ 5, 3, 23, "P24T", },
{ 5, 4, 23, "P55C MMX", },
{ 5, 7, 23, "P54C VRT", },
{ 6, 1, 16, "PentiumPro", },/* determined by trial and error */
{ 6, 3, 16, "PentiumII", }, /* determined by trial and error */
{ 6, 5, 16, "PentiumII", }, /* determined by trial and error */
{ 3, -1, 32, "386", }, /* family defaults */
{ 4, -1, 22, "486", },
{ 5, -1, 23, "Pentium", },
{ 6, -1, 16, "PentiumPro", },
{ -1, -1, 23, "unknown", }, /* total default */
};
/*
* The AMD processors all implement the CPUID instruction.
* The later ones also return the processor name via functions
* 0x80000002, 0x80000003 and 0x80000004 in registers AX, BX, CX
* and DX:
* K5 "AMD-K5(tm) Processor"
* K6 "AMD-K6tm w/ multimedia extensions"
* K6 3D "AMD-K6(tm) 3D processor"
* K6 3D+ ?
*/
static X86type x86amd[] =
{
{ 5, 0, 23, "AMD-K5", }, /* guesswork */
{ 5, 1, 23, "AMD-K5", }, /* guesswork */
{ 5, 2, 23, "AMD-K5", }, /* guesswork */
{ 5, 3, 23, "AMD-K5", }, /* guesswork */
{ 5, 6, 23, "AMD-K6", }, /* guesswork */
{ 5, 7, 23, "AMD-K6", }, /* guesswork */
{ 5, 8, 23, "AMD-K6 3D", }, /* guesswork */
{ 5, 9, 23, "AMD-K6 3D+", },/* guesswork */
{ 4, -1, 22, "Am486", }, /* guesswork */
{ 5, -1, 23, "AMD-K5/K6", }, /* guesswork */
{ -1, -1, 23, "unknown", }, /* total default */
};
c) replace the printcpufreq function with
void
printcpufreq(void)
{
int i;
char buf[128];
i = sprint(buf, "cpu%d: %dMHz ", m->machno, m->cpumhz);
if(m->cpuidid[0])
i += sprint(buf+i, "%s ", m->cpuidid);
sprint(buf+i, "%s (cpuid: AX 0x%4.4luX DX 0x%4.4luX)\n",
m->cpuidtype, m->cpuidax, m->cpuiddx);
print(buf);
}
d) in clockinit replace
x86cpuid(&cpuidax, &cpuiddx);
family = FAMILY(cpuidax);
model = MODEL(cpuidax);
for(t = x86type; t->name; t++)
if((t->family == family && t->model == model)
|| (t->family == family && t->model == -1)
|| (t->family == -1))
break;
with
cpuid(cpuidid, &cpuidax, &cpuiddx);
if(strncmp(cpuidid, "AuthenticAMD", 12) == 0)
t = x86amd;
else
t = x86intel;
family = X86FAMILY(cpuidax);
model = X86MODEL(cpuidax);
while(t->name){
if((t->family == family && t->model == model)
|| (t->family == family && t->model == -1)
|| (t->family == -1))
break;
t++;
}
next reply other threads:[~1998-04-29 2:56 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
1998-04-29 2:56 jim [this message]
1998-04-29 5:29 forsyth
1998-04-29 14:45 jim
2000-02-22 0:01 arisawa
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=19980429025614.Wh-YfF9UyqmZFkdXAfhur0-MG48a4L31OG6oFtnKGEk@z \
--to=9fans@9fans.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).