9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
* [9fans] AMD cpu detection
@ 1998-04-29  5:29 forsyth
  0 siblings, 0 replies; 4+ messages in thread
From: forsyth @ 1998-04-29  5:29 UTC (permalink / raw)


for a 233MHz AMD/K6, on a Micronics AT-03 Twister m/board, i now use:
	{ 5,	6,	11,	"AMD-K6", },	/* determined by trial and error */
which might imply this improved approximation for the other plain K6 entry:
	{ 5,	7,	11,	"AMD-K6", },	/* guesswork */
(but i haven't got that model here).  i'll try it on a 200MHz K6 when i get to
the office.

on boot, i get
	cpu0: 234MHz AuthenticAMD AMD-K6 (cpuid: AX 0x0562 DX: 0x8001BF)
reducing 11 to 10 aalcycles gave 214MHz, so i use 11.

further retrofitting changes required to get that far:

	void
	printcpufreq(void)
	{
		int i;
		char buf[128];

		i = sprint(buf, "cpu%d: %dMHz ", m->machno, cpumhz);
		if(cpuidid[0])
			i += sprint(buf+i, "%s ", cpuidid);
		sprint(buf+i, "%s (cpuid: AX 0x%4.4luX DX 0x%4.4luX)\n",
			cputype->name, cpuidax, cpuiddx);
		print(buf);
	}

ie: delete m-> from several names to refer to the newly added static variables.

add

	#define X86STEPPING(x)	((x) & 0x0F)
	#define X86MODEL(x)	(((x)>>4) & 0x0F)
	#define X86FAMILY(x)	(((x)>>8) & 0x0F)

to the top of io.h

and put

	#define CPUID		BYTE $0x0F; BYTE $0xA2	/* CPUID, argument in AX */

after
	#define NOP	XCHGL	AX,AX

in l.s

i think that's all i did to get it to work.




^ permalink raw reply	[flat|nested] 4+ messages in thread

* [9fans] AMD cpu detection
@ 2000-02-22  0:01 arisawa
  0 siblings, 0 replies; 4+ messages in thread
From: arisawa @ 2000-02-22  0:01 UTC (permalink / raw)


Hello 9fans,

I received a mail from Jim.
His patch to:
	/sys/src/9/pc/clock.c
	/sys/src/fs/pc/8253.c
fixed the problem with the CPU speed being unsteady.

Thanks Jim.

Kenji Arisawa
E-mail: arisawa@aichi-u.ac.jp

From: jmk@plan9.bell-labs.com
Subject: Re: [9fans] Re: b.com from fd
Date: Mon, 21 Feb 2000 11:45:30 -0500
To: arisawa@aichi-u.ac.jp

Here's something which might fix your problem with the CPU speed
being unsteady. This code is from our current fileserver kernel and goes
in 8253.c/clockinit:

	...
	/*
	 *  set clock for 1/HZ seconds
	 */
	outb(Tmode, Load0|Square);
	outb(T0cntr, (Freq/HZ));	/* low byte */
	outb(T0cntr, (Freq/HZ)>>8);	/* high byte */

	/*
	 * Introduce a little delay to make sure the count is
	 * latched and the timer is counting down; with a fast
	 * enough processor this may not be the case.
	 * The i8254 (which this probably is) has a read-back
	 * command which can be used to make sure the counting
	 * register has been written into the counting element.
	 */
	x = (Freq/HZ);
	for(loops = 0; loops < 100000 && x >= (Freq/HZ); loops++){
		outb(Tmode, Latch0);
		x = inb(T0cntr);
		x |= inb(T0cntr)<<8;
	}

	/* find biggest loop that doesn't wrap */
	...

I admit to not having tried this on a non-Intel processor. The delay is
also necessary in the terminal/cpuserver kernels.
If that fixes your problem, let me know and feel free to post the fix
to 9fans.

By the way, the x86amd[] table values for the Athlon are the same as
for the K6:
	{ 6,	1,	11,	"AMD-Athlon", },/* trial and error */
	{ 6,	2,	11,	"AMD-Athlon", },/* trial and error */
I have a 700MHz Athlon with an ASUS K7M motherboard; it's quite refreshing
to see not a single Intel chip in the system.

--jim




^ permalink raw reply	[flat|nested] 4+ messages in thread

* [9fans] AMD cpu detection
@ 1998-04-29 14:45 jim
  0 siblings, 0 replies; 4+ messages in thread
From: jim @ 1998-04-29 14:45 UTC (permalink / raw)


thanks for the feedback. the code changes i missed were due to
differences between the original brazil code i started with and plan9.
i'll put a complete fix up on the web site when it settels down.

--jim




^ permalink raw reply	[flat|nested] 4+ messages in thread

* [9fans] AMD cpu detection
@ 1998-04-29  2:56 jim
  0 siblings, 0 replies; 4+ messages in thread
From: jim @ 1998-04-29  2:56 UTC (permalink / 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++;
	}




^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2000-02-22  0:01 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1998-04-29  5:29 [9fans] AMD cpu detection forsyth
  -- strict thread matches above, loose matches on Subject: below --
2000-02-22  0:01 arisawa
1998-04-29 14:45 jim
1998-04-29  2:56 jim

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).