Merge branch 'for-next' of git://git.kernel.org/pub/scm/linux/kernel/git/nab/target...
[deliverable/linux.git] / Documentation / x86 / mtrr.txt
1 MTRR (Memory Type Range Register) control
2
3 Richard Gooch <rgooch@atnf.csiro.au> - 3 Jun 1999
4 Luis R. Rodriguez <mcgrof@do-not-panic.com> - April 9, 2015
5
6 ===============================================================================
7 Phasing out MTRR use
8
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.
13
14 For details refer to Documentation/x86/pat.txt.
15
16 ===============================================================================
17
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.
25
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.
29
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
32 style MTRRs.
33
34 The Centaur C6 (WinChip) has 8 MCRs, allowing write-combining. These
35 are supported.
36
37 The VIA Cyrix III and VIA C3 CPUs offer 8 Intel style MTRRs.
38
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
43 supported.
44
45
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.
51
52 ===============================================================================
53 Reading MTRRs from the shell:
54
55 % cat /proc/mtrr
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
61 or if you use bash:
62 # echo "base=0xf8000000 size=0x400000 type=write-combining" >| /proc/mtrr
63
64 And the result thereof:
65 % cat /proc/mtrr
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
69
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:
74
75 (--) S3: PCI: 968 rev 0, Linear FB @ 0xf8000000
76
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.
80
81 To find out the size of your framebuffer (what, you don't actually
82 know?), the following line will tell you:
83
84 (--) S3: videoram: 4096k
85
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:
93
94 %echo "base=0xfb000000 size=0x1000000 type=write-combining" >/proc/mtrr
95 %echo "base=0xfb000000 size=0x1000 type=uncachable" >/proc/mtrr
96
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
101
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
104 registers.
105
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
111 or using bash:
112 % echo "disable=2" >| /proc/mtrr
113 ===============================================================================
114 Reading MTRRs from a C program using ioctl()'s:
115
116 /* mtrr-show.c
117
118 Source file for mtrr-show (example program to show MTRRs using ioctl()'s)
119
120 Copyright (C) 1997-1998 Richard Gooch
121
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.
126
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.
131
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.
135
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.
139 */
140
141 /*
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.
144
145
146 Written by Richard Gooch 17-DEC-1997
147
148 Last updated by Richard Gooch 2-MAY-1998
149
150
151 */
152 #include <stdio.h>
153 #include <stdlib.h>
154 #include <string.h>
155 #include <sys/types.h>
156 #include <sys/stat.h>
157 #include <fcntl.h>
158 #include <sys/ioctl.h>
159 #include <errno.h>
160 #include <asm/mtrr.h>
161
162 #define TRUE 1
163 #define FALSE 0
164 #define ERRSTRING strerror (errno)
165
166 static char *mtrr_strings[MTRR_NUM_TYPES] =
167 {
168 "uncachable", /* 0 */
169 "write-combining", /* 1 */
170 "?", /* 2 */
171 "?", /* 3 */
172 "write-through", /* 4 */
173 "write-protect", /* 5 */
174 "write-back", /* 6 */
175 };
176
177 int main ()
178 {
179 int fd;
180 struct mtrr_gentry gentry;
181
182 if ( ( fd = open ("/proc/mtrr", O_RDONLY, 0) ) == -1 )
183 {
184 if (errno == ENOENT)
185 {
186 fputs ("/proc/mtrr not found: not supported or you don't have a PPro?\n",
187 stderr);
188 exit (1);
189 }
190 fprintf (stderr, "Error opening /proc/mtrr\t%s\n", ERRSTRING);
191 exit (2);
192 }
193 for (gentry.regnum = 0; ioctl (fd, MTRRIOC_GET_ENTRY, &gentry) == 0;
194 ++gentry.regnum)
195 {
196 if (gentry.size < 1)
197 {
198 fprintf (stderr, "Register: %u disabled\n", gentry.regnum);
199 continue;
200 }
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]);
204 }
205 if (errno == EINVAL) exit (0);
206 fprintf (stderr, "Error doing ioctl(2) on /dev/mtrr\t%s\n", ERRSTRING);
207 exit (3);
208 } /* End Function main */
209 ===============================================================================
210 Creating MTRRs from a C programme using ioctl()'s:
211
212 /* mtrr-add.c
213
214 Source file for mtrr-add (example programme to add an MTRRs using ioctl())
215
216 Copyright (C) 1997-1998 Richard Gooch
217
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.
222
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.
227
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.
231
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.
235 */
236
237 /*
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.
240
241
242 Written by Richard Gooch 17-DEC-1997
243
244 Last updated by Richard Gooch 2-MAY-1998
245
246
247 */
248 #include <stdio.h>
249 #include <string.h>
250 #include <stdlib.h>
251 #include <unistd.h>
252 #include <sys/types.h>
253 #include <sys/stat.h>
254 #include <fcntl.h>
255 #include <sys/ioctl.h>
256 #include <errno.h>
257 #include <asm/mtrr.h>
258
259 #define TRUE 1
260 #define FALSE 0
261 #define ERRSTRING strerror (errno)
262
263 static char *mtrr_strings[MTRR_NUM_TYPES] =
264 {
265 "uncachable", /* 0 */
266 "write-combining", /* 1 */
267 "?", /* 2 */
268 "?", /* 3 */
269 "write-through", /* 4 */
270 "write-protect", /* 5 */
271 "write-back", /* 6 */
272 };
273
274 int main (int argc, char **argv)
275 {
276 int fd;
277 struct mtrr_sentry sentry;
278
279 if (argc != 4)
280 {
281 fprintf (stderr, "Usage:\tmtrr-add base size type\n");
282 exit (1);
283 }
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)
287 {
288 if (strcmp (argv[3], mtrr_strings[sentry.type]) == 0) break;
289 }
290 if (sentry.type >= MTRR_NUM_TYPES)
291 {
292 fprintf (stderr, "Illegal type: \"%s\"\n", argv[3]);
293 exit (2);
294 }
295 if ( ( fd = open ("/proc/mtrr", O_WRONLY, 0) ) == -1 )
296 {
297 if (errno == ENOENT)
298 {
299 fputs ("/proc/mtrr not found: not supported or you don't have a PPro?\n",
300 stderr);
301 exit (3);
302 }
303 fprintf (stderr, "Error opening /proc/mtrr\t%s\n", ERRSTRING);
304 exit (4);
305 }
306 if (ioctl (fd, MTRRIOC_ADD_ENTRY, &sentry) == -1)
307 {
308 fprintf (stderr, "Error doing ioctl(2) on /dev/mtrr\t%s\n", ERRSTRING);
309 exit (5);
310 }
311 fprintf (stderr, "Sleeping for 5 seconds so you can see the new entry\n");
312 sleep (5);
313 close (fd);
314 fputs ("I've just closed /proc/mtrr so now the new entry should be gone\n",
315 stderr);
316 } /* End Function main */
317 ===============================================================================
This page took 0.039106 seconds and 5 git commands to generate.