summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorkato <kato@FreeBSD.org>1998-10-06 13:16:29 +0000
committerkato <kato@FreeBSD.org>1998-10-06 13:16:29 +0000
commit5c811970f93597f910f75c2df6a06a262c02984f (patch)
tree15b2411727db7060104658127a54dd17de6e7b9a /sys
parentf37c35755da9a0f27e648ac1ffc453524689aac6 (diff)
downloadFreeBSD-src-5c811970f93597f910f75c2df6a06a262c02984f.zip
FreeBSD-src-5c811970f93597f910f75c2df6a06a262c02984f.tar.gz
- Implement enabling write allocate on AMD K5/K6/K6-2 cpus.
The code was originaly contributed by Kelly Yancey <kbyanc@freedomnet.com> in PR i386/6269 and revised by Akio Morita <amorita@meadow.scphys.kyoto-u.ac.jp> and me. Test was performed by Akio Morita and Toshiomi Moriki <moriki@db.is.kyushu-u.ac.jp>. - Fix stylistic bug in identcpu.c. - Update copyright in initcpu.c - Fix typo in LINT. PR: 6269 and 6270
Diffstat (limited to 'sys')
-rw-r--r--sys/amd64/amd64/identcpu.c30
-rw-r--r--sys/amd64/amd64/initcpu.c126
-rw-r--r--sys/amd64/include/specialreg.h7
-rw-r--r--sys/conf/NOTES8
-rw-r--r--sys/conf/options.i3863
-rw-r--r--sys/conf/options.pc983
-rw-r--r--sys/i386/conf/LINT8
-rw-r--r--sys/i386/conf/NOTES8
-rw-r--r--sys/i386/conf/options.i3863
-rw-r--r--sys/i386/i386/identcpu.c30
-rw-r--r--sys/i386/i386/initcpu.c126
-rw-r--r--sys/i386/include/specialreg.h7
-rw-r--r--sys/pc98/conf/options.pc983
13 files changed, 331 insertions, 31 deletions
diff --git a/sys/amd64/amd64/identcpu.c b/sys/amd64/amd64/identcpu.c
index d504941..98b9edf 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.50 1998/07/11 05:59:34 bde Exp $
+ * $Id: identcpu.c,v 1.51 1998/07/11 07:45:28 bde Exp $
*/
#include "opt_cpu.h"
@@ -65,6 +65,10 @@ void i486_bzero __P((void *buf, size_t len));
void printcpuinfo(void); /* XXX should be in different header file */
void finishidentcpu(void);
void earlysetcpuclass(void);
+#if defined(I586_CPU) && defined(CPU_WT_ALLOC)
+void enable_K5_wt_alloc(void);
+void enable_K6_wt_alloc(void);
+#endif
void panicifcpuunsupported(void);
static void identifycyrix(void);
static void print_AMD_info(void);
@@ -273,10 +277,26 @@ printcpuinfo(void)
case 0x560:
strcat(cpu_model, "K6");
break;
+ case 0x570:
+ strcat(cpu_model, "K6 266 (model 1)");
+ break;
+ case 0x580:
+ strcat(cpu_model, "K6-2");
+ break;
default:
strcat(cpu_model, "Unknown");
break;
}
+#ifdef CPU_WT_ALLOC
+ if ((cpu_id & 0xf00) == 0x500) {
+ if (((cpu_id & 0x0f0) > 0)
+ && ((cpu_id & 0x0f0) < 0x60)
+ && ((cpu_id & 0x00f) > 3)) {
+ enable_K5_wt_alloc();
+ } else if ((cpu_id & 0x0f0) > 0x50)
+ enable_K6_wt_alloc();
+ }
+#endif
do_cpuid(0x80000000, regs);
nreg = regs[0];
if (nreg >= 0x80000004) {
@@ -488,7 +508,7 @@ printcpuinfo(void)
* 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"
@@ -636,7 +656,7 @@ identblue(void)
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
@@ -792,7 +812,7 @@ finishidentcpu(void)
}
/*
- * 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
@@ -816,7 +836,7 @@ print_AMD_assoc(int i)
}
static void
-print_AMD_info(void)
+print_AMD_info(void)
{
u_int regs[4];
diff --git a/sys/amd64/amd64/initcpu.c b/sys/amd64/amd64/initcpu.c
index 3849299..9f1f2a9 100644
--- a/sys/amd64/amd64/initcpu.c
+++ b/sys/amd64/amd64/initcpu.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) KATO Takenori, 1997.
+ * Copyright (c) KATO Takenori, 1997, 1998.
*
* All rights reserved. Unpublished rights reserved under the copyright
* laws of Japan.
@@ -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.12 1998/02/04 03:47:14 eivind Exp $
+ * $Id: initcpu.c,v 1.13 1998/05/16 14:38:10 kato Exp $
*/
#include "opt_cpu.h"
@@ -41,6 +41,11 @@
#include <machine/specialreg.h>
void initializecpu(void);
+#if defined(I586_CPU) && defined(CPU_WT_ALLOC)
+void enable_K5_wt_alloc(void);
+void enable_K6_wt_alloc(void);
+#endif
+
#ifdef I486_CPU
static void init_5x86(void);
static void init_bluelightning(void);
@@ -439,7 +444,7 @@ static void
init_ppro(void)
{
#ifndef SMP
- quad_t apicbase;
+ u_int64_t apicbase;
/*
* Local APIC should be diabled in UP kernel.
@@ -533,6 +538,121 @@ initializecpu(void)
#endif /* PC98 && !UPGRADE_CPU_HW_CACHE */
}
+#if defined(I586_CPU) && defined(CPU_WT_ALLOC)
+/*
+ * Enable write allocate feature of AMD processors.
+ * Following two functions require the Maxmem variable being set.
+ */
+void
+enable_K5_wt_alloc(void)
+{
+ u_int64_t msr;
+
+ /*
+ * Write allocate is supported only on models 1, 2, and 3, with
+ * a stepping of 4 or greater.
+ */
+ if (((cpu_id & 0xf0) > 0) && ((cpu_id & 0x0f) > 3)) {
+ disable_intr();
+ msr = rdmsr(0x83); /* HWCR */
+ wrmsr(0x83, msr & !(0x10));
+
+ /*
+ * We have to tell the chip where the top of memory is,
+ * since video cards could have frame bufferes there,
+ * memory-mapped I/O could be there, etc.
+ */
+ if(Maxmem > 0)
+ msr = Maxmem / 16;
+ else
+ msr = 0;
+ msr |= AMD_WT_ALLOC_TME | AMD_WT_ALLOC_FRE;
+#ifdef PC98
+ if (!(inb(0x43b) & 4)) {
+ wrmsr(0x86, 0x0ff00f0);
+ msr |= AMD_WT_ALLOC_PRE;
+ }
+#else
+ /*
+ * There is no way to know wheter 15-16M hole exists or not.
+ * Therefore, we disable write allocate for this range.
+ */
+ wrmsr(0x86, 0x0ff00f0);
+ msr |= AMD_WT_ALLOC_PRE;
+#endif
+ wrmsr(0x85, msr);
+
+ msr=rdmsr(0x83);
+ wrmsr(0x83, msr|0x10); /* enable write allocate */
+
+ enable_intr();
+ }
+}
+
+void
+enable_K6_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 / 256;
+ else
+ size = 0;
+ size = (size + 3) / 4;
+
+ /* Limit is 508M bytes. */
+ if (size > 127)
+ size = 127;
+ whcr = rdmsr(0xc0000082);
+ whcr &= ~0x00feLL;
+ whcr |= (size << 1);
+
+#ifdef PC98
+ if (whcr & 0x00feLL) {
+ /*
+ * If bit 2 of port 0x43b is 0, disable wrte allocate for the
+ * 15-16M range.
+ */
+ if (!(inb(0x43b) & 4))
+ whcr &= ~0x0001LL;
+ else
+ whcr |= 0x0001LL;
+ }
+#else
+ /*
+ * There is no way to know wheter 15-16M hole exists or not.
+ * Therefore, we disable write allocate for this range.
+ */
+ whcr &= 0x00feLL;
+#endif
+ wrmsr(0x0c0000082, whcr);
+
+ write_eflags(eflags);
+ enable_intr();
+}
+#endif /* I585_CPU && CPU_WT_ALLOC */
+
#include "opt_ddb.h"
#ifdef DDB
#include <ddb/ddb.h>
diff --git a/sys/amd64/include/specialreg.h b/sys/amd64/include/specialreg.h
index c09e51a..c09c2de 100644
--- a/sys/amd64/include/specialreg.h
+++ b/sys/amd64/include/specialreg.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)specialreg.h 7.1 (Berkeley) 5/9/91
- * $Id: specialreg.h,v 1.14 1997/07/21 17:53:51 fsmp Exp $
+ * $Id: specialreg.h,v 1.15 1998/03/04 11:39:16 kato Exp $
*/
#ifndef _MACHINE_SPECIALREG_H_
@@ -258,6 +258,11 @@
#define RCR_WT 0x10 /* Write-through. */
#define RCR_NLB 0x20 /* LBA# pin is not asserted. */
+/* 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 */
+
#ifndef LOCORE
static __inline u_char
diff --git a/sys/conf/NOTES b/sys/conf/NOTES
index dc8ccff..b74cb36 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.481 1998/10/02 21:00:58 ken Exp $
+# $Id: LINT,v 1.482 1998/10/05 07:45:54 obrien 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
@@ -163,7 +163,8 @@ cpu "I686_CPU" # aka Pentium Pro(tm)
# CPU_SUSP_HLT enables suspend on HALT. If this option is set, CPU
# enters suspend mode following execution of HALT instruction.
#
-# CPU_WT_ALLOC enables write-through allocation.
+# CPU_WT_ALLOC enables write allocation on Cyrix 6x86/6x86MX and AMD
+# K5/K6/K6-2 cpus.
#
# CYRIX_CACHE_WORKS enables CPU cache on Cyrix 486 CPUs with cache
# flush at hold state.
@@ -178,7 +179,7 @@ cpu "I686_CPU" # aka Pentium Pro(tm)
# on a Pentium.
#
# NOTE 1: The options, CPU_BTB_EN, CPU_LOOP_EN, CPU_IORT,
-# CPU_LOOP_ENand CPU_RSTK_EN should no be used becasue of CPU bugs.
+# CPU_LOOP_ENand CPU_RSTK_EN should not be used becasue of CPU bugs.
# These options may crash your system.
#
# NOTE 2: If CYRIX_CACHE_REALLY_WORKS is not set, CPU cache is enabled
@@ -199,6 +200,7 @@ options "CPU_IORT"
options "CPU_LOOP_EN"
options "CPU_RSTK_EN"
options "CPU_SUSP_HLT"
+options "CPU_WT_ALLOC"
options "CYRIX_CACHE_WORKS"
options "CYRIX_CACHE_REALLY_WORKS"
#options "NO_F00F_HACK"
diff --git a/sys/conf/options.i386 b/sys/conf/options.i386
index d0553ee..9cb9eb8 100644
--- a/sys/conf/options.i386
+++ b/sys/conf/options.i386
@@ -1,4 +1,4 @@
-# $Id: options.i386,v 1.88 1998/09/24 13:20:40 yokota Exp $
+# $Id: options.i386,v 1.89 1998/09/25 17:34:48 peter Exp $
DISABLE_PSE
USER_LDT
@@ -58,6 +58,7 @@ CPU_LOOP_EN opt_cpu.h
CPU_RSTK_EN opt_cpu.h
CPU_SUSP_HLT opt_cpu.h
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
diff --git a/sys/conf/options.pc98 b/sys/conf/options.pc98
index da7f2f0..d18cabc 100644
--- a/sys/conf/options.pc98
+++ b/sys/conf/options.pc98
@@ -1,4 +1,4 @@
-# $Id: options.pc98,v 1.67 1998/09/16 08:37:40 kato Exp $
+# $Id: options.pc98,v 1.68 1998/09/28 08:23:26 kato Exp $
DISABLE_PSE
USER_LDT
MATH_EMULATE opt_math_emulate.h
@@ -57,6 +57,7 @@ CPU_LOOP_EN opt_cpu.h
CPU_RSTK_EN opt_cpu.h
CPU_SUSP_HLT opt_cpu.h
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
diff --git a/sys/i386/conf/LINT b/sys/i386/conf/LINT
index dc8ccff..b74cb36 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.481 1998/10/02 21:00:58 ken Exp $
+# $Id: LINT,v 1.482 1998/10/05 07:45:54 obrien 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
@@ -163,7 +163,8 @@ cpu "I686_CPU" # aka Pentium Pro(tm)
# CPU_SUSP_HLT enables suspend on HALT. If this option is set, CPU
# enters suspend mode following execution of HALT instruction.
#
-# CPU_WT_ALLOC enables write-through allocation.
+# CPU_WT_ALLOC enables write allocation on Cyrix 6x86/6x86MX and AMD
+# K5/K6/K6-2 cpus.
#
# CYRIX_CACHE_WORKS enables CPU cache on Cyrix 486 CPUs with cache
# flush at hold state.
@@ -178,7 +179,7 @@ cpu "I686_CPU" # aka Pentium Pro(tm)
# on a Pentium.
#
# NOTE 1: The options, CPU_BTB_EN, CPU_LOOP_EN, CPU_IORT,
-# CPU_LOOP_ENand CPU_RSTK_EN should no be used becasue of CPU bugs.
+# CPU_LOOP_ENand CPU_RSTK_EN should not be used becasue of CPU bugs.
# These options may crash your system.
#
# NOTE 2: If CYRIX_CACHE_REALLY_WORKS is not set, CPU cache is enabled
@@ -199,6 +200,7 @@ options "CPU_IORT"
options "CPU_LOOP_EN"
options "CPU_RSTK_EN"
options "CPU_SUSP_HLT"
+options "CPU_WT_ALLOC"
options "CYRIX_CACHE_WORKS"
options "CYRIX_CACHE_REALLY_WORKS"
#options "NO_F00F_HACK"
diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES
index dc8ccff..b74cb36 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.481 1998/10/02 21:00:58 ken Exp $
+# $Id: LINT,v 1.482 1998/10/05 07:45:54 obrien 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
@@ -163,7 +163,8 @@ cpu "I686_CPU" # aka Pentium Pro(tm)
# CPU_SUSP_HLT enables suspend on HALT. If this option is set, CPU
# enters suspend mode following execution of HALT instruction.
#
-# CPU_WT_ALLOC enables write-through allocation.
+# CPU_WT_ALLOC enables write allocation on Cyrix 6x86/6x86MX and AMD
+# K5/K6/K6-2 cpus.
#
# CYRIX_CACHE_WORKS enables CPU cache on Cyrix 486 CPUs with cache
# flush at hold state.
@@ -178,7 +179,7 @@ cpu "I686_CPU" # aka Pentium Pro(tm)
# on a Pentium.
#
# NOTE 1: The options, CPU_BTB_EN, CPU_LOOP_EN, CPU_IORT,
-# CPU_LOOP_ENand CPU_RSTK_EN should no be used becasue of CPU bugs.
+# CPU_LOOP_ENand CPU_RSTK_EN should not be used becasue of CPU bugs.
# These options may crash your system.
#
# NOTE 2: If CYRIX_CACHE_REALLY_WORKS is not set, CPU cache is enabled
@@ -199,6 +200,7 @@ options "CPU_IORT"
options "CPU_LOOP_EN"
options "CPU_RSTK_EN"
options "CPU_SUSP_HLT"
+options "CPU_WT_ALLOC"
options "CYRIX_CACHE_WORKS"
options "CYRIX_CACHE_REALLY_WORKS"
#options "NO_F00F_HACK"
diff --git a/sys/i386/conf/options.i386 b/sys/i386/conf/options.i386
index d0553ee..9cb9eb8 100644
--- a/sys/i386/conf/options.i386
+++ b/sys/i386/conf/options.i386
@@ -1,4 +1,4 @@
-# $Id: options.i386,v 1.88 1998/09/24 13:20:40 yokota Exp $
+# $Id: options.i386,v 1.89 1998/09/25 17:34:48 peter Exp $
DISABLE_PSE
USER_LDT
@@ -58,6 +58,7 @@ CPU_LOOP_EN opt_cpu.h
CPU_RSTK_EN opt_cpu.h
CPU_SUSP_HLT opt_cpu.h
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
diff --git a/sys/i386/i386/identcpu.c b/sys/i386/i386/identcpu.c
index d504941..98b9edf 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.50 1998/07/11 05:59:34 bde Exp $
+ * $Id: identcpu.c,v 1.51 1998/07/11 07:45:28 bde Exp $
*/
#include "opt_cpu.h"
@@ -65,6 +65,10 @@ void i486_bzero __P((void *buf, size_t len));
void printcpuinfo(void); /* XXX should be in different header file */
void finishidentcpu(void);
void earlysetcpuclass(void);
+#if defined(I586_CPU) && defined(CPU_WT_ALLOC)
+void enable_K5_wt_alloc(void);
+void enable_K6_wt_alloc(void);
+#endif
void panicifcpuunsupported(void);
static void identifycyrix(void);
static void print_AMD_info(void);
@@ -273,10 +277,26 @@ printcpuinfo(void)
case 0x560:
strcat(cpu_model, "K6");
break;
+ case 0x570:
+ strcat(cpu_model, "K6 266 (model 1)");
+ break;
+ case 0x580:
+ strcat(cpu_model, "K6-2");
+ break;
default:
strcat(cpu_model, "Unknown");
break;
}
+#ifdef CPU_WT_ALLOC
+ if ((cpu_id & 0xf00) == 0x500) {
+ if (((cpu_id & 0x0f0) > 0)
+ && ((cpu_id & 0x0f0) < 0x60)
+ && ((cpu_id & 0x00f) > 3)) {
+ enable_K5_wt_alloc();
+ } else if ((cpu_id & 0x0f0) > 0x50)
+ enable_K6_wt_alloc();
+ }
+#endif
do_cpuid(0x80000000, regs);
nreg = regs[0];
if (nreg >= 0x80000004) {
@@ -488,7 +508,7 @@ printcpuinfo(void)
* 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"
@@ -636,7 +656,7 @@ identblue(void)
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
@@ -792,7 +812,7 @@ finishidentcpu(void)
}
/*
- * 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
@@ -816,7 +836,7 @@ print_AMD_assoc(int i)
}
static void
-print_AMD_info(void)
+print_AMD_info(void)
{
u_int regs[4];
diff --git a/sys/i386/i386/initcpu.c b/sys/i386/i386/initcpu.c
index 3849299..9f1f2a9 100644
--- a/sys/i386/i386/initcpu.c
+++ b/sys/i386/i386/initcpu.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) KATO Takenori, 1997.
+ * Copyright (c) KATO Takenori, 1997, 1998.
*
* All rights reserved. Unpublished rights reserved under the copyright
* laws of Japan.
@@ -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.12 1998/02/04 03:47:14 eivind Exp $
+ * $Id: initcpu.c,v 1.13 1998/05/16 14:38:10 kato Exp $
*/
#include "opt_cpu.h"
@@ -41,6 +41,11 @@
#include <machine/specialreg.h>
void initializecpu(void);
+#if defined(I586_CPU) && defined(CPU_WT_ALLOC)
+void enable_K5_wt_alloc(void);
+void enable_K6_wt_alloc(void);
+#endif
+
#ifdef I486_CPU
static void init_5x86(void);
static void init_bluelightning(void);
@@ -439,7 +444,7 @@ static void
init_ppro(void)
{
#ifndef SMP
- quad_t apicbase;
+ u_int64_t apicbase;
/*
* Local APIC should be diabled in UP kernel.
@@ -533,6 +538,121 @@ initializecpu(void)
#endif /* PC98 && !UPGRADE_CPU_HW_CACHE */
}
+#if defined(I586_CPU) && defined(CPU_WT_ALLOC)
+/*
+ * Enable write allocate feature of AMD processors.
+ * Following two functions require the Maxmem variable being set.
+ */
+void
+enable_K5_wt_alloc(void)
+{
+ u_int64_t msr;
+
+ /*
+ * Write allocate is supported only on models 1, 2, and 3, with
+ * a stepping of 4 or greater.
+ */
+ if (((cpu_id & 0xf0) > 0) && ((cpu_id & 0x0f) > 3)) {
+ disable_intr();
+ msr = rdmsr(0x83); /* HWCR */
+ wrmsr(0x83, msr & !(0x10));
+
+ /*
+ * We have to tell the chip where the top of memory is,
+ * since video cards could have frame bufferes there,
+ * memory-mapped I/O could be there, etc.
+ */
+ if(Maxmem > 0)
+ msr = Maxmem / 16;
+ else
+ msr = 0;
+ msr |= AMD_WT_ALLOC_TME | AMD_WT_ALLOC_FRE;
+#ifdef PC98
+ if (!(inb(0x43b) & 4)) {
+ wrmsr(0x86, 0x0ff00f0);
+ msr |= AMD_WT_ALLOC_PRE;
+ }
+#else
+ /*
+ * There is no way to know wheter 15-16M hole exists or not.
+ * Therefore, we disable write allocate for this range.
+ */
+ wrmsr(0x86, 0x0ff00f0);
+ msr |= AMD_WT_ALLOC_PRE;
+#endif
+ wrmsr(0x85, msr);
+
+ msr=rdmsr(0x83);
+ wrmsr(0x83, msr|0x10); /* enable write allocate */
+
+ enable_intr();
+ }
+}
+
+void
+enable_K6_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 / 256;
+ else
+ size = 0;
+ size = (size + 3) / 4;
+
+ /* Limit is 508M bytes. */
+ if (size > 127)
+ size = 127;
+ whcr = rdmsr(0xc0000082);
+ whcr &= ~0x00feLL;
+ whcr |= (size << 1);
+
+#ifdef PC98
+ if (whcr & 0x00feLL) {
+ /*
+ * If bit 2 of port 0x43b is 0, disable wrte allocate for the
+ * 15-16M range.
+ */
+ if (!(inb(0x43b) & 4))
+ whcr &= ~0x0001LL;
+ else
+ whcr |= 0x0001LL;
+ }
+#else
+ /*
+ * There is no way to know wheter 15-16M hole exists or not.
+ * Therefore, we disable write allocate for this range.
+ */
+ whcr &= 0x00feLL;
+#endif
+ wrmsr(0x0c0000082, whcr);
+
+ write_eflags(eflags);
+ enable_intr();
+}
+#endif /* I585_CPU && CPU_WT_ALLOC */
+
#include "opt_ddb.h"
#ifdef DDB
#include <ddb/ddb.h>
diff --git a/sys/i386/include/specialreg.h b/sys/i386/include/specialreg.h
index c09e51a..c09c2de 100644
--- a/sys/i386/include/specialreg.h
+++ b/sys/i386/include/specialreg.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)specialreg.h 7.1 (Berkeley) 5/9/91
- * $Id: specialreg.h,v 1.14 1997/07/21 17:53:51 fsmp Exp $
+ * $Id: specialreg.h,v 1.15 1998/03/04 11:39:16 kato Exp $
*/
#ifndef _MACHINE_SPECIALREG_H_
@@ -258,6 +258,11 @@
#define RCR_WT 0x10 /* Write-through. */
#define RCR_NLB 0x20 /* LBA# pin is not asserted. */
+/* 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 */
+
#ifndef LOCORE
static __inline u_char
diff --git a/sys/pc98/conf/options.pc98 b/sys/pc98/conf/options.pc98
index da7f2f0..d18cabc 100644
--- a/sys/pc98/conf/options.pc98
+++ b/sys/pc98/conf/options.pc98
@@ -1,4 +1,4 @@
-# $Id: options.pc98,v 1.67 1998/09/16 08:37:40 kato Exp $
+# $Id: options.pc98,v 1.68 1998/09/28 08:23:26 kato Exp $
DISABLE_PSE
USER_LDT
MATH_EMULATE opt_math_emulate.h
@@ -57,6 +57,7 @@ CPU_LOOP_EN opt_cpu.h
CPU_RSTK_EN opt_cpu.h
CPU_SUSP_HLT opt_cpu.h
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
OpenPOWER on IntegriCloud