linux/Documentation/x86/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 <stdlib.h>
 142#include <string.h>
 143#include <sys/types.h>
 144#include <sys/stat.h>
 145#include <fcntl.h>
 146#include <sys/ioctl.h>
 147#include <errno.h>
 148#include <asm/mtrr.h>
 149
 150#define TRUE 1
 151#define FALSE 0
 152#define ERRSTRING strerror (errno)
 153
 154static char *mtrr_strings[MTRR_NUM_TYPES] =
 155{
 156    "uncachable",               /* 0 */
 157    "write-combining",          /* 1 */
 158    "?",                        /* 2 */
 159    "?",                        /* 3 */
 160    "write-through",            /* 4 */
 161    "write-protect",            /* 5 */
 162    "write-back",               /* 6 */
 163};
 164
 165int main ()
 166{
 167    int fd;
 168    struct mtrr_gentry gentry;
 169
 170    if ( ( fd = open ("/proc/mtrr", O_RDONLY, 0) ) == -1 )
 171    {
 172        if (errno == ENOENT)
 173        {
 174            fputs ("/proc/mtrr not found: not supported or you don't have a PPro?\n",
 175                   stderr);
 176            exit (1);
 177        }
 178        fprintf (stderr, "Error opening /proc/mtrr\t%s\n", ERRSTRING);
 179        exit (2);
 180    }
 181    for (gentry.regnum = 0; ioctl (fd, MTRRIOC_GET_ENTRY, &gentry) == 0;
 182         ++gentry.regnum)
 183    {
 184        if (gentry.size < 1)
 185        {
 186            fprintf (stderr, "Register: %u disabled\n", gentry.regnum);
 187            continue;
 188        }
 189        fprintf (stderr, "Register: %u base: 0x%lx size: 0x%lx type: %s\n",
 190                 gentry.regnum, gentry.base, gentry.size,
 191                 mtrr_strings[gentry.type]);
 192    }
 193    if (errno == EINVAL) exit (0);
 194    fprintf (stderr, "Error doing ioctl(2) on /dev/mtrr\t%s\n", ERRSTRING);
 195    exit (3);
 196}   /*  End Function main  */
 197===============================================================================
 198Creating MTRRs from a C programme using ioctl()'s:
 199
 200/*  mtrr-add.c
 201
 202    Source file for mtrr-add (example programme to add an MTRRs using ioctl())
 203
 204    Copyright (C) 1997-1998  Richard Gooch
 205
 206    This program is free software; you can redistribute it and/or modify
 207    it under the terms of the GNU General Public License as published by
 208    the Free Software Foundation; either version 2 of the License, or
 209    (at your option) any later version.
 210
 211    This program is distributed in the hope that it will be useful,
 212    but WITHOUT ANY WARRANTY; without even the implied warranty of
 213    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 214    GNU General Public License for more details.
 215
 216    You should have received a copy of the GNU General Public License
 217    along with this program; if not, write to the Free Software
 218    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 219
 220    Richard Gooch may be reached by email at  rgooch@atnf.csiro.au
 221    The postal address is:
 222      Richard Gooch, c/o ATNF, P. O. Box 76, Epping, N.S.W., 2121, Australia.
 223*/
 224
 225/*
 226    This programme will use an ioctl() on /proc/mtrr to add an entry. The first
 227    available mtrr is used. This is an alternative to writing /proc/mtrr.
 228
 229
 230    Written by      Richard Gooch   17-DEC-1997
 231
 232    Last updated by Richard Gooch   2-MAY-1998
 233
 234
 235*/
 236#include <stdio.h>
 237#include <string.h>
 238#include <stdlib.h>
 239#include <unistd.h>
 240#include <sys/types.h>
 241#include <sys/stat.h>
 242#include <fcntl.h>
 243#include <sys/ioctl.h>
 244#include <errno.h>
 245#include <asm/mtrr.h>
 246
 247#define TRUE 1
 248#define FALSE 0
 249#define ERRSTRING strerror (errno)
 250
 251static char *mtrr_strings[MTRR_NUM_TYPES] =
 252{
 253    "uncachable",               /* 0 */
 254    "write-combining",          /* 1 */
 255    "?",                        /* 2 */
 256    "?",                        /* 3 */
 257    "write-through",            /* 4 */
 258    "write-protect",            /* 5 */
 259    "write-back",               /* 6 */
 260};
 261
 262int main (int argc, char **argv)
 263{
 264    int fd;
 265    struct mtrr_sentry sentry;
 266
 267    if (argc != 4)
 268    {
 269        fprintf (stderr, "Usage:\tmtrr-add base size type\n");
 270        exit (1);
 271    }
 272    sentry.base = strtoul (argv[1], NULL, 0);
 273    sentry.size = strtoul (argv[2], NULL, 0);
 274    for (sentry.type = 0; sentry.type < MTRR_NUM_TYPES; ++sentry.type)
 275    {
 276        if (strcmp (argv[3], mtrr_strings[sentry.type]) == 0) break;
 277    }
 278    if (sentry.type >= MTRR_NUM_TYPES)
 279    {
 280        fprintf (stderr, "Illegal type: \"%s\"\n", argv[3]);
 281        exit (2);
 282    }
 283    if ( ( fd = open ("/proc/mtrr", O_WRONLY, 0) ) == -1 )
 284    {
 285        if (errno == ENOENT)
 286        {
 287            fputs ("/proc/mtrr not found: not supported or you don't have a PPro?\n",
 288                   stderr);
 289            exit (3);
 290        }
 291        fprintf (stderr, "Error opening /proc/mtrr\t%s\n", ERRSTRING);
 292        exit (4);
 293    }
 294    if (ioctl (fd, MTRRIOC_ADD_ENTRY, &sentry) == -1)
 295    {
 296        fprintf (stderr, "Error doing ioctl(2) on /dev/mtrr\t%s\n", ERRSTRING);
 297        exit (5);
 298    }
 299    fprintf (stderr, "Sleeping for 5 seconds so you can see the new entry\n");
 300    sleep (5);
 301    close (fd);
 302    fputs ("I've just closed /proc/mtrr so now the new entry should be gone\n",
 303           stderr);
 304}   /*  End Function main  */
 305===============================================================================
 306
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.