From owner-FreeBSD-tech-jp@jp.freebsd.org  Sat Oct  3 12:08:15 1998
Received: (from daemon@localhost)
	by jaz.jp.freebsd.org (8.9.1+3.1W/8.7.3) id MAA17733;
	Sat, 3 Oct 1998 12:08:15 +0900 (JST)
	(envelope-from owner-FreeBSD-tech-jp@jp.FreeBSD.org)
Received: from gneiss.eps.nagoya-u.ac.jp (gneiss.eps.nagoya-u.ac.jp [133.6.124.148])
	by jaz.jp.freebsd.org (8.9.1+3.1W/8.7.3) with ESMTP id MAA17726
	for <FreeBSD-tech-jp@jp.freebsd.org>; Sat, 3 Oct 1998 12:08:13 +0900 (JST)
	(envelope-from kato@ganko.eps.nagoya-u.ac.jp)
Received: from localhost (localhost [127.0.0.1])
	by gneiss.eps.nagoya-u.ac.jp (8.9.1/3.7W) with ESMTP id MAA00302
	for <FreeBSD-tech-jp@jp.freebsd.org>; Sat, 3 Oct 1998 12:08:12 +0900 (JST)
To: FreeBSD-tech-jp@jp.freebsd.org
From: KATO Takenori <kato@ganko.eps.nagoya-u.ac.jp>
In-Reply-To: Your message of "Thu, 01 Oct 1998 22:52:56 +0900"
	<19981001225256W.kato@gneiss.eps.nagoya-u.ac.jp>
References: <19981001225256W.kato@gneiss.eps.nagoya-u.ac.jp>
X-Mailer: Mew version 1.92.4 on Emacs 19.28 / Mule 2.3 (SUETSUMUHANA)
X-PGP-Fingerprint: 03 72 85 36 62 46 23 03  52 B1 10 22 44 10 0D 9E
Mime-Version: 1.0
Content-Type: Text/Plain; charset=iso-2022-jp
Content-Transfer-Encoding: 7bit
Message-Id: <19981003120811S.kato@gneiss.eps.nagoya-u.ac.jp>
Date: Sat, 03 Oct 1998 12:08:11 +0900
X-Dispatcher: imput version 971024
Lines: 356
Reply-To: FreeBSD-tech-jp@jp.freebsd.org
Precedence: bulk
X-Distribute: distribute version 2.1 (Alpha) patchlevel 24e+980914
X-Sequence: FreeBSD-tech-jp 1754
Subject: [FreeBSD-tech-jp 1754] Re: AMD K5/K6/K6-2 Write Allocation patch
Errors-To: owner-FreeBSD-tech-jp@jp.freebsd.org
Sender: owner-FreeBSD-tech-jp@jp.freebsd.org

$B2CF#!wL>Bg4d9[$G$9!%(B

I wrote:

