From owner-freebsd-bugs Fri Apr 10 15:10:02 1998 Return-Path: Received: (from majordom@localhost) by hub.freebsd.org (8.8.8/8.8.8) id PAA24437 for freebsd-bugs-outgoing; Fri, 10 Apr 1998 15:10:02 -0700 (PDT) (envelope-from owner-freebsd-bugs@FreeBSD.ORG) Received: (from gnats@localhost) by hub.freebsd.org (8.8.8/8.8.8) id PAA24426; Fri, 10 Apr 1998 15:10:01 -0700 (PDT) (envelope-from gnats) Received: (from nobody@localhost) by hub.freebsd.org (8.8.8/8.8.8) id PAA24161; Fri, 10 Apr 1998 15:07:12 -0700 (PDT) (envelope-from nobody) Message-Id: <199804102207.PAA24161@hub.freebsd.org> Date: Fri, 10 Apr 1998 15:07:12 -0700 (PDT) From: kbyanc@freedomnet.com To: freebsd-gnats-submit@FreeBSD.ORG X-Send-Pr-Version: www-1.0 Subject: i386/6269: Included is a patch to support AMD Write-Allocate on K5s and K6s Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org >Number: 6269 >Category: i386 >Synopsis: Included is a patch to support AMD Write-Allocate on K5s and K6s >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Fri Apr 10 15:10:00 PDT 1998 >Last-Modified: >Originator: Kelly Yancey >Organization: FreedomNet >Release: 2.2.6-RELEASE >Environment: >Description: Included is the patch file I generated after adding support for the AMD K5/K6 Write-Allocate function. Also, I made modifications in the identcpu to better recognize the AMD K5 and K6 chips. Also added CPU_AMD_K5 and CPU_AMD_K6 defines in the cputypes.h (that patch is also included). Ample documentation was made of the changes. diff -u -R output follows... ************************************************************ diff -u -r /sys/i386/i386/identcpu.c /sys/i386/i386/identcpu.c --- /sys/i386/i386/identcpu.c Fri Apr 10 14:23:35 1998 +++ /sys/i386/i386/identcpu.c Fri Apr 10 14:22:40 1998 @@ -95,6 +95,8 @@ { "Cyrix 6x86MX", CPUCLASS_686 }, /* CPU_M2 */ { "NexGen 586", CPUCLASS_386 }, /* CPU_NX586 (XXX) */ { "Cyrix 486S/DX", CPUCLASS_486 }, /* CPU_CY486DX */ + { "AMD K5", CPUCLASS_586 }, /* CPU_AMDK5 */ + { "AMD K6", CPUCLASS_586 }, /* CPU_AMDK6 */ }; static void @@ -227,6 +229,9 @@ case 0x560: strcat(cpu_model, "K6"); break; + case 0x570: + strcat(cpu_model, "K6 266 (model 1)"); + break; default: strcat(cpu_model, "Unknown"); break; @@ -437,7 +442,7 @@ * 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" @@ -585,7 +590,7 @@ 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 @@ -735,10 +740,22 @@ } } } + else if (strcmp(cpu_vendor, "AuthenticAMD") == 0) { + switch (cpu_id & 0xff0) { + case 0x500: + case 0x510: + case 0x520: + case 0x530: cpu = CPU_AMDK5; + break; + case 0x560: + case 0x570: cpu = CPU_AMDK6; + break; + } + } } /* - * 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 @@ -762,7 +779,7 @@ } static void -print_AMD_info(void) +print_AMD_info(void) { u_long regs[4]; diff -u -r /sys/i386/i386/initcpu.c /sys/i386/i386/initcpu.c --- /sys/i386/i386/initcpu.c Fri Apr 10 14:23:35 1998 +++ /sys/i386/i386/initcpu.c Fri Apr 10 14:33:01 1998 @@ -52,10 +52,85 @@ static void init_6x86(void); #endif /* I486_CPU */ +#ifdef I586_CPU +static void init_amdK5(void); +static void init_amdK6(void); +#endif + #ifdef I686_CPU static void init_6x86MX(void); #endif +#ifdef I586_CPU +/* support for AMD write allocate function added by Kelly Yancey, + kbyanc@freedomnet.com 4/10/98 +*/ +/* bit definitions for 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 */ + +static void init_amdK5(void) +{ + u_long msr; +#ifdef CPU_AMD_WT_ALLOC +/* enable write allocate on AMD processors that support it */ +/* AMD K5, Model 1, 2, and 3 Stepping 4 or higher all support it per + AMD Write Allocate Application Note: http://www.amd.com/K6/k6docs/pdf/21326c.pdf +*/ + if(((cpu_id & 0xF0) > 0) && /* check the model number (K6 is technically model 6, but we + have already identified this as a K5 so that's moot */ + ((cpu_id & 0x0F) > 4)) { /* make sure the stepping is at least 4 */ + disable_intr(); + msr=rdmsr(0x83); /* AMD Hardware Configuration Register */ + wrmsr(0x83, msr&!(0x10)); + /* now set the programmable range to include the 15M-16M range for + compatibility with hardware that memory-maps this range + */ + wrmsr(0x86, 0x0FF00F0); + /* now we are going to set the Top-Of-Memory Enable and Fixed-Memory Enable + bits in the Write Allocate register on the AMD. We also have to tell the + chip where the top of memory is. (We don't want to write-allocate past + the top of memory because video cards could have frame buffers there, + memory-mapped I/O could be there, etc. + */ + msr=Maxmem>>PAGE_SHIFT<<16; /* load the msr with the high 16 bits of the top of physical memory */ + wrmsr(0x85, AMD_WT_ALLOC_TME|AMD_WT_ALLOC_PRE|AMD_WT_ALLOC_FRE|msr); + rdmsr(0x85); + msr=rdmsr(0x83); + wrmsr(0x83, msr|0x10); /* enable write allocate */ + enable_intr(); + printf("AMD K5 write allocate enabled\n"); + } +#endif +} + +static void init_amdK6(void) +{ + u_long eflags; +#ifdef CPU_AMD_WT_ALLOC +/* enable write allocate on AMD processors that support it */ +/* AMD K6, Model 1 Stepping 4 or higher all support it per + AMD Write Allocate Application Note: http://www.amd.com/K6/k6docs/pdf/21326c.pdf +*/ + if((cpu_id & 0xFF) > 0x60) { /* we already know it is a K6, just check the stepping + (later models appear to support write allocate no matter + what the stepping) */ + eflags = read_eflags(); + disable_intr(); + wbinvd(); /* the K6 requires us to invalidate the cache */ + wrmsr(0x0C0000082, (Maxmem>>9)&0x0FE);/* K6 uses a limit measured in 4M blocks (we convert from pages). + we also make sure that 8-63 are 0 and that we disable + write allocate for the 15-16M range */ + write_eflags(eflags); + enable_intr(); + printf("AMD K6 write allocate enabled\n"); + } +#endif +} +#endif /* I586_CPU */ + + #ifdef I486_CPU /* * IBM Blue Lightning @@ -462,6 +537,14 @@ init_6x86(); break; #endif /* I486_CPU */ +#ifdef I586_CPU + case CPU_AMDK5: + init_amdK5(); + break; + case CPU_AMDK6: + init_amdK6(); + break; +#endif /* I586_CPU */ #ifdef I686_CPU case CPU_M2: init_6x86MX(); diff -u -r /sys/i386/include/cputypes.h /sys/i386/include/cputypes.h --- /sys/i386/include/cputypes.h Fri Apr 10 14:24:12 1998 +++ /sys/i386/include/cputypes.h Fri Apr 10 14:22:45 1998 @@ -58,4 +58,6 @@ #define CPU_M2 11 /* Cyrix M2 (aka enhanced 6x86 with MMX */ #define CPU_NX586 12 /* NexGen (now AMD) 586 */ #define CPU_CY486DX 13 /* Cyrix 486S/DX/DX2/DX4 */ +#define CPU_AMDK5 14 /* AMD K5 */ +#define CPU_AMDK6 15 /* AMD K6 with MMX */ #endif /* _MACHINE_CPUTYPES_H_ */ >How-To-Repeat: >Fix: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message