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>
This commit is contained in:
Mike Smith 1998-12-27 23:23:26 +00:00
parent 96d5e20872
commit 925f368193
9 changed files with 191 additions and 23 deletions

View File

@ -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;
}
}

View File

@ -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);

View File

@ -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.

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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

View File

@ -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;
}
}

View File

@ -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);