Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Documentation: x86: convert mtrr.txt to reST

This converts the plain text documentation to reStructuredText format and
add it to Sphinx TOC tree. No essential content change.

Signed-off-by: Changbin Du <changbin.du@gmail.com>
Signed-off-by: Jonathan Corbet <corbet@lwn.net>

authored by

Changbin Du and committed by
Jonathan Corbet
26d14a20 17156044

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