summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authormsmith <msmith@FreeBSD.org>1998-12-27 23:23:26 +0000
committermsmith <msmith@FreeBSD.org>1998-12-27 23:23:26 +0000
commit7d69874701ab8fb7883fed77b6d23f1328fbb6e0 (patch)
tree0e60ef6169cbebe7c704506df6a10e2f17b83418 /sys
parent4a9f4655409a70d5a5fab4ac14d3eee37332e2f0 (diff)
downloadFreeBSD-src-7d69874701ab8fb7883fed77b6d23f1328fbb6e0.zip
FreeBSD-src-7d69874701ab8fb7883fed77b6d23f1328fbb6e0.tar.gz
From the submitter:
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. Submitted by: Brian Feldman <green@unixhelp.org>
Diffstat (limited to 'sys')
-rw-r--r--sys/amd64/amd64/identcpu.c25
-rw-r--r--sys/amd64/amd64/initcpu.c70
-rw-r--r--sys/conf/NOTES6
-rw-r--r--sys/conf/options.i3863
-rw-r--r--sys/i386/conf/LINT6
-rw-r--r--sys/i386/conf/NOTES6
-rw-r--r--sys/i386/conf/options.i3863
-rw-r--r--sys/i386/i386/identcpu.c25
-rw-r--r--sys/i386/i386/initcpu.c70
9 files changed, 191 insertions, 23 deletions
diff --git a/sys/amd64/amd64/identcpu.c b/sys/amd64/amd64/identcpu.c
index 9b6d722..64972ec 100644
--- a/sys/amd64/amd64/identcpu.c
+++ b/sys/amd64/amd64/identcpu.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* from: Id: machdep.c,v 1.193 1996/06/18 01:22:04 bde Exp
- * $Id: identcpu.c,v 1.52 1998/10/06 13:16:23 kato Exp $
+ * $Id: identcpu.c,v 1.53 1998/12/05 16:30:55 kato Exp $
*/
#include "opt_cpu.h"
@@ -68,6 +68,7 @@ void earlysetcpuclass(void);
#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 @@ printcpuinfo(void)
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,19 +863,29 @@ print_AMD_info(void)
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;
}
}
diff --git a/sys/amd64/amd64/initcpu.c b/sys/amd64/amd64/initcpu.c
index 9fb8008..330f9ef 100644
--- a/sys/amd64/amd64/initcpu.c
+++ b/sys/amd64/amd64/initcpu.c
@@ -26,7 +26,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: initcpu.c,v 1.14 1998/10/06 13:16:23 kato Exp $
+ * $Id: initcpu.c,v 1.15 1998/12/14 06:16:13 dillon Exp $
*/
#include "opt_cpu.h"
@@ -44,6 +44,7 @@ void initializecpu(void);
#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 @@ enable_K6_wt_alloc(void)
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 @@ enable_K6_wt_alloc(void)
if (!(inb(0x43b) & 4))
whcr &= ~0x0001LL;
else
+#endif
whcr |= 0x0001LL;
}
#else
@@ -644,7 +647,68 @@ enable_K6_wt_alloc(void)
* 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);
diff --git a/sys/conf/NOTES b/sys/conf/NOTES
index ba4d97b..165501e 100644
--- a/sys/conf/NOTES
+++ b/sys/conf/NOTES
@@ -2,7 +2,7 @@
# LINT -- config file for checking all the sources, tries to pull in
# as much of the source tree as it can.
#
-# $Id: LINT,v 1.520 1998/12/27 19:51:34 phk Exp $
+# $Id: LINT,v 1.521 1998/12/27 21:46:55 phk Exp $
#
# NB: You probably don't want to try running a kernel built from this
# file. Instead, you should start from GENERIC, and add options from
@@ -178,6 +178,10 @@ cpu "I686_CPU" # aka Pentium Pro(tm)
# executed. This should be included for ALL kernels that won't run
# on a Pentium.
#
+# NO_MEMORY_HOLE is an optimisation for systems with AMD K6 processors
+# which indicates that the 15-16MB range is *definitely* not being
+# occupied by an ISA memory hole.
+#
# NOTE 1: The options, CPU_BTB_EN, CPU_LOOP_EN, CPU_IORT,
# CPU_LOOP_ENand CPU_RSTK_EN should not be used becasue of CPU bugs.
# These options may crash your system.
diff --git a/sys/conf/options.i386 b/sys/conf/options.i386
index 4604c9a..3a706ab 100644
--- a/sys/conf/options.i386
+++ b/sys/conf/options.i386
@@ -1,4 +1,4 @@
-# $Id: options.i386,v 1.98 1998/12/27 14:21:08 sos Exp $
+# $Id: options.i386,v 1.99 1998/12/27 21:46:55 phk Exp $
DISABLE_PSE
IDE_DELAY
@@ -56,6 +56,7 @@ CPU_UPGRADE_HW_CACHE opt_cpu.h
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
diff --git a/sys/i386/conf/LINT b/sys/i386/conf/LINT
index ba4d97b..165501e 100644
--- a/sys/i386/conf/LINT
+++ b/sys/i386/conf/LINT
@@ -2,7 +2,7 @@
# LINT -- config file for checking all the sources, tries to pull in
# as much of the source tree as it can.
#
-# $Id: LINT,v 1.520 1998/12/27 19:51:34 phk Exp $
+# $Id: LINT,v 1.521 1998/12/27 21:46:55 phk Exp $
#
# NB: You probably don't want to try running a kernel built from this
# file. Instead, you should start from GENERIC, and add options from
@@ -178,6 +178,10 @@ cpu "I686_CPU" # aka Pentium Pro(tm)
# executed. This should be included for ALL kernels that won't run
# on a Pentium.
#
+# NO_MEMORY_HOLE is an optimisation for systems with AMD K6 processors
+# which indicates that the 15-16MB range is *definitely* not being
+# occupied by an ISA memory hole.
+#
# NOTE 1: The options, CPU_BTB_EN, CPU_LOOP_EN, CPU_IORT,
# CPU_LOOP_ENand CPU_RSTK_EN should not be used becasue of CPU bugs.
# These options may crash your system.
diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES
index ba4d97b..165501e 100644
--- a/sys/i386/conf/NOTES
+++ b/sys/i386/conf/NOTES
@@ -2,7 +2,7 @@
# LINT -- config file for checking all the sources, tries to pull in
# as much of the source tree as it can.
#
-# $Id: LINT,v 1.520 1998/12/27 19:51:34 phk Exp $
+# $Id: LINT,v 1.521 1998/12/27 21:46:55 phk Exp $
#
# NB: You probably don't want to try running a kernel built from this
# file. Instead, you should start from GENERIC, and add options from
@@ -178,6 +178,10 @@ cpu "I686_CPU" # aka Pentium Pro(tm)
# executed. This should be included for ALL kernels that won't run
# on a Pentium.
#
+# NO_MEMORY_HOLE is an optimisation for systems with AMD K6 processors
+# which indicates that the 15-16MB range is *definitely* not being
+# occupied by an ISA memory hole.
+#
# NOTE 1: The options, CPU_BTB_EN, CPU_LOOP_EN, CPU_IORT,
# CPU_LOOP_ENand CPU_RSTK_EN should not be used becasue of CPU bugs.
# These options may crash your system.
diff --git a/sys/i386/conf/options.i386 b/sys/i386/conf/options.i386
index 4604c9a..3a706ab 100644
--- a/sys/i386/conf/options.i386
+++ b/sys/i386/conf/options.i386
@@ -1,4 +1,4 @@
-# $Id: options.i386,v 1.98 1998/12/27 14:21:08 sos Exp $
+# $Id: options.i386,v 1.99 1998/12/27 21:46:55 phk Exp $
DISABLE_PSE
IDE_DELAY
@@ -56,6 +56,7 @@ CPU_UPGRADE_HW_CACHE opt_cpu.h
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
diff --git a/sys/i386/i386/identcpu.c b/sys/i386/i386/identcpu.c
index 9b6d722..64972ec 100644
--- a/sys/i386/i386/identcpu.c
+++ b/sys/i386/i386/identcpu.c
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* from: Id: machdep.c,v 1.193 1996/06/18 01:22:04 bde Exp
- * $Id: identcpu.c,v 1.52 1998/10/06 13:16:23 kato Exp $
+ * $Id: identcpu.c,v 1.53 1998/12/05 16:30:55 kato Exp $
*/
#include "opt_cpu.h"
@@ -68,6 +68,7 @@ void earlysetcpuclass(void);
#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 @@ printcpuinfo(void)
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,19 +863,29 @@ print_AMD_info(void)
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;
}
}
diff --git a/sys/i386/i386/initcpu.c b/sys/i386/i386/initcpu.c
index 9fb8008..330f9ef 100644
--- a/sys/i386/i386/initcpu.c
+++ b/sys/i386/i386/initcpu.c
@@ -26,7 +26,7 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
- * $Id: initcpu.c,v 1.14 1998/10/06 13:16:23 kato Exp $
+ * $Id: initcpu.c,v 1.15 1998/12/14 06:16:13 dillon Exp $
*/
#include "opt_cpu.h"
@@ -44,6 +44,7 @@ void initializecpu(void);
#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 @@ enable_K6_wt_alloc(void)
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 @@ enable_K6_wt_alloc(void)
if (!(inb(0x43b) & 4))
whcr &= ~0x0001LL;
else
+#endif
whcr |= 0x0001LL;
}
#else
@@ -644,7 +647,68 @@ enable_K6_wt_alloc(void)
* 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);
OpenPOWER on IntegriCloud