linux-old/Documentation/mtrr.txt
<<
>>
Prefs
   1MTRR (Memory Type Range Register) control
   23 Jun 1999
   3Richard Gooch
   4<rgooch@atnf.csiro.au>
   5
   6  On Intel P6 family processors (Pentium Pro, Pentium II and later)
   7  the Memory Type Range Registers (MTRRs) may be used to control
   8  processor access to memory ranges. This is most useful when you have
   9  a video (VGA) card on a PCI or AGP bus. Enabling write-combining
  10  allows bus write transfers to be combined into a larger transfer
  11  before bursting over the PCI/AGP bus. This can increase performance
  12  of image write operations 2.5 times or more.
  13
  14  The Cyrix 6x86, 6x86MX and M II processors have Address Range
  15  Registers (ARRs) which provide a similar functionality to MTRRs. For
  16  these, the ARRs are used to emulate the MTRRs.
  17
  18  The AMD K6-2 (stepping 8 and above) and K6-3 processors have two
  19  MTRRs. These are supported.  The AMD Athlon family provide 8 Intel
  20  style MTRRs.
  21  
  22  The Centaur C6 (WinChip) has 8 MCRs, allowing write-combining. These
  23  are supported.
  24
  25  The VIA Cyrix III and VIA C3 CPUs offer 8 Intel style MTRRs.
  26
  27  The CONFIG_MTRR option creates a /proc/mtrr file which may be used
  28  to manipulate your MTRRs. Typically the X server should use
  29  this. This should have a reasonably generic interface so that
  30  similar control registers on other processors can be easily
  31  supported.
  32
  33
  34There are two interfaces to /proc/mtrr: one is an ASCII interface
  35which allows you to read and write. The other is an ioctl()
  36interface. The ASCII interface is meant for administration. The
  37ioctl() interface is meant for C programs (i.e. the X server). The
  38interfaces are described below, with sample commands and C code.
  39
  40===============================================================================
  41Reading MTRRs from the shell:
  42
  43% cat /proc/mtrr
  44reg00: base=0x00000000 (   0MB), size= 128MB: write-back, count=1
  45reg01: base=0x08000000 ( 128MB), size=  64MB: write-back, count=1
  46===============================================================================
  47Creating MTRRs from the C-shell:
  48# echo "base=0xf8000000 size=0x400000 type=write-combining" >! /proc/mtrr
  49or if you use bash:
  50# echo "base=0xf8000000 size=0x400000 type=write-combining" >| /proc/mtrr
  51
  52And the result thereof:
  53% cat /proc/mtrr
  54reg00: base=0x00000000 (   0MB), size= 128MB: write-back, count=1
  55reg01: base=0x08000000 ( 128MB), size=  64MB: write-back, count=1
  56reg02: base=0xf8000000 (3968MB), size=   4MB: write-combining, count=1
  57
  58This is for video RAM at base address 0xf8000000 and size 4 megabytes. To
  59find out your base address, you need to look at the output of your X
  60server, which tells you where the linear framebuffer address is. A
  61typical line that you may get is:
  62
  63(--) S3: PCI: 968 rev 0, Linear FB @ 0xf8000000
  64
  65Note that you should only use the value from the X server, as it may
  66move the framebuffer base address, so the only value you can trust is
  67that reported by the X server.
  68
  69To find out the size of your framebuffer (what, you don't actually
  70know?), the following line will tell you:
  71
  72(--) S3: videoram:  4096k
  73
  74That's 4 megabytes, which is 0x400000 bytes (in hexadecimal).
  75A patch is being written for XFree86 which will make this automatic:
  76in other words the X server will manipulate /proc/mtrr using the
  77ioctl() interface, so users won't have to do anything. If you use a
  78commercial X server, lobby your vendor to add support for MTRRs.
  79===============================================================================
  80Creating overlapping MTRRs:
  81
  82%echo "base=0xfb000000 size=0x1000000 type=write-combining" >/proc/mtrr
  83%echo "base=0xfb000000 size=0x1000 type=uncachable" >/proc/mtrr
  84
  85And the results: cat /proc/mtrr
  86reg00: base=0x00000000 (   0MB), size=  64MB: write-back, count=1
  87reg01: base=0xfb000000 (4016MB), size=  16MB: write-combining, count=1
  88reg02: base=0xfb000000 (4016MB), size=   4kB: uncachable, count=1
  89
  90Some cards (especially Voodoo Graphics boards) need this 4 kB area 
  91excluded from the beginning of the region because it is used for
  92registers.
  93
  94NOTE: You can only create type=uncachable region, if the first
  95region that you created is type=write-combining.
  96===============================================================================
  97Removing MTRRs from the C-shell:
  98% echo "disable=2" >! /proc/mtrr
  99or using bash:
 100% echo "disable=2" >| /proc/mtrr
 101===============================================================================
 102Reading MTRRs from a C program using ioctl()'s:
 103
 104/*  mtrr-show.c
 105
 106    Source file for mtrr-show (example program to show MTRRs using ioctl()'s)
 107
 108    Copyright (C) 1997-1998  Richard Gooch
 109
 110    This program is free software; you can redistribute it and/or modify
 111    it under the terms of the GNU General Public License as published by
 112    the Free Software Foundation; either version 2 of the License, or
 113    (at your option) any later version.
 114
 115    This program is distributed in the hope that it will be useful,
 116    but WITHOUT ANY WARRANTY; without even the implied warranty of
 117    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 118    GNU General Public License for more details.
 119
 120    You should have received a copy of the GNU General Public License
 121    along with this program; if not, write to the Free Software
 122    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 123
 124    Richard Gooch may be reached by email at  rgooch@atnf.csiro.au
 125    The postal address is:
 126      Richard Gooch, c/o ATNF, P. O. Box 76, Epping, N.S.W., 2121, Australia.
 127*/
 128
 129/*
 130    This program will use an ioctl() on /proc/mtrr to show the current MTRR
 131    settings. This is an alternative to reading /proc/mtrr.
 132
 133
 134    Written by      Richard Gooch   17-DEC-1997
 135
 136    Last updated by Richard Gooch   2-MAY-1998
 137
 138
 139*/
 140#include <stdio.h>
 141#include <string.h>
 142#include <sys/types.h>
 143#include <sys/stat.h>
 144#include <fcntl.h>
 145#include <sys/ioctl.h>
 146#include <errno.h>
 147#define MTRR_NEED_STRINGS
 148#include <asm/mtrr.h>
 149
 150#define TRUE 1
 151#define FALSE 0
 152#define ERRSTRING strerror (errno)
 153
 154
 155int main ()
 156{
 157    int fd;
 158    struct mtrr_gentry gentry;
 159
 160    if ( ( fd = open ("/proc/mtrr", O_RDONLY, 0) ) == -1 )
 161    {
 162        if (errno == ENOENT)
 163        {
 164            fputs ("/proc/mtrr not found: not supported or you don't have a PPro?\n",
 165                   stderr);
 166            exit (1);
 167        }
 168        fprintf (stderr, "Error opening /proc/mtrr\t%s\n", ERRSTRING);
 169        exit (2);
 170    }
 171    for (gentry.regnum = 0; ioctl (fd, MTRRIOC_GET_ENTRY, &gentry) == 0;
 172         ++gentry.regnum)
 173    {
 174        if (gentry.size < 1)
 175        {
 176            fprintf (stderr, "Register: %u disabled\n", gentry.regnum);
 177            continue;
 178        }
 179        fprintf (stderr, "Register: %u base: 0x%lx size: 0x%lx type: %s\n",
 180                 gentry.regnum, gentry.base, gentry.size,
 181                 mtrr_strings[gentry.type]);
 182    }
 183    if (errno == EINVAL) exit (0);
 184    fprintf (stderr, "Error doing ioctl(2) on /dev/mtrr\t%s\n", ERRSTRING);
 185    exit (3);
 186}   /*  End Function main  */
 187===============================================================================
 188Creating MTRRs from a C programme using ioctl()'s:
 189
 190/*  mtrr-add.c
 191
 192    Source file for mtrr-add (example programme to add an MTRRs using ioctl())
 193
 194    Copyright (C) 1997-1998  Richard Gooch
 195
 196    This program is free software; you can redistribute it and/or modify
 197    it under the terms of the GNU General Public License as published by
 198    the Free Software Foundation; either version 2 of the License, or
 199    (at your option) any later version.
 200
 201    This program is distributed in the hope that it will be useful,
 202    but WITHOUT ANY WARRANTY; without even the implied warranty of
 203    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 204    GNU General Public License for more details.
 205
 206    You should have received a copy of the GNU General Public License
 207    along with this program; if not, write to the Free Software
 208    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 209
 210    Richard Gooch may be reached by email at  rgooch@atnf.csiro.au
 211    The postal address is:
 212      Richard Gooch, c/o ATNF, P. O. Box 76, Epping, N.S.W., 2121, Australia.
 213*/
 214
 215/*
 216    This programme will use an ioctl() on /proc/mtrr to add an entry. The first
 217    available mtrr is used. This is an alternative to writing /proc/mtrr.
 218
 219
 220    Written by      Richard Gooch   17-DEC-1997
 221
 222    Last updated by Richard Gooch   2-MAY-1998
 223
 224
 225*/
 226#include <stdio.h>
 227#include <string.h>
 228#include <stdlib.h>
 229#include <unistd.h>
 230#include <sys/types.h>
 231#include <sys/stat.h>
 232#include <fcntl.h>
 233#include <sys/ioctl.h>
 234#include <errno.h>
 235#define MTRR_NEED_STRINGS
 236#include <asm/mtrr.h>
 237
 238#define TRUE 1
 239#define FALSE 0
 240#define ERRSTRING strerror (errno)
 241
 242
 243int main (int argc, char **argv)
 244{
 245    int fd;
 246    struct mtrr_sentry sentry;
 247
 248    if (argc != 4)
 249    {
 250        fprintf (stderr, "Usage:\tmtrr-add base size type\n");
 251        exit (1);
 252    }
 253    sentry.base = strtoul (argv[1], NULL, 0);
 254    sentry.size = strtoul (argv[2], NULL, 0);
 255    for (sentry.type = 0; sentry.type < MTRR_NUM_TYPES; ++sentry.type)
 256    {
 257        if (strcmp (argv[3], mtrr_strings[sentry.type]) == 0) break;
 258    }
 259    if (sentry.type >= MTRR_NUM_TYPES)
 260    {
 261        fprintf (stderr, "Illegal type: \"%s\"\n", argv[3]);
 262        exit (2);
 263    }
 264    if ( ( fd = open ("/proc/mtrr", O_WRONLY, 0) ) == -1 )
 265    {
 266        if (errno == ENOENT)
 267        {
 268            fputs ("/proc/mtrr not found: not supported or you don't have a PPro?\n",
 269                   stderr);
 270            exit (3);
 271        }
 272        fprintf (stderr, "Error opening /proc/mtrr\t%s\n", ERRSTRING);
 273        exit (4);
 274    }
 275    if (ioctl (fd, MTRRIOC_ADD_ENTRY, &sentry) == -1)
 276    {
 277        fprintf (stderr, "Error doing ioctl(2) on /dev/mtrr\t%s\n", ERRSTRING);
 278        exit (5);
 279    }
 280    fprintf (stderr, "Sleeping for 5 seconds so you can see the new entry\n");
 281    sleep (5);
 282    close (fd);
 283    fputs ("I've just closed /proc/mtrr so now the new entry should be gone\n",
 284           stderr);
 285}   /*  End Function main  */
 286===============================================================================
 287
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.