Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 23 Dec 1998 23:55:54 -0500 (EST)
From:      Brian Feldman <green@unixhelp.org>
To:        current@FreeBSD.ORG
Subject:   K6-2 (3?) CPU_WT_ALLOC
Message-ID:  <Pine.BSF.4.05.9812232352170.29349-100000@janus.syracuse.net>

next in thread | raw e-mail | index | archive | help
CPU_WT_ALLOC does not work correctly for K6-2s of model 8+ and probably K6-3s
when they appear on the market soon. In addition, print_AMD_info() incorrectly
printfs write allocation's size. I've fixed them, so they now Do The Right
Thing, and added a "NO_MEMORY_HOLE" option to easily allow 15-16mb range
handling for us K6 and K6-2 users. A patch follows in cleartext and encoded
forms.

 Brian Feldman						  _ __  ___ ___ ___  
 green@unixhelp.org				      _ __ ___ | _ ) __|   \ 
		      http://www.freebsd.org/	 _ __ ___ ____ | _ \__ \ |) |
 FreeBSD: The Power to Serve!		   _ __ ___ ____ _____ |___/___/___/ 

--- src/sys/i386/conf/options.i386.orig	Wed Dec 23 20:36:45 1998
+++ src/sys/i386/conf/options.i386	Wed Dec 23 20:36:56 1998
@@ -57,6 +57,7 @@
 CPU_WT_ALLOC			opt_cpu.h
 CYRIX_CACHE_WORKS		opt_cpu.h
 CYRIX_CACHE_REALLY_WORKS	opt_cpu.h
+NO_MEMORY_HOLE			opt_cpu.h
 
 # The CPU type affects the endian conversion functions all over the kernel.
 I386_CPU		opt_global.h
--- src/sys/i386/i386/identcpu.c.orig	Mon Dec 21 23:12:18 1998
+++ src/sys/i386/i386/identcpu.c	Wed Dec 23 20:30:39 1998
@@ -68,6 +68,7 @@
 #if defined(I586_CPU) && defined(CPU_WT_ALLOC)
 void	enable_K5_wt_alloc(void);
 void	enable_K6_wt_alloc(void);
+void	enable_K6_2_wt_alloc(void);
 #endif
 void panicifcpuunsupported(void);
 static void identifycyrix(void);
@@ -291,9 +292,11 @@
 		if ((cpu_id & 0xf00) == 0x500) {
 			if (((cpu_id & 0x0f0) > 0)
 			    && ((cpu_id & 0x0f0) < 0x60)
-			    && ((cpu_id & 0x00f) > 3)) {
+			    && ((cpu_id & 0x00f) > 3))
 				enable_K5_wt_alloc();
-			} else if ((cpu_id & 0x0f0) > 0x50)
+			else if ((cpu_id & 0x0f0) > 0x70)
+				enable_K6_2_wt_alloc();
+			else if ((cpu_id & 0x0f0) > 0x50)
 				enable_K6_wt_alloc();
 		}
 #endif
@@ -860,18 +863,28 @@
 	switch (cpu_id & 0xFF0) {
 	case 0x560:	/* K6 0.35u */
 	case 0x570:	/* K6 0.25u */
-	case 0x580:	/* K6-2 */
-	case 0x590:	/* K6-3 */
 		amd_whcr = rdmsr(0xc0000082);
 		if (!(amd_whcr & 0x00fe)) {
 			printf("Write Allocate Disable\n");
 		} else {
 			printf("Write Allocate Enable Limit: %dM bytes\n",
-			    (u_int32_t)(amd_whcr & 0x00fe) * 2);
+			    (u_int32_t)(amd_whcr & 0x00fe) * 4);
 			printf("Write Allocate 15-16M bytes: %s\n",
 			    (amd_whcr & 0x0001) ? "Enable" : "Disable");
 			printf("Hardware Write Allocate Control: %s\n",
 			    (amd_whcr & 0x0100) ? "Enable" : "Disable");
+		}
+		break;
+	case 0x580:	/* K6-2 */
+	case 0x590:	/* K6-3 */
+		amd_whcr = rdmsr(0xc0000082);
+		if (!(amd_whcr & (0x3ff << 22))) {
+			printf("Write Allocate Disable\n");
+		} else {
+			printf("Write Allocate Enable Limit: %dM bytes\n",
+			    (u_int32_t)((amd_whcr & (0x3ff << 22)) >> 22) * 4);
+			printf("Write Allocate 15-16M bytes: %s\n",
+			    (amd_whcr & (1 << 16)) ? "Enable" : "Disable");
 		}
 		break;
 	}
