lkml.org 
[lkml]   [1999]   [Jan]   [19]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subject[PATCH] K6 write allocate - shining new version
Hello.

This is a new version of patch for enabling K6 write allocate - against
2.2.0pre7.

Changes:

* Things are in more appropriate place
* Misnamed amd_model function renamed to amdlike_model_cpuid
* Now the patch should correctly determine (I hope!) the amount of
physical RAM in system and does not try to re-enable write allocate if it's
already enabled by BIOS and BIOS gets some memory for its needs.

P.S. I can add support for K5 & K6-2. Do we need it? (But I cannot test
this support. So if you want support for K5, be ready to test my patches
:) ) For K6-2 probably all modern BIOSes do the appropriate thing by
itself, I guess...

--
With best wishes,
Alexey Vyskubov.
This is a message. Or something silly like that.
--- linux/arch/i386/kernel/setup.c.was Sun Jan 17 12:17:11 1999
+++ linux/arch/i386/kernel/setup.c Tue Jan 19 09:50:37 1999
@@ -243,7 +243,7 @@

}

-__initfunc(static int amd_model(struct cpuinfo_x86 *c))
+__initfunc(static int amdlike_model_cpuid(struct cpuinfo_x86 *c))
{
unsigned int n, dummy, *v;

@@ -263,6 +263,93 @@
return 1;
}

+#define AMD_WHCR 0xc0000082 /* AMD MSR WHCR */
+
+#define rdmsr(msr,val1,val2) \
+ __asm__ __volatile__("rdmsr" \
+ : "=a" (val1), "=d" (val2) \
+ : "c" (msr))
+
+#define wrmsr(msr,val1,val2) \
+ __asm__ __volatile__("wrmsr" \
+ : /* no outputs */ \
+ : "c" (msr), "a" (val1), "d" (val2))
+
+
+__initfunc(u32 enable_write_allocate (u32 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) << 1; /* Drop last bit (memory hole) */
+ return(ra);
+}
+
+__initfunc(void amd_write_allocate(struct cpuinfo_x86 *c))
+{
+ if ((c->x86_model == 6) || (c->x86_model == 7))
+ {
+
+ u32 ra, rd;
+ u32 ram;
+
+ printk("AMD K6 processor, model %d found.", c->x86_model);
+ printk("\nChecking write allocate state... ");
+
+ ram = max_mapnr << (PAGE_SHIFT - 10); /* RAM size in Kb */
+ ram >>= 10; /* RAM size in Mb */
+
+ if ( (ram << 10) != (max_mapnr << (PAGE_SHIFT - 10)) )
+ /* BIOS takes some memory, and ram is physical
+ * memory size in MB - 1 :(
+ */
+ ram++;
+
+ rdmsr(AMD_WHCR, ra, rd);
+ ra = (ra & 0xfe) << 1;
+
+ if (ra) {
+ printk("Write allocate is enabled for %d MB of memory", ra);
+ } else {
+ printk("Write allocate is disabled.");
+ }
+
+ if (!(ra == ram)) {
+ printk("\nTrying to enable write alocate for %d MB of memory", ram);
+ ra = enable_write_allocate(ram);
+
+ if (!(ra == ram)) {
+ printk("\nFailed!!!");
+ }
+ printk("\nWrite allocate is enabled for %d MB of memory\n", ra);
+ }
+
+ rdmsr(AMD_WHCR, ra, rd);
+
+ if (ra & 0x100) {
+ printk("WARNING: WCDE bit is 1.\n");
+ }
+
+ if (!(ra & 0x1)) {
+ printk("WARNING: Memory hole at 15-16M is enabled.\n");
+ }
+ }
+}
+
/*
* Read Cyrix DEVID registers (DIR) to get more detailed info. about the CPU
*/
@@ -379,7 +466,7 @@

/* GXm supports extended cpuid levels 'ala' AMD */
if (c->cpuid_level == 2) {
- amd_model(c); /* get CPU marketing name */
+ amdlike_model_cpuid(c); /* get CPU marketing name */
c->x86_capability&=~X86_FEATURE_TSC;
return;
}
@@ -502,8 +589,10 @@
return;
}

- if (c->x86_vendor == X86_VENDOR_AMD && amd_model(c))
+ if (c->x86_vendor == X86_VENDOR_AMD && amdlike_model_cpuid(c)) {
+ amd_write_allocate(c);
return;
+ }

for (i = 0; i < sizeof(cpu_models)/sizeof(struct cpu_model_info); i++) {
if (c->cpuid_level > 1) {
@@ -588,20 +677,9 @@
}


-#define rdmsr(msr,val1,val2) \
- __asm__ __volatile__("rdmsr" \
- : "=a" (val1), "=d" (val2) \
- : "c" (msr))
-
-#define wrmsr(msr,val1,val2) \
- __asm__ __volatile__("wrmsr" \
- : /* no outputs */ \
- : "c" (msr), "a" (val1), "d" (val2))
-
static char *cpu_vendor_names[] __initdata = {
"Intel", "Cyrix", "AMD", "UMC", "NexGen", "Centaur" };

-
__initfunc(void print_cpu_info(struct cpuinfo_x86 *c))
{
char *vendor = NULL;
@@ -621,8 +699,8 @@

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_CENTAUR)
{
u32 hv,lv;
rdmsr(0x107, lv, hv);
\
 
 \ /
  Last update: 2005-03-22 13:49    [from the cache]
©2003-2011 Jasper Spaans