xref: /openbmc/linux/Documentation/arch/x86/mtrr.rst (revision 1ac731c529cd4d6adbce134754b51ff7d822b145)
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