> AMD K5/K6/K6-2$B$N(BWrite Allocation$B$r%5%]!<%H$9$k$?$a$N%Q%C%A$r:n$j$^$7$?!%(B
> $B$I$J$?$+%F%9%H$7$F$b$i$($^$;$s$+!)(B
> 
> $B%Q%C%A$O!$(B3.0-current$BMQ$G$9!%(B

$B%P%0%P%0$G$7$?!%$9$$$^$;$s!%<!$N%Q%C%A$G$*4j$$$7$^$9!%(B

---------- BEGIN ----------
*** sys/i386/conf/options.i386.ORIG	Thu Oct  1 03:17:43 1998
--- sys/i386/conf/options.i386	Thu Oct  1 03:18:35 1998
***************
*** 46,51 ****
--- 46,52 ----
  CLK_USE_TSC_CALIBRATION		opt_clock.h
  
  NO_F00F_HACK			opt_cpu.h
+ CPU_AMD_WT_ALLOC		opt_cpu.h
  CPU_BLUELIGHTNING_FPU_OP_CACHE	opt_cpu.h
  CPU_BLUELIGHTNING_3X		opt_cpu.h
  CPU_BTB_EN			opt_cpu.h
***************
*** 54,59 ****
--- 55,61 ----
  CPU_FASTER_5X86_FPU		opt_cpu.h
  CPU_I486_ON_386			opt_cpu.h
  CPU_IORT			opt_cpu.h
+ CPU_DISABLE_CACHE		opt_cpu.h
  CPU_LOOP_EN			opt_cpu.h
  CPU_RSTK_EN			opt_cpu.h
  CPU_SUSP_HLT			opt_cpu.h
*** sys/i386/i386/identcpu.c.ORIG	Thu Oct  1 02:38:40 1998
--- sys/i386/i386/identcpu.c	Fri Oct  2 18:49:05 1998
***************
*** 65,70 ****
--- 65,74 ----
  void printcpuinfo(void);	/* XXX should be in different header file */
  void finishidentcpu(void);
  void earlysetcpuclass(void);
+ #if defined(I586_CPU) && defined(CPU_AMD_WT_ALLOC)
+ void	enable_K5_wt_alloc(void);
+ void	enable_K6_wt_alloc(void);
+ #endif
  void panicifcpuunsupported(void);
  static void identifycyrix(void);
  static void print_AMD_info(void);
***************
*** 273,282 ****
--- 277,301 ----
  		case 0x560:
  			strcat(cpu_model, "K6");
  			break;
+ 		case 0x570:
+ 			strcat(cpu_model, "K6 266 (model 1)");
+ 			break;
+ 		case 0x580:
+ 			strcat(cpu_model, "K6-2");
+ 			break;
  		default:
  			strcat(cpu_model, "Unknown");
  			break;
  		}
+ #ifdef CPU_AMD_WT_ALLOC
+ 		if (cpu_id & 0xf00 == 5) {
+ 			if ((cpu_id & 0x0f0 > 0) && (cpu_id & 0x0f0 < 6) &&
+ 			    (cpu_id & 0x00f > 3)) {
+ 				enable_K5_wt_alloc();
+ 			} else if (cpu_id & 0x0f0 > 5)
+ 				enable_K6_wt_alloc();
+ 		}
+ #endif
  		do_cpuid(0x80000000, regs);
  		nreg = regs[0];
  		if (nreg >= 0x80000004) {
***************
*** 488,494 ****
  			 * to check that all CPUs >= Pentium have a TSC and
  			 * MSRs.
  			 */
! 			printf("\n  Features=0x%b", cpu_feature, 
  			"\020"
  			"\001FPU"
  			"\002VME"
--- 507,513 ----
  			 * to check that all CPUs >= Pentium have a TSC and
  			 * MSRs.
  			 */
! 			printf("\n  Features=0x%b", cpu_feature,
  			"\020"
  			"\001FPU"
  			"\002VME"
***************
*** 636,642 ****
  
  	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
--- 655,661 ----
  
  	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
***************
*** 792,798 ****
  }
  
  /*
!  * 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
--- 811,817 ----
  }
  
  /*
!  * 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
***************
*** 816,822 ****
  }
  
  static void
! print_AMD_info(void) 
  {
  	u_int regs[4];
  
--- 835,841 ----
  }
  
  static void
! print_AMD_info(void)
  {
  	u_int regs[4];
  
*** sys/i386/i386/initcpu.c.ORIG	Thu Oct  1 02:38:02 1998
--- sys/i386/i386/initcpu.c	Sat Oct  3 01:09:30 1998
***************
*** 1,5 ****
  /*
!  * Copyright (c) KATO Takenori, 1997.
   * 
   * All rights reserved.  Unpublished rights reserved under the copyright
   * laws of Japan.
--- 1,5 ----
  /*
!  * Copyright (c) KATO Takenori, 1997, 1998.
   * 
   * All rights reserved.  Unpublished rights reserved under the copyright
   * laws of Japan.
***************
*** 41,46 ****
--- 41,51 ----
  #include <machine/specialreg.h>
  
  void initializecpu(void);
+ #if defined(I586_CPU) && defined(CPU_AMD_WT_ALLOC)
+ void	enable_K5_wt_alloc(void);
+ void	enable_K6_wt_alloc(void);
+ #endif
+ 
  #ifdef I486_CPU
  static void init_5x86(void);
  static void init_bluelightning(void);
***************
*** 439,445 ****
  init_ppro(void)
  {
  #ifndef SMP
! 	quad_t	apicbase;
  
  	/*
  	 * Local APIC should be diabled in UP kernel.
--- 444,450 ----
  init_ppro(void)
  {
  #ifndef SMP
! 	u_int64_t	apicbase;
  
  	/*
  	 * Local APIC should be diabled in UP kernel.
***************
*** 532,537 ****
--- 537,653 ----
  	}
  #endif /* PC98 && !UPGRADE_CPU_HW_CACHE */
  }
+ 
+ #if defined(I586_CPU) && defined(CPU_AMD_WT_ALLOC)
+ /*
+  * Enable write allocate feature of AMD processors.
+  * Following two functions require the Maxmem variable being set.
+  */
+ void
+ enable_K5_wt_alloc(void)
+ {
+ 	u_int64_t	msr;
+ 
+ 	/*
+ 	 * Write allocate is supported only on models 1, 2, and 3, with
+ 	 * a stepping of 4 or greater.
+ 	 */
+ 	if (((cpu_id & 0xf0) > 0) && ((cpu_id & 0x0f) > 4)) {
+ 		disable_intr();
+ 		msr = rdmsr(0x83);		/* HWCR */
+ 		wrmsr(0x83, msr & !(0x10));
+ 
+ 		/*
+ 		 * We have to tell the chip where the top of memory is,
+ 		 * since video cards could have frame bufferes there,
+ 		 * memory-mapped I/O could be there, etc.
+ 		 */
+ 		msr=Maxmem>>4;
+ 		msr |= AMD_WT_ALLOC_TME | AMD_WT_ALLOC_FRE;
+ #ifdef PC98
+ 		if (!(inb(0x43b) & 4)) {
+ 			wrmsr(0x86, 0x0ff00f0);
+ 			msr |= AMD_WT_ALLOC_PRE;
+ 		}
+ #else
+ 		/*
+ 		 * There is no way to know wheter 15-16M hole exists or not. 
+ 		 * Therefore, we disable write allocate for this range.
+ 		 */
+ 			wrmsr(0x86, 0x0ff00f0);
+ 			msr |= AMD_WT_ALLOC_PRE;
+ #endif
+ 		wrmsr(0x85, msr);
+ 
+ 		msr=rdmsr(0x83);
+ 		wrmsr(0x83, msr|0x10); /* enable write allocate */
+ 
+ 		enable_intr();
+ 	}
+ }
+ 
+ void
+ enable_K6_wt_alloc(void)
+ {
+ 	quad_t	size;
+ 	u_int64_t	whcr;
+ 	u_long	eflags;
+ 
+ 	eflags = read_eflags();
+ 	disable_intr();
+ 	wbinvd();
+ 
+ 	/* Don't assume that memory size is aligned with 4M. */
+ 	size = Maxmem >> 8;
+ 	size = (size + 3) / 4;
+ 
+ 	/* Limit is 508M bytes. */
+ 	if (size > 127)
+ 		size = 127;
+ 	whcr = rdmsr(0xc0000082);
+ 	whcr &= ~0x00feLL;
+ 	whcr |= (size << 1);
+ 
+ #ifdef PC98
+ 	if (whcr & 0x00fe) {
+ 		/*
+ 		 * If bit 2 of port 0x43b is 0, disable wrte allocate for the
+ 		 * 15-16M range.
+ 		 */
+ 		if (!(inb(0x43b) & 4))
+ 			whcr &= ~0x0001LL;
+ 		else
+ 			amd_whcr |=  0x0001LL;
+ 
+ #ifdef XXX
+ 		/*
+ 		 * NEC PC-98x1 does not support hardware write allocate
+ 		 * control.
+ 		 */
+ 		whcr &= ~0x0100LL;
+ #endif
+ 	}
+ #else
+ 	/*
+ 	 * There is no way to know wheter 15-16M hole exists or not. 
+ 	 * Therefore, we disable write allocate for this range.
+ 	 */
+ 	whcr &= 0x00feLL;
+ #endif
+ 
+ 	wrmsr(0x0c0000082, whcr);
+ 	write_eflags(eflags);
+ 	enable_intr();
+ 
+ 	/*
+ 	 * Certain K6-2 box becomes unstable when write allocation is
+ 	 * enabled.
+ 	 */
+ #ifdef CPU_DISABLE_CACHE
+ 	wrmsr(0x0000000e, (u_int64_t)0x0008);
+ #endif
+ }
+ #endif /* I585_CPU && CPU_AMD_WT_ALLOC */
  
  #include "opt_ddb.h"
  #ifdef DDB
*** sys/i386/include/specialreg.h.ORIG	Thu Oct  1 02:52:52 1998
--- sys/i386/include/specialreg.h	Thu Oct  1 02:50:25 1998
***************
*** 258,263 ****
--- 258,268 ----
  #define	RCR_WT	0x10	/* Write-through. */
  #define	RCR_NLB	0x20	/* LBA# pin is not asserted. */
  
+ /* 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 */
+ 
  
  #ifndef LOCORE
  static __inline u_char
*** sys/pc98/conf/options.pc98.ORIG	Fri Oct  2 14:23:54 1998
--- sys/pc98/conf/options.pc98	Fri Oct  2 14:25:22 1998
***************
*** 46,51 ****
--- 46,52 ----
  CLK_USE_TSC_CALIBRATION		opt_clock.h
  
  NO_F00F_HACK			opt_cpu.h
+ CPU_AMD_WT_ALLOC		opt_cpu.h
  CPU_BLUELIGHTNING_FPU_OP_CACHE	opt_cpu.h
  CPU_BLUELIGHTNING_3X		opt_cpu.h
  CPU_BTB_EN			opt_cpu.h
***************
*** 54,59 ****
--- 55,61 ----
  CPU_FASTER_5X86_FPU		opt_cpu.h
  CPU_I486_ON_386			opt_cpu.h
  CPU_IORT			opt_cpu.h
+ CPU_DISABLE_CACHE		opt_cpu.h
  CPU_LOOP_EN			opt_cpu.h
  CPU_RSTK_EN			opt_cpu.h
  CPU_SUSP_HLT			opt_cpu.h
---------- END ----------

-----------------------------------------------+--------------------------+
Kato Takenori <kato@ganko.eps.nagoya-u.ac.jp>  |        FreeBSD           |
Dept. Earth Planet. Sci, Nagoya Univ.          |    The power to serve!   |
Nagoya, 464-8602, Japan                        |  http://www.FreeBSD.org/ |
++++ FreeBSD(98) 2.2.7: Rev. 01 available!     +==========================+
