Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 10 Apr 1998 15:07:12 -0700 (PDT)
From:      kbyanc@freedomnet.com
To:        freebsd-gnats-submit@FreeBSD.ORG
Subject:   i386/6269: Included is a patch to support AMD Write-Allocate on K5s and K6s
Message-ID:  <199804102207.PAA24161@hub.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         6269
>Category:       i386
>Synopsis:       Included is a patch to support AMD Write-Allocate on K5s and K6s
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:
>Keywords:
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Fri Apr 10 15:10:00 PDT 1998
>Last-Modified:
>Originator:     Kelly Yancey
>Organization:
FreedomNet
>Release:        2.2.6-RELEASE
>Environment:
>Description:
Included is the patch file I generated after adding support for the
AMD K5/K6 Write-Allocate function. Also, I made modifications in the
identcpu to better recognize the AMD K5 and K6 chips. Also added
CPU_AMD_K5 and CPU_AMD_K6 defines in the cputypes.h
(that patch is also included). Ample documentation was made of the
changes.

diff -u -R output follows...
************************************************************
diff -u -r /sys/i386/i386/identcpu.c /sys/i386/i386/identcpu.c
--- /sys/i386/i386/identcpu.c	Fri Apr 10 14:23:35 1998
+++ /sys/i386/i386/identcpu.c	Fri Apr 10 14:22:40 1998
@@ -95,6 +95,8 @@
 	{ "Cyrix 6x86MX",	CPUCLASS_686 },		/* CPU_M2 */
 	{ "NexGen 586",		CPUCLASS_386 },		/* CPU_NX586 (XXX) */
 	{ "Cyrix 486S/DX",	CPUCLASS_486 },		/* CPU_CY486DX */
+	{ "AMD K5",		CPUCLASS_586 },		/* CPU_AMDK5 */
+	{ "AMD K6",		CPUCLASS_586 },		/* CPU_AMDK6 */
 };
 
 static void
@@ -227,6 +229,9 @@
 		case 0x560:
 			strcat(cpu_model, "K6");
 			break;
+		case 0x570:
+			strcat(cpu_model, "K6 266 (model 1)");
+			break;
 		default:
 			strcat(cpu_model, "Unknown");
 			break;
@@ -437,7 +442,7 @@
 			 * to check that all CPUs >= Pentium have a TSC and
 			 * MSRs.
 			 */
