1 MTRR (Memory Type Range Register) control
3 Richard Gooch <rgooch@atnf.csiro.au> - 3 Jun 1999
4 Luis R. Rodriguez <mcgrof@do-not-panic.com> - April 9, 2015
6 ===============================================================================
9 MTRR use is replaced on modern x86 hardware with PAT. Over time the only type
10 of effective MTRR that is expected to be supported will be for write-combining.
11 As MTRR use is phased out device drivers should use arch_phys_wc_add() to make
12 MTRR effective on non-PAT systems while a no-op on PAT enabled systems.
14 For details refer to Documentation/x86/pat.txt.
16 ===============================================================================
18 On Intel P6 family processors (Pentium Pro, Pentium II and later)
19 the Memory Type Range Registers (MTRRs) may be used to control
20 processor access to memory ranges. This is most useful when you have
21 a video (VGA) card on a PCI or AGP bus. Enabling write-combining
22 allows bus write transfers to be combined into a larger transfer
23 before bursting over the PCI/AGP bus. This can increase performance
24 of image write operations 2.5 times or more.
26 The Cyrix 6x86, 6x86MX and M II processors have Address Range
27 Registers (ARRs) which provide a similar functionality to MTRRs. For
28 these, the ARRs are used to emulate the MTRRs.
30 The AMD K6-2 (stepping 8 and above) and K6-3 processors have two
31 MTRRs. These are supported. The AMD Athlon family provide 8 Intel
34 The Centaur C6 (WinChip) has 8 MCRs, allowing write-combining. These
37 The VIA Cyrix III and VIA C3 CPUs offer 8 Intel style MTRRs.
39 The CONFIG_MTRR option creates a /proc/mtrr file which may be used
40 to manipulate your MTRRs. Typically the X server should use
41 this. This should have a reasonably generic interface so that
42 similar control registers on other processors can be easily
46 There are two interfaces to /proc/mtrr: one is an ASCII interface
47 which allows you to read and write. The other is an ioctl()
48 interface. The ASCII interface is meant for administration. The
49 ioctl() interface is meant for C programs (i.e. the X server). The
50 interfaces are described below, with sample commands and C code.
52 ===============================================================================
53 Reading MTRRs from the shell:
56 reg00: base=0x00000000 ( 0MB), size= 128MB: write-back, count=1
57 reg01: base=0x08000000 ( 128MB), size= 64MB: write-back, count=1
58 ===============================================================================
59 Creating MTRRs from the C-shell:
60 # echo "base=0xf8000000 size=0x400000 type=write-combining" >! /proc/mtrr
62 # echo "base=0xf8000000 size=0x400000 type=write-combining" >| /proc/mtrr
64 And the result thereof:
66 reg00: base=0x00000000 ( 0MB), size= 128MB: write-back, count=1
67 reg01: base=0x08000000 ( 128MB), size= 64MB: write-back, count=1
68 reg02: base=0xf8000000 (3968MB), size= 4MB: write-combining, count=1
70 This is for video RAM at base address 0xf8000000 and size 4 megabytes. To
71 find out your base address, you need to look at the output of your X
72 server, which tells you where the linear framebuffer address is. A
73 typical line that you may get is:
75 (--) S3: PCI: 968 rev 0, Linear FB @ 0xf8000000
77 Note that you should only use the value from the X server, as it may
78 move the framebuffer base address, so the only value you can trust is
79 that reported by the X server.
81 To find out the size of your framebuffer (what, you don't actually
82 know?), the following line will tell you:
84 (--) S3: videoram: 4096k
86 That's 4 megabytes, which is 0x400000 bytes (in hexadecimal).
87 A patch is being written for XFree86 which will make this automatic:
88 in other words the X server will manipulate /proc/mtrr using the
89 ioctl() interface, so users won't have to do anything. If you use a
90 commercial X server, lobby your vendor to add support for MTRRs.
91 ===============================================================================
92 Creating overlapping MTRRs:
94 %echo "base=0xfb000000 size=0x1000000 type=write-combining" >/proc/mtrr
95 %echo "base=0xfb000000 size=0x1000 type=uncachable" >/proc/mtrr
97 And the results: cat /proc/mtrr
98 reg00: base=0x00000000 ( 0MB), size= 64MB: write-back, count=1
99 reg01: base=0xfb000000 (4016MB), size= 16MB: write-combining, count=1
100 reg02: base=0xfb000000 (4016MB), size= 4kB: uncachable, count=1
102 Some cards (especially Voodoo Graphics boards) need this 4 kB area
103 excluded from the beginning of the region because it is used for
106 NOTE: You can only create type=uncachable region, if the first
107 region that you created is type=write-combining.
108 ===============================================================================
109 Removing MTRRs from the C-shell:
110 % echo "disable=2" >! /proc/mtrr
112 % echo "disable=2" >| /proc/mtrr
113 ===============================================================================
114 Reading MTRRs from a C program using ioctl()'s:
118 Source file for mtrr-show (example program to show MTRRs using ioctl()'s)
120 Copyright (C) 1997-1998 Richard Gooch
122 This program is free software; you can redistribute it and/or modify
123 it under the terms of the GNU General Public License as published by
124 the Free Software Foundation; either version 2 of the License, or
125 (at your option) any later version.
127 This program is distributed in the hope that it will be useful,
128 but WITHOUT ANY WARRANTY; without even the implied warranty of
129 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
130 GNU General Public License for more details.
132 You should have received a copy of the GNU General Public License
133 along with this program; if not, write to the Free Software
134 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
136 Richard Gooch may be reached by email at rgooch@atnf.csiro.au
137 The postal address is:
138 Richard Gooch, c/o ATNF, P. O. Box 76, Epping, N.S.W., 2121, Australia.
142 This program will use an ioctl() on /proc/mtrr to show the current MTRR
143 settings. This is an alternative to reading /proc/mtrr.
146 Written by Richard Gooch 17-DEC-1997
148 Last updated by Richard Gooch 2-MAY-1998
155 #include <sys/types.h>
156 #include <sys/stat.h>
158 #include <sys/ioctl.h>
160 #include <asm/mtrr.h>
164 #define ERRSTRING strerror (errno)
166 static char *mtrr_strings[MTRR_NUM_TYPES] =
168 "uncachable", /* 0 */
169 "write-combining", /* 1 */
172 "write-through", /* 4 */
173 "write-protect", /* 5 */
174 "write-back", /* 6 */
180 struct mtrr_gentry gentry;
182 if ( ( fd = open ("/proc/mtrr", O_RDONLY, 0) ) == -1 )
186 fputs ("/proc/mtrr not found: not supported or you don't have a PPro?\n",
190 fprintf (stderr, "Error opening /proc/mtrr\t%s\n", ERRSTRING);
193 for (gentry.regnum = 0; ioctl (fd, MTRRIOC_GET_ENTRY, &gentry) == 0;
198 fprintf (stderr, "Register: %u disabled\n", gentry.regnum);
201 fprintf (stderr, "Register: %u base: 0x%lx size: 0x%lx type: %s\n",
202 gentry.regnum, gentry.base, gentry.size,
203 mtrr_strings[gentry.type]);
205 if (errno == EINVAL) exit (0);
206 fprintf (stderr, "Error doing ioctl(2) on /dev/mtrr\t%s\n", ERRSTRING);
208 } /* End Function main */
209 ===============================================================================
210 Creating MTRRs from a C programme using ioctl()'s:
214 Source file for mtrr-add (example programme to add an MTRRs using ioctl())
216 Copyright (C) 1997-1998 Richard Gooch
218 This program is free software; you can redistribute it and/or modify
219 it under the terms of the GNU General Public License as published by
220 the Free Software Foundation; either version 2 of the License, or
221 (at your option) any later version.
223 This program is distributed in the hope that it will be useful,
224 but WITHOUT ANY WARRANTY; without even the implied warranty of
225 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
226 GNU General Public License for more details.
228 You should have received a copy of the GNU General Public License
229 along with this program; if not, write to the Free Software
230 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
232 Richard Gooch may be reached by email at rgooch@atnf.csiro.au
233 The postal address is:
234 Richard Gooch, c/o ATNF, P. O. Box 76, Epping, N.S.W., 2121, Australia.
238 This programme will use an ioctl() on /proc/mtrr to add an entry. The first
239 available mtrr is used. This is an alternative to writing /proc/mtrr.
242 Written by Richard Gooch 17-DEC-1997
244 Last updated by Richard Gooch 2-MAY-1998
252 #include <sys/types.h>
253 #include <sys/stat.h>
255 #include <sys/ioctl.h>
257 #include <asm/mtrr.h>
261 #define ERRSTRING strerror (errno)
263 static char *mtrr_strings[MTRR_NUM_TYPES] =
265 "uncachable", /* 0 */
266 "write-combining", /* 1 */
269 "write-through", /* 4 */
270 "write-protect", /* 5 */
271 "write-back", /* 6 */
274 int main (int argc, char **argv)
277 struct mtrr_sentry sentry;
281 fprintf (stderr, "Usage:\tmtrr-add base size type\n");
284 sentry.base = strtoul (argv[1], NULL, 0);
285 sentry.size = strtoul (argv[2], NULL, 0);
286 for (sentry.type = 0; sentry.type < MTRR_NUM_TYPES; ++sentry.type)
288 if (strcmp (argv[3], mtrr_strings[sentry.type]) == 0) break;
290 if (sentry.type >= MTRR_NUM_TYPES)
292 fprintf (stderr, "Illegal type: \"%s\"\n", argv[3]);
295 if ( ( fd = open ("/proc/mtrr", O_WRONLY, 0) ) == -1 )
299 fputs ("/proc/mtrr not found: not supported or you don't have a PPro?\n",
303 fprintf (stderr, "Error opening /proc/mtrr\t%s\n", ERRSTRING);
306 if (ioctl (fd, MTRRIOC_ADD_ENTRY, &sentry) == -1)
308 fprintf (stderr, "Error doing ioctl(2) on /dev/mtrr\t%s\n", ERRSTRING);
311 fprintf (stderr, "Sleeping for 5 seconds so you can see the new entry\n");
314 fputs ("I've just closed /proc/mtrr so now the new entry should be gone\n",
316 } /* End Function main */
317 ===============================================================================