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