more changes on original files
[linux-2.4.git] / arch / i386 / kernel / mtrr.c
1 /*  Generic MTRR (Memory Type Range Register) driver.
2
3     Copyright (C) 1997-2000  Richard Gooch
4
5     This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Library General Public
7     License as published by the Free Software Foundation; either
8     version 2 of the License, or (at your option) any later version.
9
10     This library is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13     Library General Public License for more details.
14
15     You should have received a copy of the GNU Library General Public
16     License along with this library; if not, write to the Free
17     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
19     Richard Gooch may be reached by email at  rgooch@atnf.csiro.au
20     The postal address is:
21       Richard Gooch, c/o ATNF, P. O. Box 76, Epping, N.S.W., 2121, Australia.
22
23     Source: "Pentium Pro Family Developer's Manual, Volume 3:
24     Operating System Writer's Guide" (Intel document number 242692),
25     section 11.11.7
26
27     ChangeLog
28
29     Prehistory Martin Tischhäuser <martin@ikcbarka.fzk.de>
30                Initial register-setting code (from proform-1.0).
31     19971216   Richard Gooch <rgooch@atnf.csiro.au>
32                Original version for /proc/mtrr interface, SMP-safe.
33   v1.0
34     19971217   Richard Gooch <rgooch@atnf.csiro.au>
35                Bug fix for ioctls()'s.
36                Added sample code in Documentation/mtrr.txt
37   v1.1
38     19971218   Richard Gooch <rgooch@atnf.csiro.au>
39                Disallow overlapping regions.
40     19971219   Jens Maurer <jmaurer@menuett.rhein-main.de>
41                Register-setting fixups.
42   v1.2
43     19971222   Richard Gooch <rgooch@atnf.csiro.au>
44                Fixups for kernel 2.1.75.
45   v1.3
46     19971229   David Wragg <dpw@doc.ic.ac.uk>
47                Register-setting fixups and conformity with Intel conventions.
48     19971229   Richard Gooch <rgooch@atnf.csiro.au>
49                Cosmetic changes and wrote this ChangeLog ;-)
50     19980106   Richard Gooch <rgooch@atnf.csiro.au>
51                Fixups for kernel 2.1.78.
52   v1.4
53     19980119   David Wragg <dpw@doc.ic.ac.uk>
54                Included passive-release enable code (elsewhere in PCI setup).
55   v1.5
56     19980131   Richard Gooch <rgooch@atnf.csiro.au>
57                Replaced global kernel lock with private spinlock.
58   v1.6
59     19980201   Richard Gooch <rgooch@atnf.csiro.au>
60                Added wait for other CPUs to complete changes.
61   v1.7
62     19980202   Richard Gooch <rgooch@atnf.csiro.au>
63                Bug fix in definition of <set_mtrr> for UP.
64   v1.8
65     19980319   Richard Gooch <rgooch@atnf.csiro.au>
66                Fixups for kernel 2.1.90.
67     19980323   Richard Gooch <rgooch@atnf.csiro.au>
68                Move SMP BIOS fixup before secondary CPUs call <calibrate_delay>
69   v1.9
70     19980325   Richard Gooch <rgooch@atnf.csiro.au>
71                Fixed test for overlapping regions: confused by adjacent regions
72     19980326   Richard Gooch <rgooch@atnf.csiro.au>
73                Added wbinvd in <set_mtrr_prepare>.
74     19980401   Richard Gooch <rgooch@atnf.csiro.au>
75                Bug fix for non-SMP compilation.
76     19980418   David Wragg <dpw@doc.ic.ac.uk>
77                Fixed-MTRR synchronisation for SMP and use atomic operations
78                instead of spinlocks.
79     19980418   Richard Gooch <rgooch@atnf.csiro.au>
80                Differentiate different MTRR register classes for BIOS fixup.
81   v1.10
82     19980419   David Wragg <dpw@doc.ic.ac.uk>
83                Bug fix in variable MTRR synchronisation.
84   v1.11
85     19980419   Richard Gooch <rgooch@atnf.csiro.au>
86                Fixups for kernel 2.1.97.
87   v1.12
88     19980421   Richard Gooch <rgooch@atnf.csiro.au>
89                Safer synchronisation across CPUs when changing MTRRs.
90   v1.13
91     19980423   Richard Gooch <rgooch@atnf.csiro.au>
92                Bugfix for SMP systems without MTRR support.
93   v1.14
94     19980427   Richard Gooch <rgooch@atnf.csiro.au>
95                Trap calls to <mtrr_add> and <mtrr_del> on non-MTRR machines.
96   v1.15
97     19980427   Richard Gooch <rgooch@atnf.csiro.au>
98                Use atomic bitops for setting SMP change mask.
99   v1.16
100     19980428   Richard Gooch <rgooch@atnf.csiro.au>
101                Removed spurious diagnostic message.
102   v1.17
103     19980429   Richard Gooch <rgooch@atnf.csiro.au>
104                Moved register-setting macros into this file.
105                Moved setup code from init/main.c to i386-specific areas.
106   v1.18
107     19980502   Richard Gooch <rgooch@atnf.csiro.au>
108                Moved MTRR detection outside conditionals in <mtrr_init>.
109   v1.19
110     19980502   Richard Gooch <rgooch@atnf.csiro.au>
111                Documentation improvement: mention Pentium II and AGP.
112   v1.20
113     19980521   Richard Gooch <rgooch@atnf.csiro.au>
114                Only manipulate interrupt enable flag on local CPU.
115                Allow enclosed uncachable regions.
116   v1.21
117     19980611   Richard Gooch <rgooch@atnf.csiro.au>
118                Always define <main_lock>.
119   v1.22
120     19980901   Richard Gooch <rgooch@atnf.csiro.au>
121                Removed module support in order to tidy up code.
122                Added sanity check for <mtrr_add>/<mtrr_del> before <mtrr_init>.
123                Created addition queue for prior to SMP commence.
124   v1.23
125     19980902   Richard Gooch <rgooch@atnf.csiro.au>
126                Ported patch to kernel 2.1.120-pre3.
127   v1.24
128     19980910   Richard Gooch <rgooch@atnf.csiro.au>
129                Removed sanity checks and addition queue: Linus prefers an OOPS.
130   v1.25
131     19981001   Richard Gooch <rgooch@atnf.csiro.au>
132                Fixed harmless compiler warning in include/asm-i386/mtrr.h
133                Fixed version numbering and history for v1.23 -> v1.24.
134   v1.26
135     19990118   Richard Gooch <rgooch@atnf.csiro.au>
136                Added devfs support.
137   v1.27
138     19990123   Richard Gooch <rgooch@atnf.csiro.au>
139                Changed locking to spin with reschedule.
140                Made use of new <smp_call_function>.
141   v1.28
142     19990201   Zoltán Böszörményi <zboszor@mail.externet.hu>
143                Extended the driver to be able to use Cyrix style ARRs.
144     19990204   Richard Gooch <rgooch@atnf.csiro.au>
145                Restructured Cyrix support.
146   v1.29
147     19990204   Zoltán Böszörményi <zboszor@mail.externet.hu>
148                Refined ARR support: enable MAPEN in set_mtrr_prepare()
149                and disable MAPEN in set_mtrr_done().
150     19990205   Richard Gooch <rgooch@atnf.csiro.au>
151                Minor cleanups.
152   v1.30
153     19990208   Zoltán Böszörményi <zboszor@mail.externet.hu>
154                Protect plain 6x86s (and other processors without the
155                Page Global Enable feature) against accessing CR4 in
156                set_mtrr_prepare() and set_mtrr_done().
157     19990210   Richard Gooch <rgooch@atnf.csiro.au>
158                Turned <set_mtrr_up> and <get_mtrr> into function pointers.
159   v1.31
160     19990212   Zoltán Böszörményi <zboszor@mail.externet.hu>
161                Major rewrite of cyrix_arr_init(): do not touch ARRs,
162                leave them as the BIOS have set them up.
163                Enable usage of all 8 ARRs.
164                Avoid multiplications by 3 everywhere and other
165                code clean ups/speed ups.
166     19990213   Zoltán Böszörményi <zboszor@mail.externet.hu>
167                Set up other Cyrix processors identical to the boot cpu.
168                Since Cyrix don't support Intel APIC, this is l'art pour l'art.
169                Weigh ARRs by size:
170                If size <= 32M is given, set up ARR# we were given.
171                If size >  32M is given, set up ARR7 only if it is free,
172                fail otherwise.
173     19990214   Zoltán Böszörményi <zboszor@mail.externet.hu>
174                Also check for size >= 256K if we are to set up ARR7,
175                mtrr_add() returns the value it gets from set_mtrr()
176     19990218   Zoltán Böszörményi <zboszor@mail.externet.hu>
177                Remove Cyrix "coma bug" workaround from here.
178                Moved to linux/arch/i386/kernel/setup.c and
179                linux/include/asm-i386/bugs.h
180     19990228   Richard Gooch <rgooch@atnf.csiro.au>
181                Added MTRRIOC_KILL_ENTRY ioctl(2)
182                Trap for counter underflow in <mtrr_file_del>.
183                Trap for 4 MiB aligned regions for PPro, stepping <= 7.
184     19990301   Richard Gooch <rgooch@atnf.csiro.au>
185                Created <get_free_region> hook.
186     19990305   Richard Gooch <rgooch@atnf.csiro.au>
187                Temporarily disable AMD support now MTRR capability flag is set.
188   v1.32
189     19990308   Zoltán Böszörményi <zboszor@mail.externet.hu>
190                Adjust my changes (19990212-19990218) to Richard Gooch's
191                latest changes. (19990228-19990305)
192   v1.33
193     19990309   Richard Gooch <rgooch@atnf.csiro.au>
194                Fixed typo in <printk> message.
195     19990310   Richard Gooch <rgooch@atnf.csiro.au>
196                Support K6-II/III based on Alan Cox's <alan@redhat.com> patches.
197   v1.34
198     19990511   Bart Hartgers <bart@etpmod.phys.tue.nl>
199                Support Centaur C6 MCR's.
200     19990512   Richard Gooch <rgooch@atnf.csiro.au>
201                Minor cleanups.
202   v1.35
203     19990707   Zoltán Böszörményi <zboszor@mail.externet.hu>
204                Check whether ARR3 is protected in cyrix_get_free_region()
205                and mtrr_del(). The code won't attempt to delete or change it
206                from now on if the BIOS protected ARR3. It silently skips ARR3
207                in cyrix_get_free_region() or returns with an error code from
208                mtrr_del().
209     19990711   Zoltán Böszörményi <zboszor@mail.externet.hu>
210                Reset some bits in the CCRs in cyrix_arr_init() to disable SMM
211                if ARR3 isn't protected. This is needed because if SMM is active
212                and ARR3 isn't protected then deleting and setting ARR3 again
213                may lock up the processor. With SMM entirely disabled, it does
214                not happen.
215     19990812   Zoltán Böszörményi <zboszor@mail.externet.hu>
216                Rearrange switch() statements so the driver accomodates to
217                the fact that the AMD Athlon handles its MTRRs the same way
218                as Intel does.
219     19990814   Zoltán Böszörményi <zboszor@mail.externet.hu>
220                Double check for Intel in mtrr_add()'s big switch() because
221                that revision check is only valid for Intel CPUs.
222     19990819   Alan Cox <alan@redhat.com>
223                Tested Zoltan's changes on a pre production Athlon - 100%
224                success.
225     19991008   Manfred Spraul <manfreds@colorfullife.com>
226                replaced spin_lock_reschedule() with a normal semaphore.
227   v1.36
228     20000221   Richard Gooch <rgooch@atnf.csiro.au>
229                Compile fix if procfs and devfs not enabled.
230                Formatting changes.
231   v1.37
232     20001109   H. Peter Anvin <hpa@zytor.com>
233                Use the new centralized CPU feature detects.
234
235   v1.38
236     20010309   Dave Jones <davej@suse.de>
237                Add support for Cyrix III.
238
239   v1.39
240     20010312   Dave Jones <davej@suse.de>
241                Ugh, I broke AMD support.
242                Reworked fix by Troels Walsted Hansen <troels@thule.no>
243
244   v1.40
245     20010327   Dave Jones <davej@suse.de>
246                Adapted Cyrix III support to include VIA C3.
247
248 */
249 #include <linux/types.h>
250 #include <linux/errno.h>
251 #include <linux/sched.h>
252 #include <linux/tty.h>
253 #include <linux/timer.h>
254 #include <linux/config.h>
255 #include <linux/kernel.h>
256 #include <linux/wait.h>
257 #include <linux/string.h>
258 #include <linux/slab.h>
259 #include <linux/ioport.h>
260 #include <linux/delay.h>
261 #include <linux/fs.h>
262 #include <linux/ctype.h>
263 #include <linux/proc_fs.h>
264 #include <linux/devfs_fs_kernel.h>
265 #include <linux/mm.h>
266 #include <linux/module.h>
267 #include <linux/pci.h>
268 #define MTRR_NEED_STRINGS
269 #include <asm/mtrr.h>
270 #include <linux/init.h>
271 #include <linux/smp.h>
272 #include <linux/smp_lock.h>
273
274 #include <asm/uaccess.h>
275 #include <asm/io.h>
276 #include <asm/processor.h>
277 #include <asm/system.h>
278 #include <asm/pgtable.h>
279 #include <asm/segment.h>
280 #include <asm/bitops.h>
281 #include <asm/atomic.h>
282 #include <asm/msr.h>
283
284 #include <asm/hardirq.h>
285 #include <linux/irq.h>
286
287 #define MTRR_VERSION            "1.40 (20010327)"
288
289 #define TRUE  1
290 #define FALSE 0
291
292 /*
293  * The code assumes all processors support the same MTRR
294  * interface.  This is generally a good assumption, but could
295  * potentially be a problem.
296  */
297 enum mtrr_if_type {
298     MTRR_IF_NONE,               /* No MTRRs supported */
299     MTRR_IF_INTEL,              /* Intel (P6) standard MTRRs */
300     MTRR_IF_AMD_K6,             /* AMD pre-Athlon MTRRs */
301     MTRR_IF_CYRIX_ARR,          /* Cyrix ARRs */
302     MTRR_IF_CENTAUR_MCR,        /* Centaur MCRs */
303 } mtrr_if = MTRR_IF_NONE;
304
305 static __initdata char *mtrr_if_name[] = {
306     "none", "Intel", "AMD K6", "Cyrix ARR", "Centaur MCR"
307 };
308
309 #define MTRRcap_MSR     0x0fe
310 #define MTRRdefType_MSR 0x2ff
311
312 #define MTRRphysBase_MSR(reg) (0x200 + 2 * (reg))
313 #define MTRRphysMask_MSR(reg) (0x200 + 2 * (reg) + 1)
314
315 #define NUM_FIXED_RANGES 88
316 #define MTRRfix64K_00000_MSR 0x250
317 #define MTRRfix16K_80000_MSR 0x258
318 #define MTRRfix16K_A0000_MSR 0x259
319 #define MTRRfix4K_C0000_MSR 0x268
320 #define MTRRfix4K_C8000_MSR 0x269
321 #define MTRRfix4K_D0000_MSR 0x26a
322 #define MTRRfix4K_D8000_MSR 0x26b
323 #define MTRRfix4K_E0000_MSR 0x26c
324 #define MTRRfix4K_E8000_MSR 0x26d
325 #define MTRRfix4K_F0000_MSR 0x26e
326 #define MTRRfix4K_F8000_MSR 0x26f
327
328 #ifdef CONFIG_SMP
329 #  define MTRR_CHANGE_MASK_FIXED     0x01
330 #  define MTRR_CHANGE_MASK_VARIABLE  0x02
331 #  define MTRR_CHANGE_MASK_DEFTYPE   0x04
332 #endif
333
334 /* In the Intel processor's MTRR interface, the MTRR type is always held in
335    an 8 bit field: */
336 typedef u8 mtrr_type;
337
338 #define LINE_SIZE      80
339 #define JIFFIE_TIMEOUT 100
340
341 #ifdef CONFIG_SMP
342 #  define set_mtrr(reg,base,size,type) set_mtrr_smp (reg, base, size, type)
343 #else
344 #  define set_mtrr(reg,base,size,type) (*set_mtrr_up) (reg, base, size, type, \
345                                                        TRUE)
346 #endif
347
348 #if defined(CONFIG_PROC_FS) || defined(CONFIG_DEVFS_FS)
349 # define USERSPACE_INTERFACE
350 #endif
351
352 #ifndef USERSPACE_INTERFACE
353 #  define compute_ascii() while (0)
354 #endif
355
356 #ifdef USERSPACE_INTERFACE
357 static char *ascii_buffer;
358 static unsigned int ascii_buf_bytes;
359 #endif
360 static unsigned int *usage_table;
361 static DECLARE_MUTEX(main_lock);
362
363 /*  Private functions  */
364 #ifdef USERSPACE_INTERFACE
365 static void compute_ascii (void);
366 #endif
367
368
369 struct set_mtrr_context
370 {
371     unsigned long flags;
372     unsigned long deftype_lo;
373     unsigned long deftype_hi;
374     unsigned long cr4val;
375     unsigned long ccr3;
376 };
377
378 static int arr3_protected;
379
380 /*  Put the processor into a state where MTRRs can be safely set  */
381 static void set_mtrr_prepare_save (struct set_mtrr_context *ctxt)
382 {
383     /*  Disable interrupts locally  */
384     __save_flags (ctxt->flags); __cli ();
385
386     if ( mtrr_if != MTRR_IF_INTEL && mtrr_if != MTRR_IF_CYRIX_ARR )
387          return;
388
389     /*  Save value of CR4 and clear Page Global Enable (bit 7)  */
390     if ( test_bit(X86_FEATURE_PGE, &boot_cpu_data.x86_capability) ) {
391         ctxt->cr4val = read_cr4();
392         write_cr4(ctxt->cr4val & (unsigned char) ~(1<<7));
393     }
394
395     /*  Disable and flush caches. Note that wbinvd flushes the TLBs as
396         a side-effect  */
397     {
398         unsigned int cr0 = read_cr0() | 0x40000000;
399         wbinvd();
400         write_cr0( cr0 );
401         wbinvd();
402     }
403
404     if ( mtrr_if == MTRR_IF_INTEL ) {
405         /*  Save MTRR state */
406         rdmsr (MTRRdefType_MSR, ctxt->deftype_lo, ctxt->deftype_hi);
407     } else {
408         /* Cyrix ARRs - everything else were excluded at the top */
409         ctxt->ccr3 = getCx86 (CX86_CCR3);
410     }
411 }   /*  End Function set_mtrr_prepare_save  */
412
413 static void set_mtrr_disable (struct set_mtrr_context *ctxt)
414 {
415     if ( mtrr_if != MTRR_IF_INTEL && mtrr_if != MTRR_IF_CYRIX_ARR )
416          return;
417
418     if ( mtrr_if == MTRR_IF_INTEL ) {
419         /*  Disable MTRRs, and set the default type to uncached  */
420         wrmsr (MTRRdefType_MSR, ctxt->deftype_lo & 0xf300UL, ctxt->deftype_hi);
421     } else {
422         /* Cyrix ARRs - everything else were excluded at the top */
423         setCx86 (CX86_CCR3, (ctxt->ccr3 & 0x0f) | 0x10);
424     }
425 }   /*  End Function set_mtrr_disable  */
426
427 /*  Restore the processor after a set_mtrr_prepare  */
428 static void set_mtrr_done (struct set_mtrr_context *ctxt)
429 {
430     if ( mtrr_if != MTRR_IF_INTEL && mtrr_if != MTRR_IF_CYRIX_ARR ) {
431          __restore_flags (ctxt->flags);
432          return;
433     }
434
435     /*  Flush caches and TLBs  */
436     wbinvd();
437
438     /*  Restore MTRRdefType  */
439     if ( mtrr_if == MTRR_IF_INTEL ) {
440         /* Intel (P6) standard MTRRs */
441         wrmsr (MTRRdefType_MSR, ctxt->deftype_lo, ctxt->deftype_hi);
442     } else {
443         /* Cyrix ARRs - everything else was excluded at the top */
444         setCx86 (CX86_CCR3, ctxt->ccr3);
445     }
446
447     /*  Enable caches  */
448     write_cr0( read_cr0() & 0xbfffffff );
449
450     /*  Restore value of CR4  */
451     if ( test_bit(X86_FEATURE_PGE, &boot_cpu_data.x86_capability) )
452         write_cr4(ctxt->cr4val);
453
454     /*  Re-enable interrupts locally (if enabled previously)  */
455     __restore_flags (ctxt->flags);
456 }   /*  End Function set_mtrr_done  */
457
458 /*  This function returns the number of variable MTRRs  */
459 static unsigned int get_num_var_ranges (void)
460 {
461     unsigned long config, dummy;
462
463     switch ( mtrr_if )
464     {
465     case MTRR_IF_INTEL:
466         rdmsr (MTRRcap_MSR, config, dummy);
467         return (config & 0xff);
468     case MTRR_IF_AMD_K6:
469         return 2;
470     case MTRR_IF_CYRIX_ARR:
471         return 8;
472     case MTRR_IF_CENTAUR_MCR:
473         return 8;
474     default:
475         return 0;
476     }
477 }   /*  End Function get_num_var_ranges  */
478
479 /*  Returns non-zero if we have the write-combining memory type  */
480 static int have_wrcomb (void)
481 {
482     unsigned long config, dummy;
483     struct pci_dev *dev = NULL;
484     
485    /* ServerWorks LE chipsets have problems with write-combining 
486       Don't allow it and leave room for other chipsets to be tagged */
487
488         if ((dev = pci_find_class(PCI_CLASS_BRIDGE_HOST << 8, NULL)) != NULL) {
489                 if ((dev->vendor == PCI_VENDOR_ID_SERVERWORKS) &&
490                         (dev->device == PCI_DEVICE_ID_SERVERWORKS_LE)) {
491                 printk (KERN_INFO "mtrr: Serverworks LE detected. Write-combining disabled.\n");
492                 return 0;
493                 }
494         }
495         /* Intel 450NX errata # 23. Non ascending cachline evictions to
496            write combining memory may resulting in data corruption */
497         dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82451NX, NULL);
498         if(dev)
499         {
500                 printk(KERN_INFO "mtrr: Intel 450NX MMC detected. Write-combining disabled.\n");
501                 return 0;
502         }               
503
504     switch ( mtrr_if )
505     {
506     case MTRR_IF_INTEL:
507         rdmsr (MTRRcap_MSR, config, dummy);
508         return (config & (1<<10));
509         return 1;
510     case MTRR_IF_AMD_K6:
511     case MTRR_IF_CENTAUR_MCR:
512     case MTRR_IF_CYRIX_ARR:
513         return 1;
514     default:
515         return 0;
516     }
517 }   /*  End Function have_wrcomb  */
518
519 static u32 size_or_mask, size_and_mask;
520
521 static void intel_get_mtrr (unsigned int reg, unsigned long *base,
522                             unsigned long *size, mtrr_type *type)
523 {
524     unsigned long mask_lo, mask_hi, base_lo, base_hi;
525
526     rdmsr (MTRRphysMask_MSR(reg), mask_lo, mask_hi);
527     if ( (mask_lo & 0x800) == 0 )
528     {
529         /*  Invalid (i.e. free) range  */
530         *base = 0;
531         *size = 0;
532         *type = 0;
533         return;
534     }
535
536     rdmsr(MTRRphysBase_MSR(reg), base_lo, base_hi);
537
538     /* Work out the shifted address mask. */
539     mask_lo = size_or_mask | mask_hi << (32 - PAGE_SHIFT)
540                 | mask_lo >> PAGE_SHIFT;
541
542     /* This works correctly if size is a power of two, i.e. a
543        contiguous range. */
544      *size = -mask_lo;
545      *base = base_hi << (32 - PAGE_SHIFT) | base_lo >> PAGE_SHIFT;
546      *type = base_lo & 0xff;
547 }   /*  End Function intel_get_mtrr  */
548
549 static void cyrix_get_arr (unsigned int reg, unsigned long *base,
550                            unsigned long *size, mtrr_type *type)
551 {
552     unsigned long flags;
553     unsigned char arr, ccr3, rcr, shift;
554
555     arr = CX86_ARR_BASE + (reg << 1) + reg; /* avoid multiplication by 3 */
556
557     /* Save flags and disable interrupts */
558     __save_flags (flags); __cli ();
559
560     ccr3 = getCx86 (CX86_CCR3);
561     setCx86 (CX86_CCR3, (ccr3 & 0x0f) | 0x10);          /* enable MAPEN */
562     ((unsigned char *) base)[3]  = getCx86 (arr);
563     ((unsigned char *) base)[2]  = getCx86 (arr+1);
564     ((unsigned char *) base)[1]  = getCx86 (arr+2);
565     rcr = getCx86(CX86_RCR_BASE + reg);
566     setCx86 (CX86_CCR3, ccr3);                          /* disable MAPEN */
567
568     /* Enable interrupts if it was enabled previously */
569     __restore_flags (flags);
570     shift = ((unsigned char *) base)[1] & 0x0f;
571     *base >>= PAGE_SHIFT;
572
573     /* Power of two, at least 4K on ARR0-ARR6, 256K on ARR7
574      * Note: shift==0xf means 4G, this is unsupported.
575      */
576     if (shift)
577       *size = (reg < 7 ? 0x1UL : 0x40UL) << (shift - 1);
578     else
579       *size = 0;
580
581     /* Bit 0 is Cache Enable on ARR7, Cache Disable on ARR0-ARR6 */
582     if (reg < 7)
583     {
584         switch (rcr)
585         {
586           case  1: *type = MTRR_TYPE_UNCACHABLE; break;
587           case  8: *type = MTRR_TYPE_WRBACK;     break;
588           case  9: *type = MTRR_TYPE_WRCOMB;     break;
589           case 24:
590           default: *type = MTRR_TYPE_WRTHROUGH;  break;
591         }
592     } else
593     {
594         switch (rcr)
595         {
596           case  0: *type = MTRR_TYPE_UNCACHABLE; break;
597           case  8: *type = MTRR_TYPE_WRCOMB;     break;
598           case  9: *type = MTRR_TYPE_WRBACK;     break;
599           case 25:
600           default: *type = MTRR_TYPE_WRTHROUGH;  break;
601         }
602     }
603 }   /*  End Function cyrix_get_arr  */
604
605 static void amd_get_mtrr (unsigned int reg, unsigned long *base,
606                           unsigned long *size, mtrr_type *type)
607 {
608     unsigned long low, high;
609
610     rdmsr (MSR_K6_UWCCR, low, high);
611     /*  Upper dword is region 1, lower is region 0  */
612     if (reg == 1) low = high;
613     /*  The base masks off on the right alignment  */
614     *base = (low & 0xFFFE0000) >> PAGE_SHIFT;
615     *type = 0;
616     if (low & 1) *type = MTRR_TYPE_UNCACHABLE;
617     if (low & 2) *type = MTRR_TYPE_WRCOMB;
618     if ( !(low & 3) )
619     {
620         *size = 0;
621         return;
622     }
623     /*
624      *  This needs a little explaining. The size is stored as an
625      *  inverted mask of bits of 128K granularity 15 bits long offset
626      *  2 bits
627      *
628      *  So to get a size we do invert the mask and add 1 to the lowest
629      *  mask bit (4 as its 2 bits in). This gives us a size we then shift
630      *  to turn into 128K blocks
631      *
632      *  eg              111 1111 1111 1100      is 512K
633      *
634      *  invert          000 0000 0000 0011
635      *  +1              000 0000 0000 0100
636      *  *128K   ...
637      */
638     low = (~low) & 0x1FFFC;
639     *size = (low + 4) << (15 - PAGE_SHIFT);
640     return;
641 }   /*  End Function amd_get_mtrr  */
642
643 static struct
644 {
645     unsigned long high;
646     unsigned long low;
647 } centaur_mcr[8];
648
649 static u8 centaur_mcr_reserved;
650 static u8 centaur_mcr_type;             /* 0 for winchip, 1 for winchip2 */
651
652 /*
653  *      Report boot time MCR setups 
654  */
655  
656 void mtrr_centaur_report_mcr(int mcr, u32 lo, u32 hi)
657 {
658         centaur_mcr[mcr].low = lo;
659         centaur_mcr[mcr].high = hi;
660 }
661
662 static void centaur_get_mcr (unsigned int reg, unsigned long *base,
663                              unsigned long *size, mtrr_type *type)
664 {
665     *base = centaur_mcr[reg].high >> PAGE_SHIFT;
666     *size = -(centaur_mcr[reg].low & 0xfffff000) >> PAGE_SHIFT;
667     *type = MTRR_TYPE_WRCOMB;   /*  If it is there, it is write-combining  */
668     if(centaur_mcr_type==1 && ((centaur_mcr[reg].low&31)&2))
669         *type = MTRR_TYPE_UNCACHABLE;
670     if(centaur_mcr_type==1 && (centaur_mcr[reg].low&31)==25)
671         *type = MTRR_TYPE_WRBACK;
672     if(centaur_mcr_type==0 && (centaur_mcr[reg].low&31)==31)
673         *type = MTRR_TYPE_WRBACK;
674     
675 }   /*  End Function centaur_get_mcr  */
676
677 static void (*get_mtrr) (unsigned int reg, unsigned long *base,
678                          unsigned long *size, mtrr_type *type);
679
680 static void intel_set_mtrr_up (unsigned int reg, unsigned long base,
681                                unsigned long size, mtrr_type type, int do_safe)
682 /*  [SUMMARY] Set variable MTRR register on the local CPU.
683     <reg> The register to set.
684     <base> The base address of the region.
685     <size> The size of the region. If this is 0 the region is disabled.
686     <type> The type of the region.
687     <do_safe> If TRUE, do the change safely. If FALSE, safety measures should
688     be done externally.
689     [RETURNS] Nothing.
690 */
691 {
692     struct set_mtrr_context ctxt;
693
694     if (do_safe) {
695         set_mtrr_prepare_save (&ctxt);
696         set_mtrr_disable (&ctxt);
697         }
698     if (size == 0)
699     {
700         /* The invalid bit is kept in the mask, so we simply clear the
701            relevant mask register to disable a range. */
702         wrmsr (MTRRphysMask_MSR (reg), 0, 0);
703     }
704     else
705     {
706         wrmsr (MTRRphysBase_MSR (reg), base << PAGE_SHIFT | type,
707                 (base & size_and_mask) >> (32 - PAGE_SHIFT));
708         wrmsr (MTRRphysMask_MSR (reg), -size << PAGE_SHIFT | 0x800,
709                 (-size & size_and_mask) >> (32 - PAGE_SHIFT));
710     }
711     if (do_safe) set_mtrr_done (&ctxt);
712 }   /*  End Function intel_set_mtrr_up  */
713
714 static void cyrix_set_arr_up (unsigned int reg, unsigned long base,
715                               unsigned long size, mtrr_type type, int do_safe)
716 {
717     struct set_mtrr_context ctxt;
718     unsigned char arr, arr_type, arr_size;
719
720     arr = CX86_ARR_BASE + (reg << 1) + reg; /* avoid multiplication by 3 */
721
722     /* count down from 32M (ARR0-ARR6) or from 2G (ARR7) */
723     if (reg >= 7)
724         size >>= 6;
725
726     size &= 0x7fff; /* make sure arr_size <= 14 */
727     for(arr_size = 0; size; arr_size++, size >>= 1);
728
729     if (reg<7)
730     {
731         switch (type) {
732           case MTRR_TYPE_UNCACHABLE:    arr_type =  1; break;
733           case MTRR_TYPE_WRCOMB:                arr_type =  9; break;
734           case MTRR_TYPE_WRTHROUGH:     arr_type = 24; break;
735           default:                      arr_type =  8; break;
736         }
737     }
738     else
739     {
740         switch (type)
741         {
742           case MTRR_TYPE_UNCACHABLE:    arr_type =  0; break;
743           case MTRR_TYPE_WRCOMB:                arr_type =  8; break;
744           case MTRR_TYPE_WRTHROUGH:     arr_type = 25; break;
745           default:                      arr_type =  9; break;
746         }
747     }
748
749     if (do_safe) {
750         set_mtrr_prepare_save (&ctxt);
751         set_mtrr_disable (&ctxt);
752     }
753     base <<= PAGE_SHIFT;
754     setCx86(arr,    ((unsigned char *) &base)[3]);
755     setCx86(arr+1,  ((unsigned char *) &base)[2]);
756     setCx86(arr+2, (((unsigned char *) &base)[1]) | arr_size);
757     setCx86(CX86_RCR_BASE + reg, arr_type);
758     if (do_safe) set_mtrr_done (&ctxt);
759 }   /*  End Function cyrix_set_arr_up  */
760
761 static void amd_set_mtrr_up (unsigned int reg, unsigned long base,
762                              unsigned long size, mtrr_type type, int do_safe)
763 /*  [SUMMARY] Set variable MTRR register on the local CPU.
764     <reg> The register to set.
765     <base> The base address of the region.
766     <size> The size of the region. If this is 0 the region is disabled.
767     <type> The type of the region.
768     <do_safe> If TRUE, do the change safely. If FALSE, safety measures should
769     be done externally.
770     [RETURNS] Nothing.
771 */
772 {
773     u32 regs[2];
774     struct set_mtrr_context ctxt;
775
776     if (do_safe) {
777         set_mtrr_prepare_save (&ctxt);
778         set_mtrr_disable (&ctxt);
779     }
780     /*
781      *  Low is MTRR0 , High MTRR 1
782      */
783     rdmsr (MSR_K6_UWCCR, regs[0], regs[1]);
784     /*
785      *  Blank to disable
786      */
787     if (size == 0)
788         regs[reg] = 0;
789     else
790         /* Set the register to the base, the type (off by one) and an
791            inverted bitmask of the size The size is the only odd
792            bit. We are fed say 512K We invert this and we get 111 1111
793            1111 1011 but if you subtract one and invert you get the   
794            desired 111 1111 1111 1100 mask
795
796            But ~(x - 1) == ~x + 1 == -x. Two's complement rocks!  */
797         regs[reg] = (-size>>(15-PAGE_SHIFT) & 0x0001FFFC)
798                                 | (base<<PAGE_SHIFT) | (type+1);
799
800     /*
801      *  The writeback rule is quite specific. See the manual. Its
802      *  disable local interrupts, write back the cache, set the mtrr
803      */
804         wbinvd();
805         wrmsr (MSR_K6_UWCCR, regs[0], regs[1]);
806     if (do_safe) set_mtrr_done (&ctxt);
807 }   /*  End Function amd_set_mtrr_up  */
808
809
810 static void centaur_set_mcr_up (unsigned int reg, unsigned long base,
811                                 unsigned long size, mtrr_type type,
812                                 int do_safe)
813 {
814     struct set_mtrr_context ctxt;
815     unsigned long low, high;
816
817     if (do_safe) {
818         set_mtrr_prepare_save (&ctxt);
819         set_mtrr_disable (&ctxt);
820     }
821     if (size == 0)
822     {
823         /*  Disable  */
824         high = low = 0;
825     }
826     else
827     {
828         high = base << PAGE_SHIFT;
829         if(centaur_mcr_type == 0)
830                 low = -size << PAGE_SHIFT | 0x1f; /* only support write-combining... */
831         else
832         {
833                 if(type == MTRR_TYPE_UNCACHABLE)
834                         low = -size << PAGE_SHIFT | 0x02;       /* NC */
835                 else
836                         low = -size << PAGE_SHIFT | 0x09;       /* WWO,WC */
837         }
838     }
839     centaur_mcr[reg].high = high;
840     centaur_mcr[reg].low = low;
841     wrmsr (MSR_IDT_MCR0 + reg, low, high);
842     if (do_safe) set_mtrr_done( &ctxt );
843 }   /*  End Function centaur_set_mtrr_up  */
844
845 static void (*set_mtrr_up) (unsigned int reg, unsigned long base,
846                             unsigned long size, mtrr_type type,
847                             int do_safe);
848
849 #ifdef CONFIG_SMP
850
851 struct mtrr_var_range
852 {
853     unsigned long base_lo;
854     unsigned long base_hi;
855     unsigned long mask_lo;
856     unsigned long mask_hi;
857 };
858
859
860 /*  Get the MSR pair relating to a var range  */
861 static void __init get_mtrr_var_range (unsigned int index,
862                                            struct mtrr_var_range *vr)
863 {
864     rdmsr (MTRRphysBase_MSR (index), vr->base_lo, vr->base_hi);
865     rdmsr (MTRRphysMask_MSR (index), vr->mask_lo, vr->mask_hi);
866 }   /*  End Function get_mtrr_var_range  */
867
868
869 /*  Set the MSR pair relating to a var range. Returns TRUE if
870     changes are made  */
871 static int __init set_mtrr_var_range_testing (unsigned int index,
872                                                   struct mtrr_var_range *vr)
873 {
874     unsigned int lo, hi;
875     int changed = FALSE;
876
877     rdmsr(MTRRphysBase_MSR(index), lo, hi);
878     if ( (vr->base_lo & 0xfffff0ffUL) != (lo & 0xfffff0ffUL)
879          || (vr->base_hi & 0xfUL) != (hi & 0xfUL) )
880     {
881         wrmsr (MTRRphysBase_MSR(index), vr->base_lo, vr->base_hi);
882         changed = TRUE;
883     }
884
885     rdmsr (MTRRphysMask_MSR(index), lo, hi);
886
887     if ( (vr->mask_lo & 0xfffff800UL) != (lo & 0xfffff800UL)
888          || (vr->mask_hi & 0xfUL) != (hi & 0xfUL) )
889     {
890         wrmsr(MTRRphysMask_MSR(index), vr->mask_lo, vr->mask_hi);
891         changed = TRUE;
892     }
893     return changed;
894 }   /*  End Function set_mtrr_var_range_testing  */
895
896 static void __init get_fixed_ranges(mtrr_type *frs)
897 {
898     unsigned long *p = (unsigned long *)frs;
899     int i;
900
901     rdmsr(MTRRfix64K_00000_MSR, p[0], p[1]);
902
903     for (i = 0; i < 2; i++)
904         rdmsr(MTRRfix16K_80000_MSR + i, p[2 + i*2], p[3 + i*2]);
905     for (i = 0; i < 8; i++)
906         rdmsr(MTRRfix4K_C0000_MSR + i, p[6 + i*2], p[7 + i*2]);
907 }   /*  End Function get_fixed_ranges  */
908
909 static int __init set_fixed_ranges_testing(mtrr_type *frs)
910 {
911     unsigned long *p = (unsigned long *)frs;
912     int changed = FALSE;
913     int i;
914     unsigned long lo, hi;
915
916     rdmsr(MTRRfix64K_00000_MSR, lo, hi);
917     if (p[0] != lo || p[1] != hi)
918     {
919         wrmsr (MTRRfix64K_00000_MSR, p[0], p[1]);
920         changed = TRUE;
921     }
922
923     for (i = 0; i < 2; i++)
924     {
925         rdmsr (MTRRfix16K_80000_MSR + i, lo, hi);
926         if (p[2 + i*2] != lo || p[3 + i*2] != hi)
927         {
928             wrmsr (MTRRfix16K_80000_MSR + i, p[2 + i*2], p[3 + i*2]);
929             changed = TRUE;
930         }
931     }
932
933     for (i = 0; i < 8; i++)
934     {
935         rdmsr (MTRRfix4K_C0000_MSR + i, lo, hi);
936         if (p[6 + i*2] != lo || p[7 + i*2] != hi)
937         {
938             wrmsr(MTRRfix4K_C0000_MSR + i, p[6 + i*2], p[7 + i*2]);
939             changed = TRUE;
940         }
941     }
942     return changed;
943 }   /*  End Function set_fixed_ranges_testing  */
944
945 struct mtrr_state
946 {
947     unsigned int num_var_ranges;
948     struct mtrr_var_range *var_ranges;
949     mtrr_type fixed_ranges[NUM_FIXED_RANGES];
950     unsigned char enabled;
951     mtrr_type def_type;
952 };
953
954
955 /*  Grab all of the MTRR state for this CPU into *state  */
956 static void __init get_mtrr_state(struct mtrr_state *state)
957 {
958     unsigned int nvrs, i;
959     struct mtrr_var_range *vrs;
960     unsigned long lo, dummy;
961
962     nvrs = state->num_var_ranges = get_num_var_ranges();
963     vrs = state->var_ranges
964               = kmalloc (nvrs * sizeof (struct mtrr_var_range), GFP_KERNEL);
965     if (vrs == NULL)
966         nvrs = state->num_var_ranges = 0;
967
968     for (i = 0; i < nvrs; i++)
969         get_mtrr_var_range (i, &vrs[i]);
970     get_fixed_ranges (state->fixed_ranges);
971
972     rdmsr (MTRRdefType_MSR, lo, dummy);
973     state->def_type = (lo & 0xff);
974     state->enabled = (lo & 0xc00) >> 10;
975 }   /*  End Function get_mtrr_state  */
976
977
978 /*  Free resources associated with a struct mtrr_state  */
979 static void __init finalize_mtrr_state(struct mtrr_state *state)
980 {
981     if (state->var_ranges) kfree (state->var_ranges);
982 }   /*  End Function finalize_mtrr_state  */
983
984
985 static unsigned long __init set_mtrr_state (struct mtrr_state *state,
986                                                 struct set_mtrr_context *ctxt)
987 /*  [SUMMARY] Set the MTRR state for this CPU.
988     <state> The MTRR state information to read.
989     <ctxt> Some relevant CPU context.
990     [NOTE] The CPU must already be in a safe state for MTRR changes.
991     [RETURNS] 0 if no changes made, else a mask indication what was changed.
992 */
993 {
994     unsigned int i;
995     unsigned long change_mask = 0;
996
997     for (i = 0; i < state->num_var_ranges; i++)
998         if ( set_mtrr_var_range_testing (i, &state->var_ranges[i]) )
999             change_mask |= MTRR_CHANGE_MASK_VARIABLE;
1000
1001     if ( set_fixed_ranges_testing(state->fixed_ranges) )
1002         change_mask |= MTRR_CHANGE_MASK_FIXED;
1003     /*  Set_mtrr_restore restores the old value of MTRRdefType,
1004         so to set it we fiddle with the saved value  */
1005     if ( (ctxt->deftype_lo & 0xff) != state->def_type
1006          || ( (ctxt->deftype_lo & 0xc00) >> 10 ) != state->enabled)
1007     {
1008         ctxt->deftype_lo |= (state->def_type | state->enabled << 10);
1009         change_mask |= MTRR_CHANGE_MASK_DEFTYPE;
1010     }
1011
1012     return change_mask;
1013 }   /*  End Function set_mtrr_state  */
1014
1015
1016 static atomic_t undone_count;
1017 static volatile int wait_barrier_mtrr_disable = FALSE;
1018 static volatile int wait_barrier_execute = FALSE;
1019 static volatile int wait_barrier_cache_enable = FALSE;
1020
1021 struct set_mtrr_data
1022 {
1023     unsigned long smp_base;
1024     unsigned long smp_size;
1025     unsigned int smp_reg;
1026     mtrr_type smp_type;
1027 };
1028
1029 static void ipi_handler (void *info)
1030 /*  [SUMMARY] Synchronisation handler. Executed by "other" CPUs.
1031     [RETURNS] Nothing.
1032 */
1033 {
1034     struct set_mtrr_data *data = info;
1035     struct set_mtrr_context ctxt;
1036     set_mtrr_prepare_save (&ctxt);
1037     /*  Notify master that I've flushed and disabled my cache  */
1038     atomic_dec (&undone_count);
1039     while (wait_barrier_mtrr_disable) { rep_nop(); barrier(); }
1040     set_mtrr_disable (&ctxt);
1041     /*  Notify master that I've flushed and disabled my cache  */
1042     atomic_dec (&undone_count);
1043     while (wait_barrier_execute) { rep_nop(); barrier(); }
1044     /*  The master has cleared me to execute  */
1045     (*set_mtrr_up) (data->smp_reg, data->smp_base, data->smp_size,
1046                     data->smp_type, FALSE);
1047     /*  Notify master CPU that I've executed the function  */
1048     atomic_dec (&undone_count);
1049     /*  Wait for master to clear me to enable cache and return  */
1050     while (wait_barrier_cache_enable) { rep_nop(); barrier(); }
1051     set_mtrr_done (&ctxt);
1052 }   /*  End Function ipi_handler  */
1053
1054 static void set_mtrr_smp (unsigned int reg, unsigned long base,
1055                           unsigned long size, mtrr_type type)
1056 {
1057     struct set_mtrr_data data;
1058     struct set_mtrr_context ctxt;
1059
1060     data.smp_reg = reg;
1061     data.smp_base = base;
1062     data.smp_size = size;
1063     data.smp_type = type;
1064     wait_barrier_mtrr_disable = TRUE;
1065     wait_barrier_execute = TRUE;
1066     wait_barrier_cache_enable = TRUE;
1067     atomic_set (&undone_count, smp_num_cpus - 1);
1068     /*  Start the ball rolling on other CPUs  */
1069     if (smp_call_function (ipi_handler, &data, 1, 0) != 0)
1070         panic ("mtrr: timed out waiting for other CPUs\n");
1071     /* Flush and disable the local CPU's cache */
1072     set_mtrr_prepare_save (&ctxt);
1073     /*  Wait for all other CPUs to flush and disable their caches  */
1074     while (atomic_read (&undone_count) > 0) { rep_nop(); barrier(); }
1075     /* Set up for completion wait and then release other CPUs to change MTRRs*/
1076     atomic_set (&undone_count, smp_num_cpus - 1);
1077     wait_barrier_mtrr_disable = FALSE;
1078     set_mtrr_disable (&ctxt);
1079
1080     /*  Wait for all other CPUs to flush and disable their caches  */
1081     while (atomic_read (&undone_count) > 0) { rep_nop(); barrier(); }
1082     /* Set up for completion wait and then release other CPUs to change MTRRs*/
1083     atomic_set (&undone_count, smp_num_cpus - 1);
1084     wait_barrier_execute = FALSE;
1085     (*set_mtrr_up) (reg, base, size, type, FALSE);
1086     /*  Now wait for other CPUs to complete the function  */
1087     while (atomic_read (&undone_count) > 0) { rep_nop(); barrier(); }
1088     /*  Now all CPUs should have finished the function. Release the barrier to
1089         allow them to re-enable their caches and return from their interrupt,
1090         then enable the local cache and return  */
1091     wait_barrier_cache_enable = FALSE;
1092     set_mtrr_done (&ctxt);
1093 }   /*  End Function set_mtrr_smp  */
1094
1095
1096 /*  Some BIOS's are fucked and don't set all MTRRs the same!  */
1097 static void __init mtrr_state_warn(unsigned long mask)
1098 {
1099     if (!mask) return;
1100     if (mask & MTRR_CHANGE_MASK_FIXED)
1101         printk ("mtrr: your CPUs had inconsistent fixed MTRR settings\n");
1102     if (mask & MTRR_CHANGE_MASK_VARIABLE)
1103         printk ("mtrr: your CPUs had inconsistent variable MTRR settings\n");
1104     if (mask & MTRR_CHANGE_MASK_DEFTYPE)
1105         printk ("mtrr: your CPUs had inconsistent MTRRdefType settings\n");
1106     printk ("mtrr: probably your BIOS does not setup all CPUs\n");
1107 }   /*  End Function mtrr_state_warn  */
1108
1109 #endif  /*  CONFIG_SMP  */
1110
1111 static char *attrib_to_str (int x)
1112 {
1113     return (x <= 6) ? mtrr_strings[x] : "?";
1114 }   /*  End Function attrib_to_str  */
1115
1116 static void init_table (void)
1117 {
1118     int i, max;
1119
1120     max = get_num_var_ranges ();
1121     if ( ( usage_table = kmalloc (max * sizeof *usage_table, GFP_KERNEL) )
1122          == NULL )
1123     {
1124         printk ("mtrr: could not allocate\n");
1125         return;
1126     }
1127     for (i = 0; i < max; i++) usage_table[i] = 1;
1128 #ifdef USERSPACE_INTERFACE
1129     if ( ( ascii_buffer = kmalloc (max * LINE_SIZE, GFP_KERNEL) ) == NULL )
1130     {
1131         printk ("mtrr: could not allocate\n");
1132         return;
1133     }
1134     ascii_buf_bytes = 0;
1135     compute_ascii ();
1136 #endif
1137 }   /*  End Function init_table  */
1138
1139 static int generic_get_free_region (unsigned long base, unsigned long size)
1140 /*  [SUMMARY] Get a free MTRR.
1141     <base> The starting (base) address of the region.
1142     <size> The size (in bytes) of the region.
1143     [RETURNS] The index of the region on success, else -1 on error.
1144 */
1145 {
1146     int i, max;
1147     mtrr_type ltype;
1148     unsigned long lbase, lsize;
1149
1150     max = get_num_var_ranges ();
1151     for (i = 0; i < max; ++i)
1152     {
1153         (*get_mtrr) (i, &lbase, &lsize, &ltype);
1154         if (lsize == 0) return i;
1155     }
1156     return -ENOSPC;
1157 }   /*  End Function generic_get_free_region  */
1158
1159 static int centaur_get_free_region (unsigned long base, unsigned long size)
1160 /*  [SUMMARY] Get a free MTRR.
1161     <base> The starting (base) address of the region.
1162     <size> The size (in bytes) of the region.
1163     [RETURNS] The index of the region on success, else -1 on error.
1164 */
1165 {
1166     int i, max;
1167     mtrr_type ltype;
1168     unsigned long lbase, lsize;
1169
1170     max = get_num_var_ranges ();
1171     for (i = 0; i < max; ++i)
1172     {
1173         if(centaur_mcr_reserved & (1<<i))
1174                 continue;
1175         (*get_mtrr) (i, &lbase, &lsize, &ltype);
1176         if (lsize == 0) return i;
1177     }
1178     return -ENOSPC;
1179 }   /*  End Function generic_get_free_region  */
1180
1181 static int cyrix_get_free_region (unsigned long base, unsigned long size)
1182 /*  [SUMMARY] Get a free ARR.
1183     <base> The starting (base) address of the region.
1184     <size> The size (in bytes) of the region.
1185     [RETURNS] The index of the region on success, else -1 on error.
1186 */
1187 {
1188     int i;
1189     mtrr_type ltype;
1190     unsigned long lbase, lsize;
1191
1192     /* If we are to set up a region >32M then look at ARR7 immediately */
1193     if (size > 0x2000)
1194     {
1195         cyrix_get_arr (7, &lbase, &lsize, &ltype);
1196         if (lsize == 0) return 7;
1197         /*  Else try ARR0-ARR6 first  */
1198     }
1199     else
1200     {
1201         for (i = 0; i < 7; i++)
1202         {
1203             cyrix_get_arr (i, &lbase, &lsize, &ltype);
1204             if ((i == 3) && arr3_protected) continue;
1205             if (lsize == 0) return i;
1206         }
1207         /* ARR0-ARR6 isn't free, try ARR7 but its size must be at least 256K */
1208         cyrix_get_arr (i, &lbase, &lsize, &ltype);
1209         if ((lsize == 0) && (size >= 0x40)) return i;
1210     }
1211     return -ENOSPC;
1212 }   /*  End Function cyrix_get_free_region  */
1213
1214 static int (*get_free_region) (unsigned long base,
1215                                unsigned long size) = generic_get_free_region;
1216
1217 /**
1218  *      mtrr_add_page - Add a memory type region
1219  *      @base: Physical base address of region in pages (4 KB)
1220  *      @size: Physical size of region in pages (4 KB)
1221  *      @type: Type of MTRR desired
1222  *      @increment: If this is true do usage counting on the region
1223  *
1224  *      Memory type region registers control the caching on newer Intel and
1225  *      non Intel processors. This function allows drivers to request an
1226  *      MTRR is added. The details and hardware specifics of each processor's
1227  *      implementation are hidden from the caller, but nevertheless the 
1228  *      caller should expect to need to provide a power of two size on an
1229  *      equivalent power of two boundary.
1230  *
1231  *      If the region cannot be added either because all regions are in use
1232  *      or the CPU cannot support it a negative value is returned. On success
1233  *      the register number for this entry is returned, but should be treated
1234  *      as a cookie only.
1235  *
1236  *      On a multiprocessor machine the changes are made to all processors.
1237  *      This is required on x86 by the Intel processors.
1238  *
1239  *      The available types are
1240  *
1241  *      %MTRR_TYPE_UNCACHABLE   -       No caching
1242  *
1243  *      %MTRR_TYPE_WRBACK       -       Write data back in bursts whenever
1244  *
1245  *      %MTRR_TYPE_WRCOMB       -       Write data back soon but allow bursts
1246  *
1247  *      %MTRR_TYPE_WRTHROUGH    -       Cache reads but not writes
1248  *
1249  *      BUGS: Needs a quiet flag for the cases where drivers do not mind
1250  *      failures and do not wish system log messages to be sent.
1251  */
1252
1253 int mtrr_add_page(unsigned long base, unsigned long size, unsigned int type, char increment)
1254 {
1255 /*  [SUMMARY] Add an MTRR entry.
1256     <base> The starting (base, in pages) address of the region.
1257     <size> The size of the region. (in pages)
1258     <type> The type of the new region.
1259     <increment> If true and the region already exists, the usage count will be
1260     incremented.
1261     [RETURNS] The MTRR register on success, else a negative number indicating
1262     the error code.
1263     [NOTE] This routine uses a spinlock.
1264 */
1265     int i, max;
1266     mtrr_type ltype;
1267     unsigned long lbase, lsize, last;
1268
1269     switch ( mtrr_if )
1270     {
1271     case MTRR_IF_NONE:
1272         return -ENXIO;          /* No MTRRs whatsoever */
1273
1274     case MTRR_IF_AMD_K6:
1275         /* Apply the K6 block alignment and size rules
1276            In order
1277            o Uncached or gathering only
1278            o 128K or bigger block
1279            o Power of 2 block
1280            o base suitably aligned to the power
1281         */
1282         if ( type > MTRR_TYPE_WRCOMB || size < (1 << (17-PAGE_SHIFT)) ||
1283              (size & ~(size-1))-size || ( base & (size-1) ) )
1284             return -EINVAL;
1285         break;
1286
1287     case MTRR_IF_INTEL:
1288         /*  For Intel PPro stepping <= 7, must be 4 MiB aligned 
1289             and not touch 0x70000000->0x7003FFFF */
1290         if ( boot_cpu_data.x86_vendor == X86_VENDOR_INTEL &&
1291              boot_cpu_data.x86 == 6 &&
1292              boot_cpu_data.x86_model == 1 &&
1293              boot_cpu_data.x86_mask <= 7 )
1294         {
1295             if ( base & ((1 << (22-PAGE_SHIFT))-1) )
1296             {
1297                 printk (KERN_WARNING "mtrr: base(0x%lx000) is not 4 MiB aligned\n", base);
1298                 return -EINVAL;
1299             }
1300             if (!(base + size < 0x70000000 || base > 0x7003FFFF) &&
1301                  (type == MTRR_TYPE_WRCOMB || type == MTRR_TYPE_WRBACK))
1302             {
1303                 printk (KERN_WARNING "mtrr: writable mtrr between 0x70000000 and 0x7003FFFF may hang the CPU.\n");
1304                 return -EINVAL;
1305             }
1306         }
1307         /* Fall through */
1308         
1309     case MTRR_IF_CYRIX_ARR:
1310     case MTRR_IF_CENTAUR_MCR:
1311         if ( mtrr_if == MTRR_IF_CENTAUR_MCR )
1312         {
1313             /*
1314              *  FIXME: Winchip2 supports uncached
1315              */
1316             if (type != MTRR_TYPE_WRCOMB && (centaur_mcr_type == 0 || type != MTRR_TYPE_UNCACHABLE))
1317             {
1318                 printk (KERN_WARNING "mtrr: only write-combining%s supported\n",
1319                         centaur_mcr_type?" and uncacheable are":" is");
1320                 return -EINVAL;
1321             }
1322         }
1323         else if (base + size < 0x100)
1324         {
1325             printk (KERN_WARNING "mtrr: cannot set region below 1 MiB (0x%lx000,0x%lx000)\n",
1326                     base, size);
1327             return -EINVAL;
1328         }
1329         /*  Check upper bits of base and last are equal and lower bits are 0
1330             for base and 1 for last  */
1331         last = base + size - 1;
1332         for (lbase = base; !(lbase & 1) && (last & 1);
1333              lbase = lbase >> 1, last = last >> 1);
1334         if (lbase != last)
1335         {
1336             printk (KERN_WARNING "mtrr: base(0x%lx000) is not aligned on a size(0x%lx000) boundary\n",
1337                     base, size);
1338             return -EINVAL;
1339         }
1340         break;
1341
1342     default:
1343         return -EINVAL;
1344     }
1345
1346     if (type >= MTRR_NUM_TYPES)
1347     {
1348         printk ("mtrr: type: %u illegal\n", type);
1349         return -EINVAL;
1350     }
1351
1352     /*  If the type is WC, check that this processor supports it  */
1353     if ( (type == MTRR_TYPE_WRCOMB) && !have_wrcomb () )
1354     {
1355         printk (KERN_WARNING "mtrr: your processor doesn't support write-combining\n");
1356         return -ENOSYS;
1357     }
1358
1359     if ( base & size_or_mask || size  & size_or_mask )
1360     {
1361         printk ("mtrr: base or size exceeds the MTRR width\n");
1362         return -EINVAL;
1363     }
1364
1365     increment = increment ? 1 : 0;
1366     max = get_num_var_ranges ();
1367     /*  Search for existing MTRR  */
1368     down(&main_lock);
1369     for (i = 0; i < max; ++i)
1370     {
1371         (*get_mtrr) (i, &lbase, &lsize, &ltype);
1372         if (base >= lbase + lsize) continue;
1373         if ( (base < lbase) && (base + size <= lbase) ) continue;
1374         /*  At this point we know there is some kind of overlap/enclosure  */
1375         if ( (base < lbase) || (base + size > lbase + lsize) )
1376         {
1377             up(&main_lock);
1378             printk (KERN_WARNING "mtrr: 0x%lx000,0x%lx000 overlaps existing"
1379                     " 0x%lx000,0x%lx000\n",
1380                     base, size, lbase, lsize);
1381             return -EINVAL;
1382         }
1383         /*  New region is enclosed by an existing region  */
1384         if (ltype != type)
1385         {
1386             if (type == MTRR_TYPE_UNCACHABLE) continue;
1387             up(&main_lock);
1388             printk ( "mtrr: type mismatch for %lx000,%lx000 old: %s new: %s\n",
1389                      base, size, attrib_to_str (ltype), attrib_to_str (type) );
1390             return -EINVAL;
1391         }
1392         if (increment) ++usage_table[i];
1393         compute_ascii ();
1394         up(&main_lock);
1395         return i;
1396     }
1397     /*  Search for an empty MTRR  */
1398     i = (*get_free_region) (base, size);
1399     if (i < 0)
1400     {
1401         up(&main_lock);
1402         printk ("mtrr: no more MTRRs available\n");
1403         return i;
1404     }
1405     set_mtrr (i, base, size, type);
1406     usage_table[i] = 1;
1407     compute_ascii ();
1408     up(&main_lock);
1409     return i;
1410 }   /*  End Function mtrr_add_page  */
1411
1412 /**
1413  *      mtrr_add - Add a memory type region
1414  *      @base: Physical base address of region
1415  *      @size: Physical size of region
1416  *      @type: Type of MTRR desired
1417  *      @increment: If this is true do usage counting on the region
1418  *
1419  *      Memory type region registers control the caching on newer Intel and
1420  *      non Intel processors. This function allows drivers to request an
1421  *      MTRR is added. The details and hardware specifics of each processor's
1422  *      implementation are hidden from the caller, but nevertheless the 
1423  *      caller should expect to need to provide a power of two size on an
1424  *      equivalent power of two boundary.
1425  *
1426  *      If the region cannot be added either because all regions are in use
1427  *      or the CPU cannot support it a negative value is returned. On success
1428  *      the register number for this entry is returned, but should be treated
1429  *      as a cookie only.
1430  *
1431  *      On a multiprocessor machine the changes are made to all processors.
1432  *      This is required on x86 by the Intel processors.
1433  *
1434  *      The available types are
1435  *
1436  *      %MTRR_TYPE_UNCACHABLE   -       No caching
1437  *
1438  *      %MTRR_TYPE_WRBACK       -       Write data back in bursts whenever
1439  *
1440  *      %MTRR_TYPE_WRCOMB       -       Write data back soon but allow bursts
1441  *
1442  *      %MTRR_TYPE_WRTHROUGH    -       Cache reads but not writes
1443  *
1444  *      BUGS: Needs a quiet flag for the cases where drivers do not mind
1445  *      failures and do not wish system log messages to be sent.
1446  */
1447
1448 int mtrr_add(unsigned long base, unsigned long size, unsigned int type, char increment)
1449 {
1450 /*  [SUMMARY] Add an MTRR entry.
1451     <base> The starting (base) address of the region.
1452     <size> The size (in bytes) of the region.
1453     <type> The type of the new region.
1454     <increment> If true and the region already exists, the usage count will be
1455     incremented.
1456     [RETURNS] The MTRR register on success, else a negative number indicating
1457     the error code.
1458 */
1459
1460     if ( (base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1)) )
1461     {
1462         printk ("mtrr: size and base must be multiples of 4 kiB\n");
1463         printk ("mtrr: size: 0x%lx  base: 0x%lx\n", size, base);
1464         return -EINVAL;
1465     }
1466     return mtrr_add_page(base >> PAGE_SHIFT, size >> PAGE_SHIFT, type, increment);
1467 }   /*  End Function mtrr_add  */
1468
1469 /**
1470  *      mtrr_del_page - delete a memory type region
1471  *      @reg: Register returned by mtrr_add
1472  *      @base: Physical base address
1473  *      @size: Size of region
1474  *
1475  *      If register is supplied then base and size are ignored. This is
1476  *      how drivers should call it.
1477  *
1478  *      Releases an MTRR region. If the usage count drops to zero the 
1479  *      register is freed and the region returns to default state.
1480  *      On success the register is returned, on failure a negative error
1481  *      code.
1482  */
1483  
1484 int mtrr_del_page (int reg, unsigned long base, unsigned long size)
1485 /*  [SUMMARY] Delete MTRR/decrement usage count.
1486     <reg> The register. If this is less than 0 then <<base>> and <<size>> must
1487     be supplied.
1488     <base> The base address of the region. This is ignored if <<reg>> is >= 0.
1489     <size> The size of the region. This is ignored if <<reg>> is >= 0.
1490     [RETURNS] The register on success, else a negative number indicating
1491     the error code.
1492     [NOTE] This routine uses a spinlock.
1493 */
1494 {
1495     int i, max;
1496     mtrr_type ltype;
1497     unsigned long lbase, lsize;
1498
1499     if ( mtrr_if == MTRR_IF_NONE ) return -ENXIO;
1500
1501     max = get_num_var_ranges ();
1502     down (&main_lock);
1503     if (reg < 0)
1504     {
1505         /*  Search for existing MTRR  */
1506         for (i = 0; i < max; ++i)
1507         {
1508             (*get_mtrr) (i, &lbase, &lsize, &ltype);
1509             if (lbase == base && lsize == size)
1510             {
1511                 reg = i;
1512                 break;
1513             }
1514         }
1515         if (reg < 0)
1516         {
1517             up(&main_lock);
1518             printk ("mtrr: no MTRR for %lx000,%lx000 found\n", base, size);
1519             return -EINVAL;
1520         }
1521     }
1522     if (reg >= max)
1523     {
1524         up (&main_lock);
1525         printk ("mtrr: register: %d too big\n", reg);
1526         return -EINVAL;
1527     }
1528     if ( mtrr_if == MTRR_IF_CYRIX_ARR )
1529     {
1530         if ( (reg == 3) && arr3_protected )
1531         {
1532             up (&main_lock);
1533             printk ("mtrr: ARR3 cannot be changed\n");
1534             return -EINVAL;
1535         }
1536     }
1537     (*get_mtrr) (reg, &lbase, &lsize, &ltype);
1538     if (lsize < 1)
1539     {
1540         up (&main_lock);
1541         printk ("mtrr: MTRR %d not used\n", reg);
1542         return -EINVAL;
1543     }
1544     if (usage_table[reg] < 1)
1545     {
1546         up (&main_lock);
1547         printk ("mtrr: reg: %d has count=0\n", reg);
1548         return -EINVAL;
1549     }
1550     if (--usage_table[reg] < 1) set_mtrr (reg, 0, 0, 0);
1551     compute_ascii ();
1552     up (&main_lock);
1553     return reg;
1554 }   /*  End Function mtrr_del_page  */
1555
1556 /**
1557  *      mtrr_del - delete a memory type region
1558  *      @reg: Register returned by mtrr_add
1559  *      @base: Physical base address
1560  *      @size: Size of region
1561  *
1562  *      If register is supplied then base and size are ignored. This is
1563  *      how drivers should call it.
1564  *
1565  *      Releases an MTRR region. If the usage count drops to zero the 
1566  *      register is freed and the region returns to default state.
1567  *      On success the register is returned, on failure a negative error
1568  *      code.
1569  */
1570  
1571 int mtrr_del (int reg, unsigned long base, unsigned long size)
1572 /*  [SUMMARY] Delete MTRR/decrement usage count.
1573     <reg> The register. If this is less than 0 then <<base>> and <<size>> must
1574     be supplied.
1575     <base> The base address of the region. This is ignored if <<reg>> is >= 0.
1576     <size> The size of the region. This is ignored if <<reg>> is >= 0.
1577     [RETURNS] The register on success, else a negative number indicating
1578     the error code.
1579 */
1580 {
1581     if ( (base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1)) )
1582     {
1583         printk ("mtrr: size and base must be multiples of 4 kiB\n");
1584         printk ("mtrr: size: 0x%lx  base: 0x%lx\n", size, base);
1585         return -EINVAL;
1586     }
1587     return mtrr_del_page(reg, base >> PAGE_SHIFT, size >> PAGE_SHIFT);
1588 }
1589
1590 #ifdef USERSPACE_INTERFACE
1591
1592 static int mtrr_file_add (unsigned long base, unsigned long size,
1593                           unsigned int type, char increment, struct file *file, int page)
1594 {
1595     int reg, max;
1596     unsigned int *fcount = file->private_data;
1597
1598     max = get_num_var_ranges ();
1599     if (fcount == NULL)
1600     {
1601         if ( ( fcount = kmalloc (max * sizeof *fcount, GFP_KERNEL) ) == NULL )
1602         {
1603             printk ("mtrr: could not allocate\n");
1604             return -ENOMEM;
1605         }
1606         memset (fcount, 0, max * sizeof *fcount);
1607         file->private_data = fcount;
1608     }
1609     if (!page) {
1610         if ( (base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1)) )
1611         {
1612             printk ("mtrr: size and base must be multiples of 4 kiB\n");
1613             printk ("mtrr: size: 0x%lx  base: 0x%lx\n", size, base);
1614             return -EINVAL;
1615         }
1616         base >>= PAGE_SHIFT;
1617         size >>= PAGE_SHIFT;
1618     }
1619     reg = mtrr_add_page (base, size, type, 1);
1620     if (reg >= 0) ++fcount[reg];
1621     return reg;
1622 }   /*  End Function mtrr_file_add  */
1623
1624 static int mtrr_file_del (unsigned long base, unsigned long size,
1625                           struct file *file, int page)
1626 {
1627     int reg;
1628     unsigned int *fcount = file->private_data;
1629
1630     if (!page) {
1631         if ( (base & (PAGE_SIZE - 1)) || (size & (PAGE_SIZE - 1)) )
1632         {
1633             printk ("mtrr: size and base must be multiples of 4 kiB\n");
1634             printk ("mtrr: size: 0x%lx  base: 0x%lx\n", size, base);
1635             return -EINVAL;
1636         }
1637         base >>= PAGE_SHIFT;
1638         size >>= PAGE_SHIFT;
1639     }
1640     reg = mtrr_del_page (-1, base, size);
1641     if (reg < 0) return reg;
1642     if (fcount == NULL) return reg;
1643     if (fcount[reg] < 1) return -EINVAL;
1644     --fcount[reg];
1645     return reg;
1646 }   /*  End Function mtrr_file_del  */
1647
1648 static ssize_t mtrr_read (struct file *file, char *buf, size_t len,
1649                           loff_t *ppos)
1650 {
1651         loff_t pos = *ppos;
1652         if (pos < 0 || pos >= ascii_buf_bytes)
1653                 return 0;
1654         if (len > ascii_buf_bytes - pos)
1655                 len = ascii_buf_bytes - pos;
1656         if (copy_to_user(buf, ascii_buffer + pos, len))
1657                 return -EFAULT;
1658         pos += len;
1659         *ppos = pos;
1660
1661         return len;
1662 }   /*  End Function mtrr_read  */
1663
1664 static ssize_t mtrr_write (struct file *file, const char *buf, size_t len,
1665                            loff_t *ppos)
1666 /*  Format of control line:
1667     "base=%Lx size=%Lx type=%s"     OR:
1668     "disable=%d"
1669 */
1670 {
1671     int i, err;
1672     unsigned long reg;
1673     unsigned long long base, size;
1674     char *ptr;
1675     char line[LINE_SIZE];
1676
1677     if (!len) return -EINVAL;
1678     if ( !suser () ) return -EPERM;
1679     /*  Can't seek (pwrite) on this device  */
1680     if (ppos != &file->f_pos) return -ESPIPE;
1681     memset (line, 0, LINE_SIZE);
1682     if (len > LINE_SIZE) len = LINE_SIZE;
1683     if ( copy_from_user (line, buf, len - 1) ) return -EFAULT;
1684     ptr = line + strlen (line) - 1;
1685     if (*ptr == '\n') *ptr = '\0';
1686     if ( !strncmp (line, "disable=", 8) )
1687     {
1688         reg = simple_strtoul (line + 8, &ptr, 0);
1689         err = mtrr_del_page (reg, 0, 0);
1690         if (err < 0) return err;
1691         return len;
1692     }
1693     if ( strncmp (line, "base=", 5) )
1694     {
1695         printk ("mtrr: no \"base=\" in line: \"%s\"\n", line);
1696         return -EINVAL;
1697     }
1698     base = simple_strtoull (line + 5, &ptr, 0);
1699     for (; isspace (*ptr); ++ptr);
1700     if ( strncmp (ptr, "size=", 5) )
1701     {
1702         printk ("mtrr: no \"size=\" in line: \"%s\"\n", line);
1703         return -EINVAL;
1704     }
1705     size = simple_strtoull (ptr + 5, &ptr, 0);
1706     if ( (base & 0xfff) || (size & 0xfff) )
1707     {
1708         printk ("mtrr: size and base must be multiples of 4 kiB\n");
1709         printk ("mtrr: size: 0x%Lx  base: 0x%Lx\n", size, base);
1710         return -EINVAL;
1711     }
1712     for (; isspace (*ptr); ++ptr);
1713     if ( strncmp (ptr, "type=", 5) )
1714     {
1715         printk ("mtrr: no \"type=\" in line: \"%s\"\n", line);
1716         return -EINVAL;
1717     }
1718     ptr += 5;
1719     for (; isspace (*ptr); ++ptr);
1720     for (i = 0; i < MTRR_NUM_TYPES; ++i)
1721     {
1722         if ( strcmp (ptr, mtrr_strings[i]) ) continue;
1723         base >>= PAGE_SHIFT;
1724         size >>= PAGE_SHIFT;
1725         err = mtrr_add_page ((unsigned long)base, (unsigned long)size, i, 1);
1726         if (err < 0) return err;
1727         return len;
1728     }
1729     printk ("mtrr: illegal type: \"%s\"\n", ptr);
1730     return -EINVAL;
1731 }   /*  End Function mtrr_write  */
1732
1733 static int mtrr_ioctl (struct inode *inode, struct file *file,
1734                        unsigned int cmd, unsigned long arg)
1735 {
1736     int err;
1737     mtrr_type type;
1738     struct mtrr_sentry sentry;
1739     struct mtrr_gentry gentry;
1740
1741     switch (cmd)
1742     {
1743       default:
1744         return -ENOIOCTLCMD;
1745       case MTRRIOC_ADD_ENTRY:
1746         if ( !suser () ) return -EPERM;
1747         if ( copy_from_user (&sentry, (void *) arg, sizeof sentry) )
1748             return -EFAULT;
1749         err = mtrr_file_add (sentry.base, sentry.size, sentry.type, 1, file, 0);
1750         if (err < 0) return err;
1751         break;
1752       case MTRRIOC_SET_ENTRY:
1753         if ( !suser () ) return -EPERM;
1754         if ( copy_from_user (&sentry, (void *) arg, sizeof sentry) )
1755             return -EFAULT;
1756         err = mtrr_add (sentry.base, sentry.size, sentry.type, 0);
1757         if (err < 0) return err;
1758         break;
1759       case MTRRIOC_DEL_ENTRY:
1760         if ( !suser () ) return -EPERM;
1761         if ( copy_from_user (&sentry, (void *) arg, sizeof sentry) )
1762             return -EFAULT;
1763         err = mtrr_file_del (sentry.base, sentry.size, file, 0);
1764         if (err < 0) return err;
1765         break;
1766       case MTRRIOC_KILL_ENTRY:
1767         if ( !suser () ) return -EPERM;
1768         if ( copy_from_user (&sentry, (void *) arg, sizeof sentry) )
1769             return -EFAULT;
1770         err = mtrr_del (-1, sentry.base, sentry.size);
1771         if (err < 0) return err;
1772         break;
1773       case MTRRIOC_GET_ENTRY:
1774         if ( copy_from_user (&gentry, (void *) arg, sizeof gentry) )
1775             return -EFAULT;
1776         if ( gentry.regnum >= get_num_var_ranges () ) return -EINVAL;
1777         (*get_mtrr) (gentry.regnum, &gentry.base, &gentry.size, &type);
1778
1779         /* Hide entries that go above 4GB */
1780         if (gentry.base + gentry.size > 0x100000 || gentry.size == 0x100000)
1781             gentry.base = gentry.size = gentry.type = 0;
1782         else {
1783             gentry.base <<= PAGE_SHIFT;
1784             gentry.size <<= PAGE_SHIFT;
1785             gentry.type = type;
1786         }
1787
1788         if ( copy_to_user ( (void *) arg, &gentry, sizeof gentry) )
1789              return -EFAULT;
1790         break;
1791       case MTRRIOC_ADD_PAGE_ENTRY:
1792         if ( !suser () ) return -EPERM;
1793         if ( copy_from_user (&sentry, (void *) arg, sizeof sentry) )
1794             return -EFAULT;
1795         err = mtrr_file_add (sentry.base, sentry.size, sentry.type, 1, file, 1);
1796         if (err < 0) return err;
1797         break;
1798       case MTRRIOC_SET_PAGE_ENTRY:
1799         if ( !suser () ) return -EPERM;
1800         if ( copy_from_user (&sentry, (void *) arg, sizeof sentry) )
1801             return -EFAULT;
1802         err = mtrr_add_page (sentry.base, sentry.size, sentry.type, 0);
1803         if (err < 0) return err;
1804         break;
1805       case MTRRIOC_DEL_PAGE_ENTRY:
1806         if ( !suser () ) return -EPERM;
1807         if ( copy_from_user (&sentry, (void *) arg, sizeof sentry) )
1808             return -EFAULT;
1809         err = mtrr_file_del (sentry.base, sentry.size, file, 1);
1810         if (err < 0) return err;
1811         break;
1812       case MTRRIOC_KILL_PAGE_ENTRY:
1813         if ( !suser () ) return -EPERM;
1814         if ( copy_from_user (&sentry, (void *) arg, sizeof sentry) )
1815             return -EFAULT;
1816         err = mtrr_del_page (-1, sentry.base, sentry.size);
1817         if (err < 0) return err;
1818         break;
1819       case MTRRIOC_GET_PAGE_ENTRY:
1820         if ( copy_from_user (&gentry, (void *) arg, sizeof gentry) )
1821             return -EFAULT;
1822         if ( gentry.regnum >= get_num_var_ranges () ) return -EINVAL;
1823         (*get_mtrr) (gentry.regnum, &gentry.base, &gentry.size, &type);
1824         gentry.type = type;
1825
1826         if ( copy_to_user ( (void *) arg, &gentry, sizeof gentry) )
1827              return -EFAULT;
1828         break;
1829     }
1830     return 0;
1831 }   /*  End Function mtrr_ioctl  */
1832
1833 static int mtrr_close (struct inode *ino, struct file *file)
1834 {
1835     int i, max;
1836     unsigned int *fcount = file->private_data;
1837
1838     if (fcount == NULL) return 0;
1839     lock_kernel();
1840     max = get_num_var_ranges ();
1841     for (i = 0; i < max; ++i)
1842     {
1843         while (fcount[i] > 0)
1844         {
1845             if (mtrr_del (i, 0, 0) < 0) printk ("mtrr: reg %d not used\n", i);
1846             --fcount[i];
1847         }
1848     }
1849     unlock_kernel();
1850     kfree (fcount);
1851     file->private_data = NULL;
1852     return 0;
1853 }   /*  End Function mtrr_close  */
1854
1855 static struct file_operations mtrr_fops =
1856 {
1857     owner:      THIS_MODULE,
1858     read:       mtrr_read,
1859     write:      mtrr_write,
1860     ioctl:      mtrr_ioctl,
1861     release:    mtrr_close,
1862 };
1863
1864 #  ifdef CONFIG_PROC_FS
1865
1866 static struct proc_dir_entry *proc_root_mtrr;
1867
1868 #  endif  /*  CONFIG_PROC_FS  */
1869
1870 static devfs_handle_t devfs_handle;
1871
1872 static void compute_ascii (void)
1873 {
1874     char factor;
1875     int i, max;
1876     mtrr_type type;
1877     unsigned long base, size;
1878
1879     ascii_buf_bytes = 0;
1880     max = get_num_var_ranges ();
1881     for (i = 0; i < max; i++)
1882     {
1883         (*get_mtrr) (i, &base, &size, &type);
1884         if (size == 0) usage_table[i] = 0;
1885         else
1886         {
1887             if (size < (0x100000 >> PAGE_SHIFT))
1888             {
1889                 /* less than 1MB */
1890                 factor = 'K';
1891                 size <<= PAGE_SHIFT - 10;
1892             }
1893             else
1894             {
1895                 factor = 'M';
1896                 size >>= 20 - PAGE_SHIFT;
1897             }
1898             sprintf
1899                 (ascii_buffer + ascii_buf_bytes,
1900                  "reg%02i: base=0x%05lx000 (%4liMB), size=%4li%cB: %s, count=%d\n",
1901                  i, base, base >> (20 - PAGE_SHIFT), size, factor,
1902                  attrib_to_str (type), usage_table[i]);
1903             ascii_buf_bytes += strlen (ascii_buffer + ascii_buf_bytes);
1904         }
1905     }
1906     devfs_set_file_size (devfs_handle, ascii_buf_bytes);
1907 #  ifdef CONFIG_PROC_FS
1908     if (proc_root_mtrr)
1909         proc_root_mtrr->size = ascii_buf_bytes;
1910 #  endif  /*  CONFIG_PROC_FS  */
1911 }   /*  End Function compute_ascii  */
1912
1913 #endif  /*  USERSPACE_INTERFACE  */
1914
1915 EXPORT_SYMBOL(mtrr_add);
1916 EXPORT_SYMBOL(mtrr_del);
1917
1918 #ifdef CONFIG_SMP
1919
1920 typedef struct
1921 {
1922     unsigned long base;
1923     unsigned long size;
1924     mtrr_type type;
1925 } arr_state_t;
1926
1927 arr_state_t arr_state[8] __initdata =
1928 {
1929     {0UL,0UL,0UL}, {0UL,0UL,0UL}, {0UL,0UL,0UL}, {0UL,0UL,0UL},
1930     {0UL,0UL,0UL}, {0UL,0UL,0UL}, {0UL,0UL,0UL}, {0UL,0UL,0UL}
1931 };
1932
1933 unsigned char ccr_state[7] __initdata = { 0, 0, 0, 0, 0, 0, 0 };
1934
1935 static void __init cyrix_arr_init_secondary(void)
1936 {
1937     struct set_mtrr_context ctxt;
1938     int i;
1939
1940     /* flush cache and enable MAPEN */
1941     set_mtrr_prepare_save (&ctxt);
1942     set_mtrr_disable (&ctxt);
1943
1944      /* the CCRs are not contiguous */
1945     for(i=0; i<4; i++) setCx86(CX86_CCR0 + i, ccr_state[i]);
1946     for(   ; i<7; i++) setCx86(CX86_CCR4 + i, ccr_state[i]);
1947     for(i=0; i<8; i++)
1948       cyrix_set_arr_up(i,
1949         arr_state[i].base, arr_state[i].size, arr_state[i].type, FALSE);
1950
1951     set_mtrr_done (&ctxt); /* flush cache and disable MAPEN */
1952 }   /*  End Function cyrix_arr_init_secondary  */
1953
1954 #endif
1955
1956 /*
1957  * On Cyrix 6x86(MX) and M II the ARR3 is special: it has connection
1958  * with the SMM (System Management Mode) mode. So we need the following:
1959  * Check whether SMI_LOCK (CCR3 bit 0) is set
1960  *   if it is set, write a warning message: ARR3 cannot be changed!
1961  *     (it cannot be changed until the next processor reset)
1962  *   if it is reset, then we can change it, set all the needed bits:
1963  *   - disable access to SMM memory through ARR3 range (CCR1 bit 7 reset)
1964  *   - disable access to SMM memory (CCR1 bit 2 reset)
1965  *   - disable SMM mode (CCR1 bit 1 reset)
1966  *   - disable write protection of ARR3 (CCR6 bit 1 reset)
1967  *   - (maybe) disable ARR3
1968  * Just to be sure, we enable ARR usage by the processor (CCR5 bit 5 set)
1969  */
1970 static void __init cyrix_arr_init(void)
1971 {
1972     struct set_mtrr_context ctxt;
1973     unsigned char ccr[7];
1974     int ccrc[7] = { 0, 0, 0, 0, 0, 0, 0 };
1975 #ifdef CONFIG_SMP
1976     int i;
1977 #endif
1978
1979     /* flush cache and enable MAPEN */
1980     set_mtrr_prepare_save (&ctxt);
1981     set_mtrr_disable (&ctxt);
1982
1983     /* Save all CCRs locally */
1984     ccr[0] = getCx86 (CX86_CCR0);
1985     ccr[1] = getCx86 (CX86_CCR1);
1986     ccr[2] = getCx86 (CX86_CCR2);
1987     ccr[3] = ctxt.ccr3;
1988     ccr[4] = getCx86 (CX86_CCR4);
1989     ccr[5] = getCx86 (CX86_CCR5);
1990     ccr[6] = getCx86 (CX86_CCR6);
1991
1992     if (ccr[3] & 1)
1993     {
1994         ccrc[3] = 1;
1995         arr3_protected = 1;
1996     }
1997     else
1998     {
1999         /* Disable SMM mode (bit 1), access to SMM memory (bit 2) and
2000          * access to SMM memory through ARR3 (bit 7).
2001          */
2002         if (ccr[1] & 0x80) { ccr[1] &= 0x7f; ccrc[1] |= 0x80; }
2003         if (ccr[1] & 0x04) { ccr[1] &= 0xfb; ccrc[1] |= 0x04; }
2004         if (ccr[1] & 0x02) { ccr[1] &= 0xfd; ccrc[1] |= 0x02; }
2005         arr3_protected = 0;
2006         if (ccr[6] & 0x02) {
2007             ccr[6] &= 0xfd; ccrc[6] = 1; /* Disable write protection of ARR3 */
2008             setCx86 (CX86_CCR6, ccr[6]);
2009         }
2010         /* Disable ARR3. This is safe now that we disabled SMM. */
2011         /* cyrix_set_arr_up (3, 0, 0, 0, FALSE); */
2012     }
2013     /* If we changed CCR1 in memory, change it in the processor, too. */
2014     if (ccrc[1]) setCx86 (CX86_CCR1, ccr[1]);
2015
2016     /* Enable ARR usage by the processor */
2017     if (!(ccr[5] & 0x20))
2018     {
2019         ccr[5] |= 0x20; ccrc[5] = 1;
2020         setCx86 (CX86_CCR5, ccr[5]);
2021     }
2022
2023 #ifdef CONFIG_SMP
2024     for(i=0; i<7; i++) ccr_state[i] = ccr[i];
2025     for(i=0; i<8; i++)
2026       cyrix_get_arr(i,
2027         &arr_state[i].base, &arr_state[i].size, &arr_state[i].type);
2028 #endif
2029
2030     set_mtrr_done (&ctxt); /* flush cache and disable MAPEN */
2031
2032     if ( ccrc[5] ) printk ("mtrr: ARR usage was not enabled, enabled manually\n");
2033     if ( ccrc[3] ) printk ("mtrr: ARR3 cannot be changed\n");
2034 /*
2035     if ( ccrc[1] & 0x80) printk ("mtrr: SMM memory access through ARR3 disabled\n");
2036     if ( ccrc[1] & 0x04) printk ("mtrr: SMM memory access disabled\n");
2037     if ( ccrc[1] & 0x02) printk ("mtrr: SMM mode disabled\n");
2038 */
2039     if ( ccrc[6] ) printk ("mtrr: ARR3 was write protected, unprotected\n");
2040 }   /*  End Function cyrix_arr_init  */
2041
2042 /*
2043  *      Initialise the later (saner) Winchip MCR variant. In this version
2044  *      the BIOS can pass us the registers it has used (but not their values)
2045  *      and the control register is read/write
2046  */
2047  
2048 static void __init centaur_mcr1_init(void)
2049 {
2050     unsigned i;
2051     u32 lo, hi;
2052
2053     /* Unfortunately, MCR's are read-only, so there is no way to
2054      * find out what the bios might have done.
2055      */
2056      
2057     rdmsr(MSR_IDT_MCR_CTRL, lo, hi);
2058     if(((lo>>17)&7)==1)         /* Type 1 Winchip2 MCR */
2059     {
2060         lo&= ~0x1C0;            /* clear key */
2061         lo|= 0x040;             /* set key to 1 */
2062         wrmsr(MSR_IDT_MCR_CTRL, lo, hi);        /* unlock MCR */
2063     }    
2064     
2065     centaur_mcr_type = 1;
2066     
2067     /*
2068      *  Clear any unconfigured MCR's.
2069      */
2070
2071     for (i = 0; i < 8; ++i)
2072     {
2073         if(centaur_mcr[i]. high == 0 && centaur_mcr[i].low == 0)
2074         {
2075                 if(!(lo & (1<<(9+i))))
2076                         wrmsr (MSR_IDT_MCR0 + i , 0, 0);
2077                 else
2078                         /*
2079                          *      If the BIOS set up an MCR we cannot see it
2080                          *      but we don't wish to obliterate it
2081                          */
2082                         centaur_mcr_reserved |= (1<<i);
2083         }
2084     }
2085     /*  
2086      *  Throw the main write-combining switch... 
2087      *  However if OOSTORE is enabled then people have already done far
2088      *  cleverer things and we should behave. 
2089      */
2090
2091     lo |= 15;                   /* Write combine enables */
2092     wrmsr(MSR_IDT_MCR_CTRL, lo, hi);
2093 }   /*  End Function centaur_mcr1_init  */
2094
2095 /*
2096  *      Initialise the original winchip with read only MCR registers
2097  *      no used bitmask for the BIOS to pass on and write only control
2098  */
2099  
2100 static void __init centaur_mcr0_init(void)
2101 {
2102     unsigned i;
2103
2104     /* Unfortunately, MCR's are read-only, so there is no way to
2105      * find out what the bios might have done.
2106      */
2107      
2108     /* Clear any unconfigured MCR's.
2109      * This way we are sure that the centaur_mcr array contains the actual
2110      * values. The disadvantage is that any BIOS tweaks are thus undone.
2111      *
2112      */
2113     for (i = 0; i < 8; ++i)
2114     {
2115         if(centaur_mcr[i]. high == 0 && centaur_mcr[i].low == 0)
2116                 wrmsr (MSR_IDT_MCR0 + i , 0, 0);
2117     }
2118
2119     wrmsr(MSR_IDT_MCR_CTRL, 0x01F0001F, 0);     /* Write only */
2120 }   /*  End Function centaur_mcr0_init  */
2121
2122 /*
2123  *      Initialise Winchip series MCR registers
2124  */
2125  
2126 static void __init centaur_mcr_init(void)
2127 {
2128     struct set_mtrr_context ctxt;
2129
2130     set_mtrr_prepare_save (&ctxt);
2131     set_mtrr_disable (&ctxt);
2132
2133     if(boot_cpu_data.x86_model==4)
2134         centaur_mcr0_init();
2135     else if(boot_cpu_data.x86_model==8 || boot_cpu_data.x86_model == 9)
2136         centaur_mcr1_init();
2137
2138     set_mtrr_done (&ctxt);
2139 }   /*  End Function centaur_mcr_init  */
2140
2141 static int __init mtrr_setup(void)
2142 {
2143     if ( test_bit(X86_FEATURE_MTRR, &boot_cpu_data.x86_capability) ) {
2144         /* Intel (P6) standard MTRRs */
2145         mtrr_if = MTRR_IF_INTEL;
2146         get_mtrr = intel_get_mtrr;
2147         set_mtrr_up = intel_set_mtrr_up;
2148         switch (boot_cpu_data.x86_vendor) {
2149
2150         case X86_VENDOR_AMD:
2151                 /* The original Athlon docs said that
2152                    total addressable memory is 44 bits wide.
2153                    It was not really clear whether its MTRRs
2154                    follow this or not. (Read: 44 or 36 bits).
2155                    However, "x86-64_overview.pdf" explicitly
2156                    states that "previous implementations support
2157                    36 bit MTRRs" and also provides a way to
2158                    query the width (in bits) of the physical
2159                    addressable memory on the Hammer family.
2160                  */
2161                 if (boot_cpu_data.x86 == 15 && (cpuid_eax(0x80000000) >= 0x80000008)) {
2162                         u32     phys_addr;
2163                         phys_addr = cpuid_eax(0x80000008) & 0xff ;
2164                         size_or_mask = ~((1 << (phys_addr - PAGE_SHIFT)) - 1);
2165                         size_and_mask = ~size_or_mask & 0xfff00000;
2166                         break;
2167                 }
2168                 size_or_mask  = 0xff000000; /* 36 bits */
2169                 size_and_mask = 0x00f00000;
2170                 break;
2171
2172         case X86_VENDOR_CENTAUR:
2173                 /* VIA Cyrix family have Intel style MTRRs, but don't support PAE */
2174                 if (boot_cpu_data.x86 == 6) {
2175                         size_or_mask  = 0xfff00000; /* 32 bits */
2176                         size_and_mask = 0;
2177                 }
2178                 break;
2179
2180         default:
2181                 /* Intel, etc. */
2182                 size_or_mask  = 0xff000000; /* 36 bits */
2183                 size_and_mask = 0x00f00000;
2184                 break;
2185         }
2186
2187     } else if ( test_bit(X86_FEATURE_K6_MTRR, &boot_cpu_data.x86_capability) ) {
2188         /* Pre-Athlon (K6) AMD CPU MTRRs */
2189         mtrr_if = MTRR_IF_AMD_K6;
2190         get_mtrr = amd_get_mtrr;
2191         set_mtrr_up = amd_set_mtrr_up;
2192         size_or_mask  = 0xfff00000; /* 32 bits */
2193         size_and_mask = 0;
2194     } else if ( test_bit(X86_FEATURE_CYRIX_ARR, &boot_cpu_data.x86_capability) ) {
2195         /* Cyrix ARRs */
2196         mtrr_if = MTRR_IF_CYRIX_ARR;
2197         get_mtrr = cyrix_get_arr;
2198         set_mtrr_up = cyrix_set_arr_up;
2199         get_free_region = cyrix_get_free_region;
2200         cyrix_arr_init();
2201         size_or_mask  = 0xfff00000; /* 32 bits */
2202         size_and_mask = 0;
2203     } else if ( test_bit(X86_FEATURE_CENTAUR_MCR, &boot_cpu_data.x86_capability) ) {
2204         /* Centaur MCRs */
2205         mtrr_if = MTRR_IF_CENTAUR_MCR;
2206         get_mtrr = centaur_get_mcr;
2207         set_mtrr_up = centaur_set_mcr_up;
2208         get_free_region = centaur_get_free_region;
2209         centaur_mcr_init();
2210         size_or_mask  = 0xfff00000; /* 32 bits */
2211         size_and_mask = 0;
2212     } else {
2213         /* No supported MTRR interface */
2214         mtrr_if = MTRR_IF_NONE;
2215     }
2216
2217     printk ("mtrr: v%s Richard Gooch (rgooch@atnf.csiro.au)\n"
2218             "mtrr: detected mtrr type: %s\n",
2219             MTRR_VERSION, mtrr_if_name[mtrr_if]);
2220
2221     return (mtrr_if != MTRR_IF_NONE);
2222 }   /*  End Function mtrr_setup  */
2223
2224 #ifdef CONFIG_SMP
2225
2226 static volatile unsigned long smp_changes_mask __initdata = 0;
2227 static struct mtrr_state smp_mtrr_state __initdata = {0, 0};
2228
2229 void __init mtrr_init_boot_cpu(void)
2230 {
2231     if ( !mtrr_setup () )
2232         return;
2233
2234     if ( mtrr_if == MTRR_IF_INTEL ) {
2235         /* Only for Intel MTRRs */
2236         get_mtrr_state (&smp_mtrr_state);
2237     }
2238 }   /*  End Function mtrr_init_boot_cpu  */
2239
2240 static void __init intel_mtrr_init_secondary_cpu(void)
2241 {
2242     unsigned long mask, count;
2243     struct set_mtrr_context ctxt;
2244
2245     /*  Note that this is not ideal, since the cache is only flushed/disabled
2246         for this CPU while the MTRRs are changed, but changing this requires
2247         more invasive changes to the way the kernel boots  */
2248     set_mtrr_prepare_save (&ctxt);
2249     set_mtrr_disable (&ctxt);
2250     mask = set_mtrr_state (&smp_mtrr_state, &ctxt);
2251     set_mtrr_done (&ctxt);
2252     /*  Use the atomic bitops to update the global mask  */
2253     for (count = 0; count < sizeof mask * 8; ++count)
2254     {
2255         if (mask & 0x01) set_bit (count, &smp_changes_mask);
2256         mask >>= 1;
2257     }
2258 }   /*  End Function intel_mtrr_init_secondary_cpu  */
2259
2260 void __init mtrr_init_secondary_cpu(void)
2261 {
2262     switch ( mtrr_if ) {
2263     case MTRR_IF_INTEL:
2264         /* Intel (P6) standard MTRRs */
2265         intel_mtrr_init_secondary_cpu();
2266         break;
2267     case MTRR_IF_CYRIX_ARR:
2268         /* This is _completely theoretical_!
2269          * I assume here that one day Cyrix will support Intel APIC.
2270          * In reality on non-Intel CPUs we won't even get to this routine.
2271          * Hopefully no one will plug two Cyrix processors in a dual P5 board.
2272          *  :-)
2273          */
2274         cyrix_arr_init_secondary ();
2275         break;
2276     case MTRR_IF_NONE:
2277         break;
2278     default:
2279         /* I see no MTRRs I can support in SMP mode... */
2280         printk ("mtrr: SMP support incomplete for this vendor\n");
2281     }
2282 }   /*  End Function mtrr_init_secondary_cpu  */
2283 #endif  /*  CONFIG_SMP  */
2284
2285 int __init mtrr_init(void)
2286 {
2287 #ifdef CONFIG_SMP
2288     /* mtrr_setup() should already have been called from mtrr_init_boot_cpu() */
2289
2290     if ( mtrr_if == MTRR_IF_INTEL ) {
2291         finalize_mtrr_state (&smp_mtrr_state);
2292         mtrr_state_warn (smp_changes_mask);
2293     }
2294 #else
2295     if ( !mtrr_setup() )
2296         return 0;               /* MTRRs not supported? */
2297 #endif
2298
2299 #ifdef CONFIG_PROC_FS
2300     proc_root_mtrr = create_proc_entry ("mtrr", S_IWUSR | S_IRUGO, &proc_root);
2301     if (proc_root_mtrr) {
2302         proc_root_mtrr->owner = THIS_MODULE;
2303         proc_root_mtrr->proc_fops = &mtrr_fops;
2304     }
2305 #endif
2306 #ifdef USERSPACE_INTERFACE
2307     devfs_handle = devfs_register (NULL, "cpu/mtrr", DEVFS_FL_DEFAULT, 0, 0,
2308                                    S_IFREG | S_IRUGO | S_IWUSR,
2309                                    &mtrr_fops, NULL);
2310 #endif
2311     init_table ();
2312     return 0;
2313 }   /*  End Function mtrr_init  */
2314
2315 /*
2316  * Local Variables:
2317  * mode:c
2318  * c-file-style:"k&r"
2319  * c-basic-offset:4
2320  * End:
2321  */