--- src/sys/i386/i386/initcpu.c.orig	Mon Dec 21 23:01:26 1998
+++ src/sys/i386/i386/initcpu.c	Wed Dec 23 19:53:10 1998
@@ -44,6 +44,7 @@
 #if defined(I586_CPU) && defined(CPU_WT_ALLOC)
 void	enable_K5_wt_alloc(void);
 void	enable_K6_wt_alloc(void);
+void	enable_K6_2_wt_alloc(void);
 #endif
 
 #ifdef I486_CPU
@@ -628,8 +629,9 @@
 	whcr &= ~0x00feLL;
 	whcr |= (size << 1);
 
-#ifdef PC98
+#if defined(PC98) || defined(NO_MEMORY_HOLE)
 	if (whcr & 0x00feLL) {
+#ifdef PC98
 		/*
 		 * If bit 2 of port 0x43b is 0, disable wrte allocate for the
 		 * 15-16M range.
@@ -637,6 +639,7 @@
 		if (!(inb(0x43b) & 4))
 			whcr &= ~0x0001LL;
 		else
+#endif
 			whcr |=  0x0001LL;
 	}
 #else
@@ -644,7 +647,68 @@
 	 * There is no way to know wheter 15-16M hole exists or not. 
 	 * Therefore, we disable write allocate for this range.
 	 */
-	whcr &= 0x00feLL;
+	whcr &= ~0x0001LL;
+#endif
+	wrmsr(0x0c0000082, whcr);
+
+	write_eflags(eflags);
+	enable_intr();
+}
+
+void
+enable_K6_2_wt_alloc(void)
+{
+	quad_t	size;
+	u_int64_t	whcr;
+	u_long	eflags;
+
+	eflags = read_eflags();
+	disable_intr();
+	wbinvd();
+
+#ifdef CPU_DISABLE_CACHE
+	/*
+	 * Certain K6-2 box becomes unstable when write allocation is
+	 * enabled.
+	 */
+	/*
+	 * The AMD-K6 processer provides the 64-bit Test Register 12(TR12),
+	 * but only the Cache Inhibit(CI) (bit 3 of TR12) is suppported.
+	 * All other bits in TR12 have no effect on the processer's operation.
+	 * The I/O Trap Restart function (bit 9 of TR12) is always enabled
+	 * on the AMD-K6.
+	 */
+	wrmsr(0x0000000e, (u_int64_t)0x0008);
+#endif
+	/* Don't assume that memory size is aligned with 4M. */
+	if (Maxmem > 0)
+	  size = ((Maxmem >> 8) + 3) >> 2;
+	else
+	  size = 0;
+
+	/* Limit is 4092M bytes. */
+	size &= 0x3ff;
+	whcr = (rdmsr(0xc0000082) & ~(0x3ffLL << 22)) | (size << 22);
+
+#if defined(PC98) || defined(NO_MEMORY_HOLE)
+	if (whcr & (0x3ffLL << 22)) {
+#ifdef PC98
+		/*
+		 * If bit 2 of port 0x43b is 0, disable wrte allocate for the
+		 * 15-16M range.
+		 */
+		if (!(inb(0x43b) & 4))
+			whcr &= ~(1LL << 16);
+		else
+#endif
+			whcr |=  1LL << 16;
+	}
+#else
+	/*
+	 * There is no way to know wheter 15-16M hole exists or not. 
+	 * Therefore, we disable write allocate for this range.
+	 */
+	whcr &= ~(1LL << 16);
 #endif
 	wrmsr(0x0c0000082, whcr);
 



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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.05.9812232352170.29349-100000>