Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 19 Nov 1997 15:38:44 -0500 (EST)
From:      "John S. Dyson" <toor@dyson.iquest.net>
To:        hasty@rah.star-gate.com (Amancio Hasty)
Cc:        henrich@crh.cl.msu.edu, freebsd-multimedia@freebsd.org
Subject:   Re: Faster X Updates
Message-ID:  <199711192038.PAA05049@dyson.iquest.net>
In-Reply-To: <199711191813.KAA01443@rah.star-gate.com> from Amancio Hasty at "Nov 19, 97 10:13:31 am"

next in thread | previous in thread | raw e-mail | index | archive | help
Amancio Hasty said:
> 
> For pentium pro and pentium II systems you can enable write combine 
> for your display buffer . this is what I do for my matrox millenium
> frame buffer. Do a netsearch on fastvid for an explanation on 
> PCI write combinining . 
> 
> 	wrmsr(0x204, 0xf9800001);
> 	wrmsr(0x205, 0xffc00000 | 0x800);
> 
> You can get the details on the above instructions from the Pentium Pro's
> developers manual, chapter 11. the full manual is at:
> ftp://rah.star-gate.com/pub/242692_1.pdf
> 
> The above hack can boot your frame buffer thruput from 20MB/sec to 
> 90MB/sec
> 
My (P6DNF) bios automatically sets the frame buffer write combining as
it should.  At the end of this file is a loadable driver that will print
out your msr info.  Before that, there is the output for my system.  In
SMP-current, we synchronize the P6 processors MSR's.  (Not all bios's
do so.)

THIS WILL WORK ONLY ON P6 (tested) or P-II processors (untested).


Nov 19 15:34:54 dyson /kernel: default: type: 0xc00
Nov 19 15:34:54 dyson /kernel: 0: type: 6, addr: 0x0000, mask: 0xff8000000
Nov 19 15:34:54 dyson /kernel:      basehi: 0x       0, baselo: 0x       6
Nov 19 15:34:54 dyson /kernel:      maskhi: 0x       f, masklo: 0xf8000800
Nov 19 15:34:54 dyson /kernel: 5: type: 1, addr: 0xfe000000, mask: 0xfffc00000
Nov 19 15:34:54 dyson /kernel:      basehi: 0x       0, baselo: 0xfe000001
Nov 19 15:34:54 dyson /kernel:      maskhi: 0x       f, masklo: 0xffc00800
Nov 19 15:34:54 dyson /kernel: MTRRfix64K_00000: 0x 6060606 0x 6060606
Nov 19 15:34:54 dyson /kernel: MTRRfix16K_80000: 0x 6060606 0x 6060606
Nov 19 15:34:54 dyson /kernel: MTRRfix16K_A0000: 0x 1010101 0x 1010101
Nov 19 15:34:54 dyson /kernel: MTRRfix4K_C0000: 0x       0 0x       0
Nov 19 15:34:54 dyson /kernel: MTRRfix4K_C8000: 0x       0 0x       0
Nov 19 15:34:54 dyson /kernel: MTRRfix4K_D0000: 0x       0 0x       0
Nov 19 15:34:54 dyson /kernel: MTRRfix4K_D8000: 0x       0 0x       0
Nov 19 15:34:54 dyson /kernel: MTRRfix4K_E0000: 0x       0 0x       0
Nov 19 15:34:54 dyson /kernel: MTRRfix4K_E8000: 0x       0 0x       0
Nov 19 15:34:54 dyson /kernel: MTRRfix4K_F0000: 0x       0 0x       0
Nov 19 15:34:54 dyson /kernel: MTRRfix4K_F8000: 0x       0 0x       0
Nov 19 15:34:54 dyson /kernel: BKUPTMPDR6: ff0
Nov 19 15:34:54 dyson /kernel: BKUPTMPDR6: c0500000
Nov 19 15:34:54 dyson /kernel: 4MB page: 0xe7(f0000000)

Memory type 1 means "write combining."