-			printf("\n  Features=0x%b", cpu_feature, 
+			printf("\n  Features=0x%b", cpu_feature,
 			"\020"
 			"\001FPU"
 			"\002VME"
@@ -585,7 +590,7 @@
 
 	trap_by_rdmsr = 0;
 
-	/* 
+	/*
 	 * Cyrix 486-class CPU does not support rdmsr instruction.
 	 * The rdmsr instruction generates invalid opcode fault, and exception
 	 * will be trapped by bluetrap6() on Cyrix 486-class CPU.  The
@@ -735,10 +740,22 @@
 			}
 		}
 	}
+	else if (strcmp(cpu_vendor, "AuthenticAMD") == 0) {
+		switch (cpu_id & 0xff0) {
+		case 0x500:
+		case 0x510:
+		case 0x520:
+		case 0x530: cpu = CPU_AMDK5;
+			    break;
+		case 0x560:
+		case 0x570: cpu = CPU_AMDK6;
+                	    break;
+		}
+	}
 }
 
 /*
- * This routine is called specifically to set up cpu_class before 
+ * This routine is called specifically to set up cpu_class before
  * startrtclock() uses it.  Probably this should be rearranged so that
  * startrtclock() doesn't need to run until after identifycpu() has been
  * called.  Another alternative formulation would be for this routine
@@ -762,7 +779,7 @@
 }
 
 static void
-print_AMD_info(void) 
+print_AMD_info(void)
 {
 	u_long regs[4];
 
diff -u -r /sys/i386/i386/initcpu.c /sys/i386/i386/initcpu.c
--- /sys/i386/i386/initcpu.c	Fri Apr 10 14:23:35 1998
+++ /sys/i386/i386/initcpu.c	Fri Apr 10 14:33:01 1998
@@ -52,10 +52,85 @@
 static void init_6x86(void);
 #endif /* I486_CPU */
 
+#ifdef I586_CPU
+static void init_amdK5(void);
+static void init_amdK6(void);
+#endif
+
 #ifdef I686_CPU
 static void	init_6x86MX(void);
 #endif
 
+#ifdef I586_CPU
+/* support for AMD write allocate function added by Kelly Yancey,
+   kbyanc@freedomnet.com 4/10/98
+*/
+/* bit definitions for AMD Write Allocate Top-Of-Memory and Control Register */
+#define AMD_WT_ALLOC_TME	0x40000	/* top-of-memory enable */
+#define AMD_WT_ALLOC_PRE	0x20000 /* programmable range enable */
+#define AMD_WT_ALLOC_FRE	0x10000 /* fixed (A0000-FFFFF) range enable */
+
+static void init_amdK5(void)
+{
+	u_long	msr;
+#ifdef CPU_AMD_WT_ALLOC
+/* enable write allocate on AMD processors that support it */
+/* AMD K5, Model 1, 2, and 3 Stepping 4 or higher all support it per
+   AMD Write Allocate Application Note: http://www.amd.com/K6/k6docs/pdf/21326c.pdf
+*/
+	if(((cpu_id & 0xF0) > 0) &&  /* check the model number (K6 is technically model 6, but we
+					have already identified this as a K5 so that's moot */
+	  ((cpu_id & 0x0F) > 4)) {   /* make sure the stepping is at least 4 */
+		disable_intr();
+		msr=rdmsr(0x83);     /* AMD Hardware Configuration Register */
+		wrmsr(0x83, msr&!(0x10));
+		/* now set the programmable range to include the 15M-16M range for
+		   compatibility with hardware that memory-maps this range
+		*/
+                wrmsr(0x86, 0x0FF00F0);
+		/* now we are going to set the Top-Of-Memory Enable and Fixed-Memory Enable
+		   bits in the Write Allocate register on the AMD. We also have to tell the
+		   chip where the top of memory is. (We don't want to write-allocate past
+		   the top of memory because video cards could have frame buffers there,
+		   memory-mapped I/O could be there, etc.
+		*/
+		msr=Maxmem>>PAGE_SHIFT<<16; /* load the msr with the high 16 bits of the top of physical memory */
+		wrmsr(0x85, AMD_WT_ALLOC_TME|AMD_WT_ALLOC_PRE|AMD_WT_ALLOC_FRE|msr);
+		rdmsr(0x85);
+		msr=rdmsr(0x83);
+		wrmsr(0x83, msr|0x10); /* enable write allocate */
+		enable_intr();
+		printf("AMD K5 write allocate enabled\n");
+	}
+#endif
+}
+
+static void init_amdK6(void)
+{
+	u_long	eflags;
+#ifdef CPU_AMD_WT_ALLOC
+/* enable write allocate on AMD processors that support it */
+/* AMD K6, Model 1 Stepping 4 or higher all support it per
+   AMD Write Allocate Application Note: http://www.amd.com/K6/k6docs/pdf/21326c.pdf
+*/
+	if((cpu_id & 0xFF) > 0x60) {   /* we already know it is a K6, just check the stepping
+					 (later models appear to support write allocate no matter
+					 what the stepping) */
+		eflags = read_eflags();
+		disable_intr();
+		wbinvd();			/* the K6 requires us to invalidate the cache */
+		wrmsr(0x0C0000082, (Maxmem>>9)&0x0FE);/* K6 uses a limit measured in 4M blocks (we convert from pages).
+							 we also make sure that 8-63 are 0 and that we disable
+							 write allocate for the 15-16M range */
+		write_eflags(eflags);
+		enable_intr();
+		printf("AMD K6 write allocate enabled\n");
+	}
+#endif
+}
+#endif /* I586_CPU */
+
+
 #ifdef I486_CPU
 /*
  * IBM Blue Lightning
@@ -462,6 +537,14 @@
 		init_6x86();
 		break;
 #endif /* I486_CPU */
+#ifdef I586_CPU
+	case CPU_AMDK5:
+		init_amdK5();
+		break;
+	case CPU_AMDK6:
+		init_amdK6();
+		break;
+#endif /* I586_CPU */
 #ifdef I686_CPU
 	case CPU_M2:
 		init_6x86MX();
diff -u -r /sys/i386/include/cputypes.h /sys/i386/include/cputypes.h
--- /sys/i386/include/cputypes.h	Fri Apr 10 14:24:12 1998
+++ /sys/i386/include/cputypes.h	Fri Apr 10 14:22:45 1998
@@ -58,4 +58,6 @@
 #define	CPU_M2		11	/* Cyrix M2 (aka enhanced 6x86 with MMX */
 #define CPU_NX586	12	/* NexGen (now AMD) 586 */
 #define	CPU_CY486DX	13	/* Cyrix 486S/DX/DX2/DX4 */
+#define CPU_AMDK5	14	/* AMD K5 */
+#define CPU_AMDK6	15	/* AMD K6 with MMX */
 #endif /* _MACHINE_CPUTYPES_H_ */

>How-To-Repeat:

>Fix:

>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199804102207.PAA24161>