Contents of /alx-src/tags/kernel26-2.6.12-alx-r9/Documentation/mtrr.txt
Parent Directory | Revision Log
Revision 630 -
(show annotations)
(download)
Wed Mar 4 11:03:09 2009 UTC (15 years, 6 months ago) by niro
File MIME type: text/plain
File size: 9780 byte(s)
Wed Mar 4 11:03:09 2009 UTC (15 years, 6 months ago) by niro
File MIME type: text/plain
File size: 9780 byte(s)
Tag kernel26-2.6.12-alx-r9
1 | MTRR (Memory Type Range Register) control |
2 | 3 Jun 1999 |
3 | Richard 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 | |
34 | There are two interfaces to /proc/mtrr: one is an ASCII interface |
35 | which allows you to read and write. The other is an ioctl() |
36 | interface. The ASCII interface is meant for administration. The |
37 | ioctl() interface is meant for C programs (i.e. the X server). The |
38 | interfaces are described below, with sample commands and C code. |
39 | |
40 | =============================================================================== |
41 | Reading MTRRs from the shell: |
42 | |
43 | % cat /proc/mtrr |
44 | reg00: base=0x00000000 ( 0MB), size= 128MB: write-back, count=1 |
45 | reg01: base=0x08000000 ( 128MB), size= 64MB: write-back, count=1 |
46 | =============================================================================== |
47 | Creating MTRRs from the C-shell: |
48 | # echo "base=0xf8000000 size=0x400000 type=write-combining" >! /proc/mtrr |
49 | or if you use bash: |
50 | # echo "base=0xf8000000 size=0x400000 type=write-combining" >| /proc/mtrr |
51 | |
52 | And the result thereof: |
53 | % cat /proc/mtrr |
54 | reg00: base=0x00000000 ( 0MB), size= 128MB: write-back, count=1 |
55 | reg01: base=0x08000000 ( 128MB), size= 64MB: write-back, count=1 |
56 | reg02: base=0xf8000000 (3968MB), size= 4MB: write-combining, count=1 |
57 | |
58 | This is for video RAM at base address 0xf8000000 and size 4 megabytes. To |
59 | find out your base address, you need to look at the output of your X |
60 | server, which tells you where the linear framebuffer address is. A |
61 | typical line that you may get is: |
62 | |
63 | (--) S3: PCI: 968 rev 0, Linear FB @ 0xf8000000 |
64 | |
65 | Note that you should only use the value from the X server, as it may |
66 | move the framebuffer base address, so the only value you can trust is |
67 | that reported by the X server. |
68 | |
69 | To find out the size of your framebuffer (what, you don't actually |
70 | know?), the following line will tell you: |
71 | |
72 | (--) S3: videoram: 4096k |
73 | |
74 | That's 4 megabytes, which is 0x400000 bytes (in hexadecimal). |
75 | A patch is being written for XFree86 which will make this automatic: |
76 | in other words the X server will manipulate /proc/mtrr using the |
77 | ioctl() interface, so users won't have to do anything. If you use a |
78 | commercial X server, lobby your vendor to add support for MTRRs. |
79 | =============================================================================== |
80 | Creating 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 | |
85 | And the results: cat /proc/mtrr |
86 | reg00: base=0x00000000 ( 0MB), size= 64MB: write-back, count=1 |
87 | reg01: base=0xfb000000 (4016MB), size= 16MB: write-combining, count=1 |
88 | reg02: base=0xfb000000 (4016MB), size= 4kB: uncachable, count=1 |
89 | |
90 | Some cards (especially Voodoo Graphics boards) need this 4 kB area |
91 | excluded from the beginning of the region because it is used for |
92 | registers. |
93 | |
94 | NOTE: You can only create type=uncachable region, if the first |
95 | region that you created is type=write-combining. |
96 | =============================================================================== |
97 | Removing MTRRs from the C-shell: |
98 | % echo "disable=2" >! /proc/mtrr |
99 | or using bash: |
100 | % echo "disable=2" >| /proc/mtrr |
101 | =============================================================================== |
102 | Reading 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 | |
155 | int 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 | =============================================================================== |
188 | Creating 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 | |
243 | int 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 | =============================================================================== |