[PATCH] AMD K6 write allocate

Alexey Vyskubov (alexey@alv.stud.pu.ru)
Sun, 17 Jan 1999 14:55:06 +0300 (MSK)


Well, now this patch is in the right file (I hope).

This patch enable write allocate for AMD K6 processors model 6 and model
7. (There are some stupid motherboards with BIOSes which don't do it, e.g.
my Chaintech 5VGM1.)

The patch is against 2.2.0pre7.

It checks the processor model and if it's K6 model 6/7 patch tries to
enable write allocate. One thing you should do **BY THE HAND**: change
#define WRITE_ALLOCATE_LIMIT 48
to
#define WRITE_ALLOCATE_LIMIT <your RAM size>

Sorry, I don't know how to obtain memory size. (Help will be appreciated!)

Write allocate is described in AMD's application note 21326e
"Implementation of write allocate in the K86(tm) processors".

"Write allocate, if enabled, occurs when the processor has a pending memory
write cycle to a cacheable line and the line does not currently reside in
the L1 data cache. In this case, the processor performs a burst read cycle
to fetch the cache line addressed by the pending write cycle. The data
associated with the pending write cycle is merged with the
recently-allocated cache line and stored in the processor's L1 data cache.
The final MESI (Modified, Exclusive, Shared, Invalid) state of the cache
line depends on the state of the WB/WT# and PWT signals during the burst
read cycle and the subsequent cache write hit. During the write
allocation, a 32-byte burst read cycle is executed in place of a non-burst
write cycle. While the burst read cycle generally takes longer to execute
than the write cycle, performance gains are realized on subsequent write
cycle hits to the write-allocated cache line. Due to the nature of
software, memory accesses tend to occur within proximity of each other
(principle of locality). The likelihood of additional write hits to the
write-allocated cache line is high."

It looks like this patch gives to my system 5-7% increase in speed. If
you're going to test my patch, please tell me about results.

Patch comes here:

-------------- begin: k6-patch --------------
--- linux/arch/i386/kernel/setup.c.was Sun Jan 17 12:17:11 1999
+++ linux/arch/i386/kernel/setup.c Sun Jan 17 14:46:51 1999
@@ -601,6 +601,31 @@
static char *cpu_vendor_names[] __initdata = {
"Intel", "Cyrix", "AMD", "UMC", "NexGen", "Centaur" };

+#define AMD_WHCR 0xc0000082 /* AMD MSR WHCR */
+
+int enable_write_allocate (int size)
+{
+ u32 ra, rd;
+ rd = 0;
+
+ ra = size >> 2; /* EAX = 2*(RAM/4) */
+ ra = (ra << 1) + 1; /* +1 for no memory hole at 15-16MB */
+
+
+#define walloc(msr, val1, val2) __asm__ __volatile__ (" pushf
+ cli
+ wbinvd
+ wrmsr
+ popf"\
+ : /* no outputs */\
+ : "c" (msr),\
+ "a" (val1), "d"
(val2))
+ walloc(AMD_WHCR, ra, rd);
+ rdmsr(AMD_WHCR, ra, rd); /* Let's see what's happened */
+ ra = ra & 0xfe; /* Drop last bit (memory hole) */
+ ra = ra << 1;
+ return((int)ra);
+}

__initfunc(void print_cpu_info(struct cpuinfo_x86 *c))
{
@@ -621,8 +646,50 @@

if (c->x86_mask || c->cpuid_level>=0)
printk(" stepping %02x", c->x86_mask);
-
- if(c->x86_vendor == X86_VENDOR_CENTAUR)
+
+ if ( (c->x86_vendor == X86_VENDOR_AMD) &&
+ ((c->x86_model == 6) || (c->x86_model == 7)))
+ {
+
+ u32 ra, rd;
+ int mem;
+
+ printk("\nAMD K6 processor, model %d found.",
c->x86_model);
+ printk("\nChecking write allocate state... ");
+
+#define WRITE_ALLOCATE_LIMIT 48
+/* FIXME We should use real memory size instead of fixed limit */
+
+ rdmsr(AMD_WHCR, ra, rd);
+ mem = (ra & 0xfe) << 1;
+
+ if (mem) {
+ printk("Write allocate is enabled for %d MB of
memory", mem);
+ } else {
+ printk("Write allocate is disabled.");
+ }
+
+ if (!(mem == WRITE_ALLOCATE_LIMIT)) {
+ printk("\nTrying to enable write alocate for %d MB
of memory", WRITE_ALLOCATE_LIMIT);
+ mem = WRITE_ALLOCATE_LIMIT;
+ mem = enable_write_allocate(mem);
+
+ if (!(mem == WRITE_ALLOCATE_LIMIT)) {
+ printk("\nFailed!!!");
+ }
+ printk("\nWrite allocate is enabled for %d MB of
memory", mem);
+ }
+
+ if (ra & 0x100) {
+ printk("\nWARNING: WCDE bit is 1.");
+ }
+
+ if (ra & 0x1) {
+ printk("\nWARNING: Memory hole at 15-16M is
enabled.");
+ }
+ }
+
+ if (c->x86_vendor == X86_VENDOR_CENTAUR)
{
u32 hv,lv;
rdmsr(0x107, lv, hv);
@@ -735,3 +802,4 @@
}
return p - buffer;
}
+
--------------- end: k6-patch ---------------

--
With best wishes,
Alexey Vyskubov.
This is a message. Or something silly like that.

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/