# This is a shell archive. Save it in a file, remove anything before # this line, and then unpack it by entering "sh file". Note, it may # create directories; files and directories will be owned by you and # have default permissions. # # This archive contains: # # COPYRIGHT # Makefile # Makefile.inc # README # memconfig # module # xf86test # memconfig/Makefile # memconfig/memconfig.8 # memconfig/memconfig.c # module/Makefile # module/aperture.c # module/i686_mem.c # module/k6_mem.c # module/memrange.h # module/xf86.4 # module/xf86_mod.c # module/xf86_mod.h # module/xf86_mod_install # module/xf86_reg.h # xf86test/Makefile # xf86test/xf86test.c # # $XFree86: xc/programs/Xserver/hw/xfree86/etc/apNetBSD.shar,v 3.13 2000/10/24 18:07:51 dawes Exp $ # echo x - COPYRIGHT sed 's/^X//' >COPYRIGHT << 'END-of-COPYRIGHT' XCopyright (C) 1999 The XFree86 Project Inc. X XPermission is hereby granted, free of charge, to any person obtaining Xa copy of this software and associated documentation files (the X"Software"), to deal in the Software without restriction, including Xwithout limitation the rights to use, copy, modify, merge, publish, Xdistribute, sublicense, and/or sell copies of the Software, and to Xpermit persons to whom the Software is furnished to do so, subject to Xthe following conditions: X XThe above copyright notice and the following permission notice shall be Xincluded in all copies of the Software: X XTHE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS XOR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE WARRANTIES OF XMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON- XINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR ANY XCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, XTORT OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE XSOFTWARE OR THE USE OF OTHER DEALINGS IN THE SOFTWARE. X XExcept as contained in this notice, the name of The XFree86 Project Xshall not be used in advertising or otherwise to promote the use or Xother dealings in this Software without prior written authorization Xfrom The XFree86 Project. X END-of-COPYRIGHT echo x - Makefile sed 's/^X//' >Makefile << 'END-of-Makefile' X# Makefile for the XFree86 aperture driver X# X# Copyright (C) 1999 The XFree86 Project Inc. X# X XSUBDIR= module memconfig xf86test X XDISTRIB= COPYRIGHT Makefile Makefile.inc README memconfig module xf86test \ X memconfig/Makefile memconfig/memconfig.8 memconfig/memconfig.c \ X module/Makefile module/aperture.c \ X module/i686_mem.c module/k6_mem.c module/memrange.h \ X module/xf86.4 module/xf86_mod.c module/xf86_mod.h \ X module/xf86_mod_install module/xf86_reg.h \ X xf86test/Makefile xf86test/xf86test.c X Xbuild: dirs X ${MAKE} ${_J} cleandir X ${MAKE} ${_J} includes X ${MAKE} ${_J} depend X ${MAKE} ${_J} X ${MAKE} ${_J} install X Xdirs: X if [ ! -d ${KMODDIR} ]; then ${INSTALL} -d ${KMODDIR} ; fi X if [ ! -d ${INCSDIR} ]; then ${INSTALL} -d ${INCSDIR} ; fi X if [ ! -d ${BINDIR} ]; then ${INSTALL} -d ${BINDIR} ; fi X if [ ! -d ${MANDIR}/man4 ]; then ${INSTALL} -d ${MANDIR}/man4 ; fi X if [ ! -d ${MANDIR}/cat4 ]; then ${INSTALL} -d ${MANDIR}/cat4 ; fi X if [ ! -d ${MANDIR}/man8 ]; then ${INSTALL} -d ${MANDIR}/man8 ; fi X if [ ! -d ${MANDIR}/cat8 ]; then ${INSTALL} -d ${MANDIR}/cat8 ; fi X Xshar: X shar $(DISTRIB) > apNetBSD.shar X Xclean: X rm -f apNetBSD.shar X X.include "Makefile.inc" X.include END-of-Makefile echo x - Makefile.inc sed 's/^X//' >Makefile.inc << 'END-of-Makefile.inc' X# Define the directory where to install the aperture driver X# If you change it from the default value, also define the X# NetBSDApertureDir variable in xc/config/cf/host.def before rebuilding X# the X server X XAPDIR= /usr/local/aperture X XKMODDIR= ${APDIR}/lkm XBINDIR= ${APDIR}/bin XMANDIR= ${APDIR}/man XINCSDIR= ${APDIR}/include END-of-Makefile.inc echo x - README sed 's/^X//' >README << 'END-of-README' X X XFree86 Framebuffer "aperture" driver for NetBSD. X ------------------------------------------------- X XVersion 2.0 X----------- X XThis module was originally written to help work around the security Xfeature of NetBSD that prevents read/write access to /dev/mem. It also Xprovide Pentium II and AMD K6 MTRR control in order to control Xwrite-combining to the framebuffer memory. X XXFree86 can take advantage of having direct access to video Xmemory (especially with VLB and PCI cards) and even requires it for Xthe most recent PCI or AGP video boards. X XThis driver works like the standard /dev/mem driver. It just allows Xmapping of the VGA framebuffer and BIOS even if kernel security level Xis > 0. The driver only implements the open(), close(), ioctl() and Xmmap() calls. In order not to defeat kernel security, only one open() Xat a time is allowed and only a process with effective user id of 0 can Xperform it. So while you're running XFree86, no other process will be Xallowed to open /dev/xf86. X XThis work is originally heavily inspired from the Solaris x86 aperture Xdriver by Doug Anson (danson@lgc.com) and David Holland X(davidh@use.com). MTRR support is derived from FreeBSD. X X XInstallation: X------------- X Xo Optionnally, edit Makefile.inc to set the APDIR variable to the X directory where you want to install the aperture driver. If you change X this, and want to rebuild XFree86 from source, also define X NetBSDApertureDir in xc/config/cf/host.def before rebuilding it. X Xo run 'make build' as root. This will build and install the XFree86 X aperture kernel module. X Xo add the following line to /etc/lkm.conf (replace /usr/local/aperture X by the $APDIR directory): X X /usr/local/aperture/lkm/xf86.o - - /usr/local/aperture/lkm/xf86_mod_install - - X X and set: X X lkm=YES X X in /etc/rc.conf X Xo Reboot your system. X Xo Test the module by running 'aptest' as root. The output will look like: X X # ./aptest X NOTICE: VGA mapped [0xa0000 ,size=4096) to addr=0x10073000... X X DONE displaying memory contents (80 bytes) X UNMAPPING [0xa0000 ,size=4096) to addr=0x10073000... and closing...DONE. X Exiting successful... X Xo Start the XFree86 server. All XFree86 versions post 3.9.16d have support X for the aperture driver enabled. X XBug reports, comments, suggestions can be sent to X X--Matthieu Herrb X X---------------------------------------------------------------------- X X Copyright (c) 1994,1999 The XFree86 Project Inc. X END-of-README echo c - memconfig mkdir -p memconfig > /dev/null 2>&1 echo c - module mkdir -p module > /dev/null 2>&1 echo c - xf86test mkdir -p xf86test > /dev/null 2>&1 echo x - memconfig/Makefile sed 's/^X//' >memconfig/Makefile << 'END-of-memconfig/Makefile' X# $FreeBSD: src/usr.sbin/memcontrol/Makefile,v 1.2 1999/09/29 21:43:31 chris Exp $ X XPROG= memconfig XMAN= memconfig.8 XCPPFLAGS+= -I${.CURDIR}/../module X X.include END-of-memconfig/Makefile echo x - memconfig/memconfig.8 sed 's/^X//' >memconfig/memconfig.8 << 'END-of-memconfig/memconfig.8' X.\" Copyright (c) 1999 Chris Costello X.\" All rights reserved. X.\" X.\" Redistribution and use in source and binary forms, with or without X.\" modification, are permitted provided that the following conditions X.\" are met: X.\" 1. Redistributions of source code must retain the above copyright X.\" notice, this list of conditions and the following disclaimer. X.\" 2. Redistributions in binary form must reproduce the above copyright X.\" notice, this list of conditions and the following disclaimer in the X.\" documentation and/or other materials provided with the distribution. X.\" X.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND X.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE X.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE X.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE X.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL X.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS X.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) X.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT X.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY X.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF X.\" SUCH DAMAGE. X.\" X.\" $FreeBSD: src/usr.sbin/memcontrol/memcontrol.8,v 1.2 1999/10/09 16:37:37 chris Exp $ X.\" X.Dd November 14, 1999 X.Dt MEMCONFIG 8 X.Os NetBSD X.Sh NAME X.Nm memconfig X.Nd "Control system cache behaviour with respect to memory" X.Sh SYNOPSIS X.Nm X.Ar list X.Op Fl a X.Pp X.Nm X.Ar set X.Fl b Ar base X.Fl l Ar length X.Fl o Ar owner X.Ar attribute X.Pp X.Nm X.Ar clear X.Fl o Ar owner X.Pp X.Nm X.Ar clear X.Fl b Ar base X.Fl l Ar length X.Sh DESCRIPTION XA number of supported system architectures allow the behaviour of the CPU Xcache to be programmed to behave differently depending on the region being Xwritten. X.Pp X.Nm Memconfig Xprovides an interface to this facility, allowing CPU cache behavior to Xbe altered for ranges of system physical memory. X.Pp XThese ranges are typically power-of-2 aligned and sized, however the specific Xrules governing their layout vary between architectures. The X.Nm memconfig Xprogram does not attempt to enforce these rules, however the system will Xreject any attempt to set an illegal combination. X.Bl -tag -width clear X.It Ar list XList range slots. X.Bl -tag -width xxxxxx X.It Op Fl a XList all range slots, even those that are inactive X.El X.It Ar set XSet memory range attributes. X.Bl -tag -width xxxxxx X.It Fl b Ar base XMemory range base address X.It Fl l Ar length XLength of memory range in bytes, power of 2 X.It Fl o Ar owner XText identifier for this setting (7 char max) X.It Ar attribute XAttributes applied to this range; one of X.Ar uncacheable , X.Ar write-combine , X.Ar write-through , X.Ar write-back , X.Ar write-protect X.El X.It Ar clear XClear memory range attributes. Ranges may be cleared by owner or by Xbase/length combination. X.Pp XTo clear based on ownership: X.Bl -tag -width xxxxxx X.It Fl o Ar owner XAll ranges with this owner will be cleared X.El X.Pp XTo clear based on the base/length combination: X.Bl -tag -width xxxxxx X.It Fl b Ar base XMemory range base address X.It Fl l Ar length XLength of memory range in bytes, power of 2 X.El X.Pp XBase and length must exactly match an existing range. X.El X.Sh NOTE XSince X.Nm memconfig Xuses the XFree86 aperture driver X.Pa /dev/xf86 Xon NetBSD, it can only be run after the driver has beed loaded and Xbefore the X server starts. X.Sh HISTORY X.Nm memconfig Xwas originally introduced in FreeBSD 3.3 as X.Xr memcontrol 8 . XIt is provided as part of the XFree86 aperture driver version 2.0 for XNetBSD. X.Sh SEE ALSO X.Xr xf86 4 END-of-memconfig/memconfig.8 echo x - memconfig/memconfig.c sed 's/^X//' >memconfig/memconfig.c << 'END-of-memconfig/memconfig.c' X/*- X * Copyright (c) 1999 Michael Smith X * All rights reserved. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * X * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE X * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF X * SUCH DAMAGE. X * X * $FreeBSD: src/usr.sbin/memcontrol/memcontrol.c,v 1.3 1999/08/28 01:17:00 peter Exp $ X */ X X#include X#include X X#include X#include X#include X#include X#include X#include X X#include "memrange.h" X Xstruct X{ X char *name; X int val; X int kind; X#define MDF_SETTABLE (1<<0) X} attrnames[] = { X {"uncacheable", MDF_UNCACHEABLE, MDF_SETTABLE}, X {"write-combine", MDF_WRITECOMBINE, MDF_SETTABLE}, X {"write-through", MDF_WRITETHROUGH, MDF_SETTABLE}, X {"write-back", MDF_WRITEBACK, MDF_SETTABLE}, X {"write-protect", MDF_WRITEPROTECT, MDF_SETTABLE}, X {"fixed-base", MDF_FIXBASE, 0}, X {"fixed-length", MDF_FIXLEN, 0}, X {"set-by-firmware", MDF_FIRMWARE, 0}, X {"active", MDF_ACTIVE, MDF_SETTABLE}, X {"bogus", MDF_BOGUS, 0}, X {NULL, 0, 0} X}; X Xstatic void listfunc(int memfd, int argc, char *argv[]); Xstatic void setfunc(int memfd, int argc, char *argv[]); Xstatic void clearfunc(int memfd, int argc, char *argv[]); Xstatic void helpfunc(int memfd, int argc, char *argv[]); Xstatic void help(char *what); X Xstruct X{ X char *cmd; X char *desc; X void (*func)(int memfd, int argc, char *argv[]); X} functions[] = { X {"list", X "List current memory range attributes\n" X " list [-a]\n" X " -a list all range slots, even those that are inactive", X listfunc}, X {"set", X "Set memory range attributes\n" X " set -b -l -o \n" X " memory range base address\n" X " length of memory range in bytes, power of 2\n" X " text identifier for this setting (7 char max)\n" X " attribute(s) to be applied to this range:\n" X " uncacheable\n" X " write-combine\n" X " write-through\n" X " write-back\n" X " write-protect", X setfunc}, X {"clear", X "Clear memory range attributes\n" X " clear -o \n" X " all ranges with this owner will be cleared\n" X " clear -b -l \n" X " memory range base address\n" X " length of memory range in bytes, power of 2\n" X " Base and length must exactly match an existing range", X clearfunc}, X {NULL, NULL, helpfunc} X}; X Xint Xmain(int argc, char *argv[]) X{ X int i, memfd; X X if (argc < 2) { X help(NULL); X } else { X if ((memfd = open("/dev/xf86", O_RDONLY)) == -1) X err(1, "can't open /dev/xf86"); X X for (i = 0; functions[i].cmd != NULL; i++) X if (!strcmp(argv[1], functions[i].cmd)) X break; X functions[i].func(memfd, argc - 1, argv + 1); X close(memfd); X } X return(0); X} X Xstatic struct mem_range_desc * Xmrgetall(int memfd, int *nmr) X{ X struct mem_range_desc *mrd; X struct mem_range_op mro; X X mro.mo_arg[0] = 0; X if (ioctl(memfd, MEMRANGE_GET, &mro)) X err(1, "can't size range descriptor array"); X X *nmr = mro.mo_arg[0]; X mrd = malloc(*nmr * sizeof(struct mem_range_desc)); X if (mrd == NULL) X errx(1, "can't allocate %d bytes for %d range descriptors", X *nmr * sizeof(struct mem_range_desc), *nmr); X X mro.mo_arg[0] = *nmr; X mro.mo_desc = mrd; X if (ioctl(memfd, MEMRANGE_GET, &mro)) X err(1, "can't fetch range descriptor array"); X X return(mrd); X} X X Xstatic void Xlistfunc(int memfd, int argc, char *argv[]) X{ X struct mem_range_desc *mrd; X int nd, i, j; X int error; X int ch; X int showall = 0; X char *owner; X X owner = NULL; X while ((ch = getopt(argc, argv, "ao:")) != -1) X switch(ch) { X case 'a': X showall = 1; X break; X case 'o': X owner = strdup(optarg); X break; X case '?': X default: X help("list"); X } X X mrd = mrgetall(memfd, &nd); X X for (i = 0; i < nd; i++) { X if (!showall && !(mrd[i].mr_flags & MDF_ACTIVE)) X continue; X if (owner && strcmp(mrd[i].mr_owner, owner)) X continue; X printf("%qx/%qx %.8s ", mrd[i].mr_base, mrd[i].mr_len, X mrd[i].mr_owner[0] ? mrd[i].mr_owner : "-"); X for (j = 0; attrnames[j].name != NULL; j++) X if (mrd[i].mr_flags & attrnames[j].val) X printf("%s ", attrnames[j].name); X printf("\n"); X } X free(mrd); X if (owner) X free(owner); X} X Xstatic void Xsetfunc(int memfd, int argc, char *argv[]) X{ X struct mem_range_desc mrd; X struct mem_range_op mro; X int i; X int ch; X char *ep; X X mrd.mr_base = 0; X mrd.mr_len = 0; X mrd.mr_flags = 0; X strcpy(mrd.mr_owner, "user"); X while ((ch = getopt(argc, argv, "b:l:o:")) != -1) X switch(ch) { X case 'b': X mrd.mr_base = strtouq(optarg, &ep, 0); X if ((ep == optarg) || (*ep != 0)) X help("set"); X break; X case 'l': X mrd.mr_len = strtouq(optarg, &ep, 0); X if ((ep == optarg) || (*ep != 0)) X help("set"); X break; X case 'o': X if ((*optarg == 0) || (strlen(optarg) > 7)) X help("set"); X strcpy(mrd.mr_owner, optarg); X break; X X case '?': X default: X help("set"); X } X X if (mrd.mr_len == 0) X help("set"); X X argc -= optind; X argv += optind; X X while(argc--) { X for (i = 0; attrnames[i].name != NULL; i++) { X if (!strcmp(attrnames[i].name, argv[0])) { X if (!attrnames[i].kind & MDF_SETTABLE) X help("flags"); X mrd.mr_flags |= attrnames[i].val; X break; X } X } X if (attrnames[i].name == NULL) X help("flags"); X argv++; X } X X mro.mo_desc = &mrd; X mro.mo_arg[0] = 0; X if (ioctl(memfd, MEMRANGE_SET, &mro)) X err(1, "can't set range"); X} X Xstatic void Xclearfunc(int memfd, int argc, char *argv[]) X{ X struct mem_range_desc mrd, *mrdp; X struct mem_range_op mro; X int i, nd; X int ch; X char *ep, *owner; X X mrd.mr_base = 0; X mrd.mr_len = 0; X owner = NULL; X while ((ch = getopt(argc, argv, "b:l:o:")) != -1) X switch(ch) { X case 'b': X mrd.mr_base = strtouq(optarg, &ep, 0); X if ((ep == optarg) || (*ep != 0)) X help("clear"); X break; X case 'l': X mrd.mr_len = strtouq(optarg, &ep, 0); X if ((ep == optarg) || (*ep != 0)) X help("clear"); X break; X case 'o': X if ((*optarg == 0) || (strlen(optarg) > 7)) X help("clear"); X owner = strdup(optarg); X break; X X case '?': X default: X help("clear"); X } X X if (owner != NULL) { X /* clear-by-owner */ X if ((mrd.mr_base != 0) || (mrd.mr_len != 0)) X help("clear"); X X mrdp = mrgetall(memfd, &nd); X mro.mo_arg[0] = MEMRANGE_SET_REMOVE; X for (i = 0; i < nd; i++) { X if (!strcmp(owner, mrdp[i].mr_owner) && X (mrdp[i].mr_flags & MDF_ACTIVE) && X !(mrdp[i].mr_flags & MDF_FIXACTIVE)) { X X mro.mo_desc = mrdp + i; X if (ioctl(memfd, MEMRANGE_SET, &mro)) X warn("couldn't clear range owned by '%s'", owner); X } X } X } else if ((mrd.mr_base != 0) && (mrd.mr_len != 0)) { X /* clear-by-base/len */ X mro.mo_arg[0] = MEMRANGE_SET_REMOVE; X mro.mo_desc = &mrd; X if (ioctl(memfd, MEMRANGE_SET, &mro)) X err(1, "couldn't clear range"); X } else { X help("clear"); X } X} X Xstatic void Xhelpfunc(int memfd, int argc, char *argv[]) X{ X help(argv[1]); X} X Xstatic void Xhelp(char *what) X{ X int i; X X if (what != NULL) { X /* find a function that matches */ X for (i = 0; functions[i].cmd != NULL; i++) X if (!strcmp(what, functions[i].cmd)) { X fprintf(stderr, "%s\n", functions[i].desc); X return; X } X fprintf(stderr, "Unknown command '%s'\n", what); X } X X /* print general help */ X fprintf(stderr, "Valid commands are :\n"); X for (i = 0; functions[i].cmd != NULL; i++) X fprintf(stderr, " %s\n", functions[i].cmd); X fprintf(stderr, "Use help for command-specific help\n"); X} END-of-memconfig/memconfig.c echo x - module/Makefile sed 's/^X//' >module/Makefile << 'END-of-module/Makefile' X# X# Loadable Kernel Module for the XFree86 Aperture Driver X# X# Copyright (c) 1994-1999 The XFree86 Project Inc. X# X X# Add -DXF86_DEBUG to CPPFLAGS to add debugging printfs XCPPFLAGS+= $(PC98) XWARNS?= 1 X XKMOD= xf86 XSRCS= aperture.c i686_mem.c k6_mem.c xf86_mod.c XMAN= xf86.4 X XPOSTINSTALL= ${.CURDIR}/xf86_mod_install X Xafterinstall: X ${INSTALL} -c -o root -g wheel -m 755 $(POSTINSTALL) $(KMODDIR) X X Xincludes: X install -c -p -o root -g wheel -m 444 ${.CURDIR}/memrange.h $(INCSDIR) X XKMOD_LOADFLAGS= -p$(POSTINSTALL) X X.include END-of-module/Makefile echo x - module/aperture.c sed 's/^X//' >module/aperture.c << 'END-of-module/aperture.c' X/*- X * Copyright (c) 1988 University of Utah. X * Copyright (c) 1982, 1986, 1990 The Regents of the University of California. X * Copyright (c) 1994, 1999 The XFree86 Project Inc. X * All rights reserved. X * X * This code is derived from software contributed to Berkeley by X * the Systems Programming Group of the University of Utah Computer X * Science Department, and code derived from software contributed to X * Berkeley by William Jolitz. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * 3. All advertising materials mentioning features or use of this software X * must display the following acknowledgement: X * This product includes software developed by the University of X * California, Berkeley and its contributors. X * 4. Neither the name of the University nor the names of its contributors X * may be used to endorse or promote products derived from this software X * without specific prior written permission. X * X * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE X * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF X * SUCH DAMAGE. X * X * from: Utah $Hdr: mem.c 1.13 89/10/08$ X * from: @(#)mem.c 7.2 (Berkeley) 5/9/91 X * from: $FreeBSD: src/sys/i386/i386/mem.c,v 1.76 1999/10/30 06:31:46 phk Exp $ X */ X X/* X * linear framebuffer aperture driver for NetBSD X */ X X#include X#include X#include X#include X#include X#include X#include X#include X#include X X#ifdef _LKM X#include "xf86_mod.h" X#endif X#include "xf86_reg.h" X#include "memrange.h" X X#define ISA_END 0xFFFFF X#ifdef PC98 X#define HOLE16M_START 0xF00000 X#define HOLE16M_END 0xFFFFFF X#endif X X/* open counter */ Xstatic int xf86_open_count = 0; X X/* mem range descriptors */ Xstruct mem_range_softc mem_range_softc; X X/* X * Open the device X */ Xint Xxf86open(dev, oflags, devtype, p) X dev_t dev; X int oflags; X int devtype; X struct proc *p; X{ X X if (suser(p->p_ucred, &p->p_acflag) != 0) { X return(EPERM); X } X /* authorize only one simultaneous open() */ X if (xf86_open_count > 0) { X return(EPERM); X } X xf86_open_count++; X X return(0); X} X X/* X * Close the device X */ Xint Xxf86close(dev, cflags, devtype, p) X dev_t dev; X int cflags; X int devtype; X struct proc *p; X{ X xf86_open_count--; X return(0); X} X X/* X * mmap() physical memory sections X * X * allow only section in the vga framebuffer and above main memory X * to be mapped X */ X#if !defined(__NetBSD_Version__) || \ X (defined(__NetBSD_Version__) && (__NetBSD_Version__ < 105000000)) Xint Xxf86mmap(dev, offset, length) X dev_t dev; X int offset; X int length; X#else Xpaddr_t Xxf86mmap(dev, offset, length) X dev_t dev; X off_t offset; X int length; X#endif /* __NetBSD_Version__ */ X{ X X#ifdef XF86_DEBUG X printf("xf86mmap: addr 0x%x\n", offset); X#endif X if ((minor(dev) == 0) X && ((offset <= ISA_END ) X || (unsigned)offset > (unsigned)ctob(physmem) X#ifdef PC98 X || ((unsigned)offset >=HOLE16M_START X && (unsigned)offset <= HOLE16M_END) X#endif X )) { X return i386_btop(offset); X } else { X return(-1); X } X} X Xint Xxf86ioctl(dev, cmd, data, flags, p) X dev_t dev; X u_long cmd; X caddr_t data; X int flags; X struct proc *p; X{ X int nd, error = 0; X struct mem_range_op *mo = (struct mem_range_op *)data; X struct mem_range_desc *md; X X /* is this for us? */ X if ((cmd != MEMRANGE_GET) && X (cmd != MEMRANGE_SET)) X return (ENOTTY); X X /* any chance we can handle this? */ X if (mem_range_softc.mr_op == NULL) X return (EOPNOTSUPP); X X /* do we have any descriptors? */ X if (mem_range_softc.mr_ndesc == 0) X return (ENXIO); X X switch (cmd) { X case MEMRANGE_GET: X nd = imin(mo->mo_arg[0], mem_range_softc.mr_ndesc); X if (nd > 0) { X md = (struct mem_range_desc *) X malloc(nd * sizeof(struct mem_range_desc), X M_MEMDESC, M_WAITOK); X error = mem_range_attr_get(md, &nd); X if (!error) X error = copyout(md, mo->mo_desc, X nd * sizeof(struct mem_range_desc)); X free(md, M_MEMDESC); X } else { X nd = mem_range_softc.mr_ndesc; X } X mo->mo_arg[0] = nd; X break; X X case MEMRANGE_SET: X md = (struct mem_range_desc *)malloc(sizeof(struct mem_range_desc), X M_MEMDESC, M_WAITOK); X error = copyin(mo->mo_desc, md, sizeof(struct mem_range_desc)); X /* clamp description string */ X md->mr_owner[sizeof(md->mr_owner) - 1] = 0; X if (error == 0) X error = mem_range_attr_set(md, &mo->mo_arg[0]); X free(md, M_MEMDESC); X break; X } X return (error); X} X X/* X * Implementation-neutral, kernel-callable functions for manipulating X * memory range attributes. X */ Xint Xmem_range_attr_get(mrd, arg) X struct mem_range_desc *mrd; X int *arg; X{ X /* can we handle this? */ X if (mem_range_softc.mr_op == NULL) X return (EOPNOTSUPP); X X if (*arg == 0) { X *arg = mem_range_softc.mr_ndesc; X } else { X bcopy(mem_range_softc.mr_desc, mrd, (*arg) * sizeof(struct mem_range_desc)); X } X return (0); X} X Xint Xmem_range_attr_set(mrd, arg) X struct mem_range_desc *mrd; X int *arg; X{ X /* can we handle this? */ X if (mem_range_softc.mr_op == NULL) X return (EOPNOTSUPP); X X return (mem_range_softc.mr_op->set(&mem_range_softc, mrd, arg)); X } END-of-module/aperture.c echo x - module/i686_mem.c sed 's/^X//' >module/i686_mem.c << 'END-of-module/i686_mem.c' X/*- X * Copyright (c) 1999 Michael Smith X * All rights reserved. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * X * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE X * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF X * SUCH DAMAGE. X * X * $FreeBSD: src/sys/i386/i386/i686_mem.c,v 1.8 1999/10/12 22:53:05 green Exp $ X */ X X#include X#include X#include X X#include X#include X X#include "memrange.h" X#include "xf86_reg.h" X X/* X * i686 memory range operations X * X * This code will probably be impenetrable without reference to the X * Intel Pentium Pro documentation. X */ X Xstatic char *mem_owner_bios = "BIOS"; X X#define MR686_FIXMTRR (1<<0) X X#define mrwithin(mr, a) \ X (((a) >= (mr)->mr_base) && ((a) < ((mr)->mr_base + (mr)->mr_len))) X#define mroverlap(mra, mrb) \ X (mrwithin(mra, mrb->mr_base) || mrwithin(mrb, mra->mr_base)) X X#define mrvalid(base, len) \ X ((!(base & ((1 << 12) - 1))) && /* base is multiple of 4k */ \ X ((len) >= (1 << 12)) && /* length is >= 4k */ \ X powerof2((len)) && /* ... and power of two */ \ X !((base) & ((len) - 1))) /* range is not discontiuous */ X X#define mrcopyflags(curr, new) (((curr) & ~MDF_ATTRMASK) | ((new) & MDF_ATTRMASK)) X Xstatic void i686_mrinit(struct mem_range_softc * sc); X Xstatic int i686_mrset __P((struct mem_range_softc * sc, X struct mem_range_desc * mrd, X int *arg)); Xstatic void i686_mrAPinit __P((struct mem_range_softc * sc)); X Xstruct mem_range_ops i686_mrops = { X i686_mrinit, X i686_mrset, X i686_mrAPinit X}; X X/* XXX for AP startup hook */ Xstatic u_int64_t mtrrcap, mtrrdef; X Xstatic struct mem_range_desc *mem_range_match __P((struct mem_range_softc * sc, X struct mem_range_desc * mrd)); Xstatic void i686_mrfetch __P((struct mem_range_softc * sc)); Xstatic int i686_mtrrtype __P((int flags)); Xstatic void i686_mrstore __P((struct mem_range_softc * sc)); Xstatic void i686_mrstoreone __P((void *arg)); Xstatic struct mem_range_desc *i686_mtrrfixsearch __P((struct mem_range_softc * sc, X u_int64_t addr)); Xstatic int i686_mrsetlow __P((struct mem_range_softc * sc, X struct mem_range_desc * mrd, X int *arg)); Xstatic int i686_mrsetvariable __P((struct mem_range_softc * sc, X struct mem_range_desc * mrd, X int *arg)); X X/* i686 MTRR type to memory range type conversion */ Xstatic int i686_mtrrtomrt[] = { X MDF_UNCACHEABLE, X MDF_WRITECOMBINE, X 0, X 0, X MDF_WRITETHROUGH, X MDF_WRITEPROTECT, X MDF_WRITEBACK X}; X X/* X * i686 MTRR conflict matrix for overlapping ranges X * X * Specifically, this matrix allows writeback and uncached ranges X * to overlap (the overlapped region is uncached). The array index X * is the translated i686 code for the flags (because they map well). X */ Xstatic int i686_mtrrconflict[] = { X MDF_WRITECOMBINE | MDF_WRITETHROUGH | MDF_WRITEPROTECT, X MDF_ATTRMASK, X 0, X 0, X MDF_ATTRMASK, X MDF_ATTRMASK, X MDF_WRITECOMBINE | MDF_WRITETHROUGH | MDF_WRITEPROTECT X}; X X/* X * Look for an exactly-matching range. X */ Xstatic struct mem_range_desc * Xmem_range_match(struct mem_range_softc * sc, struct mem_range_desc * mrd) X{ X struct mem_range_desc *cand; X int i; X X for (i = 0, cand = sc->mr_desc; i < sc->mr_ndesc; i++, cand++) X if ((cand->mr_base == mrd->mr_base) && X (cand->mr_len == mrd->mr_len)) X return (cand); X return (NULL); X} X X/* X * Fetch the current mtrr settings from the current CPU (assumed to all X * be in sync in the SMP case). Note that if we are here, we assume X * that MTRRs are enabled, and we may or may not have fixed MTRRs. X */ Xstatic void Xi686_mrfetch(struct mem_range_softc * sc) X{ X struct mem_range_desc *mrd; X u_int64_t msrv; X int i, j, msr; X X mrd = sc->mr_desc; X X /* Get fixed-range MTRRs */ X if (sc->mr_cap & MR686_FIXMTRR) { X msr = MSR_MTRR64kBase; X for (i = 0; i < (MTRR_N64K / 8); i++, msr++) { X msrv = rdmsr(msr); X for (j = 0; j < 8; j++, mrd++) { X mrd->mr_flags = (mrd->mr_flags & ~MDF_ATTRMASK) | X i686_mtrrtomrt[msrv & 0xff] | X MDF_ACTIVE; X if (mrd->mr_owner[0] == 0) X strcpy(mrd->mr_owner, mem_owner_bios); X msrv = msrv >> 8; X } X } X msr = MSR_MTRR16kBase; X for (i = 0; i < (MTRR_N16K / 8); i++, msr++) { X msrv = rdmsr(msr); X for (j = 0; j < 8; j++, mrd++) { X mrd->mr_flags = (mrd->mr_flags & ~MDF_ATTRMASK) | X i686_mtrrtomrt[msrv & 0xff] | X MDF_ACTIVE; X if (mrd->mr_owner[0] == 0) X strcpy(mrd->mr_owner, mem_owner_bios); X msrv = msrv >> 8; X } X } X msr = MSR_MTRR4kBase; X for (i = 0; i < (MTRR_N4K / 8); i++, msr++) { X msrv = rdmsr(msr); X for (j = 0; j < 8; j++, mrd++) { X mrd->mr_flags = (mrd->mr_flags & ~MDF_ATTRMASK) | X i686_mtrrtomrt[msrv & 0xff] | X MDF_ACTIVE; X if (mrd->mr_owner[0] == 0) X strcpy(mrd->mr_owner, mem_owner_bios); X msrv = msrv >> 8; X } X } X } X /* Get remainder which must be variable MTRRs */ X msr = MSR_MTRRVarBase; X for (; (mrd - sc->mr_desc) < sc->mr_ndesc; msr += 2, mrd++) { X msrv = rdmsr(msr); X mrd->mr_flags = (mrd->mr_flags & ~MDF_ATTRMASK) | X i686_mtrrtomrt[msrv & 0xff]; X mrd->mr_base = msrv & 0x0000000ffffff000LL; X msrv = rdmsr(msr + 1); X mrd->mr_flags = (msrv & 0x800) ? X (mrd->mr_flags | MDF_ACTIVE) : X (mrd->mr_flags & ~MDF_ACTIVE); X /* Compute the range from the mask. Ick. */ X mrd->mr_len = (~(msrv & 0x0000000ffffff000LL) & 0x0000000fffffffffLL) + 1; X if (!mrvalid(mrd->mr_base, mrd->mr_len)) X mrd->mr_flags |= MDF_BOGUS; X /* If unclaimed and active, must be the BIOS */ X if ((mrd->mr_flags & MDF_ACTIVE) && (mrd->mr_owner[0] == 0)) X strcpy(mrd->mr_owner, mem_owner_bios); X } X} X X/* X * Return the MTRR memory type matching a region's flags X */ Xstatic int Xi686_mtrrtype(int flags) X{ X int i; X X flags &= MDF_ATTRMASK; X X for (i = 0; i < (sizeof(i686_mtrrtomrt) / sizeof(i686_mtrrtomrt[0])); i++) { X if (i686_mtrrtomrt[i] == 0) X continue; X if (flags == i686_mtrrtomrt[i]) X return (i); X } X return (-1); X} X X/* X * Update running CPU(s) MTRRs to match the ranges in the descriptor X * list. X * X * XXX Must be called with interrupts enabled. X */ Xstatic void Xi686_mrstore(struct mem_range_softc * sc) X{ X disable_intr(); /* disable interrupts */ X i686_mrstoreone((void *) sc); X enable_intr(); X} X X/* X * Update the current CPU's MTRRs with those represented in the X * descriptor list. Note that we do this wholesale rather than X * just stuffing one entry; this is simpler (but slower, of course). X */ Xstatic void Xi686_mrstoreone(void *arg) X{ X struct mem_range_softc *sc = (struct mem_range_softc *) arg; X struct mem_range_desc *mrd; X u_int64_t msrv; X int i, j, msr; X u_int cr4save; X X mrd = sc->mr_desc; X X cr4save = rcr4(); /* save cr4 */ X if (cr4save & CR4_PGE) X lcr4(cr4save & ~CR4_PGE); X lcr0((rcr0() & ~CR0_NW) | CR0_CD); /* disable caches (CD = 1, NW X * = 0) */ X wbinvd(); /* flush caches, TLBs */ X wrmsr(MSR_MTRRdefType, rdmsr(MSR_MTRRdefType) & ~0x800); /* disable MTRRs (E = 0) */ X X /* Set fixed-range MTRRs */ X if (sc->mr_cap & MR686_FIXMTRR) { X msr = MSR_MTRR64kBase; X for (i = 0; i < (MTRR_N64K / 8); i++, msr++) { X msrv = 0; X for (j = 7; j >= 0; j--) { X msrv = msrv << 8; X msrv |= (i686_mtrrtype((mrd + j)->mr_flags) & 0xff); X } X wrmsr(msr, msrv); X mrd += 8; X } X msr = MSR_MTRR16kBase; X for (i = 0; i < (MTRR_N16K / 8); i++, msr++) { X msrv = 0; X for (j = 7; j >= 0; j--) { X msrv = msrv << 8; X msrv |= (i686_mtrrtype((mrd + j)->mr_flags) & 0xff); X } X wrmsr(msr, msrv); X mrd += 8; X } X msr = MSR_MTRR4kBase; X for (i = 0; i < (MTRR_N4K / 8); i++, msr++) { X msrv = 0; X for (j = 7; j >= 0; j--) { X msrv = msrv << 8; X msrv |= (i686_mtrrtype((mrd + j)->mr_flags) & 0xff); X } X wrmsr(msr, msrv); X mrd += 8; X } X } X /* Set remainder which must be variable MTRRs */ X msr = MSR_MTRRVarBase; X for (; (mrd - sc->mr_desc) < sc->mr_ndesc; msr += 2, mrd++) { X /* base/type register */ X if (mrd->mr_flags & MDF_ACTIVE) { X msrv = mrd->mr_base & 0x0000000ffffff000LL; X msrv |= (i686_mtrrtype(mrd->mr_flags) & 0xff); X } else { X msrv = 0; X } X wrmsr(msr, msrv); X X /* mask/active register */ X if (mrd->mr_flags & MDF_ACTIVE) { X msrv = 0x800 | (~(mrd->mr_len - 1) & 0x0000000ffffff000LL); X } else { X msrv = 0; X } X wrmsr(msr + 1, msrv); X } X wbinvd(); /* flush caches, TLBs */ X wrmsr(MSR_MTRRdefType, rdmsr(MSR_MTRRdefType) | 0x800); /* restore MTRR state */ X lcr0(rcr0() & ~(CR0_CD | CR0_NW)); /* enable caches CD = 0 and NW X * = 0 */ X lcr4(cr4save); /* restore cr4 */ X} X X/* X * Hunt for the fixed MTRR referencing (addr) X */ Xstatic struct mem_range_desc * Xi686_mtrrfixsearch(struct mem_range_softc * sc, u_int64_t addr) X{ X struct mem_range_desc *mrd; X int i; X X for (i = 0, mrd = sc->mr_desc; i < (MTRR_N64K + MTRR_N16K + MTRR_N4K); i++, mrd++) X if ((addr >= mrd->mr_base) && (addr < (mrd->mr_base + mrd->mr_len))) X return (mrd); X return (NULL); X} X X/* X * Try to satisfy the given range request by manipulating the fixed MTRRs that X * cover low memory. X * X * Note that we try to be generous here; we'll bloat the range out to the X * next higher/lower boundary to avoid the consumer having to know too much X * about the mechanisms here. X * X * XXX note that this will have to be updated when we start supporting "busy" ranges. X */ Xstatic int Xi686_mrsetlow(struct mem_range_softc * sc, struct mem_range_desc * mrd, int *arg) X{ X struct mem_range_desc *first_md, *last_md, *curr_md; X X /* range check */ X if (((first_md = i686_mtrrfixsearch(sc, mrd->mr_base)) == NULL) || X ((last_md = i686_mtrrfixsearch(sc, mrd->mr_base + mrd->mr_len - 1)) == NULL)) X return (EINVAL); X X /* set flags, clear set-by-firmware flag */ X for (curr_md = first_md; curr_md <= last_md; curr_md++) { X curr_md->mr_flags = mrcopyflags(curr_md->mr_flags & ~MDF_FIRMWARE, mrd->mr_flags); X bcopy(mrd->mr_owner, curr_md->mr_owner, sizeof(mrd->mr_owner)); X } X X return (0); X} X X X/* X * Modify/add a variable MTRR to satisfy the request. X * X * XXX needs to be updated to properly support "busy" ranges. X */ Xstatic int Xi686_mrsetvariable(struct mem_range_softc * sc, struct mem_range_desc * mrd, int *arg) X{ X struct mem_range_desc *curr_md, *free_md; X int i; X X /* Scan the currently active variable descriptors, look for one we X * exactly match (straight takeover) and for possible accidental X * overlaps. Keep track of the first empty variable descriptor in case X * we can't perform a takeover. */ X i = (sc->mr_cap & MR686_FIXMTRR) ? MTRR_N64K + MTRR_N16K + MTRR_N4K : 0; X curr_md = sc->mr_desc + i; X free_md = NULL; X for (; i < sc->mr_ndesc; i++, curr_md++) { X if (curr_md->mr_flags & MDF_ACTIVE) { X /* exact match? */ X if ((curr_md->mr_base == mrd->mr_base) && X (curr_md->mr_len == mrd->mr_len)) { X /* whoops, owned by someone */ X if (curr_md->mr_flags & MDF_BUSY) X return (EBUSY); X /* Ok, just hijack this entry */ X free_md = curr_md; X break; X } X /* non-exact overlap ? */ X if (mroverlap(curr_md, mrd)) { X /* between conflicting region types? */ X if ((i686_mtrrconflict[i686_mtrrtype(curr_md->mr_flags)] & mrd->mr_flags) || X (i686_mtrrconflict[i686_mtrrtype(mrd->mr_flags)] & curr_md->mr_flags)) X return (EINVAL); X } X } else if (free_md == NULL) { X free_md = curr_md; X } X } X /* got somewhere to put it? */ X if (free_md == NULL) X return (ENOSPC); X X /* Set up new descriptor */ X free_md->mr_base = mrd->mr_base; X free_md->mr_len = mrd->mr_len; X free_md->mr_flags = mrcopyflags(MDF_ACTIVE, mrd->mr_flags); X bcopy(mrd->mr_owner, free_md->mr_owner, sizeof(mrd->mr_owner)); X return (0); X} X X/* X * Handle requests to set memory range attributes by manipulating MTRRs. X * X */ Xstatic int Xi686_mrset(struct mem_range_softc * sc, struct mem_range_desc * mrd, int *arg) X{ X struct mem_range_desc *targ; X int error = 0; X X switch (*arg) { X case MEMRANGE_SET_UPDATE: X /* make sure that what's being asked for is even possible at X * all */ X if (!mrvalid(mrd->mr_base, mrd->mr_len) || X (i686_mtrrtype(mrd->mr_flags & MDF_ATTRMASK) == -1)) X return (EINVAL); X X#define FIXTOP ((MTRR_N64K * 0x10000) + (MTRR_N16K * 0x4000) + (MTRR_N4K * 0x1000)) X X /* are the "low memory" conditions applicable? */ X if ((sc->mr_cap & MR686_FIXMTRR) && X ((mrd->mr_base + mrd->mr_len) <= FIXTOP)) { X if ((error = i686_mrsetlow(sc, mrd, arg)) != 0) X return (error); X } else { X /* it's time to play with variable MTRRs */ X if ((error = i686_mrsetvariable(sc, mrd, arg)) != 0) X return (error); X } X break; X X case MEMRANGE_SET_REMOVE: X if ((targ = mem_range_match(sc, mrd)) == NULL) X return (ENOENT); X if (targ->mr_flags & MDF_FIXACTIVE) X return (EPERM); X if (targ->mr_flags & MDF_BUSY) X return (EBUSY); X targ->mr_flags &= ~MDF_ACTIVE; X targ->mr_owner[0] = 0; X break; X X default: X return (EOPNOTSUPP); X } X X /* update the hardware */ X i686_mrstore(sc); X i686_mrfetch(sc); /* refetch to see where we're at */ X return (0); X} X X/* X * Work out how many ranges we support, initialise storage for them, X * fetch the initial settings. X */ Xstatic void Xi686_mrinit(struct mem_range_softc * sc) X{ X struct mem_range_desc *mrd; X int nmdesc = 0; X int i; X X mtrrcap = rdmsr(MSR_MTRRcap); X mtrrdef = rdmsr(MSR_MTRRdefType); X X /* For now, bail out if MTRRs are not enabled */ X if (!(mtrrdef & 0x800)) { X printf("CPU supports MTRRs but not enabled\n"); X return; X } X nmdesc = mtrrcap & 0xff; X printf("Pentium Pro MTRR support enabled\n"); X X /* If fixed MTRRs supported and enabled */ X if ((mtrrcap & 0x100) && (mtrrdef & 0x400)) { X sc->mr_cap = MR686_FIXMTRR; X nmdesc += MTRR_N64K + MTRR_N16K + MTRR_N4K; X } X sc->mr_desc = X (struct mem_range_desc *) malloc(nmdesc * sizeof(struct mem_range_desc), X M_MEMDESC, M_WAITOK); X bzero(sc->mr_desc, nmdesc * sizeof(struct mem_range_desc)); X sc->mr_ndesc = nmdesc; X X mrd = sc->mr_desc; X X /* Populate the fixed MTRR entries' base/length */ X if (sc->mr_cap & MR686_FIXMTRR) { X for (i = 0; i < MTRR_N64K; i++, mrd++) { X mrd->mr_base = i * 0x10000; X mrd->mr_len = 0x10000; X mrd->mr_flags = MDF_FIXBASE | MDF_FIXLEN | MDF_FIXACTIVE; X } X for (i = 0; i < MTRR_N16K; i++, mrd++) { X mrd->mr_base = i * 0x4000 + 0x80000; X mrd->mr_len = 0x4000; X mrd->mr_flags = MDF_FIXBASE | MDF_FIXLEN | MDF_FIXACTIVE; X } X for (i = 0; i < MTRR_N4K; i++, mrd++) { X mrd->mr_base = i * 0x1000 + 0xc0000; X mrd->mr_len = 0x1000; X mrd->mr_flags = MDF_FIXBASE | MDF_FIXLEN | MDF_FIXACTIVE; X } X } X /* Get current settings, anything set now is considered to have been X * set by the firmware. (XXX has something already played here?) */ X i686_mrfetch(sc); X mrd = sc->mr_desc; X for (i = 0; i < sc->mr_ndesc; i++, mrd++) { X if (mrd->mr_flags & MDF_ACTIVE) X mrd->mr_flags |= MDF_FIRMWARE; X } X} X X/* X * Initialise MTRRs on an AP after the BSP has run the init code. X */ Xstatic void Xi686_mrAPinit(struct mem_range_softc * sc) X{ X i686_mrstoreone((void *) sc); /* set MTRRs to match BSP */ X wrmsr(MSR_MTRRdefType, mtrrdef); /* set MTRR behaviour to match X * BSP */ X} END-of-module/i686_mem.c echo x - module/k6_mem.c sed 's/^X//' >module/k6_mem.c << 'END-of-module/k6_mem.c' X/*- X * Copyright (c) 1999 Brian Fundakowski Feldman X * All rights reserved. X * X * Redistribution and use in source and binary forms, with or without X * modification, are permitted provided that the following conditions X * are met: X * 1. Redistributions of source code must retain the above copyright X * notice, this list of conditions and the following disclaimer. X * 2. Redistributions in binary form must reproduce the above copyright X * notice, this list of conditions and the following disclaimer in the X * documentation and/or other materials provided with the distribution. X * X * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE X * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF X * SUCH DAMAGE. X * X * $FreeBSD: src/sys/i386/i386/k6_mem.c,v 1.4 1999/09/05 15:45:57 green Exp $ X * X */ X X#include X#include X#include X X#include X X#include "memrange.h" X#include "xf86_reg.h" X X/* X * A K6-2 MTRR is defined as the highest 15 bits having the address, the next X * 15 having the mask, the 1st bit being "write-combining" and the 0th bit X * being "uncacheable". X * X * Address Mask WC UC X * | XXXXXXXXXXXXXXX | XXXXXXXXXXXXXXX | X | X | X * X * There are two of these in the 64-bit UWCCR. X */ X X/* X * NOTE: I do _not_ comment my code unless it's truly necessary. Don't X * expect anything frivolous here, and do NOT touch my bit-shifts X * unless you want to break this. X */ X X#define UWCCR 0xc0000085 X X#define k6_reg_get(reg, addr, mask, wc, uc) do { \ X addr = (reg) & 0xfffe0000; \ X mask = ((reg) & 0x1fffc) >> 2; \ X wc = ((reg) & 0x2) >> 1; \ X uc = (reg) & 0x1; \ X } while (0) X X#define k6_reg_make(addr, mask, wc, uc) \ X ((addr) | ((mask) << 2) | ((wc) << 1) | uc) X Xstatic void k6_mrinit __P((struct mem_range_softc * sc)); Xstatic int k6_mrset __P((struct mem_range_softc *, struct mem_range_desc *, int *)); Xstatic __inline int k6_mrmake __P((struct mem_range_desc *, u_int32_t *)); X Xstruct mem_range_ops k6_mrops = { X k6_mrinit, X k6_mrset, X NULL X}; X Xstatic __inline int Xk6_mrmake(struct mem_range_desc * desc, u_int32_t * mtrr) X{ X u_int32_t len = 0, wc, uc; X register int bit; X X if (desc->mr_base & ~0xfffe0000) X return EINVAL; X if (desc->mr_len < 131072 || !powerof2(desc->mr_len)) X return EINVAL; X if (desc->mr_flags & ~(MDF_WRITECOMBINE | MDF_UNCACHEABLE)) X return EOPNOTSUPP; X X for (bit = ffs(desc->mr_len >> 17) - 1; bit < 15; bit++) X len |= 1 << (14 - bit); X wc = (desc->mr_flags & MDF_WRITECOMBINE) ? 1 : 0; X uc = (desc->mr_flags & MDF_UNCACHEABLE) ? 1 : 0; X X *mtrr = k6_reg_make(desc->mr_base, len, wc, uc); X return 0; X} X Xstatic void Xk6_mrinit(struct mem_range_softc * sc) X{ X u_int64_t reg; X u_int32_t addr, mask, wc, uc; X int d; X X sc->mr_cap = 0; X sc->mr_ndesc = 2; /* XXX (BFF) For now, we only have one msr for X * this */ X sc->mr_desc = malloc(sc->mr_ndesc * sizeof(struct mem_range_desc), X M_MEMDESC, M_NOWAIT); X if (sc->mr_desc == NULL) X panic("k6_mrinit: malloc returns NULL"); X bzero(sc->mr_desc, sc->mr_ndesc * sizeof(struct mem_range_desc)); X X reg = rdmsr(UWCCR); X for (d = 0; d < sc->mr_ndesc; d++) { X u_int32_t one = (reg & (0xffffffff << (32 * d))) >> (32 * d); X X k6_reg_get(one, addr, mask, wc, uc); X sc->mr_desc[d].mr_base = addr; X sc->mr_desc[d].mr_len = ffs(mask) << 17; X if (wc) X sc->mr_desc[d].mr_flags |= MDF_WRITECOMBINE; X if (uc) X sc->mr_desc[d].mr_flags |= MDF_UNCACHEABLE; X } X X printf("K6-family MTRR support enabled (%d registers)\n", sc->mr_ndesc); X} X Xstatic int Xk6_mrset(struct mem_range_softc * sc, struct mem_range_desc * desc, int *arg) X{ X u_int64_t reg; X u_int32_t mtrr; X int error, d; X X switch (*arg) { X case MEMRANGE_SET_UPDATE: X error = k6_mrmake(desc, &mtrr); X if (error) X return error; X for (d = 0; d < sc->mr_ndesc; d++) { X if (!sc->mr_desc[d].mr_len) { X sc->mr_desc[d] = *desc; X goto out; X } X if (sc->mr_desc[d].mr_base == desc->mr_base && X sc->mr_desc[d].mr_len == desc->mr_len) X return EEXIST; X } X X return ENOSPC; X case MEMRANGE_SET_REMOVE: X mtrr = 0; X for (d = 0; d < sc->mr_ndesc; d++) X if (sc->mr_desc[d].mr_base == desc->mr_base && X sc->mr_desc[d].mr_len == desc->mr_len) { X bzero(&sc->mr_desc[d], sizeof(sc->mr_desc[d])); X goto out; X } X return ENOENT; X default: X return EOPNOTSUPP; X } X Xout: X X disable_intr(); X wbinvd(); X reg = rdmsr(UWCCR); X reg &= ~(0xffffffff << (32 * d)); X reg |= mtrr << (32 * d); X wrmsr(UWCCR, reg); X wbinvd(); X enable_intr(); X X return 0; X} END-of-module/k6_mem.c echo x - module/memrange.h sed 's/^X//' >module/memrange.h << 'END-of-module/memrange.h' X#ifndef _MEMRANGE_H X#define _MEMRANGE_H X/* X * Memory range attribute operations, peformed on /dev/mem X */ X X/* Memory range attributes */ X#define MDF_UNCACHEABLE (1<<0) /* region not cached */ X#define MDF_WRITECOMBINE (1<<1) /* region supports "write combine" X * action */ X#define MDF_WRITETHROUGH (1<<2) /* write-through cached */ X#define MDF_WRITEBACK (1<<3) /* write-back cached */ X#define MDF_WRITEPROTECT (1<<4) /* read-only region */ X#define MDF_ATTRMASK (0x00ffffff) X X#define MDF_FIXBASE (1<<24) /* fixed base */ X#define MDF_FIXLEN (1<<25) /* fixed length */ X#define MDF_FIRMWARE (1<<26) /* set by firmware (XXX not useful?) */ X#define MDF_ACTIVE (1<<27) /* currently active */ X#define MDF_BOGUS (1<<28) /* we don't like it */ X#define MDF_FIXACTIVE (1<<29) /* can't be turned off */ X#define MDF_BUSY (1<<30) /* range is in use */ X Xstruct mem_range_desc { X u_int64_t mr_base; X u_int64_t mr_len; X int mr_flags; X char mr_owner[8]; X}; X Xstruct mem_range_op { X struct mem_range_desc *mo_desc; X int mo_arg[2]; X#define MEMRANGE_SET_UPDATE 0 X#define MEMRANGE_SET_REMOVE 1 X /* XXX want a flag that says "set and undo when I exit" */ X}; X#define MEMRANGE_GET _IOWR('m', 50, struct mem_range_op) X#define MEMRANGE_SET _IOW('m', 51, struct mem_range_op) X X#ifdef _KERNEL X Xstruct mem_range_softc; Xstruct mem_range_ops { X void (*init) __P((struct mem_range_softc * sc)); X int (*set) __P((struct mem_range_softc * sc, struct mem_range_desc * mrd, int *arg)); X void (*initAP) __P((struct mem_range_softc * sc)); X}; X Xstruct mem_range_softc { X struct mem_range_ops *mr_op; X int mr_cap; X int mr_ndesc; X struct mem_range_desc *mr_desc; X}; X Xextern struct mem_range_softc mem_range_softc; X Xextern int mem_range_attr_get __P((struct mem_range_desc * mrd, int *arg)); Xextern int mem_range_attr_set __P((struct mem_range_desc * mrd, int *arg)); Xextern void mem_range_AP_init __P((void)); X#endif X X#endif END-of-module/memrange.h echo x - module/xf86.4 sed 's/^X//' >module/xf86.4 << 'END-of-module/xf86.4' X.\" X.\" Copyright (c) 1998 Matthieu Herrb X.\" All rights reserved. X.\" X.\" Redistribution and use in source and binary forms, with or without X.\" modification, are permitted provided that the following conditions X.\" are met: X.\" 1. Redistributions of source code must retain the above copyright X.\" notice, this list of conditions and the following disclaimer. X.\" 2. Redistributions in binary form must reproduce the above copyright X.\" notice, this list of conditions and the following disclaimer in the X.\" documentation and/or other materials provided with the distribution. X.\" 3. The name of the author may not be used to endorse or promote products X.\" derived from this software without specific prior written permission X.\" X.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR X.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES X.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. X.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, X.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT X.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, X.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY X.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT X.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF X.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. X.\" X.Dd November 14, 1999 X.Dt XF86 4 i386 X.Os X.Sh NAME X.Nm xf86 X.Nd XXFree86 aperture driver X.Sh SYNOPSIS X.Cd "modload -oxf86 -pxf86_mod_install xf86.o" X.Sh DESCRIPTION XThe X.Pa /dev/xf86 Xdriver provides access to the memory of a VGA board as well as to the XISA BIOS for Xuse by the XFree86 X servers Xwhen running with a kernel security level > 0. X.Pp XOn X.Tn ISA Xthe X.Tn I/O Xmemory space begins at physical address 0x000a0000 Xand runs to 0x00100000. X.Pp XMost X servers can take advantage of the use of this driver X.Sh IOCTL INTERFACE XSeveral architectures allow attributes to be associated with ranges of physical Xmemory. These attributes can be manipulated via X.Fn ioctl Xcalls performed on X.Nm /dev/mem . XDeclarations and data types are to be found in X.Pa X.Pp XThe specific attributes, and number of programmable ranges may vary between Xarchitectures. The full set of supported attributes is: X.Bl -tag -width 10 X.It MDF_UNCACHEABLE XThe region is not cached. X.It MDF_WRITECOMBINE XWrites to the region may be combined or performed out of order. X.It MDF_WRITETHROUGH XWrites to the region are committed synchronously. X.It MDF_WRITEBACK XWrites to the region are committed asynchronously. X.It MDF_WRITEPROTECT XThe region cannot be written to. X.El X.Pp XMemory ranges are described by X.Fa struct mem_range_desc : X.Bd -literal -offset indent Xu_int64_t mr_base; /\(** physical base address \(**/ Xu_int64_t mr_len; /\(** physical length of region \(**/ Xint mr_flags; /\(** attributes of region \(**/ Xchar mr_owner[8]; X.Ed X.Pp XIn addition to the region attributes listed above, the following flags Xmay also be set in the X.Fa mr_flags Xfield: X.Bl -tag -width 10 X.It MDF_FIXBASE XThe region's base address cannot be changed. X.It MDF_FIXLEN XThe region's length cannot be changed. X.It MDF_FIRMWARE XThe region is believed to have been established by the system firmare. X.It MDF_ACTIVE XThe region is currently active. X.It MDF_BOGUS XWe believe the region to be invalid or otherwise erroneous. X.It MDF_FIXACTIVE XThe region cannot be disabled. X.It MDF_BUSY XThe region is currently owned by another process and may not be Xaltered. X.El X.Pp XOperations are performed using X.Fa struct mem_range_op : X.Bd -literal -offset indent Xstruct mem_range_desc *mo_desc; Xint mo_arg[2]; X.Ed X.Pp XThe X.Fa MEMRANGE_GET Xioctl is used to retrieve current memory range attributes. If X.Fa mo_arg[0] Xis set to 0, it will be updated with the total number of memory range Xdescriptors. If greater than 0, the array at X.Fa mo_desc Xwill be filled with a corresponding number of descriptor structures, Xor the maximum, whichever is less. X.Pp XThe X.Fa MEMRANGE_SET Xioctl is used to add, alter and remove memory range attributes. A range Xwith the MDF_FIXACTIVE flag may not be removed; a range with the MDF_BUSY Xflag may not be removed or updated. X.Pp X.Fa mo_arg[0] Xshould be set to MEMRANGE_SET_UPDATE to update an existing Xor establish a new range, or to MEMRANGE_SET_REMOVE to remove a range. X.Pp X.Sh RETURN VALUES X.Bl -tag -width 10 X.It EOPNOTSUPP XMemory range operations are not supported on this architecture. X.It ENXIO XNo memory range descriptors are available (eg. firmware has not enabled Xany). X.It EINVAL XThe memory range supplied as an argument is invalid or overlaps another Xrange in a fashion not supported by this architecture. X.It EBUSY XAn attempt to remove or update a range failed because the range is busy. X.It ENOSPC XAn attempt to create a new range failed due to a shortage of hardware Xresources (eg. descriptor slots). X.It ENOENT XAn attempt to remove a range failed because no range matches the descriptor Xbase/length supplued. X.It EPERM XAn attempt to remove a range failed because the range is permanently Xenabled. X.El X.Sh SEE ALSO X.Xr XF86_Accel 1 , X.Xr XF86_SVGA 1 , X.Xr options 4 , X.Xr lkm.conf 5 , X.Xr config 8 , X.Xr init 8 , X.Xr memconfig 8 X.Sh HISTORY X.Pa /dev/xf86 Xwas introduced as a loadable kernel module for NetBSD 0.9C Xwith XFree86 3.1. The version 2.0 of the driver added MTRR support. X.Sh AUTHOR XThe aperture driver was written for the XFree86 Project Inc. by XMatthieu Herrb. The memory range Xattributes support was originally written by Michael Smith for FreeBSD. X.Sh BUGS XThis driver allows access to all addresses above X.Va physmem . XIt should be restricted to the actual address range of the video Xmemory. X.Pp XBusy range attributes are not yet managed correctly. X.Pp XMemory range attributes configuration should probably be controlled through X.Pa /dev/mem . END-of-module/xf86.4 echo x - module/xf86_mod.c sed 's/^X//' >module/xf86_mod.c << 'END-of-module/xf86_mod.c' X/* X * Copyright (c) 1994 The XFree86 Project Inc. X */ X X#include X#include X#include X#include X#include X#include X#include X X#include X X#include "xf86_reg.h" X#include "xf86_mod.h" X#include "memrange.h" X X/* Pull in the cpuid values from locore.s */ Xextern int cpu_id; Xextern int cpu_feature; Xextern char cpu_vendor[]; X Xextern struct mem_range_ops i686_mrops, k6_mrops; X Xstatic struct cdevsw newdev = { X xf86open, xf86close, X (dev_type_read((*))) enodev, (dev_type_write((*))) enodev, X xf86ioctl, X (dev_type_stop((*))) enodev, X 0, X seltrue, xf86mmap, 0}; X XMOD_DEV("xf86", LM_DT_CHAR, -1, &newdev) X Xchar *xf86_major_version = "2"; Xchar *xf86_minor_version = "0"; X Xstatic int xf86action __P((struct lkm_table *lktmp, int cmd)); X Xstatic int Xxf86action(lkmtp, cmd) X struct lkm_table *lkmtp; X int cmd; X{ X int err = 0; X X switch (cmd) { X case LKM_E_LOAD: X if (lkmexists(lkmtp)) X return EEXIST; X X printf("XFree86 aperture driver version %s.%s\n", X xf86_major_version, xf86_minor_version); X X /* Try for i686 MTRRs */ X if ((cpu_feature & CPUID_MTRR) && X ((cpu_id & 0xf00) == 0x600) && X ((strcmp(cpu_vendor, "GenuineIntel") == 0) || X (strcmp(cpu_vendor, "AuthenticAMD") == 0))) { X mem_range_softc.mr_op = &i686_mrops; X X } else if (!strcmp(cpu_vendor, "AuthenticAMD") && X (cpu_id & 0xf00) == 0x500 && X ((cpu_id & 0xf0) > 0x80 || X ((cpu_id & 0xf0) == 0x80 && X (cpu_id & 0xf) > 0x7)) X ) X mem_range_softc.mr_op = &k6_mrops; X X /* Initialise memory range handling */ X if (mem_range_softc.mr_op != NULL) X mem_range_softc.mr_op->init(&mem_range_softc); X X break; X X case LKM_E_UNLOAD: X /* Free allocated memory */ X free(mem_range_softc.mr_desc, M_MEMDESC); X break; X X case LKM_E_STAT: X break; X X default: X err = EIO; X break; X } X return err; X} X Xint Xxf86_lkmentry(lkmtp, cmd, ver) X struct lkm_table *lkmtp; X int cmd; X int ver; X{ X DISPATCH(lkmtp, cmd, ver, xf86action, xf86action, xf86action) X} END-of-module/xf86_mod.c echo x - module/xf86_mod.h sed 's/^X//' >module/xf86_mod.h << 'END-of-module/xf86_mod.h' X/* X * Copyright (C) 1999, The XFree86 Project Inc. X * X * $XFree86: xc/programs/Xserver/hw/xfree86/etc/apNetBSD.shar,v 3.13 2000/10/24 18:07:51 dawes Exp $ X */ X#ifndef _XF86_MOD_H X#define _XF86_MOD_H X X/* X * This is the exported driver interface X */ Xdev_type_open(xf86open); Xdev_type_close(xf86close); Xdev_type_mmap(xf86mmap); Xdev_type_ioctl(xf86ioctl); X Xextern int xf86_lkmentry __P((struct lkm_table *lkmtp, int cmd, int ver)); X X/* X * version number X */ Xextern char *xf86_major_version; Xextern char *xf86_minor_version; X X#endif END-of-module/xf86_mod.h echo x - module/xf86_mod_install sed 's/^X//' >module/xf86_mod_install << 'END-of-module/xf86_mod_install' X#! /bin/sh X# X# Postinstall script for the XFree86 Aperture Driver for NetBSD X# X# Copyright (C) 1994,1999 The XFree86 Project Inc. X# Xif [ $# -ne 3 ]; then X echo "$0: should be called by modload(8) with 3 arguments" X exit 1 Xfi X Xecho "Major device number: $3" Xrm -f /dev/xf86 Xmknod /dev/xf86 c $3 0 Xexit 0 END-of-module/xf86_mod_install echo x - module/xf86_reg.h sed 's/^X//' >module/xf86_reg.h << 'END-of-module/xf86_reg.h' X/* X * Copyright (C) 1999 The XFree86 Project Inc. X */ X#ifndef _XF86_REG_H X#define _XF86_REG_H X X#define MSR_MTRRcap 0x0fe X#define MSR_MTRRVarBase 0x200 X#define MSR_MTRR64kBase 0x250 X#define MSR_MTRR16kBase 0x258 X#define MSR_MTRR4kBase 0x268 X#define MSR_MTRRdefType 0x2ff X X/* X * Constants related to MTRRs X */ X#define MTRR_N64K 8 /* numbers of fixed-size entries */ X#define MTRR_N16K 16 X#define MTRR_N4K 64 X X#if defined(__NetBSD__) && (__NetBSD_Version__ < 10424000) X/* X * XXX - These belong to cpufunc.h X */ Xstatic __inline u_int64_t Xrdmsr(u_int msr) X{ X u_int64_t rv; X X __asm __volatile(".byte 0x0f, 0x32" : "=A" (rv) : "c" (msr)); X return (rv); X} X Xstatic __inline void Xwbinvd(void) X{ X __asm __volatile("wbinvd"); X} X Xstatic __inline void Xwrmsr(u_int msr, u_int64_t newval) X{ X __asm __volatile(".byte 0x0f, 0x30" : : "A" (newval), "c" (msr)); X} X#endif /* __NetBSD_Version__ */ X X#ifndef M_MEMDESC X#define M_MEMDESC M_TEMP /* XXX */ X#endif X X X#endif END-of-module/xf86_reg.h echo x - xf86test/Makefile sed 's/^X//' >xf86test/Makefile << 'END-of-xf86test/Makefile' X# Makefile for xf86test X# X# Copyright (C) 1999 The XFree86 Project Inc. X# XPROG= xf86test XMKMAN= no X XWARNS?= 1 X X.include END-of-xf86test/Makefile echo x - xf86test/xf86test.c sed 's/^X//' >xf86test/xf86test.c << 'END-of-xf86test/xf86test.c' X/* X * Copyright 1994 Doug Anson, danson@lgc.com & David Holland, davidh@use.com X * X * Author: Doug Anson (danson@lgc.com) X * Date : 2/21/94 X * Modifed: David Holland (davidh@use.com) X * Log: X * DWH - Changed names/added comments 2/23/94 X * DWH - Removed annoying delays. 2/23/94 X * X * This program test the fb aperture driver by 'cheating' X * it uses the aperture driver to access/read the main X * system BIOS header X * X * Copyright notice: X * Permission to use, copy, modify, distribute, and sell this software and its X * documentation for any purpose is hereby granted without fee, provided that X * the above copyright notice appear in all copies and that both that X * copyright notice and this permission notice appear in supporting X * documentation, and that the name of Doug Anson, and David Holland be used in X * advertising or publicity pertaining to distribution of the software X * Doug Anson, and David Holland make no * representations about the X * suitability of this software for any purpose. X * It is provided "as is" without express or implied warranty. X * X * Disclaimer: X * DOUG ANSON, AND DAVID HOLLAND DISCLAIMS ALL WARRIENTS WITH REGARD TO THIS X * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, AND FITNESS, X * IN NO EVENT SHALL DOUG ANSON, OR DAVID HOLLAND BE LIABLE FOR ANY SPECIAL, X * INDIRECT, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM X * USAGE OF THIS SOFTWARE. X */ X X/* X * linear framebuffer aperture driver test program X */ X X#include X#include X#include X#include X#include X#include X#include X X/* framebuffer access defines */ X#define AP_DEV "/dev/xf86" /* framebuffer apperture device */ X#define PADDR 0xa0000 /* offset from fbmem base */ X#define BUF_LENGTH 0x1000 /* length in bytes -- ignored */ X X/* debug testing defines */ X#define START_INDEX 0 /* display starting index(>=0)*/ X#define STOP_INDEX 80 /* display stopping index */ X#define INCR 1 /* display increment */ X X/* main program */ Xint Xmain(int argc,char **argv) X{ X caddr_t addr = (caddr_t)0; X int fb_dev; X long start = START_INDEX; X long stop = STOP_INDEX; X int i; X X /* open the framebuffer device */ X fb_dev = open (AP_DEV,O_RDWR); X if (fb_dev < 0) X { X /* failed to open framebuffer driver */ X printf("ERROR: failed to open %s\n",AP_DEV); X perror("ERROR: open()"); X exit(1); X } X X /* memory map the framebuffer */ X addr = (caddr_t)mmap((caddr_t)0,BUF_LENGTH,PROT_READ|PROT_WRITE,MAP_SHARED, X fb_dev,(off_t)PADDR); X if (addr == (caddr_t)-1) X { X /* failed to memory map framebuffer driver */ X printf("ERROR: failed to mmap [0x%x ,size=%d bytes)\n", X PADDR,BUF_LENGTH); X perror("ERROR: mmap()"); X close(fb_dev); X exit(1); X } X else X { X /* frame buffer mapped */ X close(fb_dev); X printf("NOTICE: BIOS mapped [0x%x ,size=%d) to addr=0x%x...\n", X PADDR,BUF_LENGTH,(int)addr); X X /* display the buffer */ X for(i=start;i