- 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
This commit is contained in:
parent
f92f33e090
commit
4536af6a70
@ -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];
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
||||
|
@ -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];
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user