#!/bin/sh
# This is a shell archive (produced by GNU sharutils 4.1.4).
# To extract the files from this archive, save it to some FILE, remove
# everything before the `!/bin/sh' line above, then type `sh FILE'.
#
# Made on 1997-11-19 15:35 EST by <root@dyson.iquest.net>.
# Source directory was `/usr4/root/mtrr'.
#
# Existing files will *not* be overwritten unless `-c' is specified.
#
# This shar contains:
# length mode       name
# ------ ---------- ------------------------------------------
#   3647 (null) -rw-r--r--
#    107 (null) -rw-r--r--
#
touch -am 1231235999 $$.touch >/dev/null 2>&1
if test ! -f 1231235999 && test -f $$.touch; then
  shar_touch=touch
else
  shar_touch=:
  echo
  echo 'WARNING: not restoring timestamps.  Consider getting and'
  echo "installing GNU \`touch', distributed in GNU File Utilities..."
  echo
fi
rm -f 1231235999 $$.touch
#
# ============= mycall.c ==============
if test -f 'mycall.c' && test X"$1" != X"-c"; then
  echo 'x - skipping mycall.c (file already exists)'
else
  echo 'x - extracting mycall.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'mycall.c' &&
/*
X * LKM to instrument kernel bzero().
X * i586 only (uses rdtsc).
X */
X
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/exec.h>
#include <sys/sysent.h>
#include <sys/lkm.h>
#include <sys/lock.h>
#include <sys/proc.h>
#include <vm/vm.h>
#include <vm/vm_prot.h>
#include <vm/vm_page.h>
#include <vm/vm_extern.h>
#include <vm/vm_map.h>
#include <vm/pmap.h>
X
#define I586_CPU			/* XXX for i586_ctr_freq */
#include <machine/clock.h>
X
static int load(struct lkm_table *lkmtp, int cmd);
static int mycall(struct proc *p, void *uap, int *retval);
extern int newsyscall_mod(struct lkm_table *lkmtp, int cmd, int ver);
static int unload(struct lkm_table *lkmtp, int cmd);
vm_offset_t contigaddr;
struct proc *curproc;
X
static struct sysent newent = {
X	0,	mycall			/* # of args, function pointer*/
};
X
MOD_SYSCALL(newsyscall_mod, -1, &newent);
X
static struct {
X	int	address;
X	char *name;
} ranges[] = {
X	{0x250, "MTRRfix64K_00000"},
X	{0x258, "MTRRfix16K_80000"},
X	{0x259, "MTRRfix16K_A0000"},
X	{0x268, "MTRRfix4K_C0000"},
X	{0x269, "MTRRfix4K_C8000"},
X	{0x26a, "MTRRfix4K_D0000"},
X	{0x26b, "MTRRfix4K_D8000"},
X	{0x26c, "MTRRfix4K_E0000"},
X	{0x26d, "MTRRfix4K_E8000"},
X	{0x26e, "MTRRfix4K_F0000"},
X	{0x26f, "MTRRfix4K_F8000"},
X	{0x0, NULL}
};
X	
X
static int load(struct lkm_table *lkmtp, int cmd)
{
X	int i;
X	long long base;
X	long long mask;
X	vm_offset_t kernaddr;
X	struct proc *otherp;
X	int tbase, tmask, type;
X	pmap_t pmap;
X	base = rdmsr(0x2ff);
X	tbase = base & 0xfff;
X	printf("default: type: 0x%x\n", tbase);
X	for(i=0;i<8;i++) {
X		int basehi, baselo;
X		int maskhi, masklo;
X		base = rdmsr(0x200 + i * 2);
X		basehi = (unsigned long long) base >> 32;
X		baselo = (unsigned long long) base & 0xffffffffL;
X		type = base & 0xff;
X		base >>= 12;
X		tbase = base;
X		mask = rdmsr(0x201 + i * 2);
X		if ((mask & 0x800) == 0)
X			continue;
X		maskhi = (unsigned long long) mask >> 32;
X		masklo = (unsigned long long) mask & 0xffffffffL;
X		mask >>= 12;
X		tmask = mask;
X		printf("%d: type: %d, addr: 0x%x000, mask: 0x%x000\n     basehi: 0x%8.8x, baselo: 0x%8.8x\n     maskhi: 0x%8.8x, masklo: 0x%8.8x\n",
X			i, type, tbase, tmask, basehi, baselo, maskhi, masklo);
X	}
X
X	for(i=0;ranges[i].address;i++) {
X		int maskhi, masklo;
X		mask = rdmsr(ranges[i].address);
X		maskhi = (unsigned long long) mask >> 32;
X		masklo = (unsigned long long) mask & 0xffffffffL;
X		printf("%s: 0x%8.8x 0x%8.8x\n",
X			ranges[i].name, maskhi, masklo);
X	}
X		
X	tbase = rdmsr(0x1e0);
X	printf("BKUPTMPDR6: %x\n", tbase);
X	tbase = rdmsr(0x2a);
X	printf("BKUPTMPDR6: %x\n", tbase);
X
X	pmap = &curproc->p_vmspace->vm_pmap;
#if 0
X	kernaddr = 0xf0000000;
X	for(i=0;i<1024;i++) {
X		vm_offset_t kva;
X		kva = kernaddr + i * 4096;
X		printf("%d (0x%x): 0x%x\n", i, kva, pmap_kextract(kva));
X		tsleep(&kva, PVM, "TSLOOO", 10);
X	}
#endif
X
X	for(i=0;i<1024;i++) {
X		unsigned entry;
X
X		entry = curproc->p_vmspace->vm_pmap.pm_pdir[i];
X		if (entry & PG_PS) {
X			printf("4MB page: 0x%x(%x)\n", entry, i << 22);
X		}
X	}
X
X	otherp = pfind(153);
X	if (otherp) {
X	for(i=0;i<1024;i++) {
X		unsigned entry;
X
X		entry = otherp->p_vmspace->vm_pmap.pm_pdir[i];
X		if (entry & PG_PS) {
X			printf("4MB page: 0x%x(%x)\n", entry, i << 22);
X		}
X	}
X	}
X
X		
X
X	return 0;
}
X
static int mycall(struct proc *p, void *uap, int *retval)
{
X	return ENODEV;
}
X
int newsyscall_mod(struct lkm_table *lkmtp, int cmd, int ver)
{
#if 0
X	DISPATCH(lkmtp, cmd, ver, load, unload, lkm_nullcmd)
#endif
X	MOD_DISPATCH(newsyscall_mod,
X		lkmtp, cmd, ver, load, unload, lkm_nullcmd)
#if 0
X	MOD_DISPATCH(newsyscall_mod, lkmtp, cmd, ver,
X	    newsyscall_load, lkm_nullcmd, lkm_nullcmd)
#endif
}
X
static int unload(struct lkm_table *lkmtp, int cmd)
{
X    return 0;
}
SHAR_EOF
  $shar_touch -am 1119153497 'mycall.c' &&
  chmod 0644 'mycall.c' ||
  echo 'restore of mycall.c failed'
  shar_count="`wc -c < 'mycall.c'`"
  test 3647 -eq "$shar_count" ||
    echo "mycall.c: original size 3647, current size $shar_count"
fi
# ============= Makefile ==============
if test -f 'Makefile' && test X"$1" != X"-c"; then
  echo 'x - skipping Makefile (file already exists)'
else
  echo 'x - extracting Makefile (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'Makefile' &&
BINDIR=	/tmp
SRCS=	mycall.c
KMOD=	newsyscall_mod
NOMAN=	none
X
CLEANFILES+= ${KMOD}
X
X.include <bsd.kmod.mk>
SHAR_EOF
  $shar_touch -am 1116215996 'Makefile' &&
  chmod 0644 'Makefile' ||
  echo 'restore of Makefile failed'
  shar_count="`wc -c < 'Makefile'`"
  test 107 -eq "$shar_count" ||
    echo "Makefile: original size 107, current size $shar_count"
fi
exit 0

-- 
John
dyson@freebsd.org
jdyson@nc.com



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199711192038.PAA05049>