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:
parent
96d5e20872
commit
925f368193
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user